Use .mercurial-sever file instead of hardcoding
authorPaul Crowley <paul@lshift.net>
Mon, 09 Nov 2009 12:15:09 +0000
changeset 165 3606d60b07e5
parent 164 32131253c2f1
child 166 d7e6f114e8e4
Use .mercurial-sever file instead of hardcoding
install
src/hg-ssh
src/init/hginit
src/mercurialserver/paths.py
src/mercurialserver/refreshauth.py
src/refresh-auth
--- a/install	Fri Oct 30 16:55:07 2009 +0000
+++ b/install	Mon Nov 09 12:15:09 2009 +0000
@@ -47,6 +47,7 @@
     'src/mercurialserver/ruleset.py')
 installFiles(options.prefix + '/share/mercurial-server/init',
     'src/init/hginit',
+    'src/init/dot-mercurial-server',
     'src/init/hgadmin-hgrc')
 installFiles(options.prefix + '/share/doc/mercurial-server',
     'README',
@@ -64,6 +65,7 @@
         os.setegid(p.pw_gid)
         os.setuid(p.pw_uid)
         os.seteuid(p.pw_uid)
+        os.chdir(p.pw_dir)
     return become
 
 if options.root == '':
--- a/src/hg-ssh	Fri Oct 30 16:55:07 2009 +0000
+++ b/src/hg-ssh	Mon Nov 09 12:15:09 2009 +0000
@@ -84,13 +84,11 @@
 # Use a different hgrc for remote pulls - this way you can set
 # up access.py for everything at once without affecting local operations
 
-os.environ['HGRCPATH'] = paths.getEtcPath() + "/remote-hgrc"
-
-os.chdir('repos')
+os.environ['HGRCPATH'] = paths.getHgrcPaths()
 
-for f in [
-    paths.getEtcPath() + "/access.conf", 
-    os.getcwd() + "/hgadmin/access.conf"]:
+os.chdir(paths.getReposPath())
+
+for f in paths.getAccessPaths():
     if os.path.isfile(f):
         ruleset.rules.readfile(f)
 
--- a/src/init/hginit	Fri Oct 30 16:55:07 2009 +0000
+++ b/src/init/hginit	Mon Nov 09 12:15:09 2009 +0000
@@ -1,8 +1,10 @@
 #!/bin/sh
 
+# WARNING: this must be run from the hg user's home directory
+
 set -e
 
-cd ~hg
+cp $1/init/dot-mercurial-server .mercurial-server
 mkdir -p repos/hgadmin .ssh
 cd repos/hgadmin
 hg init .
--- a/src/mercurialserver/paths.py	Fri Oct 30 16:55:07 2009 +0000
+++ b/src/mercurialserver/paths.py	Mon Nov 09 12:15:09 2009 +0000
@@ -1,10 +1,43 @@
 # Copyright 2008-2009 LShift Ltd
 
-# Crude but it will do
-
 import sys
 import os.path
+import mercurial.config
 
+globalconfig = None
+
+def _getConf():
+    global globalconfig
+    if globalconfig is None:
+        globalconfig = mercurial.config.config()
+        globalconfig.read(os.path.expanduser("~/.mercurial-server"))
+    return globalconfig
+
+def configExists():
+    try:
+        _getConf()
+        return True
+    except:
+        return False
+
+def _getPath(name):
+    return os.path.expanduser(_getConf()["paths"][name])
+
+def _getPaths(name): 
+    return [os.path.expanduser(p)
+        for p in _getConf()["paths"][name].split(":")]
+
+
+def getExePath(): return _getPath("exe")
+def getReposPath(): return _getPath("repos")
+
+def getKeysPaths(): return _getPaths("keys")
+def getAccessPaths(): return _getPaths("access")
+
+# This goes into an env var, so pass it on verbatim.
+def getHgrcPaths(): return _getConf()["paths"]["hgrc"]
+
+# Work out where we are, don't use config.
 def setExePath():
     global _exePath
     _exePath = os.path.dirname(os.path.abspath(sys.argv[0]))
@@ -12,5 +45,3 @@
 def getExePath():
     return _exePath
 
-def getEtcPath():
-    return "/etc/mercurial-server"
--- a/src/mercurialserver/refreshauth.py	Fri Oct 30 16:55:07 2009 +0000
+++ b/src/mercurialserver/refreshauth.py	Mon Nov 09 12:15:09 2009 +0000
@@ -9,16 +9,14 @@
 import base64
 import os
 import os.path
-import pwd
 import subprocess
 from mercurialserver import paths
 
 goodkey = re.compile("[/A-Za-z0-9._-]+$")
 
-def refreshAuth(pw_dir):
-    akeyfile = pw_dir + "/.ssh/authorized_keys"
+def refreshAuth():
+    akeyfile = os.path.expanduser("~/.ssh/authorized_keys")
     wrappercommand = paths.getExePath() + "/hg-ssh"
-    keydirs = [paths.getEtcPath() + "/keys", pw_dir + "/repos/hgadmin/keys"]
     prefix='no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command='
 
     if os.path.exists(akeyfile):
@@ -31,7 +29,7 @@
             f.close()
 
     akeys = open(akeyfile + "_new", "w")
-    for keyroot in keydirs:
+    for keyroot in paths.getKeysPaths():
         kr = keyroot + "/"
         #print "Processing keyroot", keyroot
         for root, dirs, files in os.walk(keyroot):
@@ -63,6 +61,5 @@
     os.rename(akeyfile + "_new", akeyfile)
     
 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
-    pentry = pwd.getpwuid(os.geteuid())
-    refreshAuth(pentry.pw_dir)
+    refreshAuth()
 
--- a/src/refresh-auth	Fri Oct 30 16:55:07 2009 +0000
+++ b/src/refresh-auth	Mon Nov 09 12:15:09 2009 +0000
@@ -8,19 +8,17 @@
 
 import sys
 import os
-import pwd
 from mercurialserver import refreshauth, paths
 
 if len(sys.argv) != 1:
     sys.stderr.write("refresh-auth: must be called with no arguments (%s)\n" % sys.argv)
     sys.exit(-1)
 
-pentry = pwd.getpwuid(os.geteuid())
-if pentry.pw_name != "hg":
-    # FIXME: re-execute
+# To protect the authorized_keys file for innocent users, you have to have
+# a ~/.mercurial-server file to run this.
+if not paths.configExists():
     print >>sys.stderr, "Must be run as the 'hg' user"
     sys.exit(-1)
 
 paths.setExePath()
-
-refreshauth.refreshAuth(pentry.pw_dir)
+refreshauth.refreshAuth()