diff -Nru trac-authopenid-0.4.1/authopenid/authopenid.py trac-authopenid-0.4.7/authopenid/authopenid.py --- trac-authopenid-0.4.1/authopenid/authopenid.py 2012-06-25 21:06:18.000000000 +0000 +++ trac-authopenid-0.4.7/authopenid/authopenid.py 2013-12-06 14:59:25.000000000 +0000 @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2007 Dalius Dobravolskas +# Copyright (C) 2007-2013 Dalius Dobravolskas and Geoffrey T. Dairiki # All rights reserved. # # This software is licensed using the same licence as Trac: # http://trac.edgewall.org/wiki/TracLicense. # -# Author: Dalius Dobravolskas -# +# Original Author: Dalius Dobravolskas +# Current Maintainer: Jeff Dairiki + # Most probably you will want to add following lines to your configuration file: # # [components] @@ -22,10 +23,11 @@ import itertools from trac.core import * -from trac.config import Option, BoolOption, IntOption +from trac.config import Option, BoolOption, ListOption from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet, add_script from trac.env import IEnvironmentSetupParticipant from trac.web.main import IRequestHandler, IAuthenticator +from trac.perm import IPermissionGroupProvider, PermissionSystem from trac.web.session import DetachedSession try: from acct_mgr.web_ui import LoginModule @@ -40,8 +42,11 @@ from openid.consumer import consumer from openid.extensions import sreg, pape, ax - from openid import oidutil +try: + from openid_teams.teams import TeamsRequest, TeamsResponse +except ImportError: + TeamsRequest = TeamsResponse = None import socket import struct @@ -73,7 +78,8 @@ lastname='http://axschema.org/namePerson/last', ) - implements(INavigationContributor, IRequestHandler, ITemplateProvider, IAuthenticator, IEnvironmentSetupParticipant) + implements(INavigationContributor, IRequestHandler, ITemplateProvider, IAuthenticator, IEnvironmentSetupParticipant, + IPermissionGroupProvider) # Do not declare options in the [trac] section. We should not # be creating new declared options there, and we should not be @@ -132,6 +138,18 @@ is backwards-incompatible if you already have user sessions which you would like to preserve. """) + use_nickname_as_authname = BoolOption('openid', 'use_nickname_as_authname', False, + """ Whether the nickname as retrieved by SReg is used as username""") + + trust_authname = BoolOption('openid', 'trust_authname', False, + """WARNING: Only enable this if you know what this mean! + This could make identity theft very easy if you do not control the OpenID provider! + Enabling this option makes the retrieved authname from the + OpenID provider authorative, i.e. it trusts the authname + to be the unique username of the user. Enabling this disables + the collision checking, so it may be possible to take over + an existing username or permission group.""") + pape_method = Option('openid', 'pape_method', None, """Default PAPE method to request from OpenID provider.""") @@ -180,6 +198,12 @@ custom_provider_size = Option('openid', 'custom_provider_size', 'small', """ Custom OpenId provider image size (small or large).""") + groups_to_request = ListOption('openid', 'groups_to_request', '', + doc=""" Which 'team names' to request via the OpenIDTeams extension. + To use this option you must have python-openid-teams installed. + """) + + def _get_masked_address(self, address): if self.check_ip: @@ -231,6 +255,12 @@ if type(store) is not MemoryStore: store.createTables() + # IPermissionGroupProvider methods + def get_permission_groups(self, username): + ds = DetachedSession(self.env, username) + return ds.get('openid.teams', '').split(',') + + # IEnvironmentSetupParticipant methods def environment_created(self): @@ -327,7 +357,7 @@ 'custom_provider_size': self.custom_provider_size, }, None - def _get_session(self, req): + def _get_oidsession(self, req): """Returns a session dict that can store any kind of object.""" try: return cPickle.loads(str(req.session[self.openid_session_key])) @@ -346,11 +376,11 @@ return base_url - def _commit_session(self, session, req): - req.session[self.openid_session_key] = str(cPickle.dumps(session)) + def _commit_oidsession(self, oidsession, req): + req.session[self.openid_session_key] = str(cPickle.dumps(oidsession)) def _get_consumer(self, req, db): - s = self._get_session(req) + s = self._get_oidsession(req) if 'id' not in s: s['id'] = req.session.sid store = self._getStore(db) @@ -385,7 +415,7 @@ immediate = 'immediate' in req.args db = self.env.get_db_cnx() - oidconsumer, session = self._get_consumer(req, db) + oidconsumer, oidsession = self._get_consumer(req, db) try: self.env.log.debug('beginning OpenID authentication.') request = oidconsumer.begin(openid_url) @@ -425,7 +455,7 @@ 'custom_provider_size': self.custom_provider_size, }, None else: - self._commit_session(session, req) + self._commit_oidsession(oidsession, req) # Then, ask the library to begin the authorization. # Here we find out the identity server that will verify the # user's identity, and get a token that allows us to @@ -451,6 +481,8 @@ sreg_req = sreg_fields else: sreg_opt = sreg_fields + if self.use_nickname_as_authname: + sreg_req.append('nickname') sreg_request = sreg.SRegRequest(optional=sreg_opt, required=sreg_req) request.addExtension(sreg_request) @@ -460,6 +492,16 @@ ax_request.add(attr_info) request.addExtension(ax_request) + if self.groups_to_request: + if not TeamsRequest: + self.env.log.error( + 'The python-openid-teams package is not installed.' + ' The groups_to_request configuration option will' + ' be ignored.') + else: + request.addExtension( + TeamsRequest(requested=self.groups_to_request)) + trust_root = self._get_trust_root(req) if self.absolute_trust_root: trust_root += '/' @@ -482,17 +524,50 @@ 'form': form_html }, None + def get_user(self, openid_identifier): + """ Look up username by OpenID identifier + + In the case that multiple users match, the one who has most + recently logged in will be returned. + + :returns: username or ``None``. + """ + db = self.env.get_db_cnx() + cursor = db.cursor() + cursor.execute("SELECT session.sid" + " FROM session" + " INNER JOIN session_attribute AS attr" + " USING(sid, authenticated)" + " WHERE session.authenticated=%s" + " AND attr.name=%s AND attr.value=%s" + " ORDER BY session.last_visit DESC", + (1, self.openid_session_identity_url_key, openid_identifier)) + rows = cursor.fetchall() + if len(rows) == 0: + return None + elif len(rows) > 1: + # Multiple users matched. (We will return the one who most + # recently logged in.) + + # FIXME: Probably should provide a config option which + # controls whether this is a error or not. + self.log.warning( + "Multiple users share the same openid identifier: %s", + ', '.join("'%s'" % user for (user,) in rows)) + return rows[0][0] + def _do_process(self, req): """Handle the redirect from the OpenID server. """ db = self.env.get_db_cnx() - oidconsumer, session = self._get_consumer(req, db) + oidconsumer, oidsession = self._get_consumer(req, db) # Ask the library to check the response that the server sent # us. Status is a code indicating the response type. info is # either None or a string containing more information about # the return type. - info = oidconsumer.complete(req.args,req.args['openid.return_to']) + current_url = req.abs_href(req.path_info) + info = oidconsumer.complete(req.args,current_url) css_class = 'error' if info.status == consumer.FAILURE and info.identity_url: @@ -508,6 +583,8 @@ # the verification. css_class = 'alert' + session_attr = {} # attributes for new "user" + # This is a successful verification attempt. If this # was a real application, we would do our login, # comment posting, etc. here. @@ -529,10 +606,23 @@ or ax_info.get('email2') or sreg_info.get('email')) - fullname = (' '.join(filter(None, map(ax_info.get, - ('firstname', 'lastname')))) - or sreg_info.get('fullname') - or email.split('@',1)[0].replace('.', ' ').title()) + fullname = ( + ' '.join(filter(None, map(ax_info.get, + ('firstname', 'lastname')))) + or sreg_info.get('fullname') + or (email and email.split('@',1)[0].replace('.', ' ').title())) + + nickname = sreg_info.get('nickname') + + if self.groups_to_request and TeamsResponse: + teams_response = TeamsResponse.fromSuccessResponse(info) + if teams_response: + # be careful not to make user a member of any trac groups + # not named in groups_to_request + teams = set(teams_response.teams + ).intersection(self.groups_to_request) + if teams: + session_attr['openid.teams'] = ','.join(teams) if self.strip_protocol: remote_user = remote_user[remote_user.find('://')+3:] @@ -561,27 +651,33 @@ if item.match(remote_user): allowed = False self.env.log.debug("User black-listed.") - if allowed and email and self.re_email_white_list: - self.env.log.debug("Filtering email '%s' through email white-list." % email) + if allowed and self.re_email_white_list: + self.env.log.debug("Filtering email %r through email white-list." % email) allowed = False - for item in self.re_email_white_list: - if not allowed and item.match(email): - allowed = True - self.env.log.debug("User email white-listed.") + if email: + for item in self.re_email_white_list: + if not allowed and item.match(email): + allowed = True + self.env.log.debug("User email white-listed.") if allowed and self.check_list: + allowed = False params = {self.check_list_key: remote_user} if email: params['email'] = email url = self.check_list + '?' + urllib.urlencode(params) self.env.log.debug('OpenID check list URL: %s' % url) - result = json.load(urllib.urlopen(url)) - if not result[self.check_list_key]: - allowed = False - elif self.check_list_username: - new_user = result[self.check_list_username] - if new_user: - remote_user = new_user + try: + result = json.load(urllib.urlopen(url)) + if result[self.check_list_key]: + if self.check_list_username: + cl_username = unicode( + result[self.check_list_username]) + if not cl_username: + raise ValueError("Bad value for username") + allowed = True + except Exception, ex: + self.env.log.error('OpenID check_list failed: %s' % ex) if allowed: cookie = hex_entropy() @@ -592,46 +688,81 @@ if cookie_lifetime > 0: req.outcookie['trac_auth']['expires'] = cookie_lifetime - req.session[self.openid_session_identity_url_key] = info.identity_url + session_attr[self.openid_session_identity_url_key] = info.identity_url if email: - req.session['email'] = email + session_attr['email'] = email if fullname: - req.session['name'] = fullname - - self._commit_session(session, req) + session_attr['name'] = fullname - if req.session.get('name'): - authname = req.session['name'] - if self.combined_username: - authname = '%s <%s>' % (authname, remote_user) - - # Possibly lower-case the authname. - if self.lowercase_authname: - authname = authname.lower() - - # Make authname unique in case of collisions - # - # XXX: We ought to first look for an existing authenticated - # ssession with matching identity_url, and just use that - # for the authid. (E.g. what if the user changes his - # fullname at the openid provider?) However, trac does - # not seem to provide an API for searching sessions other - # than by sid/authname. - # - def authnames(base): - yield base - for attempt in itertools.count(2): - yield "%s (%d)" % (base, attempt) + self._commit_oidsession(oidsession, req) - for authname in authnames(authname): + # First look for an existing authenticated session with + # matching identity_url. + self.env.log.debug('Checking URL: %s' % info.identity_url) + authname_for_identity_url = self.get_user(info.identity_url) + if authname_for_identity_url: + authname = authname_for_identity_url ds = DetachedSession(self.env, authname) - if ds.last_visit == 0 and len(ds) == 0: - # At least in 0.12.2, this mean no session exists. - break - ds_identity = ds.get(self.openid_session_identity_url_key) - if ds_identity == info.identity_url: - # No collision - break + # The user already exists, update team membership + # XXX: Should also update name and/or email? (This would + # be an API change.) + for name in ['openid.teams']: + if name in session_attr: + ds[name] = session_attr[name] + elif name in ds: + del ds[name] + ds.save() + else: + # New identity URL -> create new authname/user. + if self.check_list and self.check_list_username: + authname = cl_username + elif self.use_nickname_as_authname and nickname: + authname = nickname + elif session_attr.get('name'): + authname = session_attr['name'] + if self.combined_username: + authname = '%s <%s>' % (authname, remote_user) + else: + authname = remote_user + + # Possibly lower-case the authname. + if self.lowercase_authname: + authname = authname.lower() + + if self.trust_authname: + ds = DetachedSession(self.env, authname) + else: + # Make authname unique in case of collisions + def authnames(base): + yield base + for attempt in itertools.count(2): + yield "%s (%d)" % (base, attempt) + + users_and_groups_with_permissions = set( + user + for user, perm + in PermissionSystem(self.env).get_all_permissions()) + + for authname in authnames(authname): + ds = DetachedSession(self.env, authname) + # At least in 0.12.2, this means no session exists. + no_session_exists = ds.last_visit == 0 and len(ds) == 0 + no_permissions_defined = authname not in users_and_groups_with_permissions + if (no_session_exists and no_permissions_defined): + # name is free :-) + break + # Set attributes for new user on the + # current anonymous session. It will be promoted to + # the new authenticated session on the next request + # (by Session.__init__). + # + # NB: avoid dict.update here to ensure that + # DetachedSession.__getitem__ gets a chance to + # normalize values + for name, value in session_attr.items(): + req.session[name] = value + self.env.log.info("Created new user '%s' for " + "OpenID identifier %s", authname, info.identity_url) req.authname = authname @@ -663,7 +794,7 @@ # information in a log. message = 'Verification failed.' - self._commit_session(session, req) + self._commit_oidsession(oidsession, req) add_stylesheet(req, 'authopenid/css/openid.css') add_script(req, 'authopenid/js/openid-jquery.js') diff -Nru trac-authopenid-0.4.1/CHANGES.rst trac-authopenid-0.4.7/CHANGES.rst --- trac-authopenid-0.4.1/CHANGES.rst 2012-06-25 22:48:18.000000000 +0000 +++ trac-authopenid-0.4.7/CHANGES.rst 2013-12-06 15:12:42.000000000 +0000 @@ -2,6 +2,120 @@ Changes ======= +Version 0.4.7 (2013-12-06) +========================== + +Bug Fixes +--------- + +- Avoid ``KeyError: 'openid.return_to'`` error when user cancels verification. + (Fix__ by @sleske) + +__ https://github.com/dairiki/authopenid-plugin/pull/16 + +- On login, first try to look up the username by the supplied OpenID + identifier. Only create a (new) username if the lookup fails. Thus + returning users will no longer get a new username if the data returned + by their OpenID provider changes. (Fixes `#14`_.) + Note that previous releases would create a new username with the same + OpenID identifier in this case. If that has happened in your + installation, there will be multiple usernames with the same OpenID + identifier. In that case the user will now always be logged into the + username that was last used, and a warning will be logged ("Multiple + users share the same openid identifier"). You should probably clean up + these "duplicate" usernames (usually by joining them). (Fix by @sleske) + +.. _#14: https://github.com/dairiki/authopenid-plugin/issues/14 + + +Version 0.4.6 (2013-06-27) +========================== + +Bug Fixes +--------- + +- Avoid ``AttributeError`` when neither name nor email is returned from + the OP. (Fixes `#9`_.) + +.. _#9: https://github.com/dairiki/authopenid-plugin/issues/9 + + +Version 0.4.5 (2013-06-23) +========================== + +(Another) brown bag release. I botched release 0.4.4, *and* managed to +totally delete the PyPI repository in the process. (Sorry.) + +Version 0.4.4 (2013-06-23) +========================== + +New Features +------------ + +- (Contributed by Patrick Uiterwijk) Users can be added to trac groups + according to group membership provided via the OpenIDTeams_ + extension. Only groups listed in the new ``groups_to_request`` + config option will be considered for possible membership. To use + this feature you must install the python-openid-teams_ package. + +.. _OpenIDTeams: https://dev.launchpad.net/OpenIDTeams +.. _python-openid-teams: https://pypi.python.org/pypi/python-openid-teams + +Bug/Security Fixes +------------------ + +- Previously, if no email address was returned via AX or SREG, the + ``email_white_list`` config option was being ignored. Now if + ``email_white_list`` is set and no email address can be determined, + authorization will be denied. + +- Do not create new users with a username which already has trac permissions + assigned to it. (E.g. this might be the name of a trac group.) + +Documentation +------------- + +- Updated the example config in the README__ so that it more closely + matches current reality. (Baby steps...) + +__ https://github.com/dairiki/authopenid-plugin#options + +Version 0.4.3 (2013-05-22) +========================== + +Bug Fixes +--------- + +- Fix so that ``check_list_username`` actually works. Now one can + actually use the ``check_list`` web API to implement custom identity + to username mapping. + +- Fall back to using the identifier URL as the authname (rather than + throwing an exception) if the OpenID provider did not return a full + name (or nickname). + +Packaging +--------- + +- README.rst: Patrick Uiterwijk has packaged this plugin for Fedora + + +Version 0.4.2 (2013-03-24) +========================== + +New Features +------------ + +These features were contributed by Patrick Uiterwijk. + +- New config option ``use_nickname_as_authname``. If set, the OpenID + nickname will be used for the authname (or trac username). + +- New config option ``trust_authname``. If set, trust the + OpenID-derived authname to be unique. **Security warning**: do not + set this unless you know what you are doing. + + Version 0.4.1 (2012-06-25) ========================== diff -Nru trac-authopenid-0.4.1/debian/changelog trac-authopenid-0.4.7/debian/changelog --- trac-authopenid-0.4.1/debian/changelog 2013-04-04 20:58:10.000000000 +0000 +++ trac-authopenid-0.4.7/debian/changelog 2014-06-19 09:34:54.000000000 +0000 @@ -1,3 +1,13 @@ +trac-authopenid (0.4.7-1) unstable; urgency=low + + * New upstream release. + * Drop patch handle-no-fullname.patch (merged upstream). + * Update Standards-Version to 3.9.5 (no changes). + * Update compatibility version to 9. + * Move htdocs to /usr/share/trac-authopenid/htdocs. + + -- Jeremy Lainé Thu, 19 Jun 2014 11:34:53 +0200 + trac-authopenid (0.4.1-2) unstable; urgency=low * Avoid crash when OpenID provider does not give a full name diff -Nru trac-authopenid-0.4.1/debian/compat trac-authopenid-0.4.7/debian/compat --- trac-authopenid-0.4.1/debian/compat 2008-11-29 14:31:01.000000000 +0000 +++ trac-authopenid-0.4.7/debian/compat 2014-06-18 10:46:44.000000000 +0000 @@ -1 +1 @@ -5 +9 diff -Nru trac-authopenid-0.4.1/debian/control trac-authopenid-0.4.7/debian/control --- trac-authopenid-0.4.1/debian/control 2013-04-04 20:45:35.000000000 +0000 +++ trac-authopenid-0.4.7/debian/control 2014-06-19 08:53:39.000000000 +0000 @@ -4,10 +4,11 @@ Maintainer: Jeremy Lainé Uploaders: Daniel Kahn Gillmor Build-Depends: debhelper (>= 9), python (>= 2.6.6-3~), python-setuptools -Standards-Version: 3.9.3 +Standards-Version: 3.9.5 Homepage: http://github.com/dairiki/authopenid-plugin -Vcs-Svn: svn://svn.debian.org/collab-maint/deb-maint/trac-authopenid/trunk/ -Vcs-Browser: http://svn.debian.org/viewsvn/collab-maint/deb-maint/trac-authopenid/trunk/ +Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/trac-authopenid.git +Vcs-Git: git://anonscm.debian.org/collab-maint/trac-authopenid.git +X-Python-Version: >= 2.5 Package: trac-authopenid Architecture: all diff -Nru trac-authopenid-0.4.1/debian/copyright trac-authopenid-0.4.7/debian/copyright --- trac-authopenid-0.4.1/debian/copyright 2010-06-24 15:51:19.000000000 +0000 +++ trac-authopenid-0.4.7/debian/copyright 2014-06-18 10:44:59.000000000 +0000 @@ -7,7 +7,7 @@ Copyright: -Copyright (C) 2007 Dalius Dobravolskas +Copyright (C) 2007-2013 Dalius Dobravolskas and Geoffrey T. Dairiki All rights reserved. This software is licensed using the same licence as Trac: diff -Nru trac-authopenid-0.4.1/debian/gbp.conf trac-authopenid-0.4.7/debian/gbp.conf --- trac-authopenid-0.4.1/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ trac-authopenid-0.4.7/debian/gbp.conf 2014-06-18 10:44:59.000000000 +0000 @@ -0,0 +1,4 @@ +[DEFAULT] +upstream-tag = trac-authopenid_upstream/%(version)s +debian-tag = trac-authopenid_debian/%(version)s +pristine-tar = true diff -Nru trac-authopenid-0.4.1/debian/patches/handle-no-fullname.patch trac-authopenid-0.4.7/debian/patches/handle-no-fullname.patch --- trac-authopenid-0.4.1/debian/patches/handle-no-fullname.patch 2013-04-04 20:44:25.000000000 +0000 +++ trac-authopenid-0.4.7/debian/patches/handle-no-fullname.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ ---- a/authopenid/authopenid.py 2012-06-25 17:06:18.000000000 -0400 -+++ b/authopenid/authopenid.py 2013-04-04 16:04:57.542661061 -0400 -@@ -584,6 +584,7 @@ - remote_user = new_user - - if allowed: -+ authname = None - cookie = hex_entropy() - cookie_lifetime = self.trac_auth_cookie_lifetime - -@@ -604,9 +605,11 @@ - authname = req.session['name'] - if self.combined_username: - authname = '%s <%s>' % (authname, remote_user) -+ else: -+ authname = remote_user - - # Possibly lower-case the authname. -- if self.lowercase_authname: -+ if authname and self.lowercase_authname: - authname = authname.lower() - - # Make authname unique in case of collisions diff -Nru trac-authopenid-0.4.1/debian/patches/series trac-authopenid-0.4.7/debian/patches/series --- trac-authopenid-0.4.1/debian/patches/series 2013-04-04 20:07:39.000000000 +0000 +++ trac-authopenid-0.4.7/debian/patches/series 2014-06-19 09:19:01.000000000 +0000 @@ -1 +1 @@ -handle-no-fullname.patch +use_debian_share diff -Nru trac-authopenid-0.4.1/debian/patches/use_debian_share trac-authopenid-0.4.7/debian/patches/use_debian_share --- trac-authopenid-0.4.1/debian/patches/use_debian_share 1970-01-01 00:00:00.000000000 +0000 +++ trac-authopenid-0.4.7/debian/patches/use_debian_share 2014-06-19 09:39:20.000000000 +0000 @@ -0,0 +1,18 @@ +Subject: Place htdocs in /usr/share +Description: Upstream source includes some CSS, JS and images + for the sign-in view. Place them in /usr/share instead of the + python library path. + +diff --git a/authopenid/authopenid.py b/authopenid/authopenid.py +index d21ce21..da98b19 100644 +--- a/authopenid/authopenid.py ++++ b/authopenid/authopenid.py +@@ -816,7 +816,7 @@ class AuthOpenIdPlugin(Component): + # ITemplateProvider methods + + def get_htdocs_dirs(self): +- return [('authopenid', pkg_resources.resource_filename(__name__, 'htdocs'))] ++ return [('authopenid', '/usr/share/trac-authopenid/htdocs')] + + def get_templates_dirs(self): + return [pkg_resources.resource_filename(__name__, 'templates')] diff -Nru trac-authopenid-0.4.1/debian/pycompat trac-authopenid-0.4.7/debian/pycompat --- trac-authopenid-0.4.1/debian/pycompat 2008-11-29 14:31:01.000000000 +0000 +++ trac-authopenid-0.4.7/debian/pycompat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -2 diff -Nru trac-authopenid-0.4.1/debian/rules trac-authopenid-0.4.7/debian/rules --- trac-authopenid-0.4.1/debian/rules 2012-09-07 12:15:57.000000000 +0000 +++ trac-authopenid-0.4.7/debian/rules 2014-06-19 09:15:27.000000000 +0000 @@ -3,5 +3,10 @@ %: dh $@ --with python2 +override_dh_auto_install: + dh_auto_install + mkdir -p debian/trac-authopenid/usr/share/trac-authopenid + mv debian/trac-authopenid/usr/lib/python2.*/dist-packages/authopenid/htdocs debian/trac-authopenid/usr/share/trac-authopenid + override_dh_installchangelogs: dh_installchangelogs CHANGES.rst diff -Nru trac-authopenid-0.4.1/LICENSE.txt trac-authopenid-0.4.7/LICENSE.txt --- trac-authopenid-0.4.1/LICENSE.txt 2012-03-05 20:07:27.000000000 +0000 +++ trac-authopenid-0.4.7/LICENSE.txt 2013-06-23 18:45:53.000000000 +0000 @@ -1,4 +1,4 @@ -Copyright (C) 2007-2012 Dalius Dobravolskas and Geoffrey T. Dairiki +Copyright (C) 2007-2013 Dalius Dobravolskas and Geoffrey T. Dairiki All rights reserved. Redistribution and use in source and binary forms, with or without diff -Nru trac-authopenid-0.4.1/PKG-INFO trac-authopenid-0.4.7/PKG-INFO --- trac-authopenid-0.4.1/PKG-INFO 2012-06-25 22:51:20.000000000 +0000 +++ trac-authopenid-0.4.7/PKG-INFO 2013-12-06 15:18:17.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: TracAuthOpenId -Version: 0.4.1 +Version: 0.4.7 Summary: OpenID plugin for Trac Home-page: https://github.com/dairiki/authopenid-plugin/ Author: Jeff Dairiki @@ -37,11 +37,26 @@ pip install TracAuthOpenId - 2. There is `Debian package` for this plugin:: + .. _PyPI: http://pypi.python.org/pypi/TracAuthOpenId/ + .. _pip: http://www.pip-installer.org/ + + 2. There is a `Debian package`_ for this plugin:: sudo aptitude install trac-authopenid - 3. You can clone git repository somewhere in your system:: + .. _Debian package: http://packages.qa.debian.org/t/trac-authopenid.html + + 3. `Patrick Uiterwijk`_ has packaged__ this plugin for Fedora:: + + yum install trac-authopenid-plugin + + Should you have questions regarding the Fedora packaging, please file + them in the Fedora `bug tracker`_. + + __ https://apps.fedoraproject.org/packages/trac-authopenid-plugin + .. _bug tracker: https://apps.fedoraproject.org/packages/trac-authopenid-plugin/bugs + + 4. You can clone git repository somewhere in your system:: cd /your/3rdparty/src git clone git://github.com/dairiki/authopenid-plugin.git @@ -60,9 +75,6 @@ installation, you will have to do this with *root* permissions (e.g. using ``su`` or ``sudo``). - .. _PyPI: http://pypi.python.org/pypi/TracAuthOpenId/ - .. _Debian package: http://packages.qa.debian.org/t/trac-authopenid.html - .. _pip: http://www.pip-installer.org/ How to enable ============= @@ -81,98 +93,186 @@ Options ======= - This plugin has number of configuration options. Examples are best way - to illustrate them. - (NB: some of this is out of date and needs to be updated):: - - [trac] - # Check user IP address. IP addresses are masked because - # in some cases user is behind internal proxy and last - # number in IP address might vary. Disable check_auth_ip - # if you are using IPv6. If you still want to have IPv6 - # support please contact me. - check_auth_ip = true - check_auth_ip_mask = 255.255.255.0 - # number of seconds until cookie will expire - auth_cookie_lifetime = 86400 + This plugin has number of configuration options. Here is an excerpt + from an example config file which lists all available options:: [openid] - # In some cases company might have internal OpenID server that - # automatically identifies user (e.g. windows SSPI). Also known as - # single sign-on. default_openid = http://openid.ee Require sreg - # data - sreg_required = false + ################################################################ + # Provider selection - # If you want username to be written as - # "username_in_remote_system " use: - #combined_username = true + # Single sign-on support + # + # If you want to support only a single OpenID provider and that + # provider allows the users to select his account as part of its + # authentication process, set default_openid to the OP identifier + # of the provider. Then clicking the _OpenID Login_ link will take + # the user directly to the providers authentication interface, + # bypassing the openid provider/identity selection dialog. + # + # E.g. to use google as your sole openid provider, use + #default_openid = https://www.google.com/accounts/o8/id - # Default PAPE method to request from OpenID provider. - # pape_method = + # (If you have set default_openid, the identity selection dialog is + # not displayed, and the rest of the options in this section are moot.) + + # Explicit set of provider names to display. Should be set to a comman + # separated list of provider names. Choices include: + # google, yahoo, aol, openid, myopenid, livejournal, flickr, technorati, + # wordpress, blogger, verisign, vidoop, claimid, as well as any + # custom provider you may have configured (via custom_provider_name). + # By default all known providers are listed. + #providers = google, myopenid + + # Add a custom openid provider to the form + # provider name + #custom_provider_name = myprovider + # label + #custom_provider_label = Enter your username + # identity template + #custom_provider_url = http://myprovider.example.net/{username} + # URL to image/icon + #custom_provider_image = /static/icons/myprovider.png + # image size (small or large) + #custom_provider_size = small # What is OpenID link. - whatis = http://openid.net/what/ + whatis_link = http://openid.net/what/ # Sign-up link - signup = http://openid.net/get - # Gmail login button (default: true) - # gmail = false - # In some cases you might want allow users to login to different - # projects using different OpenIDs. In that case don't use - # absolute trust root. - absolute_trust_root = false - - # Remove http:// or https:// from URL that is used as - # username. (Default: false) - strip_protocol = false + signup_link = http://openid.net/get - # Remove trailing slash from URL that is user as username (Defaul: false) - strip_trailing_slash = false + ################################################################ + # Authorization - # Expiration time acts as timeout. E.g. if expiration time is 24 - # hour and you login again in those 24 hours. Expiration time is - # extended for another 24 hours. (Default: false) - timeout = false - - # White and black lists. - # E.g.: Allows all the people from Lithuania, Latvia or Estonia - # except delfi domain. - # IMPORTANT: strip_protocol and strip_trailing_slash affects what + # Identity white and black lists + # + # IMPORTANT: strip_protocol and strip_trailing_slash (see below) affectswhat # openid will be given to white_list or black_list - #white_list = *.lt, *.lv, *.ee - #black_list = *.delfi.lt,*.delfi.lv,*.delfi.ee - # In addition to white and black lists you can use external + # white_list: If set, only identities matching this list will be accepted + # E.g. to allow only google and myopenid provided identities, use + #white_list = https://www.google.com/accounts/o8/id?id=*, http://*.myopenid.com/ + + # black_list: If set, matching identities will not be accepted + #black_list = http://spammer.myopenid.com/ + + # Comma separated list of allowed users, using the email address + # resolved via SREG or AX. Use in combination with trusted + # identity patterns in white_list. + #email_white_list = joe@example.com + + # In addition to white and black lists you can use external web # service for allowing users into trac. To control that you must # use check_list and check_list_key option. It will generate URL: # - # check_list?check_list_key=openid&email=email + # ?=openid&email=email # # email will be attached only if available. # # It expects JSON result in following format: # - # {"check_list_key": true} + # {"": true} + # + # Your check_list web app may also be used to map openid + # identifiers to your own internal authnames (usernames). (See + # check_list_username below.) # # IMPORTANT: strip_protocol and strip_trailing_slash affects what # openid will be send to service - # NOTE: You can specify check_list_username as well. In that case - # JSON service should return new username as - # well. E.g. check_list_username=username. Expected result from - # JSON service is: - # - # {"check_list_key": true, "username": "Peter"} # # You can use this option to map your OpenIDs to internal username. #check_list = http://your.site.com/openidallow + + # The parameter name used both for passing the claimed identity + # to the authorization app, as well as for returning the authorization + # status. Defaults to "check_list". #check_list_key = check_list + + # Expiration time acts as timeout. E.g. if expiration time is 24 + # hour and you login again in those 24 hours. Expiration time is + # extended for another 24 hours. (Default: false) + timeout = false + + ################################################################ + # OpenID protocol and extensions + + # Require sreg data + sreg_required = false + + # Default PAPE method to request from OpenID provider. + # pape_method = + + # In some cases you might want allow users to login to different + # projects using different OpenIDs. In that case don't use + # absolute trust root. + absolute_trust_root = false + + + # Use the OpenIDTeams extension to request user's group membership. + # If a user is a member of any of the teams listed in this option, + # the user will be added to the trac permission group(s) of the same + # name. (Set to to a comma-separated list.) + # + # NOTE: To use this option, the python-openid-teams package must be + # installed. + groups_to_request = + + ################################################################ + # Authname (trac SID) generation + + # Force authname to lowercase (default true) + #lowercase_authname = true + + # Use SREG nickname as authname (default false) + #use_nickname_as_authname = false + + # If you want username to be written as + # "username_in_remote_system " use: + #combined_username = true + + # Remove http:// or https:// from URL that is used as + # username. (Default: false) + strip_protocol = false + + # Remove trailing slash from URL that is user as username (Defaul: false) + strip_trailing_slash = false + + # If you have an external authorization web app configured (via + # check_list), you may also use that to map openid identifiers to + # local usernames (authnames). Set check_list_username to the name + # of a parameter which will be used to return the authname. + # E.g. if check_list_username=username, the expected JSON result from + # the authorization service is + # + # {"check_list": true, "username": "Peter"} + # #check_list_username= + + # Normally, the authname is not trusted to uniquely identify the user. + # (What if another user has already registered with the same username?) + # By default, a small integer is appended to the authname to make it + # unique. To default this, you may set trust_authname to true. + # + # WARNING: Setting this can is many circumstances make identity theft + # very easy. Only set this if you understand what you are doing. + #trust_authname = false + + + # Authentication cookie controls. # - # You can add one custom openid provider: - #custom_provider_name = test - #custom_provider_label = Enter openidprovider username: - #custom_provider_url = http://openidprovider/{username} - #custom_provider_image = http://openidprovider/favicon.png + # Note that these are in the [trac] config section. + + [trac] + + # Check user IP address. IP addresses are masked because + # in some cases user is behind internal proxy and last + # number in IP address might vary. + # (Does not currently support IPv6.) + check_auth_ip = true + check_auth_ip_mask = 255.255.255.0 + + # number of seconds until cookie will expire + auth_cookie_lifetime = 86400 Authors @@ -180,15 +280,132 @@ This plugin was written by `Dalius Dobravolskas`_. It is currently being maintained by `Jeff Dairiki`_. + Other contributors include: `Patrick Uiterwijk`_ and `@sleske`_. .. _Jeff Dairiki: mailto:dairiki@dairiki.org .. _Dalius Dobravolskas: mailto:dalius@sandbox.lt + .. _Patrick Uiterwijk: https://github.com/puiterwijk + .. _@sleske: https://github.com/sleske ======= Changes ======= + Version 0.4.7 (2013-12-06) + ========================== + + Bug Fixes + --------- + + - Avoid ``KeyError: 'openid.return_to'`` error when user cancels verification. + (Fix__ by @sleske) + + __ https://github.com/dairiki/authopenid-plugin/pull/16 + + - On login, first try to look up the username by the supplied OpenID + identifier. Only create a (new) username if the lookup fails. Thus + returning users will no longer get a new username if the data returned + by their OpenID provider changes. (Fixes `#14`_.) + Note that previous releases would create a new username with the same + OpenID identifier in this case. If that has happened in your + installation, there will be multiple usernames with the same OpenID + identifier. In that case the user will now always be logged into the + username that was last used, and a warning will be logged ("Multiple + users share the same openid identifier"). You should probably clean up + these "duplicate" usernames (usually by joining them). (Fix by @sleske) + + .. _#14: https://github.com/dairiki/authopenid-plugin/issues/14 + + + Version 0.4.6 (2013-06-27) + ========================== + + Bug Fixes + --------- + + - Avoid ``AttributeError`` when neither name nor email is returned from + the OP. (Fixes `#9`_.) + + .. _#9: https://github.com/dairiki/authopenid-plugin/issues/9 + + + Version 0.4.5 (2013-06-23) + ========================== + + (Another) brown bag release. I botched release 0.4.4, *and* managed to + totally delete the PyPI repository in the process. (Sorry.) + + Version 0.4.4 (2013-06-23) + ========================== + + New Features + ------------ + + - (Contributed by Patrick Uiterwijk) Users can be added to trac groups + according to group membership provided via the OpenIDTeams_ + extension. Only groups listed in the new ``groups_to_request`` + config option will be considered for possible membership. To use + this feature you must install the python-openid-teams_ package. + + .. _OpenIDTeams: https://dev.launchpad.net/OpenIDTeams + .. _python-openid-teams: https://pypi.python.org/pypi/python-openid-teams + + Bug/Security Fixes + ------------------ + + - Previously, if no email address was returned via AX or SREG, the + ``email_white_list`` config option was being ignored. Now if + ``email_white_list`` is set and no email address can be determined, + authorization will be denied. + + - Do not create new users with a username which already has trac permissions + assigned to it. (E.g. this might be the name of a trac group.) + + Documentation + ------------- + + - Updated the example config in the README__ so that it more closely + matches current reality. (Baby steps...) + + __ https://github.com/dairiki/authopenid-plugin#options + + Version 0.4.3 (2013-05-22) + ========================== + + Bug Fixes + --------- + + - Fix so that ``check_list_username`` actually works. Now one can + actually use the ``check_list`` web API to implement custom identity + to username mapping. + + - Fall back to using the identifier URL as the authname (rather than + throwing an exception) if the OpenID provider did not return a full + name (or nickname). + + Packaging + --------- + + - README.rst: Patrick Uiterwijk has packaged this plugin for Fedora + + + Version 0.4.2 (2013-03-24) + ========================== + + New Features + ------------ + + These features were contributed by Patrick Uiterwijk. + + - New config option ``use_nickname_as_authname``. If set, the OpenID + nickname will be used for the authname (or trac username). + + - New config option ``trust_authname``. If set, trust the + OpenID-derived authname to be unique. **Security warning**: do not + set this unless you know what you are doing. + + Version 0.4.1 (2012-06-25) ========================== diff -Nru trac-authopenid-0.4.1/README.rst trac-authopenid-0.4.7/README.rst --- trac-authopenid-0.4.1/README.rst 2012-06-25 21:20:05.000000000 +0000 +++ trac-authopenid-0.4.7/README.rst 2013-12-06 15:12:42.000000000 +0000 @@ -29,11 +29,26 @@ pip install TracAuthOpenId -2. There is `Debian package` for this plugin:: +.. _PyPI: http://pypi.python.org/pypi/TracAuthOpenId/ +.. _pip: http://www.pip-installer.org/ + +2. There is a `Debian package`_ for this plugin:: sudo aptitude install trac-authopenid -3. You can clone git repository somewhere in your system:: +.. _Debian package: http://packages.qa.debian.org/t/trac-authopenid.html + +3. `Patrick Uiterwijk`_ has packaged__ this plugin for Fedora:: + + yum install trac-authopenid-plugin + + Should you have questions regarding the Fedora packaging, please file + them in the Fedora `bug tracker`_. + +__ https://apps.fedoraproject.org/packages/trac-authopenid-plugin +.. _bug tracker: https://apps.fedoraproject.org/packages/trac-authopenid-plugin/bugs + +4. You can clone git repository somewhere in your system:: cd /your/3rdparty/src git clone git://github.com/dairiki/authopenid-plugin.git @@ -52,9 +67,6 @@ installation, you will have to do this with *root* permissions (e.g. using ``su`` or ``sudo``). -.. _PyPI: http://pypi.python.org/pypi/TracAuthOpenId/ -.. _Debian package: http://packages.qa.debian.org/t/trac-authopenid.html -.. _pip: http://www.pip-installer.org/ How to enable ============= @@ -73,98 +85,186 @@ Options ======= -This plugin has number of configuration options. Examples are best way -to illustrate them. -(NB: some of this is out of date and needs to be updated):: - - [trac] - # Check user IP address. IP addresses are masked because - # in some cases user is behind internal proxy and last - # number in IP address might vary. Disable check_auth_ip - # if you are using IPv6. If you still want to have IPv6 - # support please contact me. - check_auth_ip = true - check_auth_ip_mask = 255.255.255.0 - # number of seconds until cookie will expire - auth_cookie_lifetime = 86400 +This plugin has number of configuration options. Here is an excerpt +from an example config file which lists all available options:: [openid] - # In some cases company might have internal OpenID server that - # automatically identifies user (e.g. windows SSPI). Also known as - # single sign-on. default_openid = http://openid.ee Require sreg - # data - sreg_required = false - - # If you want username to be written as - # "username_in_remote_system " use: - #combined_username = true + ################################################################ + # Provider selection - # Default PAPE method to request from OpenID provider. - # pape_method = + # Single sign-on support + # + # If you want to support only a single OpenID provider and that + # provider allows the users to select his account as part of its + # authentication process, set default_openid to the OP identifier + # of the provider. Then clicking the _OpenID Login_ link will take + # the user directly to the providers authentication interface, + # bypassing the openid provider/identity selection dialog. + # + # E.g. to use google as your sole openid provider, use + #default_openid = https://www.google.com/accounts/o8/id + + # (If you have set default_openid, the identity selection dialog is + # not displayed, and the rest of the options in this section are moot.) + + # Explicit set of provider names to display. Should be set to a comman + # separated list of provider names. Choices include: + # google, yahoo, aol, openid, myopenid, livejournal, flickr, technorati, + # wordpress, blogger, verisign, vidoop, claimid, as well as any + # custom provider you may have configured (via custom_provider_name). + # By default all known providers are listed. + #providers = google, myopenid + + # Add a custom openid provider to the form + # provider name + #custom_provider_name = myprovider + # label + #custom_provider_label = Enter your username + # identity template + #custom_provider_url = http://myprovider.example.net/{username} + # URL to image/icon + #custom_provider_image = /static/icons/myprovider.png + # image size (small or large) + #custom_provider_size = small # What is OpenID link. - whatis = http://openid.net/what/ + whatis_link = http://openid.net/what/ # Sign-up link - signup = http://openid.net/get - # Gmail login button (default: true) - # gmail = false - # In some cases you might want allow users to login to different - # projects using different OpenIDs. In that case don't use - # absolute trust root. - absolute_trust_root = false - - # Remove http:// or https:// from URL that is used as - # username. (Default: false) - strip_protocol = false - - # Remove trailing slash from URL that is user as username (Defaul: false) - strip_trailing_slash = false + signup_link = http://openid.net/get - # Expiration time acts as timeout. E.g. if expiration time is 24 - # hour and you login again in those 24 hours. Expiration time is - # extended for another 24 hours. (Default: false) - timeout = false + ################################################################ + # Authorization - # White and black lists. - # E.g.: Allows all the people from Lithuania, Latvia or Estonia - # except delfi domain. - # IMPORTANT: strip_protocol and strip_trailing_slash affects what + # Identity white and black lists + # + # IMPORTANT: strip_protocol and strip_trailing_slash (see below) affectswhat # openid will be given to white_list or black_list - #white_list = *.lt, *.lv, *.ee - #black_list = *.delfi.lt,*.delfi.lv,*.delfi.ee - # In addition to white and black lists you can use external + # white_list: If set, only identities matching this list will be accepted + # E.g. to allow only google and myopenid provided identities, use + #white_list = https://www.google.com/accounts/o8/id?id=*, http://*.myopenid.com/ + + # black_list: If set, matching identities will not be accepted + #black_list = http://spammer.myopenid.com/ + + # Comma separated list of allowed users, using the email address + # resolved via SREG or AX. Use in combination with trusted + # identity patterns in white_list. + #email_white_list = joe@example.com + + # In addition to white and black lists you can use external web # service for allowing users into trac. To control that you must # use check_list and check_list_key option. It will generate URL: # - # check_list?check_list_key=openid&email=email + # ?=openid&email=email # # email will be attached only if available. # # It expects JSON result in following format: # - # {"check_list_key": true} + # {"": true} + # + # Your check_list web app may also be used to map openid + # identifiers to your own internal authnames (usernames). (See + # check_list_username below.) # # IMPORTANT: strip_protocol and strip_trailing_slash affects what # openid will be send to service - # NOTE: You can specify check_list_username as well. In that case - # JSON service should return new username as - # well. E.g. check_list_username=username. Expected result from - # JSON service is: - # - # {"check_list_key": true, "username": "Peter"} # # You can use this option to map your OpenIDs to internal username. #check_list = http://your.site.com/openidallow + + # The parameter name used both for passing the claimed identity + # to the authorization app, as well as for returning the authorization + # status. Defaults to "check_list". #check_list_key = check_list + + # Expiration time acts as timeout. E.g. if expiration time is 24 + # hour and you login again in those 24 hours. Expiration time is + # extended for another 24 hours. (Default: false) + timeout = false + + ################################################################ + # OpenID protocol and extensions + + # Require sreg data + sreg_required = false + + # Default PAPE method to request from OpenID provider. + # pape_method = + + # In some cases you might want allow users to login to different + # projects using different OpenIDs. In that case don't use + # absolute trust root. + absolute_trust_root = false + + + # Use the OpenIDTeams extension to request user's group membership. + # If a user is a member of any of the teams listed in this option, + # the user will be added to the trac permission group(s) of the same + # name. (Set to to a comma-separated list.) + # + # NOTE: To use this option, the python-openid-teams package must be + # installed. + groups_to_request = + + ################################################################ + # Authname (trac SID) generation + + # Force authname to lowercase (default true) + #lowercase_authname = true + + # Use SREG nickname as authname (default false) + #use_nickname_as_authname = false + + # If you want username to be written as + # "username_in_remote_system " use: + #combined_username = true + + # Remove http:// or https:// from URL that is used as + # username. (Default: false) + strip_protocol = false + + # Remove trailing slash from URL that is user as username (Defaul: false) + strip_trailing_slash = false + + # If you have an external authorization web app configured (via + # check_list), you may also use that to map openid identifiers to + # local usernames (authnames). Set check_list_username to the name + # of a parameter which will be used to return the authname. + # E.g. if check_list_username=username, the expected JSON result from + # the authorization service is + # + # {"check_list": true, "username": "Peter"} + # #check_list_username= + + # Normally, the authname is not trusted to uniquely identify the user. + # (What if another user has already registered with the same username?) + # By default, a small integer is appended to the authname to make it + # unique. To default this, you may set trust_authname to true. + # + # WARNING: Setting this can is many circumstances make identity theft + # very easy. Only set this if you understand what you are doing. + #trust_authname = false + + + # Authentication cookie controls. # - # You can add one custom openid provider: - #custom_provider_name = test - #custom_provider_label = Enter openidprovider username: - #custom_provider_url = http://openidprovider/{username} - #custom_provider_image = http://openidprovider/favicon.png + # Note that these are in the [trac] config section. + + [trac] + + # Check user IP address. IP addresses are masked because + # in some cases user is behind internal proxy and last + # number in IP address might vary. + # (Does not currently support IPv6.) + check_auth_ip = true + check_auth_ip_mask = 255.255.255.0 + + # number of seconds until cookie will expire + auth_cookie_lifetime = 86400 Authors @@ -172,6 +272,9 @@ This plugin was written by `Dalius Dobravolskas`_. It is currently being maintained by `Jeff Dairiki`_. +Other contributors include: `Patrick Uiterwijk`_ and `@sleske`_. .. _Jeff Dairiki: mailto:dairiki@dairiki.org .. _Dalius Dobravolskas: mailto:dalius@sandbox.lt +.. _Patrick Uiterwijk: https://github.com/puiterwijk +.. _@sleske: https://github.com/sleske diff -Nru trac-authopenid-0.4.1/setup.py trac-authopenid-0.4.7/setup.py --- trac-authopenid-0.4.1/setup.py 2012-06-25 22:42:18.000000000 +0000 +++ trac-authopenid-0.4.7/setup.py 2013-11-09 16:14:56.000000000 +0000 @@ -3,7 +3,7 @@ import sys PACKAGE = 'TracAuthOpenId' -VERSION = '0.4.1' +VERSION = '0.4.7' here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.rst')).read() @@ -60,4 +60,7 @@ }, install_requires=install_requires, + extras_require = { + 'teams': ['python-openid-teams'], + }, ) diff -Nru trac-authopenid-0.4.1/TracAuthOpenId.egg-info/PKG-INFO trac-authopenid-0.4.7/TracAuthOpenId.egg-info/PKG-INFO --- trac-authopenid-0.4.1/TracAuthOpenId.egg-info/PKG-INFO 2012-06-25 22:51:20.000000000 +0000 +++ trac-authopenid-0.4.7/TracAuthOpenId.egg-info/PKG-INFO 2013-12-06 15:18:15.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: TracAuthOpenId -Version: 0.4.1 +Version: 0.4.7 Summary: OpenID plugin for Trac Home-page: https://github.com/dairiki/authopenid-plugin/ Author: Jeff Dairiki @@ -37,11 +37,26 @@ pip install TracAuthOpenId - 2. There is `Debian package` for this plugin:: + .. _PyPI: http://pypi.python.org/pypi/TracAuthOpenId/ + .. _pip: http://www.pip-installer.org/ + + 2. There is a `Debian package`_ for this plugin:: sudo aptitude install trac-authopenid - 3. You can clone git repository somewhere in your system:: + .. _Debian package: http://packages.qa.debian.org/t/trac-authopenid.html + + 3. `Patrick Uiterwijk`_ has packaged__ this plugin for Fedora:: + + yum install trac-authopenid-plugin + + Should you have questions regarding the Fedora packaging, please file + them in the Fedora `bug tracker`_. + + __ https://apps.fedoraproject.org/packages/trac-authopenid-plugin + .. _bug tracker: https://apps.fedoraproject.org/packages/trac-authopenid-plugin/bugs + + 4. You can clone git repository somewhere in your system:: cd /your/3rdparty/src git clone git://github.com/dairiki/authopenid-plugin.git @@ -60,9 +75,6 @@ installation, you will have to do this with *root* permissions (e.g. using ``su`` or ``sudo``). - .. _PyPI: http://pypi.python.org/pypi/TracAuthOpenId/ - .. _Debian package: http://packages.qa.debian.org/t/trac-authopenid.html - .. _pip: http://www.pip-installer.org/ How to enable ============= @@ -81,98 +93,186 @@ Options ======= - This plugin has number of configuration options. Examples are best way - to illustrate them. - (NB: some of this is out of date and needs to be updated):: - - [trac] - # Check user IP address. IP addresses are masked because - # in some cases user is behind internal proxy and last - # number in IP address might vary. Disable check_auth_ip - # if you are using IPv6. If you still want to have IPv6 - # support please contact me. - check_auth_ip = true - check_auth_ip_mask = 255.255.255.0 - # number of seconds until cookie will expire - auth_cookie_lifetime = 86400 + This plugin has number of configuration options. Here is an excerpt + from an example config file which lists all available options:: [openid] - # In some cases company might have internal OpenID server that - # automatically identifies user (e.g. windows SSPI). Also known as - # single sign-on. default_openid = http://openid.ee Require sreg - # data - sreg_required = false + ################################################################ + # Provider selection - # If you want username to be written as - # "username_in_remote_system " use: - #combined_username = true + # Single sign-on support + # + # If you want to support only a single OpenID provider and that + # provider allows the users to select his account as part of its + # authentication process, set default_openid to the OP identifier + # of the provider. Then clicking the _OpenID Login_ link will take + # the user directly to the providers authentication interface, + # bypassing the openid provider/identity selection dialog. + # + # E.g. to use google as your sole openid provider, use + #default_openid = https://www.google.com/accounts/o8/id - # Default PAPE method to request from OpenID provider. - # pape_method = + # (If you have set default_openid, the identity selection dialog is + # not displayed, and the rest of the options in this section are moot.) + + # Explicit set of provider names to display. Should be set to a comman + # separated list of provider names. Choices include: + # google, yahoo, aol, openid, myopenid, livejournal, flickr, technorati, + # wordpress, blogger, verisign, vidoop, claimid, as well as any + # custom provider you may have configured (via custom_provider_name). + # By default all known providers are listed. + #providers = google, myopenid + + # Add a custom openid provider to the form + # provider name + #custom_provider_name = myprovider + # label + #custom_provider_label = Enter your username + # identity template + #custom_provider_url = http://myprovider.example.net/{username} + # URL to image/icon + #custom_provider_image = /static/icons/myprovider.png + # image size (small or large) + #custom_provider_size = small # What is OpenID link. - whatis = http://openid.net/what/ + whatis_link = http://openid.net/what/ # Sign-up link - signup = http://openid.net/get - # Gmail login button (default: true) - # gmail = false - # In some cases you might want allow users to login to different - # projects using different OpenIDs. In that case don't use - # absolute trust root. - absolute_trust_root = false - - # Remove http:// or https:// from URL that is used as - # username. (Default: false) - strip_protocol = false + signup_link = http://openid.net/get - # Remove trailing slash from URL that is user as username (Defaul: false) - strip_trailing_slash = false + ################################################################ + # Authorization - # Expiration time acts as timeout. E.g. if expiration time is 24 - # hour and you login again in those 24 hours. Expiration time is - # extended for another 24 hours. (Default: false) - timeout = false - - # White and black lists. - # E.g.: Allows all the people from Lithuania, Latvia or Estonia - # except delfi domain. - # IMPORTANT: strip_protocol and strip_trailing_slash affects what + # Identity white and black lists + # + # IMPORTANT: strip_protocol and strip_trailing_slash (see below) affectswhat # openid will be given to white_list or black_list - #white_list = *.lt, *.lv, *.ee - #black_list = *.delfi.lt,*.delfi.lv,*.delfi.ee - # In addition to white and black lists you can use external + # white_list: If set, only identities matching this list will be accepted + # E.g. to allow only google and myopenid provided identities, use + #white_list = https://www.google.com/accounts/o8/id?id=*, http://*.myopenid.com/ + + # black_list: If set, matching identities will not be accepted + #black_list = http://spammer.myopenid.com/ + + # Comma separated list of allowed users, using the email address + # resolved via SREG or AX. Use in combination with trusted + # identity patterns in white_list. + #email_white_list = joe@example.com + + # In addition to white and black lists you can use external web # service for allowing users into trac. To control that you must # use check_list and check_list_key option. It will generate URL: # - # check_list?check_list_key=openid&email=email + # ?=openid&email=email # # email will be attached only if available. # # It expects JSON result in following format: # - # {"check_list_key": true} + # {"": true} + # + # Your check_list web app may also be used to map openid + # identifiers to your own internal authnames (usernames). (See + # check_list_username below.) # # IMPORTANT: strip_protocol and strip_trailing_slash affects what # openid will be send to service - # NOTE: You can specify check_list_username as well. In that case - # JSON service should return new username as - # well. E.g. check_list_username=username. Expected result from - # JSON service is: - # - # {"check_list_key": true, "username": "Peter"} # # You can use this option to map your OpenIDs to internal username. #check_list = http://your.site.com/openidallow + + # The parameter name used both for passing the claimed identity + # to the authorization app, as well as for returning the authorization + # status. Defaults to "check_list". #check_list_key = check_list + + # Expiration time acts as timeout. E.g. if expiration time is 24 + # hour and you login again in those 24 hours. Expiration time is + # extended for another 24 hours. (Default: false) + timeout = false + + ################################################################ + # OpenID protocol and extensions + + # Require sreg data + sreg_required = false + + # Default PAPE method to request from OpenID provider. + # pape_method = + + # In some cases you might want allow users to login to different + # projects using different OpenIDs. In that case don't use + # absolute trust root. + absolute_trust_root = false + + + # Use the OpenIDTeams extension to request user's group membership. + # If a user is a member of any of the teams listed in this option, + # the user will be added to the trac permission group(s) of the same + # name. (Set to to a comma-separated list.) + # + # NOTE: To use this option, the python-openid-teams package must be + # installed. + groups_to_request = + + ################################################################ + # Authname (trac SID) generation + + # Force authname to lowercase (default true) + #lowercase_authname = true + + # Use SREG nickname as authname (default false) + #use_nickname_as_authname = false + + # If you want username to be written as + # "username_in_remote_system " use: + #combined_username = true + + # Remove http:// or https:// from URL that is used as + # username. (Default: false) + strip_protocol = false + + # Remove trailing slash from URL that is user as username (Defaul: false) + strip_trailing_slash = false + + # If you have an external authorization web app configured (via + # check_list), you may also use that to map openid identifiers to + # local usernames (authnames). Set check_list_username to the name + # of a parameter which will be used to return the authname. + # E.g. if check_list_username=username, the expected JSON result from + # the authorization service is + # + # {"check_list": true, "username": "Peter"} + # #check_list_username= + + # Normally, the authname is not trusted to uniquely identify the user. + # (What if another user has already registered with the same username?) + # By default, a small integer is appended to the authname to make it + # unique. To default this, you may set trust_authname to true. + # + # WARNING: Setting this can is many circumstances make identity theft + # very easy. Only set this if you understand what you are doing. + #trust_authname = false + + + # Authentication cookie controls. # - # You can add one custom openid provider: - #custom_provider_name = test - #custom_provider_label = Enter openidprovider username: - #custom_provider_url = http://openidprovider/{username} - #custom_provider_image = http://openidprovider/favicon.png + # Note that these are in the [trac] config section. + + [trac] + + # Check user IP address. IP addresses are masked because + # in some cases user is behind internal proxy and last + # number in IP address might vary. + # (Does not currently support IPv6.) + check_auth_ip = true + check_auth_ip_mask = 255.255.255.0 + + # number of seconds until cookie will expire + auth_cookie_lifetime = 86400 Authors @@ -180,15 +280,132 @@ This plugin was written by `Dalius Dobravolskas`_. It is currently being maintained by `Jeff Dairiki`_. + Other contributors include: `Patrick Uiterwijk`_ and `@sleske`_. .. _Jeff Dairiki: mailto:dairiki@dairiki.org .. _Dalius Dobravolskas: mailto:dalius@sandbox.lt + .. _Patrick Uiterwijk: https://github.com/puiterwijk + .. _@sleske: https://github.com/sleske ======= Changes ======= + Version 0.4.7 (2013-12-06) + ========================== + + Bug Fixes + --------- + + - Avoid ``KeyError: 'openid.return_to'`` error when user cancels verification. + (Fix__ by @sleske) + + __ https://github.com/dairiki/authopenid-plugin/pull/16 + + - On login, first try to look up the username by the supplied OpenID + identifier. Only create a (new) username if the lookup fails. Thus + returning users will no longer get a new username if the data returned + by their OpenID provider changes. (Fixes `#14`_.) + Note that previous releases would create a new username with the same + OpenID identifier in this case. If that has happened in your + installation, there will be multiple usernames with the same OpenID + identifier. In that case the user will now always be logged into the + username that was last used, and a warning will be logged ("Multiple + users share the same openid identifier"). You should probably clean up + these "duplicate" usernames (usually by joining them). (Fix by @sleske) + + .. _#14: https://github.com/dairiki/authopenid-plugin/issues/14 + + + Version 0.4.6 (2013-06-27) + ========================== + + Bug Fixes + --------- + + - Avoid ``AttributeError`` when neither name nor email is returned from + the OP. (Fixes `#9`_.) + + .. _#9: https://github.com/dairiki/authopenid-plugin/issues/9 + + + Version 0.4.5 (2013-06-23) + ========================== + + (Another) brown bag release. I botched release 0.4.4, *and* managed to + totally delete the PyPI repository in the process. (Sorry.) + + Version 0.4.4 (2013-06-23) + ========================== + + New Features + ------------ + + - (Contributed by Patrick Uiterwijk) Users can be added to trac groups + according to group membership provided via the OpenIDTeams_ + extension. Only groups listed in the new ``groups_to_request`` + config option will be considered for possible membership. To use + this feature you must install the python-openid-teams_ package. + + .. _OpenIDTeams: https://dev.launchpad.net/OpenIDTeams + .. _python-openid-teams: https://pypi.python.org/pypi/python-openid-teams + + Bug/Security Fixes + ------------------ + + - Previously, if no email address was returned via AX or SREG, the + ``email_white_list`` config option was being ignored. Now if + ``email_white_list`` is set and no email address can be determined, + authorization will be denied. + + - Do not create new users with a username which already has trac permissions + assigned to it. (E.g. this might be the name of a trac group.) + + Documentation + ------------- + + - Updated the example config in the README__ so that it more closely + matches current reality. (Baby steps...) + + __ https://github.com/dairiki/authopenid-plugin#options + + Version 0.4.3 (2013-05-22) + ========================== + + Bug Fixes + --------- + + - Fix so that ``check_list_username`` actually works. Now one can + actually use the ``check_list`` web API to implement custom identity + to username mapping. + + - Fall back to using the identifier URL as the authname (rather than + throwing an exception) if the OpenID provider did not return a full + name (or nickname). + + Packaging + --------- + + - README.rst: Patrick Uiterwijk has packaged this plugin for Fedora + + + Version 0.4.2 (2013-03-24) + ========================== + + New Features + ------------ + + These features were contributed by Patrick Uiterwijk. + + - New config option ``use_nickname_as_authname``. If set, the OpenID + nickname will be used for the authname (or trac username). + + - New config option ``trust_authname``. If set, trust the + OpenID-derived authname to be unique. **Security warning**: do not + set this unless you know what you are doing. + + Version 0.4.1 (2012-06-25) ========================== diff -Nru trac-authopenid-0.4.1/TracAuthOpenId.egg-info/requires.txt trac-authopenid-0.4.7/TracAuthOpenId.egg-info/requires.txt --- trac-authopenid-0.4.1/TracAuthOpenId.egg-info/requires.txt 2012-06-25 22:51:20.000000000 +0000 +++ trac-authopenid-0.4.7/TracAuthOpenId.egg-info/requires.txt 2013-12-06 15:18:15.000000000 +0000 @@ -1 +1,4 @@ -python-openid >= 2.1.0 \ No newline at end of file +python-openid >= 2.1.0 + +[teams] +python-openid-teams \ No newline at end of file diff -Nru trac-authopenid-0.4.1/TracAuthOpenId.egg-info/SOURCES.txt trac-authopenid-0.4.7/TracAuthOpenId.egg-info/SOURCES.txt --- trac-authopenid-0.4.1/TracAuthOpenId.egg-info/SOURCES.txt 2012-06-25 22:51:20.000000000 +0000 +++ trac-authopenid-0.4.7/TracAuthOpenId.egg-info/SOURCES.txt 2013-12-06 15:18:17.000000000 +0000 @@ -10,7 +10,6 @@ TracAuthOpenId.egg-info/entry_points.txt TracAuthOpenId.egg-info/requires.txt TracAuthOpenId.egg-info/top_level.txt -TracAuthOpenId.egg-info/trac_plugin.txt authopenid/__init__.py authopenid/authopenid.py authopenid/htdocs/css/openid.css diff -Nru trac-authopenid-0.4.1/TracAuthOpenId.egg-info/trac_plugin.txt trac-authopenid-0.4.7/TracAuthOpenId.egg-info/trac_plugin.txt --- trac-authopenid-0.4.1/TracAuthOpenId.egg-info/trac_plugin.txt 2012-06-25 21:09:15.000000000 +0000 +++ trac-authopenid-0.4.7/TracAuthOpenId.egg-info/trac_plugin.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -authopenid - -