Subversion + Redmine + LDAP automatically generate AuthzSVNAccessFile
While implementing Redmine we came across difficulty integrating Redmine and Subversion using LDAP. One of the main reason was subversion uses AuthzSVNAccess file to authorize users. We don’t want all LDAP users to access SVN, only users added in respective Redmine project should able to access SVN repositories.
To solve this we end up creating PHP scripts to auto generate AuthzSVNAccessFile based on Redmine database. Script can be added to crontab to run periodically. Below are detail steps and script.
3) Automatically create SVN repository when a new project is added in Redmine
Add this script in crontab on Subvserion server (in case your subversion is hosted on different server). Below script is scheduled to run every 10 minutes.
10 * * * * root ruby /root/redmine-1.0.0/extra/svn/reposman.rb --redmine-host http://my.redmine./ --svn-dir /data/svn/ --url my.svn.server --key=mykey --owner apache --verbose >> /var/log/reposman.log
4) Configure Apache to use LDAP for subversion
ErrorDocument 404 default
DAV svn
Require valid-user
SVNParentPath /data/svn/
SVNListParentPath off
#LDAP configuration
AuthType Basic
AuthName "USVN"
AuthBasicProvider "ldap"
AuthLDAPURL "ldap://ldapserver"
authzldapauthoritative on
AuthLDAPBindDN "DN"
AuthLDAPBindPassword "LDAP Password"
Require valid-user
# Path to AuthzSVNAccessFile which will be auto generated using script
AuthzSVNAccessFile /etc/svn-acl-conf
5) PHP script to automatically generate AuthzSVNAccessFile
$authfile = "/etc/svn-acl-conf"; //path of AuthzSVNAccessFile
//redmine database detail. I have used Postgres.
$pg_sqldb_host = "localhost";
$pg_sqldb_user = "redmine";
$pg_sqldb_pass = "redmine";
$pg_sqldb_name = "redmine";
$fp = fopen($authfile, "w");
fwrite($fp, "# Subversion authorization file created by script \n");
$redmine_link = pg_connect("host=$pg_sqldb_host port=5432 dbname=$pg_sqldb_name user=$pg_sqldb_user password=$pg_sqldb_pass") or die("Could not connect to Redmine: " . pg_last_error());
#section [groups]
fwrite($fp, "[groups]\n");
#create groups from redmine projects
$query = "select id,name,identifier from projects";
$result = pg_query($redmine_link, $query);
while ($row = pg_fetch_array($result,NULL,PGSQL_ASSOC)) {
$group_name = $row["identifier"];
$group_id = $row["id"];
$group_users = NULL;
//get users for this group
$query = "select b.id, b.login from members a, users b where a.user_id=b.id AND a.project_id=$group_id";
$usvn_users_result = pg_query($redmine_link, $query);
while ($userrow = pg_fetch_array($usvn_users_result,NULL,PGSQL_ASSOC)) {
$group_users = $group_users . ($group_users != NULL ? ", " : "") . $userrow["login"];
}
pg_free_result($usvn_users_result);
fwrite($fp, "$group_name = $group_users \n");
}
pg_free_result($result);
#section [project]
fwrite($fp, "\n\n#Projects from Redmine \n");
$query = "select id,name,identifier from projects";
$result = pg_query($redmine_link, $query);
while ($row = pg_fetch_array($result,NULL,PGSQL_ASSOC)) {
$project_name = $row["name"];
$project_id = $row["id"];
$project_identifier = $row["identifier"];
fwrite($fp, "#Project $project_name \n");
fwrite($fp, "[$project_identifier:/] \n");
fwrite($fp, "@$project_identifier = rw \n\n");
}
pg_free_result($result);
pg_close($redmine_link);
fclose($fp);
print("SVN Auth file $authfile generated sucessfully");
?>
//End of code
- Make sure apache user has write access to AuthzSVNAccessFile- Add PHP script in crontab to run every 10 minutes10 * * * * /usr/bin/php /path/myscript.php