Commits

ejucovy committed 2e2bafb

make package

Comments (0)

Files changed (5)

+from setuptools import setup
+
+try:
+    long_description = open("README.txt").read()
+except:
+    long_description = ''
+try:
+    long_description += open("CHANGES.txt").read()
+except:
+    pass
+
+setup(name='trac_gitolite',
+      version='0.1dev',
+      description="",
+      long_description=long_description,
+      packages=['trac_gitolite'],
+      author='Ethan Jucovy',
+      author_email='ejucovy@gmail.com',
+      url="http://trac-hacks.org/wiki/GitolitePlugin",
+      license='BSD',
+      entry_points = {'trac.plugins': ['trac_gitolite = trac_gitolite']})

trac_gitolite/__init__.py

+from .conf_writer import GitoliteConfWriter
+from .perm_policy import GitolitePermissionPolicy

trac_gitolite/conf_writer.py

+from trac.admin import IAdminPanelProvider
+from trac.core import *
+from trac.config import Option, BoolOption
+from trac.util.translation import _
+
+from trac_gitolite import utils
+
+class GitoliteConfWriter(Component):
+    implements(IAdminPanelProvider)
+
+    gitolite_admin_reponame = Option('trac-gitolite', 'admin_reponame',
+                                     default="gitolite-admin")
+
+    def read_config(self):
+        return utils.read_config(self.env, self.gitolite_admin_reponame)
+    
+    ## IAdminPanelProvider methods
+
+    def get_admin_panels(self, req):
+        if 'VERSIONCONTROL_ADMIN' in req.perm:
+            yield ('versioncontrol', _('Version Control'), 'permissions', 
+                   _('Permissions'))
+
+    def render_admin_panel(self, req, category, page, path_info):
+        req.perm.require('VERSIONCONTROL_ADMIN')
+
+        perms = self.read_config()
+
+        if req.method == 'POST':
+            req.redirect(req.href.admin(category, page))
+        
+        data = {'perms': perms}
+        return 'admin_repository_permissions.html', data

trac_gitolite/perm_policy.py

+from trac.core import *
+from trac.config import Option, BoolOption
+from trac.perm import IPermissionPolicy
+
+from trac_gitolite import utils
+
+class GitolitePermissionPolicy(Component):
+    implements(IPermissionPolicy)
+
+    gitolite_admin_reponame = Option('trac-gitolite', 'admin_reponame',
+                                     default="gitolite-admin")
+    default_to_private = BoolOption('trac-gitolite', 'default_private',
+                                    default=False,
+        doc=("If this flag is set to True, then repositories will be private by default, "
+             "causing all permissions to be denied to all users if the repository "
+             "is not mentioned in the gitolite conf file."))
+    all_includes_anonymous = BoolOption('trac-gitolite', 'all_includes_anonymous',
+                                        default=False,
+        doc=("If this flag is set to True, then anonymous users will be granted permissions "
+             "on repositories that specify ``@all = R``.  By default, the ``@all`` token "
+             "is considered to mean all logged-in users only."))
+    
+    ## Helper methods
+
+    def parent_repository(self, resource):
+        while True:
+            if resource is None:
+                return None
+            if resource.realm == 'repository':
+                return resource
+            resource = resource.parent
+
+    def read_config(self):
+        repo = self.env.get_repository(reponame=self.gitolite_admin_reponame)
+        node = repo.get_node("conf/gitolite.conf")
+        fp = node.get_content()
+        return utils.read_config(fp)
+
+    def check_repository_permission(self, action, username, repository, resource, perm):
+        repos = self.read_config()
+
+        ## If the repo is not known in the config, we defer to the supersystem's decisions,
+        ## unless our configuration says otherwise.
+        if repository.id not in repos:
+            if self.default_to_private:
+                return False
+            else:
+                return None
+
+        perms = repos[repository.id]
+
+        if username == 'anonymous':
+            if self.all_includes_anonymous:
+                if '@all' in perms.get('R', []):
+                    return True
+            ## If the repo is known in the config then we assume that anonymous users can't see it
+            ## unless the @all-check in the previous stanza was triggered.
+            return False
+
+        if username in perms.get('R', []):
+            return True
+
+        if '@all' in perms.get('R', []):
+            return True
+
+        ## If the repo is known in the config but the user isn't explicitly granted access there,
+        ## then the user does not have access.
+        return False
+
+
+    ## IPermissionPolicy methods
+            
+    def check_permission(self, action, username, resource, perm):
+        ## This policy only covers entities that live within a repository
+        ## so we'll decline to state any permission if it's not a repository subresource
+        repository = self.parent_repository(resource)
+        if repository is None:
+            return None
+
+        return self.check_repository_permission(action, username, repository, resource, perm)
+

trac_gitolite/utils.py

+from StringIO import StringIO
+
+def read_config(fp):
+    repos = dict()
+    this_repo = None
+    info = {}
+    for line in fp:
+        line = line.strip()
+        if line.startswith("repo"):
+            if this_repo is not None and len(info) > 0:
+                repos[this_repo] = info
+            this_repo = line[len("repo"):].strip()
+            info = {}
+        elif '=' in line:
+            perms, users = line.split("=")
+            perms = perms.strip().upper()
+            users = [i.strip() for i in users.split()]
+            for perm in perms:
+                if perm in info:
+                    info[perm].extend(users)
+                else:
+                    info[perm] = list(users) ## Copy it!
+
+    if this_repo is not None and len(info) > 0:
+        repos[this_repo] = info
+
+    fp.close()
+    return repos
+
+
+def to_string(config):
+
+    def _sort(perms):
+        tail = []
+        ## Ensure the + goes last
+        if '+' in perms:
+            perms = perms.replace("+", '')
+            tail.append("+")
+        perms = sorted(perms)
+        perms.extend(tail)
+        return ''.join(perms)
+
+    fp = StringIO()
+    for repo in sorted(config):
+        fp.write("repo\t%s\n" % repo)
+
+        ## Combine permissions
+        perms = config[repo]
+        transposed = {}
+        for perm in perms:
+            for user in perms[perm]:
+                if user in transposed:
+                    transposed[user] += perm
+                    transposed[user] = _sort(transposed[user])
+                else:
+                    transposed[user] = perm
+
+
+        detransposed = {}
+        for user in transposed:
+            if transposed[user] in detransposed:
+                detransposed[transposed[user]].append(user)
+                detransposed[transposed[user]] = sorted(detransposed[transposed[user]])
+            else:
+                detransposed[transposed[user]] = [user]
+
+        for permset in sorted(detransposed):
+            fp.write("\t%s\t=\t%s\n" % (permset, ' '.join(detransposed[permset])))
+
+        fp.write("\n")
+    fp.seek(0)
+    return fp.read()
+