Commits

ejucovy committed c22bf10

add initial work on TracGitolitePlugin, by stripping down the overengineered MultiRepoPermissionSystemPlugin that i recently coded

Comments (0)

Files changed (3)

+*.egg-info*
+.svn
+*~
+#*
+*#
+*.pyc
+.DS_Store
+.#*
+*.orig
+This plugin provides four integrations with gitolite:
+
+ 1. Trac's repository permissions (BROWSER_VIEW, CHANGESET_VIEW) are inherited from the gitolite.conf file per repository and per user
+
+ 1. Add and remove users' read and write permissions from each repository through the Trac admin UI
+
+ 1. Management of users' SSH public keys through the Trac web UI, as an admin panel and as a per-user preferences panel
+
+ 1. A "Create New Repository" feature allows you to initialize an empty git repository through the Trac web UI if the user has sufficient permissions (REPOSITORY_CREATE)
+from trac.core import *
+from trac.config import Option, BoolOption
+from trac.perm import IPermissionPolicy
+
+class GitoliteMultiRepoPermissionPolicyProvider(Component):
+    implements(IPermissionPolicy)
+
+    gitolite_admin_reponame = Option('multirepo-permissions', 'gitolite_admin_reponame',
+                                     default="gitolite-admin")
+    default_to_private = BoolOption(
+        'multirepo-permissions', '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(
+        'multirepo-permissions', '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()
+        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()
+                users = [i.strip() for i in users.split()]
+                if 'R' not in perms.upper():
+                    continue
+                info.extend(users)
+            pass
+        if this_repo is not None and len(info) > 0:
+            repos[this_repo] = info
+
+        fp.close()
+        return repos
+
+    def check_repository_permission(self, action, username, repository, resource, perm):
+        repos = self.read_config()
+        if username != 'anonymous' and username in repos.get(repository.id, []):
+            return True
+        if '@all' in repos.get(repository.id, []):
+            if username != 'anonymous':
+                return True
+            elif self.all_includes_anonymous:
+                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.
+        if repository.id in repos:
+            return False
+
+        ## If the repo is not known in the config, we defer to the supersystem's decisions,
+        ## unless our configuration says otherwise.
+        if self.default_to_private:
+            return False
+        return None
+
+    ## 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)
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.