Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit 2cc723c21f1b5401d838b36e43cf489f18c0d507 @dr4Ke committed with Christophe Drevet Jul 15, 2010
@@ -0,0 +1 @@
+tracgitosis
@@ -0,0 +1,22 @@
+from setuptools import find_packages, setup
+
+version='1.0'
+
+setup(name='TracGitosis',
+ version=version,
+ description="user's ssh public key for use with gitosis",
+ author='Christophe Drevet',
+ author_email='dr4ke@dr4ke.net',
+ url='',
+ keywords='trac gitosis plugin',
+ license="GPLv3+",
+ packages=find_packages(exclude=['ez_setup', 'examples', 'tests*']),
+ include_package_data=True,
+ package_data={ 'tracgitosis': ['templates/*', 'htdocs/*'] },
+ zip_safe=False,
+ entry_points = """
+ [trac.plugins]
+ tracgitosis = tracgitosis
+ """,
+ )
+
@@ -0,0 +1,2 @@
+#
+from tracgitosisprefs import *
@@ -0,0 +1,29 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="prefs.html" />
+ <head>
+ <title>gitosis SSH public key</title>
+ </head>
+ <body>
+
+ <div class="field">
+ <label>Username: ${username}</label>
+ </div>
+ <div class="field">
+ <label>gitosis SSH public key:
+ <input name="sshkey" size="100"
+ value="${sshkey}"/>
+ </label>
+ <p class="hint">The SSH public key is used by gitosis-admin to grant
+ access to git repositories following configuration file directives.</p>
+ </div>
+ <div>
+ <pre>${message}</pre>
+ </div>
+
+ </body>
+</html>
@@ -0,0 +1,157 @@
+"""
+tracgitosis:
+a plugin for Trac, interface for some gitosis-admin configuration
+http://trac.edgewall.org
+"""
+
+from trac.core import *
+
+from trac.prefs.api import IPreferencePanelProvider
+from trac.web.chrome import ITemplateProvider, add_notice, add_warning
+from trac.util.translation import _
+
+from subprocess import Popen, PIPE
+import os
+
+class TracGitosisPrefs(Component):
+
+ implements(IPreferencePanelProvider, ITemplateProvider)
+
+ admrepo = 'gitosis-admin'
+
+ ### methods for IPreferencePanelProvider
+
+ def get_preference_panels(self, req):
+ """Return a list of available preference panels.
+
+ The items returned by this function must be tuple of the form
+ `(panel, label)`.
+ """
+ return [('sshkey', 'gitosis SSH public key')]
+
+ def render_preference_panel(self, req, panel):
+ """Process a request for a preference panel.
+
+ This function should return a tuple of the form `(template, data)`,
+ where `template` is the name of the template to use and `data` is the
+ data to be passed to the template.
+ """
+ print req
+ if req.method == 'POST':
+ self.setsshkey(req)
+ req.redirect(req.href.prefs(panel or None))
+
+ print '<pre>'+str(self)+'</pre>'
+ status, message = self.init_admin()
+ data = {}
+ if status != 0:
+ message = 'return code: '+str(status)+'\nmessage:\n'+message
+ data['message'] = message
+ sshkey = self.getsshkey(req)
+ data['username'] = req.session.sid
+ data['sshkey'] = sshkey
+ return 'prefs_tracgitosis.html', data
+
+ def getsshkey(self, req):
+ """ Read current ssh public key.
+
+ This function read the file keydir/<user>.pub in the local gitosis-admin working tree.
+ """
+ keyfile = self.env.path+'/'+self.admrepo+'/keydir/'+req.session.sid+'.pub'
+ if os.path.exists(keyfile):
+ f = open(keyfile, 'r')
+ pubkey = f.readline()
+ f.close()
+ else:
+ pubkey = ''
+ return pubkey
+
+ def setsshkey(self, req):
+ """ Set ssh public key.
+
+ This function write the file keydir/<user>.pub in the local gitosis-admin working tree
+ with the given public key.
+ """
+ key = req.args.get('sshkey', '').strip()
+ # On vérifie si la clé a bien une syntaxe normale
+ import re
+ status = 0
+ if re.search(r'^ssh-rsa [A-Za-z0-9+/]*=* ', key) == None:
+ status = 1
+ message = 'malformed key (must begin with \'ssh-rsa \' followed by a BASE64 encoded chain)'
+ if status == 0:
+ relkeyfile = 'keydir/'+req.session.sid+'.pub'
+ keyfile = self.env.path+'/'+self.admrepo+'/'+relkeyfile
+ f = open(keyfile, 'w')
+ f.write(key+'\n')
+ f.close()
+ status, message = self.commitkey(relkeyfile)
+ if status == 0:
+ add_notice(req, _('Your preferences have been saved.'))
+ else:
+ add_warning(req, _('Error while saving your preferences. Message: '+message))
+
+ def get_templates_dirs(self):
+ from pkg_resources import resource_filename
+ return [resource_filename(__name__, 'templates')]
+
+ def commitkey(self, file):
+ """ Commit new SSH public key.
+
+ """
+ stdout = ''
+ stderr = ''
+ message = ''
+ status = 0
+ repodir = self.env.path+'/'+self.admrepo
+ # On met le dépôt à jour
+ cmd = ['git', 'pull']
+ proc = Popen(cmd, shell=False, stdin=None, stdout=PIPE, stderr=PIPE, cwd=repodir)
+ stdout, stderr = proc.communicate()
+ status = proc.returncode
+ if status == 0:
+ # on fait le commit
+ cmd = ['git', 'add', file]
+ proc = Popen(cmd, shell=False, stdin=None, stdout=PIPE, stderr=PIPE, cwd=repodir)
+ stdout, stderr = proc.communicate()
+ status = proc.returncode
+ cmd = ['git', 'commit', '-m', 'commited by trac']
+ proc = Popen(cmd, shell=False, stdin=None, stdout=PIPE, stderr=PIPE, cwd=repodir)
+ stdout, stderr = proc.communicate()
+ status = proc.returncode
+ if status == 1:
+ # On vérifie si le message de commit indique qu'il n'y a rien à faire
+ pattern = 'nothing to commit'
+ if stdout.find(pattern) >= 0:
+ status = 0
+ if status == 0:
+ # On pousse vers gitosis
+ cmd = ['git', 'push']
+ proc = Popen(cmd, shell=False, stdin=None, stdout=PIPE, stderr=PIPE, cwd=repodir)
+ stdout, stderr = proc.communicate()
+ status = proc.returncode
+ if status == 0:
+ message = stdout
+ else:
+ message = stderr
+ return status, message
+
+ def init_admin(self):
+ """ Initialisation ou mise à jour du dépôt d'admin.
+
+ """
+ # on initialise le dépôt git s'il n'existe pas
+ status = 0
+ stdout = ''
+ stderr = ''
+ message = ''
+ if not os.path.exists(self.env.path+'/'+self.admrepo):
+ cmd = ['git', 'clone', 'gitosis:'+self.admrepo]
+ proc = Popen(cmd, shell=False, stdin=None, stdout=PIPE, stderr=PIPE, cwd=self.env.path)
+ stdout, stderr = proc.communicate()
+ status = proc.returncode
+ if status == 0:
+ message = stdout
+ else:
+ message = stderr
+ return status, message

0 comments on commit 2cc723c

Please sign in to comment.