[Trac-tickets] [The Trac Project] #2310: Domain\username problem in windows - fixed

The Trac Project noreply at edgewall.com
Fri Nov 4 20:40:47 CST 2005


#2310: Domain\username problem in windows - fixed
----------------------------------------------------------+-----------------
 Reporter:  anonymous                                     |       Owner:  jonas
     Type:  enhancement                                   |      Status:  new  
 Priority:  normal                                        |   Milestone:       
Component:  general                                       |     Version:  0.9b2
 Severity:  major                                         |   Keywords:  login authentication lower upper case ignore  |  
----------------------------------------------------------+-----------------
 Here at Bowne Rio, we started to use trac in Windows without the
 ''ignore_auth_case'' setting turned on.  We have, then, standardized that
 the domain should be written in uppercase and the username in lowercase,
 since that seems to be the way subversion reports the usernames.

 Some time after that, I've tried to turn on the trac auto-logon for users
 inside our intranet.  I have expected that the ''ignore_auth_case''
 setting would help us.  Unfortunately, when we tried to turn it on, all
 the existing issues remained assigned to the 'other-case' usernames.

 Aiming to fix that, my first idea was to update the database.  But I've
 found it would be easier to try my first Python attempt.

 Here it follows an ''auth.py'' patch to give the administrator the ability
 to force a fixed case for both Windows domain and username.

 Since the ''ignore_auth_case'' setting didn't feet our needs, I've
 included the ''auth_domain_case'' and ''auth_username_case'' settings.
 Setting both to 'lower' is equivalent to set ignore_auth_case to true.

 The two settings are expected under the [trac] section of trac.ini, as
 seen below:
 {{{
 [trac]
 ignore_auth_case = [true|false]
 auth_domain_case = [lower|upper]
 auth_username_case = [lower|upper]
 }}}

 The patch:
 {{{
 --- .\trac\web\auth.py.orig     2005-09-25 17:06:28.000000000 -0200
 +++ .\trac\web\auth.py  2005-11-04 23:54:05.000000000 -0200
 @@ -20,12 +20,14 @@

  from trac.core import *
  from trac.web.api import IAuthenticator, IRequestHandler
  from trac.web.chrome import INavigationContributor
  from trac.util import escape, hex_entropy, TRUE

 +LOWER = ['l', 'lo', 'lower']
 +UPPER = ['u', 'up', 'upper']

  class LoginModule(Component):
      """Implements user authentication based on HTTP authentication
 provided by
      the web-server, combined with cookies for communicating the login
      information across the whole site.

 @@ -48,17 +50,13 @@
          elif req.incookie.has_key('trac_auth'):
              authname = self._get_name_for_cookie(req,
 req.incookie['trac_auth'])

          if not authname:
              return None

 -        ignore_case = self.env.config.get('trac', 'ignore_auth_case')
 -        ignore_case = ignore_case.strip().lower() in TRUE
 -        if ignore_case:
 -            authname = authname.lower()
 -        return authname
 +        return self._fix_auth_id_case(req, authname)

      # INavigationContributor methods

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

 @@ -82,12 +80,52 @@
          elif req.path_info.startswith('/logout'):
              self._do_logout(req)
          self._redirect_back(req)

      # Internal methods

 +    def _fix_auth_id_case(self, req, auth_id):
 +        fixed_id = auth_id
 +
 +        ignore_case = self.env.config.get('trac', 'ignore_auth_case')
 +        ignore_case = ignore_case.strip().lower() in TRUE
 +        if ignore_case:
 +            fixed_id = fixed_id.lower()
 +
 +        auth_domain_case = self.env.config.get('trac',
 'auth_domain_case')
 +        lower_auth_domain_case = auth_domain_case.strip().lower() in
 LOWER
 +        upper_auth_domain_case = auth_domain_case.strip().lower() in
 UPPER
 +        change_domain_case = lower_auth_domain_case or
 upper_auth_domain_case
 +
 +        auth_username_case = self.env.config.get('trac',
 'auth_username_case')
 +        lower_auth_username_case = auth_username_case.strip().lower() in
 LOWER
 +        upper_auth_username_case = auth_username_case.strip().lower() in
 UPPER
 +        change_username_case = lower_auth_username_case or
 upper_auth_username_case
 +
 +        change_auth_case = change_domain_case or change_username_case
 +        if change_domain_case:
 +            expected_pair = fixed_id.split('\\')
 +            has_domain_in_id = (len(expected_pair) == 2)
 +            if has_domain_in_id:
 +                domain_part = expected_pair[0]
 +                username_part = expected_pair[1]
 +
 +                if lower_auth_domain_case:
 +                    domain_part = domain_part.lower()
 +                if upper_auth_domain_case:
 +                    domain_part = domain_part.upper()
 +
 +                if lower_auth_username_case:
 +                    username_part = username_part.lower()
 +                if upper_auth_username_case:
 +                    username_part = username_part.upper()
 +
 +                fixed_id = '%s\\%s' % (domain_part, username_part)
 +
 +        return fixed_id
 +
      def _do_login(self, req):
          """Log the remote user in.

          This function expects to be called when the remote user name is
          available. The user name is inserted into the `auth_cookie` table
 and a
          cookie identifying the user on subsequent requests is sent back
 to the
 @@ -98,17 +136,13 @@
          will be converted to lower case before being used. This is to
 avoid
          problems on installations authenticating against Windows which is
 not
          case sensitive regarding user names and domain names
          """
          assert req.remote_user, 'Authentication information not
 available.'

 -        remote_user = req.remote_user
 -        ignore_case = self.env.config.get('trac', 'ignore_auth_case')
 -        ignore_case = ignore_case.strip().lower() in TRUE
 -        if ignore_case:
 -            remote_user = remote_user.lower()
 +        remote_user = self._fix_auth_id_case(req, req.remote_user)

          assert req.authname in ('anonymous', remote_user), \
                 'Already logged in as %s.' % req.authname

          cookie = hex_entropy()
          db = self.env.get_db_cnx()
 }}}

 Enrique Pessoa < enrique_dot_pessoa_at_bowne_dot_com >

-- 
Ticket URL: <http://projects.edgewall.com/trac/ticket/2310>
The Trac Project <http://trac.edgewall.com/>


More information about the Trac-Tickets mailing list