We want to use SSH+SVN. We do!
However, access rights can be a pain with this protocol since we cannot use SVN's built-in access management. We want to achieve the following:
User "user1" can access repositories "project_a" and "project_b". User "user2" can only access repository "project_b". Now, "user1" and "user2" do not have the same primary group. The first has "staff" as a primary group and the latter, group "users".
In order to do this, we will create a group for every repository. This way we can assign different users to different groups and therefore to different repositories. To give an overview:
svnadm: svn-users user1: staff, svn-users, svn-project-a, svn-project-b user2: users, svn-users, svn-project-b
Since both users need to access one or more repositories, they are all part of group "svn-users". There is a sort of super-user called "svnadm", which is not really important for this explanation.
Let's set up our directory structure and keep in mind that all groups have write permission (g+wr):
/var/svn svnadm svn-users /var/svn/project_a user1 svn-project-a /var/svn/project_b user2 svn-project-b
The whole "project_a" directory and all it's children have "svn-project-a" as group. The same goes for "project_b" that has "svn-project-b" as group.
Theres one problem though: If a user commits a change to a repository, his primary group is used for some repository administration files (in repo/db) which renders the repository inaccessible to others that are not in the same group. Thus, if "user1" commits to "project_b", some files will have group "staff" and "user2" cannot access them.
Suddenly you might have this:
/var/svn svnadm svn-users /var/svn/project_a user1 svn-project-a /var/svn/project_b user2 svn-project-b /var/svn/project_b/db/current user1 staff
Oops!
The solution is something I haven't found that clear on the internet, so here it is:
find /var/svn/project_a/db -type d -exec chmod g+s '{}' \; find /var/svn/project_b/db -type d -exec chmod g+s '{}' \;
What this does is simple. We give a g+s-bit to all repo/db directories. Setting directories g+s makes all new files created in said directory have their group set to the directory's group. You should do this for every repository.
If you also set your default umask to 002 you're done. This allows users and groups to write and can be set in your ~/.bashrc file or set as default in /etc/login.defs (on some Linux distributions).
Have fun!
Allow ssh-agent to work when using sudo Using Fabric to update a remote svn checkout with ssh public key authentication