Package: trac-authopenid
Version: 0.4.7-1
Severity: grave
Tags: patch
Justification: renders package unusable

on debian stretch and later, trac is version 1.2.  but trac-authopenid
0.4.7-1 uses get_db_cnx(), which was deprecated in trac 0.12 and
removed in trac 1.1.

As a result, if trac-authopenid is installed and configured for a trac
environment, that environment will fail to load at all.

see https://trac.edgewall.org/wiki/TracDev/ApiChanges/1.1#DatabaseAPIChanges

the attached patch appears to fix the worst errors, but hasn't been
well-tested.

        --dkg


-- System Information:
Debian Release: buster/sid
  APT prefers testing-debug
  APT policy: (500, 'testing-debug'), (500, 'testing'), (500, 'oldstable'), 
(200, 'unstable-debug'), (200, 'unstable'), (1, 'experimental-debug'), (1, 
'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.15.0-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages trac-authopenid depends on:
ii  python         2.7.14-4
ii  python-openid  2.2.5-6
ii  trac           1.2.2+dfsg-1

trac-authopenid recommends no packages.

trac-authopenid suggests no packages.

-- no debconf information
From: Daniel Kahn Gillmor <d...@fifthhorseman.net>
Date: Mon, 9 Apr 2018 07:30:15 -0400
Subject: move from get_db_cnx() to context manager

See
https://trac.edgewall.org/wiki/TracDev/ApiChanges/1.1#DatabaseAPIChanges
for more details about this migration.
---
 authopenid/authopenid.py | 660 +++++++++++++++++++++++------------------------
 1 file changed, 330 insertions(+), 330 deletions(-)

diff --git a/authopenid/authopenid.py b/authopenid/authopenid.py
index da98b19..112c175 100644
--- a/authopenid/authopenid.py
+++ b/authopenid/authopenid.py
@@ -227,7 +227,6 @@ class AuthOpenIdPlugin(Component):
         return generated_list
 
     def __init__(self):
-        db = self.env.get_db_cnx()
         oidutil.log = OpenIdLogger(self.env)
         self.env.log.debug("Compiling white-list")
         self.re_white_list = self.generate_re_list(self.white_list)
@@ -264,9 +263,9 @@ class AuthOpenIdPlugin(Component):
     # IEnvironmentSetupParticipant methods
 
     def environment_created(self):
-        db = self.env.get_db_cnx()
-        self._initStore(db)
-        db.commit()
+        with self.env.db_transaction as db:
+            self._initStore(db)
+            db.commit()
 
     def environment_needs_upgrade(self, db):
         c = db.cursor()
@@ -414,36 +413,18 @@ class AuthOpenIdPlugin(Component):
 
         immediate = 'immediate' in req.args
 
-        db = self.env.get_db_cnx()
-        oidconsumer, oidsession = self._get_consumer(req, db)
-        try:
-            self.env.log.debug('beginning OpenID authentication.')
-            request = oidconsumer.begin(openid_url)
-        except consumer.DiscoveryFailure, exc:
-            fetch_error_string = 'Error in discovery: %s' % (
-                cgi.escape(str(exc[0])))
-            return 'openidlogin.html', {
-                'images': req.href.chrome('authopenid/images') + '/',
-                'action': req.href.openidverify(),
-                'message': fetch_error_string,
-                'signup': self.signup_link,
-                'whatis': self.whatis_link,
-                'css_class': 'error',
-                'providers_regexp': self.providers_regexp,
-                'custom_provider_name': self.custom_provider_name,
-                'custom_provider_label': self.custom_provider_label,
-                'custom_provider_url': self.custom_provider_url,
-                'custom_provider_image': self.custom_provider_image,
-                'custom_provider_size': self.custom_provider_size,
-                }, None
-        else:
-            if request is None:
-                msg = 'No OpenID services found for <code>%s</code>' % (
-                    cgi.escape(openid_url),)
+        with self.env.db_transaction as db:
+            oidconsumer, oidsession = self._get_consumer(req, db)
+            try:
+                self.env.log.debug('beginning OpenID authentication.')
+                request = oidconsumer.begin(openid_url)
+            except consumer.DiscoveryFailure, exc:
+                fetch_error_string = 'Error in discovery: %s' % (
+                    cgi.escape(str(exc[0])))
                 return 'openidlogin.html', {
                     'images': req.href.chrome('authopenid/images') + '/',
                     'action': req.href.openidverify(),
-                    'message': msg,
+                    'message': fetch_error_string,
                     'signup': self.signup_link,
                     'whatis': self.whatis_link,
                     'css_class': 'error',
@@ -453,25 +434,43 @@ class AuthOpenIdPlugin(Component):
                     'custom_provider_url': self.custom_provider_url,
                     'custom_provider_image': self.custom_provider_image,
                     'custom_provider_size': self.custom_provider_size,
-                   }, None
+                }, None
             else:
-                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
-                # communicate securely with the identity server.
+                if request is None:
+                    msg = 'No OpenID services found for <code>%s</code>' % (
+                        cgi.escape(openid_url),)
+                    return 'openidlogin.html', {
+                        'images': req.href.chrome('authopenid/images') + '/',
+                        'action': req.href.openidverify(),
+                        'message': msg,
+                        'signup': self.signup_link,
+                        'whatis': self.whatis_link,
+                        'css_class': 'error',
+                        'providers_regexp': self.providers_regexp,
+                        'custom_provider_name': self.custom_provider_name,
+                        'custom_provider_label': self.custom_provider_label,
+                        'custom_provider_url': self.custom_provider_url,
+                        'custom_provider_image': self.custom_provider_image,
+                        'custom_provider_size': self.custom_provider_size,
+                    }, None
+                else:
+                    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
+                    # communicate securely with the identity server.
 
-                requested_policies = []
-                if self.pape_method:
-                   requested_policies.append(self.pape_method)
+                    requested_policies = []
+                    if self.pape_method:
+                        requested_policies.append(self.pape_method)
 
-                pape_method = req.args.get('pape_method')
-                if pape_method:
-                    requested_policies.append(pape_method)
+                    pape_method = req.args.get('pape_method')
+                    if pape_method:
+                        requested_policies.append(pape_method)
 
-                if requested_policies:
-                    pape_request = pape.Request(requested_policies)
-                    request.addExtension(pape_request)
+                    if requested_policies:
+                        pape_request = pape.Request(requested_policies)
+                        request.addExtension(pape_request)
 
                 # Let the sreg policy be configurable
                 sreg_opt = []
@@ -532,17 +531,17 @@ class AuthOpenIdPlugin(Component):
 
         :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()
+        with self.env.db_query as db:
+            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:
@@ -559,242 +558,242 @@ class AuthOpenIdPlugin(Component):
     def _do_process(self, req):
         """Handle the redirect from the OpenID server.
         """
-        db = self.env.get_db_cnx()
-        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.
-        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:
-            # In the case of failure, if info is non-None, it is the
-            # URL that we were verifying. We include it in the error
-            # message to help the user figure out what happened.
-            fmt = "Verification of %s failed: %s"
-            message = fmt % (cgi.escape(info.identity_url),
-                             info.message)
-        elif info.status == consumer.SUCCESS:
-            # Success means that the transaction completed without
-            # error. If info is None, it means that the user cancelled
-            # 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.
-            fmt = "You have successfully verified %s as your identity."
-            message = fmt % (cgi.escape(info.identity_url),)
-            remote_user = info.identity_url
-
-            sreg_info = sreg.SRegResponse.fromSuccessResponse(info) or {}
-
-            ax_response = ax.FetchResponse.fromSuccessResponse(info)
-            ax_info = {}
-            if ax_response:
-                for alias, uri in self.openid_ax_attrs.items():
-                    values = ax_response.data.get(uri,[])
-                    if values:
-                        ax_info[alias] = values[0]
-
-            email = (ax_info.get('email')
-                     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 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:]
-            if self.strip_trailing_slash and remote_user[-1] == '/':
-                remote_user = remote_user[:-1]
-            if info.endpoint.canonicalID:
-                # You should authorize i-name users by their canonicalID,
-                # rather than their more human-friendly identifiers.  That
-                # way their account with you is not compromised if their
-                # i-name registration expires and is bought by someone else.
-                message += ("  This is an i-name, and its persistent ID is %s"
-                            % (cgi.escape(info.endpoint.canonicalID),))
-                remote_user = info.endpoint.canonicalID
-
-            allowed = True
-            if self.re_white_list:
-                self.env.log.debug("Filtering REMOTE_USER '%s' through 
white-list." % remote_user)
-                allowed = False
-                for item in self.re_white_list:
-                    if not allowed and item.match(remote_user):
-                        allowed = True
-                        self.env.log.debug("User white-listed.")
-            if allowed and self.re_black_list:
-                self.env.log.debug("Filtering REMOTE_USER '%s' through 
black-list." % remote_user)
-                for item in self.re_black_list:
-                    if item.match(remote_user):
-                        allowed = False
-                        self.env.log.debug("User black-listed.")
-            if allowed and self.re_email_white_list:
-                self.env.log.debug("Filtering email %r through email 
white-list." % email)
-                allowed = False
-                if email:
-                    for item in self.re_email_white_list:
-                        if not allowed and item.match(email):
+        with self.env.db_transaction as 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.
+            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:
+                # In the case of failure, if info is non-None, it is the
+                # URL that we were verifying. We include it in the error
+                # message to help the user figure out what happened.
+                fmt = "Verification of %s failed: %s"
+                message = fmt % (cgi.escape(info.identity_url),
+                                 info.message)
+            elif info.status == consumer.SUCCESS:
+                # Success means that the transaction completed without
+                # error. If info is None, it means that the user cancelled
+                # 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.
+                fmt = "You have successfully verified %s as your identity."
+                message = fmt % (cgi.escape(info.identity_url),)
+                remote_user = info.identity_url
+
+                sreg_info = sreg.SRegResponse.fromSuccessResponse(info) or {}
+
+                ax_response = ax.FetchResponse.fromSuccessResponse(info)
+                ax_info = {}
+                if ax_response:
+                    for alias, uri in self.openid_ax_attrs.items():
+                        values = ax_response.data.get(uri,[])
+                        if values:
+                            ax_info[alias] = values[0]
+
+                email = (ax_info.get('email')
+                         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 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:]
+                if self.strip_trailing_slash and remote_user[-1] == '/':
+                    remote_user = remote_user[:-1]
+                if info.endpoint.canonicalID:
+                    # You should authorize i-name users by their canonicalID,
+                    # rather than their more human-friendly identifiers.  That
+                    # way their account with you is not compromised if their
+                    # i-name registration expires and is bought by someone 
else.
+                    message += ("  This is an i-name, and its persistent ID is 
%s"
+                                % (cgi.escape(info.endpoint.canonicalID),))
+                    remote_user = info.endpoint.canonicalID
+
+                allowed = True
+                if self.re_white_list:
+                    self.env.log.debug("Filtering REMOTE_USER '%s' through 
white-list." % remote_user)
+                    allowed = False
+                    for item in self.re_white_list:
+                        if not allowed and item.match(remote_user):
                             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)
-                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()
-                cookie_lifetime = self.trac_auth_cookie_lifetime
-
-                req.outcookie['trac_auth'] = cookie
-                req.outcookie['trac_auth']['path'] = req.href()
-                if cookie_lifetime > 0:
-                    req.outcookie['trac_auth']['expires'] = cookie_lifetime
-
-                session_attr[self.openid_session_identity_url_key] = 
info.identity_url
-                if email:
-                    session_attr['email'] = email
-                if fullname:
-                    session_attr['name'] = fullname
-
-                self._commit_oidsession(oidsession, req)
-
-                # 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)
-                    # 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
+                            self.env.log.debug("User white-listed.")
+                if allowed and self.re_black_list:
+                    self.env.log.debug("Filtering REMOTE_USER '%s' through 
black-list." % remote_user)
+                    for item in self.re_black_list:
+                        if item.match(remote_user):
+                            allowed = False
+                            self.env.log.debug("User black-listed.")
+                if allowed and self.re_email_white_list:
+                    self.env.log.debug("Filtering email %r through email 
white-list." % email)
+                    allowed = False
+                    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)
+                    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)
 
-                    # Possibly lower-case the authname.
-                    if self.lowercase_authname:
-                        authname = authname.lower()
+                if allowed:
+                    cookie = hex_entropy()
+                    cookie_lifetime = self.trac_auth_cookie_lifetime
 
-                    if self.trust_authname:
+                    req.outcookie['trac_auth'] = cookie
+                    req.outcookie['trac_auth']['path'] = req.href()
+                    if cookie_lifetime > 0:
+                        req.outcookie['trac_auth']['expires'] = cookie_lifetime
+
+                    session_attr[self.openid_session_identity_url_key] = 
info.identity_url
+                    if email:
+                        session_attr['email'] = email
+                    if fullname:
+                        session_attr['name'] = fullname
+
+                    self._commit_oidsession(oidsession, req)
+
+                    # 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)
+                        # 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:
-                        # 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):
+                        # 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)
-                            # 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
-
-                db = self.env.get_db_cnx()
-                cursor = db.cursor()
-                cursor.execute("INSERT INTO auth_cookie 
(cookie,name,ipnr,time) "
-                               "VALUES (%s, %s, %s, %s)", (cookie, authname,
-                               self._get_masked_address(req.remote_addr), 
int(time.time())))
-                db.commit()
-
-                req.redirect(req.session.get('oid.referer') or 
self.env.abs_href())
-            else:
-                message = 'You are not allowed here.'
-        elif info.status == consumer.CANCEL:
-            # cancelled
-            message = 'Verification cancelled'
-        elif info.status == consumer.SETUP_NEEDED:
-            if info.setup_url:
-                message = '<a href=%s>Setup needed</a>' % (
-                    quoteattr(info.setup_url),)
+                        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
+
+                    with self.env.db_transaction as db:
+                        cursor = db.cursor()
+                        cursor.execute("INSERT INTO auth_cookie 
(cookie,name,ipnr,time) "
+                                       "VALUES (%s, %s, %s, %s)", (cookie, 
authname,
+                                                                   
self._get_masked_address(req.remote_addr), int(time.time())))
+                        db.commit()
+
+                    req.redirect(req.session.get('oid.referer') or 
self.env.abs_href())
+                else:
+                    message = 'You are not allowed here.'
+            elif info.status == consumer.CANCEL:
+                # cancelled
+                message = 'Verification cancelled'
+            elif info.status == consumer.SETUP_NEEDED:
+                if info.setup_url:
+                    message = '<a href=%s>Setup needed</a>' % (
+                        quoteattr(info.setup_url),)
+                else:
+                    # This means auth didn't succeed, but you're welcome to try
+                    # non-immediate mode.
+                    message = 'Setup needed'
             else:
-                # This means auth didn't succeed, but you're welcome to try
-                # non-immediate mode.
-                message = 'Setup needed'
-        else:
-            # Either we don't understand the code or there is no
-            # openid_url included with the error. Give a generic
-            # failure message. The library should supply debug
-            # information in a log.
-            message = 'Verification failed.'
+                # Either we don't understand the code or there is no
+                # openid_url included with the error. Give a generic
+                # failure message. The library should supply debug
+                # information in a log.
+                message = 'Verification failed.'
 
-        self._commit_oidsession(oidsession, req)
+            self._commit_oidsession(oidsession, req)
 
         add_stylesheet(req, 'authopenid/css/openid.css')
         add_script(req, 'authopenid/js/openid-jquery.js')
@@ -838,17 +837,18 @@ class AuthOpenIdPlugin(Component):
         stale = int(time.time()) - expires
         authcookie = req.incookie.get('trac_auth')
 
-        db = self.env.get_db_cnx()
-        cursor = db.cursor()
-        if authcookie:
-            cursor.execute("DELETE FROM auth_cookie"
-                           " WHERE cookie=%s OR time < %s",
-                           (authcookie.value, stale))
-        else:
-            cursor.execute("DELETE FROM auth_cookie"
-                           " WHERE name=%s OR time < %s",
-                           (req.authname, stale))
-        db.commit()
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            if authcookie:
+                cursor.execute("DELETE FROM auth_cookie"
+                               " WHERE cookie=%s OR time < %s",
+                               (authcookie.value, stale))
+            else:
+                cursor.execute("DELETE FROM auth_cookie"
+                               " WHERE name=%s OR time < %s",
+                               (req.authname, stale))
+            db.commit()
+
         self._expire_cookie(req)
         custom_redirect = self.config['metanav'].get('logout.redirect')
         if custom_redirect:
@@ -868,39 +868,39 @@ class AuthOpenIdPlugin(Component):
 
     def _get_name_for_cookie(self, req, cookie):
         masked_addr = self._get_masked_address(req.remote_addr)
-        db = self.env.get_db_cnx()
-        cursor = db.cursor()
-        if self.check_ip:
-            cursor.execute("SELECT name FROM auth_cookie "
-                           "WHERE cookie=%s AND ipnr=%s",
-                           (cookie.value, masked_addr))
-        else:
-            cursor.execute("SELECT name FROM auth_cookie WHERE cookie=%s",
-                           (cookie.value,))
-
-        row = cursor.fetchone()
-        if row:
-            name = row[0]
-            if self.timeout:
-                now = int(time.time())
-                if self.check_ip:
-                    cursor.execute("UPDATE auth_cookie SET time=%s "
-                                   "WHERE cookie=%s AND ipnr=%s AND name=%s",
-                                   (now, cookie.value, masked_addr, name))
-                else:
-                    cursor.execute("UPDATE auth_cookie SET time=%s "
-                                   "WHERE cookie=%s AND name=%s",
-                                   (now, cookie.value, name))
-
-                cookie_lifetime = self.trac_auth_cookie_lifetime
-                if cookie_lifetime > 0:
-                    req.outcookie['trac_auth'] = cookie.value
-                    req.outcookie['trac_auth']['path'] = req.href()
-                    req.outcookie['trac_auth']['expires'] = cookie_lifetime
-        else:
-            # The cookie is invalid but we don't expire it because it might
-            # be generated by different trac authentication mechanism.
-            name = None
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            if self.check_ip:
+                cursor.execute("SELECT name FROM auth_cookie "
+                               "WHERE cookie=%s AND ipnr=%s",
+                               (cookie.value, masked_addr))
+            else:
+                cursor.execute("SELECT name FROM auth_cookie WHERE cookie=%s",
+                               (cookie.value,))
+
+            row = cursor.fetchone()
+            if row:
+                name = row[0]
+                if self.timeout:
+                    now = int(time.time())
+                    if self.check_ip:
+                        cursor.execute("UPDATE auth_cookie SET time=%s "
+                                       "WHERE cookie=%s AND ipnr=%s AND 
name=%s",
+                                       (now, cookie.value, masked_addr, name))
+                    else:
+                        cursor.execute("UPDATE auth_cookie SET time=%s "
+                                       "WHERE cookie=%s AND name=%s",
+                                       (now, cookie.value, name))
+
+                    cookie_lifetime = self.trac_auth_cookie_lifetime
+                    if cookie_lifetime > 0:
+                        req.outcookie['trac_auth'] = cookie.value
+                        req.outcookie['trac_auth']['path'] = req.href()
+                        req.outcookie['trac_auth']['expires'] = cookie_lifetime
+            else:
+                # The cookie is invalid but we don't expire it because it might
+                # be generated by different trac authentication mechanism.
+                name = None
 
-        db.commit()
+            db.commit()
         return name

Reply via email to