[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Removing the domain from mod_auth_sspi usernames

From: Rob Oxspring <roxspring_at_imapmail.org>
Date: 2006-03-16 15:58:40 CET

Hi,

We have a Windows box serving svn through mod_dav_svn and authenticating
using mod_auth_sspi. It seems to be working well, except that the
svn:author property ends up having the windows domain name in it which
looks a little ugly. Maybe I've got things set up wrongly and someone
can correct my setup, but until then I have written a hook that strips
the domainname from svn:author.

I say written, but its actually shamelessly stolen log-police.py that
I've hacked slightly as my first attempt at python coding (so be gentle
with me please).

Thought I'd share it in case others are interested,

Rob

#!/usr/bin/python

# author-police.py: Ensure that log messages end with a single newline.
# See usage() function for details, or just run with no arguments.

import os
import sys
import getopt
import string

import svn
import svn.fs
import svn.repos
import svn.core

# Pretend we have true booleans on older python versions
try:
  True
except:
  True = 1
  False = 0

def fix_author(author):
  """Strips the domain information from the beginning of an author."""
  
  index = author.find("\\")
  author = author[index+1:]
  return author

def fix_txn(fs, txn_name):
  "Fix up the log message for txn TXN_NAME in FS. See fix_log_author()."
  txn = svn.fs.svn_fs_open_txn(fs, txn_name)
  old_author = svn.fs.svn_fs_txn_prop(txn, "svn:author")
  if old_author is not None:
    new_author = fix_author(old_author)
    if new_author != old_author:
      svn.fs.svn_fs_change_txn_prop(txn, "svn:author", new_author)

def fix_rev(fs, revnum):
  "Fix up the log message for revision REVNUM in FS. See fix_log_author()."
  old_author = svn.fs.svn_fs_revision_prop(fs, revnum, 'svn:author')
  if old_author is not None:
    new_author = fix_author(old_author)
    if new_author != old_author:
      svn.fs.svn_fs_change_rev_prop(fs, revnum, "svn:author", new_author)

def usage_and_exit(error_msg=None):
  """Write usage information and exit. If ERROR_MSG is provide, that
  error message is printed first (to stderr), the usage info goes to
  stderr, and the script exits with a non-zero status. Otherwise,
  usage info goes to stdout and the script exits with a zero status."""
  import os.path
  stream = error_msg and sys.stderr or sys.stdout
  if error_msg:
    stream.write("ERROR: %s\n\n" % error_msg)
  stream.write("USAGE: %s [-t TXN_NAME | -r REV_NUM | --all-revs] REPOS\n"
               % (os.path.basename(sys.argv[0])))
  stream.write("""
Ensure that log messages end with exactly one newline and no other
whitespace characters. Use as a pre-commit hook by passing '-t TXN_NAME';
fix up a single revision by passing '-r REV_NUM'; fix up all revisions by
passing '--all-revs'. (When used as a pre-commit hook, may modify the
svn:log property on the txn.)
""")
  sys.exit(error_msg and 1 or 0)

def main(ignored_pool, argv):
  repos_path = None
  txn_name = None
  rev_name = None
  all_revs = False
  
  try:
    opts, args = getopt.getopt(argv[1:], 't:r:h?', ["help", "all-revs"])
  except:
    usage_and_exit("problem processing arguments / options.")
  for opt, value in opts:
    if opt == '--help' or opt == '-h' or opt == '-?':
      usage_and_exit()
    elif opt == '-t':
      txn_name = value
    elif opt == '-r':
      rev_name = value
    elif opt == '--all-revs':
      all_revs = True
    else:
      usage_and_exit("unknown option '%s'." % opt)

  if txn_name is not None and rev_name is not None:
    usage_and_exit("cannot pass both -t and -r.")
  if txn_name is not None and all_revs:
    usage_and_exit("cannot pass --all-revs with -t.")
  if rev_name is not None and all_revs:
    usage_and_exit("cannot pass --all-revs with -r.")
  if rev_name is None and txn_name is None and not all_revs:
    usage_and_exit("must provide exactly one of -r, -t, or --all-revs.")
  if len(args) != 1:
    usage_and_exit("only one argument allowed (the repository).")
  
  # svn_path_canonicalize doesn't seem to work from a stock 1.3.0 on windows
  # repos_path = svn.core.svn_path_canonicalize(args[0])
  repos_path = args[0]
  
  # A non-bindings version of this could be implemented by calling out
  # to 'svnlook getlog' and 'svnadmin setlog'. However, using the
  # bindings results in much simpler code.

  fs = svn.repos.svn_repos_fs(svn.repos.svn_repos_open(repos_path))
  if txn_name is not None:
    fix_txn(fs, txn_name)
  elif rev_name is not None:
    fix_rev(fs, int(rev_name))
  elif all_revs:
    # Do it such that if we're running on a live repository, we'll
    # catch up even with commits that came in after we started.
    last_youngest = 0
    while True:
      youngest = svn.fs.svn_fs_youngest_rev(fs)
      if youngest >= last_youngest:
        for this_rev in range(last_youngest, youngest + 1):
          fix_rev(fs, this_rev)
        last_youngest = youngest + 1
      else:
        break

if __name__ == '__main__':
  sys.exit(svn.core.run_app(main, sys.argv))

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu Mar 16 16:06:42 2006

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.