Installing Subversion
In the following example I'm using Subversion (SVN) through WebDAV via an Apache web server running on Ubuntu Linux 18.
- Installation
- Configuration
- LDAP authentication
- Commit only with comment
- Make SVN properties modifiable
- Sources
Installation
For installing Ubuntu Linux 18 see the Installing Ubuntu 18 tutorial.
As SVN is shipped with Ubuntu the installation is pretty easy:
root@machine~# apt-get install subversion libapache2-mod-svn apache2
This installs Subversion, the module for the Apache web server as well as the Apache web server itself.
Configuration
Next we create the directories for our SVN repository:
root@machine~# mkdir -p /var/local/svn root@machine~# svnadmin create --fs-type fsfs /var/local/svn root@machine~# chown -R www-data:www-data /var/local/svn
Now we have to activate the SVN support in the Apache web server:
(Should already be the case)
root@machine~# a2enmod dav_svn root@machine~# ln -s /etc/apache2/mods-available/authz_svn.load /etc/apache2/mods-enabled/authz_svn.load
(If you want to have LDAP support)
root@machine~# ln -s /etc/apache2/mods-available/ldap.load /etc/apache2/mods-enabled/ldap.load root@machine~# ln -s /etc/apache2/mods-available/authnz_ldap.load /etc/apache2/mods-enabled/authnz_ldap.load
(In any case)
root@machine~# nano /etc/apache2/mods-enabled/dav_svn.conf
Jump to the end of the file (the file should just consist of comments). If you want authentication via a password file:
<Location /svn> DAV svn SVNPath /var/local/svn AuthType Basic AuthName "Subversion Repository" # --- Authentication by htpasswd file --- AuthUserFile /etc/apache2/dav_svn.passwd # --- LimitExcept allows read-only access for everyone --- <LimitExcept GET PROFFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
Location
specifies the folder at which the SVN will be accessible through the web server. Let's say the system's IP is 192.168.1.2
the URL in this case would be:
Now we create the password file (instead of "john.doe" fill in the name of the user). -c
creates a new file, -m
forces MD5 encryption of the password.
root@machine~# htpasswd -cm /etc/apache2/dav_svn.passwd john.doe New password: Re-type new password: Adding password for user john.doe
Okay, now we restart the Apache web server:
root@machine~# service apache2 restart
Now we can test if the SVN works as expected. In our case we type the following URL into a web browser:
You should get access without the need of an user:
svn - Revision 0: / Powered by Apache Subversion version 1.9.7 (r1800392).
If you don't want read-only access for everyone just comment out the <LimitExcept>
tags like this:
root@machine~# nano /etc/apache2/mods-enabled/dav_svn.conf
<Location /svn> [...] # --- LimitExcept allows read-only access for everyone --- #<LimitExcept GET PROFFIND OPTIONS REPORT> Require valid-user #</LimitExcept> </Location>
Restart the web server:
root@machine~# service apache2 restart
Try to access the URL again:
Now you should get an authentication dialogue by your web browser. If you cancel it, you'll get an Unauthorized
page. If you enter your user and password you defined in the password file, you should get access.
LDAP authentication
The following I've tested on Ubuntu 16 as well as on Ubuntu 18. I also tested it with OpenLDAP as well as Microsoft Active Directory.
If you want to have LDAP authentication (e.g. via Microsoft Active Directory), you'll need to activate the LDAP and LDAP authentication modules like mentioned earlier in the Configuration section.
I also have a tutorial about how to install an OpenLDAP service / directory.
In addition the configuration must be changed:
root@machine~# nano /etc/apache2/mods-enabled/dav_svn.conf
<Location /svn> DAV svn SVNPath /var/local/svn AuthType Basic AuthName "Subversion Repository" # --- Authentication by LDAP --- #AuthLDAPAuthoritative on AuthBasicProvider ldap AuthLDAPBindDN "cn=svn-admin,ou=Service Accounts,dc=mydomain,dc=com" AuthLDAPBindPassword "password" # --- Filter by group - only group members are allowed to access the repository --- AuthLDAPURL "ldap://192.168.1.3:389/ou=Users,dc=mydomain,dc=com?sAMAAccount?sub?(&(objectClass=*)(memberOf=cn=Development,ou=Security Groups,ou=Users,dc=mydomain,dc=com))" # --- LimitExcept allows read-only access for everyone --- <LimitExcept GET PROFFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
In this case svn-admin
is an account in the service account group having the password password
. The Active Directory is running on 192.168.1.3
and LDAP via port 389
is activated. The log-in name is the sAMAccount
field content (which is the Windows log-in name). All members (or more precisely: all objects) of the security group Development
should have access.
In case of a generic LDAP server / an OpenLDAP server the AuthLDAPURL
may look like this:
ldap://[IP-ADDRESS]:[PORT]/[BASE-DN]?uid?sub?(objectClass=inetOrgPerson)
In case of a Microsoft Active Directory the AuthLDAPURL
may look like this:
ldap://[IP-ADDRESS]:[PORT]/[BASE-DN]?sAMAccountName?sub?(objectClass=user)
If you want to add a group membership as a requirement in a Microsoft Active Directory environment, you can do so by changing the last part:
(&(objectClass=user)(memberOf=[GROUP-DN]))
where [GROUP-DN] is the DN of the required group.
Restart the web server:
root@machine~# service apache2 restart
Commit only with comment
Every commit into the repository should at least have a comment. Therefore we set-up a so called hook
(those hooks also can be used for other things like triggering a build):
root@machine~# cp /var/local/svn/hooks/pre-commit.tmpl /var/local/svn/hooks/pre-commit root@machine~# chown www-data:www-data /var/local/svn/hooks/pre-commit root@machine~# nano /var/local/svn/hooks/pre-commit
The following lines have to be modified / added:
# script aims to execute. # For similar reasons, you should also add a trailing @ to URLs which # are passed to SVN commands accepting URLs with peg revisions. # # Here is an example hook script, for a Unix /bin/sh interpreter. # For more examples and pre-written hooks, see those in # /usr/share/subversion/hook-scripts, and in the repository at # http://svn.apache.org/repos/asf/subversion/trunk/tools/hook-scripts/ and # http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/ REPOS="$1" TXN="$2" # Make sure that the log message contains some text. SVNLOOK=/usr/bin/svnlook #$SVNLOOK log -t "$TXN" "$REPOS" | \ # grep "[a-zA-Z0-9]" > /dev/null || exit 1 $SVNLOOK log -t "$TXN" "$REPOS" | \ grep "[a-zA-Z0-9]" > /dev/null # Check that a commit comment is available. GREP_STATUS=$? if [ GREP_STATUS -ne 0 ] then echo "Your commit has been blocked because you didn't give any log message" >&2 echo "Please write a log message describing the purpose of your changed and" >&2 echo "then try committing again. --- Thank you" >&2 exit 1 fi # Exit on all errors. #set -e # Check that the author of this commit has the rights to perform # the commit on the files and directories being modified. #"$REPOS"/hooks/commit-access-control.pl "$REPOS" $TXN \ # "$REPOS"/hooks/commit-access-control.cfg # All checks passed, so allow the commit. exit 0
Restart the web server:
root@machine~# service apache2 restart
Make SVN properties modifiable
If you want to make the SVN properties editable (e.g. during the migration from another source control management to SVN), you can do it the following way:
root@machine~# cp /var/local/svn/hooks/pre-revprop-change.tmpl /var/local/svn/hooks/pre-revprop-change root@machine~# chown www-data:www-data /var/local/svn/hooks/pre-revprop-change root@machine~# nano /var/local/svn/hooks/pre-revprop-change
REPOS="$1" REV="$2" USER="$3" PROPNAME="$4" ACTION="$5" if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi if [ "$ACTION" = "A" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:date" ]; then exit 0; fi if [ "$ACTION" = "A" -a "$PROPNAME" = "svn:date" ]; then exit 0; fi if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:author" ]; then exit 0; fi if [ "$ACTION" = "A" -a "$PROPNAME" = "svn:author" ]; then exit 0; fi echo "Changing revision properties other than svn:log is prohibited (repos $REPOS; rev $REV; user $USER; propName: $PROPNAME; action $ACTION)" >&2 exit 1