Index: main.py
===================================================================
--- main.py	(revision 6047)
+++ main.py	(working copy)
@@ -102,11 +102,29 @@
             # others are file uploads
 
 
+class ISessionObserver(Interface):
+    def pass_user_fields(self, username, email, _name):
+        """
+        Method called every time get_session() is called
+        'username' will be the authenticated user's username or
+        'anonymous'.  'email' and '_name' will be None if they have never
+        been set for the user.  This method should return a tuple
+        (email, _name) containing their (possibly modified) values.
+        
+        It is recommended that only one plugin implement ISessionObserver; 
+        since there is no way to guarantee the order in which Components 
+        are called via an ExtensionPoint, multiple ISessionObservers that
+        modify these fields would yield unpredictable results.
+        """
+        raise NotImplementedError
+
+
 class RequestDispatcher(Component):
     """Component responsible for dispatching requests to registered handlers."""
 
     authenticators = ExtensionPoint(IAuthenticator)
     handlers = ExtensionPoint(IRequestHandler)
+    session_observers = ExtensionPoint(ISessionObserver)
 
     filters = OrderedExtensionsOption('trac', 'request_filters', IRequestFilter,
         doc="""Ordered list of filters to apply to all requests
@@ -247,7 +265,16 @@
         return PermissionCache(self.env, self.authenticate(req))
 
     def _get_session(self, req):
-        return Session(self.env, req)
+        curr_session = Session(self.env, req)
+        for obs in self.session_observers:
+            (newemail, newname) = obs.pass_user_fields(req.authname, 
+                                            curr_session.get('email',None),
+                                            curr_session.get('name',None))
+            if newemail and newemail != curr_session.get('email',None):
+                curr_session['email'] = newemail
+            if newname and newname != curr_session.get('name',None):
+                curr_session['name'] = newname
+        return curr_session
 
     def _get_timezone(self, req):
         try:

