Hi all, I've never coded python or trac before so please excuse me if
what I am doing is totally wrong, but I cannot for the life of me
figure this out.

What i've done is totally rip out the trac session / login system,
because what I want to do is replace it with an XML API call to a URL
on my website. The basic code is:

-----

IAuthenticator
authenticate method

 if we haven't already checked
   call api to validate user

return valid or not

-----

Problem is, it seems trac or python remembers all values set to the
self.authenticated field, across every refresh, even if different
people are viewing the page. How can I make it so this function runs
once every page reload, saves if the user is authenticated and thats
it? My code is:

-----

import sys, urllib

from genshi.builder import tag
from xml.dom import minidom
from trac.core import *
from trac.web.api import IAuthenticator
from trac.web import chrome
from trac.web.chrome import INavigationContributor
from trac.db.api import DatabaseManager
from trac.config import Option

class AuthXMLModule(Component):
    """ Automatically try and login anonymous users on each request.
"""

    implements(IAuthenticator, INavigationContributor)

    authenticated = False
    authname = None

    # This is here so that the account manager configuration page will
pick
    username_cookie = Option('xmlauth', 'username_cookie', None,
                      'Cookie containing the users id')
    password_cookie = Option('xmlauth', 'password_cookie', None,
                      'Cookie containing the users password')
    xml_url = Option('xmlauth', 'xml_url', None,
                      'URL called with the cookies to validate')
    ok_code = Option('xmlauth', 'ok_code', 0,
                      'XML code indicating the request was a success')

    # IAuthenticator methods

    def authenticate(self, req):
        """ Connect to the API specified and attempt to validate the user """

        if not self.authenticated:
                self.authenticated = True

                if req.incookie.has_key(self.username_cookie) and
req.incookie.has_key(self.password_cookie):
                        username = req.incookie[self.username_cookie].value
                        password = req.incookie[self.password_cookie].value
                        params = urllib.urlencode({'username': username, 
'password':
password})

                        try:
                                dom = 
minidom.parse(urllib.urlopen(self.xml_url, params))
                                trac = dom.getElementsByTagName("trac")[0]
                                status = 
trac.getElementsByTagName('status')[0].getAttribute
('code')

                                if status == self.ok_code:
                                        ignore_auth_case = 
self.env.config.get('trac',
'ignore_auth_case')
                                        memberdetails = 
trac.getElementsByTagName('member')[0]
                                        # member = 
memberdetails.getAttribute('siteareaid')
                                        self.authname = 
self._get_text(memberdetails.getElementsByTagName
('username')[0].childNodes)
                                        email = 
self._get_text(memberdetails.getElementsByTagName('email')
[0].childNodes)
                                        datelastvisit = 
self._get_text(memberdetails.getElementsByTagName
('datelastvisit')[0].childNodes)

                                        if ignore_auth_case:
                                                self.authname = 
self.authname.lower()

                                        
self._populate_user_session([self.authname, email,
datelastvisit])
                                else:
                                        chrome.add_notice(req, 
self._get_text(trac.getElementsByTagName
('status')[0].childNodes))

                                dom.unlink()
                        except Exception, e:
                                self.log.warning('Exception processing the 
session data: %s' %
(e))
                                chrome.add_warning(req, 'An error has occured 
logging you in to
trac.')

        self.log.error(self.authname)

        return self.authname

    # INavigationContributor methods

    def get_active_navigation_item(self, req):
        return 'login'

    def get_navigation_items(self, req):
        if req.authname and req.authname != 'anonymous':
            yield ('metanav', 'login', ('logged in as %s' %
(req.authname)))
        else:
            yield ('metanav', 'login', 'not logged in')

    # Internal methods

    def _populate_user_session(self, userinfo):
        """ Create user session entries and populate email and last
visit """

        # Replace the current session and update the email with data
from the API
        uname, email, lastvisit = userinfo

        cnx = self.env.get_db_cnx()

        try:
            cur = cnx.cursor()
            cur.execute('REPLACE INTO session (sid, authenticated, '
                        'last_visit) VALUES (%s, 1, %s)',
                        (uname, lastvisit))
            cnx.commit()
        except:
            cnx.rollback()
        try:
            cur = cnx.cursor()
            cur.execute("REPLACE INTO session_attribute"
                        "    (sid, authenticated, name, value)"
                        " VALUES (%s, 1, 'email', %s)",
                        (uname, email))
            cnx.commit()
        except:
            cnx.rollback()

        cnx.close()

    def _get_text(self, nodelist):
        rc = ""
        for node in nodelist:
            if node.nodeType == node.TEXT_NODE:
                rc = rc + node.data
        return rc

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Trac 
Development" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/trac-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to