Uploaded image for project: 'Crowd Data Center'
  1. Crowd Data Center
  2. CWD-776

Apache module's Subversion support should support the SVNParentPath directive

    • Our product teams collect and evaluate feedback from a number of different sources. To learn more about how we use customer feedback in the planning process, check out our new feature policy.

      As of Crowd 1.2, the support for using subversion authorization files to control access on a per directory basis doesn't work if the SVNParentPath directive is used in the apache config file. This is a known limitation.

      SVNParentPath allows you to put multiple svn repositories in a directory and access them through a single URL (see http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html and http://svnbook.red-bean.com/nightly/en/svn.ref.mod_dav_svn.conf.html).

      If you do have multiple repositories you can make it work by defining apache <Location> blocks for each one and using a separate authz file for each, but it's a bit more work to set up and maintain.

      Example:

      <Location /svn/tools1>
      DAV svn
      SVNPath /usr/local/svnrepos/tools1
      ...
      </Location>
      
      <Location /svn/tools2>
      DAV svn
      SVNPath /usr/local/svnrepos/tools2
      ...
      </Location>
      
      <Location /svn/tools3>
      DAV svn
      SVNPath /usr/local/svnrepos/tools3
      ...
      </Location>
      

            [CWD-776] Apache module's Subversion support should support the SVNParentPath directive

            timmjd added a comment -

            I figured out a hack with Apache configfile Macros.
            Not soo nice but minimal config overhead for a bunch of repositories:

            <Macro crowd $svn_path $crowd_group>
              <Location /svn/$svn_path/>
                DAV svn
                SVNPath /mnt/svnroot/$svn_path/
            
                AuthName Crowd-Login
                AuthType Basic
                require valid-user
            
                PerlAuthenHandler Apache::CrowdAuth
                PerlAuthzHandler Apache::CrowdAuthz
            
                PerlSetVar CrowdAppName user
                PerlSetVar CrowdAppPassword pass
                PerlSetVar CrowdSOAPURL localhost:8095/crowd/services/SecurityServer
            
                PerlSetVar CrowdAllowedGroups '$crowd_group'
              </Location>
            </Macro>
            

            For instancing the repository from inside the apache config file:

            Use crowd foo_repo 'groupA, groupB'
            Use crowd bar_repo 'groupA, groupB'
            

            For geting the SVNParentPath listing:

            <Location /svnlist>
              DAV svn
              RedirectMatch ^/svnlist/(.+) /svn/$1
            
              SVNParentPath /mnt/svnroot
              SVNListParentPath On
            </Location>
            

            So finaly you can use:
            hxxp://localhost/svnlist (to display the repository listing)
            hxxp://localhost/svn/foo_repo/ (to access a single repository)

            Does anybody know how to get my listing to hxxp://localhost/svn ?

            timmjd added a comment - I figured out a hack with Apache configfile Macros. Not soo nice but minimal config overhead for a bunch of repositories: <Macro crowd $svn_path $crowd_group> <Location /svn/$svn_path/> DAV svn SVNPath /mnt/svnroot/$svn_path/ AuthName Crowd-Login AuthType Basic require valid-user PerlAuthenHandler Apache::CrowdAuth PerlAuthzHandler Apache::CrowdAuthz PerlSetVar CrowdAppName user PerlSetVar CrowdAppPassword pass PerlSetVar CrowdSOAPURL localhost:8095/crowd/services/SecurityServer PerlSetVar CrowdAllowedGroups '$crowd_group' </Location> </Macro> For instancing the repository from inside the apache config file: Use crowd foo_repo 'groupA, groupB' Use crowd bar_repo 'groupA, groupB' For geting the SVNParentPath listing: <Location /svnlist> DAV svn RedirectMatch ^/svnlist/(.+) /svn/$1 SVNParentPath /mnt/svnroot SVNListParentPath On </Location> So finaly you can use: hxxp://localhost/svnlist (to display the repository listing) hxxp://localhost/svn/foo_repo/ (to access a single repository) Does anybody know how to get my listing to hxxp://localhost/svn ?

            Rob Kooper added a comment -

            Here is what I did to get SVNParentPath to work. No guarantees. Apply the following patch to Crowd-Apache-Connector-1.2.3.zip, and install as normally. This patch will do the path check as before, but if it fails it will take the first element in the path and treat it as the repository, so for example when checking for access to /bar/trunk/folder it will first check that folder in the svn.auth file. If no match is found it will check for bar:/trunk/folder in the svn.auth file.

            diff -cr apachecrowd.orig/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm apachecrowd/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm
            *** apachecrowd.orig/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm	2009-03-02 05:08:25.000000000 -0600
            --- apachecrowd/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm	2010-06-21 23:40:22.750190714 -0500
            ***************
            *** 387,392 ****
            --- 387,393 ----
              	my $access_specified = '';
              	my $access_granted = 0;
              	my $working_path = $repos_path;
            + 	my $parentpath;
              	
              	if($access eq "rw") {
              		$access = "wr";
            ***************
            *** 405,411 ****
              	
              	PATH: while($working_path ne '') {
              		$access_specified = evaluate_single_path_authz($section_hash, $working_path, $user, $groups);
            ! 		
              		#Test::More::diag("WORKING_PATH: $working_path -> $access_specified");
              		if($access_specified ne 'n') {
              			last PATH;
            --- 406,416 ----
              	
              	PATH: while($working_path ne '') {
              		$access_specified = evaluate_single_path_authz($section_hash, $working_path, $user, $groups);
            ! 		if($access_specified eq 'n' && $working_path ne '/') {
            ! 			($parentpath = $working_path) =~ s/^\/([^\/]*)\/?/$1:\//;
            ! 			$access_specified = evaluate_single_path_authz($section_hash, $parentpath, $user, $groups);
            ! 		}
            ! 	
              		#Test::More::diag("WORKING_PATH: $working_path -> $access_specified");
              		if($access_specified ne 'n') {
              			last PATH;
            

            Next make sure your svn.auth file uses [<repository>:<path>] notations, you can also use [<repository>/<path>] if you want. For example, the following will give anybody read access and only those in group 'foo' write access to repository 'bar':

            [/] * = r
            
            [bar:/]
            @foo = rw
            

            Finally mke sure you set up your location for SSL, this is what we use:

                    # SVN
                    <Location /svn>
                            # Uncomment this to enable the repository
                            DAV svn
            
                            # Set this to the path to your repository
                            SVNParentPath /home/svn
                            SVNListParentPath on
            
                            # use autoversioning for dav clients
                            SVNAutoVersioning on
            
                            # Authentication
                            AuthName crowd
                            AuthType Basic
            
                            PerlAuthenHandler Apache::CrowdAuth
                            PerlSetVar CrowdAppName subversion
                            PerlSetVar CrowdAppPassword xyz
                            PerlSetVar CrowdSOAPURL http://localhost:8095/crowd/services/SecurityServer
            
                            # Autorization
                            PerlAccessHandler Apache::CrowdAuthz->access_handler
                            PerlAuthzHandler Apache::CrowdAuthz
                            PerlSetVar CrowdAuthzSVNAccessFile /home/svn/svn.auth
            
                            Satisfy Any
                            Require valid-user
            
                            # The following three lines allow anonymous read, but make
                            # committers authenticate themselves.
                            <LimitExcept GET PROPFIND OPTIONS REPORT>
                                    Require valid-user
                            </LimitExcept>
                    </Location>
            
            

            Please let me know if this does or does not work, it seems to work in our case.

            Rob Kooper added a comment - Here is what I did to get SVNParentPath to work. No guarantees. Apply the following patch to Crowd-Apache-Connector-1.2.3.zip, and install as normally. This patch will do the path check as before, but if it fails it will take the first element in the path and treat it as the repository, so for example when checking for access to /bar/trunk/folder it will first check that folder in the svn.auth file. If no match is found it will check for bar:/trunk/folder in the svn.auth file. diff -cr apachecrowd.orig/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm apachecrowd/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm *** apachecrowd.orig/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm 2009-03-02 05:08:25.000000000 -0600 --- apachecrowd/Atlassian-Crowd-1.2.3/lib/Atlassian/Crowd.pm 2010-06-21 23:40:22.750190714 -0500 *************** *** 387,392 **** --- 387,393 ---- my $access_specified = ''; my $access_granted = 0; my $working_path = $repos_path; + my $parentpath; if($access eq "rw") { $access = "wr"; *************** *** 405,411 **** PATH: while($working_path ne '') { $access_specified = evaluate_single_path_authz($section_hash, $working_path, $user, $groups); ! #Test::More::diag("WORKING_PATH: $working_path -> $access_specified"); if($access_specified ne 'n') { last PATH; --- 406,416 ---- PATH: while($working_path ne '') { $access_specified = evaluate_single_path_authz($section_hash, $working_path, $user, $groups); ! if($access_specified eq 'n' && $working_path ne '/') { ! ($parentpath = $working_path) =~ s/^\/([^\/]*)\/?/$1:\//; ! $access_specified = evaluate_single_path_authz($section_hash, $parentpath, $user, $groups); ! } ! #Test::More::diag("WORKING_PATH: $working_path -> $access_specified"); if($access_specified ne 'n') { last PATH; Next make sure your svn.auth file uses [<repository>:<path>] notations, you can also use [<repository>/<path>] if you want. For example, the following will give anybody read access and only those in group 'foo' write access to repository 'bar': [/] * = r [bar:/] @foo = rw Finally mke sure you set up your location for SSL, this is what we use: # SVN <Location /svn> # Uncomment this to enable the repository DAV svn # Set this to the path to your repository SVNParentPath /home/svn SVNListParentPath on # use autoversioning for dav clients SVNAutoVersioning on # Authentication AuthName crowd AuthType Basic PerlAuthenHandler Apache::CrowdAuth PerlSetVar CrowdAppName subversion PerlSetVar CrowdAppPassword xyz PerlSetVar CrowdSOAPURL http://localhost:8095/crowd/services/SecurityServer # Autorization PerlAccessHandler Apache::CrowdAuthz->access_handler PerlAuthzHandler Apache::CrowdAuthz PerlSetVar CrowdAuthzSVNAccessFile /home/svn/svn.auth Satisfy Any Require valid-user # The following three lines allow anonymous read, but make # committers authenticate themselves. <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location> Please let me know if this does or does not work, it seems to work in our case.

            We just recently integrated our Subversion into Crowd and did not notice until now that SVNParentPath is not supported.
            Is this issue still being worked on?

            Francisco Villar Romasanta added a comment - We just recently integrated our Subversion into Crowd and did not notice until now that SVNParentPath is not supported. Is this issue still being worked on?

            omega added a comment -

            We sort of did something like this, and I'll just leave our config here for anyone else who might need somehting like this. What we basically ended up doing was open the option of having a group pr repo on demand. In that way we can give consultants etc rw-access to selected repos only, by creating and adding them to the right group in crowd.

            # Our topmost location under which each repo lives.
            <Location /svn>
            
                AuthType Basic
                AuthName crowd
            
                # We configure the CrowdAuth-stuff on the top location
                PerlAuthenHandler Apache::CrowdAuth
                PerlSetVar CrowdAppName CROWD_SVN_APP_USER
                PerlSetVar CrowdAppPassword CROWD_SVN_APP_PASSWORD
                PerlSetVar CrowdSOAPURL http://CROWD_HOSTNAME:8095/crowd/services/SecurityServer
            
                # We set some sane defaults, allowing all internal developers and operations rw to all repos
                # builder:r is what we use for our CI and auto-package systems.
                PerlAuthzHandler Apache::CrowdAuthz
                PerlSetVar CrowdAllowedGroups utvikling,drift,builder:r 
            
                # Uncomment this to enable the repository,
                DAV svn
            
                # Set this to the path to your repository
                SVNParentPath /our/svn/root
            
                require valid-user
            </Location>
            
            # Next we use mod_perl to generate per repo <Location> blocks
            <Perl>
                use Path::Class;
            
                my $dir = dir('/our/svn/root');
            
                while (my $repo = $dir->next) {
                    my $repo_name = $repo->dir_list(-1);
                    # If for some reason someone created some other directory, we just skip it
                    next unless -f $repo->file('format'); # We weed out everything not a svn repo
                    
                    # We have a policy where we rename defunct repos to X-, so we just skip those.
                    next if ($repo_name =~ m/^X-/); # We skip X-*
            
                    # And here we "Override" the CrowdAllowedGroups by adding a group with the same name
                    # as the repo, in lowercase.
                    $Location{'/svn/' . $repo_name} = {
                        PerlSetVar => [CrowdAllowedGroups => "utvikling,drift,builder:r" . lc($repo_name)],
                    };
            
                }
            </Perl>
            

            The perl-code is only executed on server-startup, but you only really need to restart if you need to pinpoint access to a certain repo, since the defaults will allow internal developers access. You could of course easily manipulate what groups you give access to, if you don't want to allow a single group to everyone. If so inclined, you could maintain a config-file that the perl-section reads as well.

            I realize it's not ideal, but it works for us at least

            omega added a comment - We sort of did something like this, and I'll just leave our config here for anyone else who might need somehting like this. What we basically ended up doing was open the option of having a group pr repo on demand. In that way we can give consultants etc rw-access to selected repos only, by creating and adding them to the right group in crowd. # Our topmost location under which each repo lives. <Location /svn> AuthType Basic AuthName crowd # We configure the CrowdAuth-stuff on the top location PerlAuthenHandler Apache::CrowdAuth PerlSetVar CrowdAppName CROWD_SVN_APP_USER PerlSetVar CrowdAppPassword CROWD_SVN_APP_PASSWORD PerlSetVar CrowdSOAPURL http: //CROWD_HOSTNAME:8095/crowd/services/SecurityServer # We set some sane defaults, allowing all internal developers and operations rw to all repos # builder:r is what we use for our CI and auto- package systems. PerlAuthzHandler Apache::CrowdAuthz PerlSetVar CrowdAllowedGroups utvikling,drift,builder:r # Uncomment this to enable the repository, DAV svn # Set this to the path to your repository SVNParentPath /our/svn/root require valid-user </Location> # Next we use mod_perl to generate per repo <Location> blocks <Perl> use Path:: Class ; my $dir = dir( '/our/svn/root' ); while (my $repo = $dir->next) { my $repo_name = $repo->dir_list(-1); # If for some reason someone created some other directory, we just skip it next unless -f $repo->file( 'format' ); # We weed out everything not a svn repo # We have a policy where we rename defunct repos to X-, so we just skip those. next if ($repo_name =~ m/^X-/); # We skip X-* # And here we "Override" the CrowdAllowedGroups by adding a group with the same name # as the repo, in lowercase. $Location{ '/svn/' . $repo_name} = { PerlSetVar => [CrowdAllowedGroups => "utvikling,drift,builder:r" . lc($repo_name)], }; } </Perl> The perl-code is only executed on server-startup, but you only really need to restart if you need to pinpoint access to a certain repo, since the defaults will allow internal developers access. You could of course easily manipulate what groups you give access to, if you don't want to allow a single group to everyone. If so inclined, you could maintain a config-file that the perl-section reads as well. I realize it's not ideal, but it works for us at least

            Sorry ingard, have been absolutely flat out recently. Decided I'd take some time out to take my changes live. They seem to be OK, but at the moment I need to add in support for nested groups before I can release it.

            Chris Boulton added a comment - Sorry ingard, have been absolutely flat out recently. Decided I'd take some time out to take my changes live. They seem to be OK, but at the moment I need to add in support for nested groups before I can release it.

            ingard added a comment -

            Hi

            this is a major issue for us as well. How did things go on your end Chris? I think we might be able to help out if things still needs testing as we are a perl shop.

            regards
            ingard

            ingard added a comment - Hi this is a major issue for us as well. How did things go on your end Chris? I think we might be able to help out if things still needs testing as we are a perl shop. regards ingard

            Hi all,

            I've actually just finished writing the modifications necessary for this to work & am in the process of updating the existing tests and adding in new tests.

            If all goes to plan, I'll attach a patched version of the Apache connector here as well as a diff file and hopefully we can see the changes incorporated in to the official connector.

            Chris Boulton added a comment - Hi all, I've actually just finished writing the modifications necessary for this to work & am in the process of updating the existing tests and adding in new tests. If all goes to plan, I'll attach a patched version of the Apache connector here as well as a diff file and hopefully we can see the changes incorporated in to the official connector.

            We're using Crowd 1.6.1 and REALLY need support for this. While using Location directives seems to work it is really a workaround especially as it requires a server restart. Not having this feature is proving painful for us.

            Ken Carroll added a comment - We're using Crowd 1.6.1 and REALLY need support for this. While using Location directives seems to work it is really a workaround especially as it requires a server restart. Not having this feature is proving painful for us.

            Toby Baier added a comment -

            Hi Dave,
            I'm sorry but we don't have Perl expertise in-house. We could help with QA, though. Or, if you have an expert on this topic, we might try our "luck" when we get some code pointers and hints on how to try it.

            Cheers,
            Toby

            Toby Baier added a comment - Hi Dave, I'm sorry but we don't have Perl expertise in-house. We could help with QA, though. Or, if you have an expert on this topic, we might try our "luck" when we get some code pointers and hints on how to try it. Cheers, Toby

            Hi Toby,

            You're more than welcome to help implement the support. If you have the Perl expertise in-house, feel free to make modifications to the connector. If you then attach the patch to this issue, we'll roll it back into the main release.

            Cheers,
            Dave.

            David O'Flynn [Atlassian] added a comment - Hi Toby, You're more than welcome to help implement the support. If you have the Perl expertise in-house, feel free to make modifications to the connector. If you then attach the patch to this issue, we'll roll it back into the main release. Cheers, Dave.

              Unassigned Unassigned
              beb930a06022 Andrew Reid
              Votes:
              20 Vote for this issue
              Watchers:
              18 Start watching this issue

                Created:
                Updated:
                Resolved: