<?xml version="1.0" encoding="UTF-8"?>
<wiki-page>
  <author>Chris Miller</author>
  <content>This script takes all users in the Committers group (group six for me, check your SQL tables to be sure) and takes their password hashes and puts them into a Subversion authentication file (assuming you're served through Apache mod_svn).  It is necessary to modify your Retro installation to not salt your passwords (which is less secure, obviously).

"app/models/user.rb":http://retrospectiva.org/browse/trunk/app/models/user.rb line 188

{{{ Digest::SHA1.hexdigest("+++{{#{pass}:#{self.salt}}---") }}}

Will become this

bc. Digest::SHA1.hexdigest("#{pass}")

+Update+ I've been considering attempting to write a forum extension myself (I'm just nutty like that) So I was reading through the sources on a public terminal and ran into this little thing that might also help.

user.rb line 202:
{{{ ["+++{{#{pass}}---", "c-o-l-l-a-b-o-a--#{pass}--"].map do |pattern| }}}

Will become this:

@ ["+++{{#{pass}}}---", "+++{{#{pass}:#{self.salt}}}---", "c-o-l-l-a-b-o-a--#{pass}--"].map do |pattern| @

Update: No more warning.  I tested it and it works just fine.  No errors, no nothing.  Perfectly safe.  Of course this makes you more vulnerable if your SQL db is ever compromised, but then again that's not terribly likely anyways.  And if that does happen, chances are you've got more problems than someone being able to view the password hashes.  I hope you like it.  I only wish it were in Ruby so it could integrate more seamlessly with Retrospectiva.

I made it a cronjob to run every night: (using crontab -e)

bc. @daily /usr/local/bin/php /path/to/script

It does echo the new files, which is mailed to me because of a mailto directive in crontab:

bc. MAILTO="your-address@example.com"

{{{
&lt;?php

$destination_access='/home/fsdev/svn/fsdevsvn.access'; // the location of the Subversion access file
$destination_passwd='/home/fsdev/svn/fsdevsvn.passwd'; // the location of the Subversion passwd file

$committers_gid='6'; // The Group ID of your committers group.

$sql_hostname = "sql.fsdev.net"; // replace this with your own sql server
$sql_username = "open"; // replace this with the username to your SQL server
$sql_password = "sesame"; // replace this with the password to your SQL server

$sql_db_name = "retro"; // replace this with the db name of your Retro installation

$sql_user_query_string=sprintf("SELECT login, id, password, admin FROM users");
$sql_group_query_string=sprintf("SELECT user_id FROM groups_users WHERE group_id = $committers_gid");

$access_template="[/]\n* = r\n";


$sql_connection=@mysql_connect($sql_hostname, $sql_username, $sql_password);
or die("Could not connect to MySQL server!")
if(!$sql_connection) echo "no connection\n";

mysql_select_db($sql_db_name, $sql_connection);

$sql_user_result=mysql_query($sql_user_query_string, $sql_connection);
if(!$sql_user_result) echo "bad query\n";

$sql_group_result=mysql_query($sql_group_query_string, $sql_connection);
if(!$sql_group_result) echo "bad query\n";

$users=array(); $i=0;
$groups=array(); $j=0;

while($temp = mysql_fetch_object($sql_user_result)){
	$users[$i++]=$temp;
}

while($temp = mysql_fetch_object($sql_group_result)){
	$groups[$j++]=$temp;
}

$committers=array();

foreach($users as $user){
	if($user-&gt;admin==true) $committers[]=$user;
}

foreach($groups as $group){
	foreach($users as $user){
		if($group-&gt;user_id===$user-&gt;id)
			$committers[]=$user;
	}
}

$access_file=complete_access_file($committers, $access_template);

echo "==== ACCESS FILE ====\n";
echo $access_file;

$file=fopen($destination_access, "w+");
fwrite($file, $access_file);
fclose($file);

$passwd_file=make_passwd_file($committers);

echo "\n\n==== PASSWORD FILE ====\n";
echo $passwd_file;

$file=fopen($destination_passwd, "w+");
fwrite($file, $passwd_file);
fclose($file);

function complete_access_file($committers, $access_template){
	$access_file=$access_template;
	foreach($committers as $committer){
		$access_file.="$committer-&gt;login = rw\n";
	}
	return $access_file;
}

function make_passwd_file($committers){
	$passwd_file="";
	foreach($committers as $committer){
		$base64passwd=convert_to_base64($committer-&gt;password);
		$passwd_file.=$committer-&gt;login;
		$passwd_file.=":{SHA}";
		$passwd_file.=$base64passwd;
		$passwd_file.="\n";
	}
	return $passwd_file;
}


function convert_to_base64($src) {
	$hex_= preg_replace("/[^0-9a-fA-F]/","", $src);
	for($i = 0; $i &lt; strlen($hex_); $i = $i +2)
		$ascii = $ascii.chr(hexdec(substr($hex_, $i, 2)));
	return base64_encode($ascii);
}

mysql_close($sql_connection);

?&gt;
}}}</content>
  <created-at type="datetime">2008-03-13T02:16:51+00:00</created-at>
  <title>Saurons Script</title>
  <updated-at type="datetime">2008-03-16T22:14:04+00:00</updated-at>
  <version type="integer">8</version>
</wiki-page>
