Wednesday, August 11, 2010

Subversion + Redmine + LDAP automatically generate AuthzSVNAccessFile


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.
1) Install Redmine
2) Install Subversion
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

1 comment:

Антон Титков said...
This comment has been removed by the author.