
  This is the README file of the libapache2-mod-auth-gforge.

  Copyright and Licenses can be found in file Copyright distributed
  within this package.

  Version 0.5.9.2

  1.Introduction
  ==============
  
  This is a control module for Apache2 HTTPD Server(http://httpd.apache.org) 
  which will support use of WebDAV in Gforge and restrict who can access and create
  project and user data using Gforge logic.
  
  2.Compilation
  =============
  
  This library use autotool, so it should be easy to install it.
  So, first at all:
  
  $ PG_DIR=/usr/include/postgresql PG_LIB=/usr/lib ./configure --prefix=/usr \
    --mandir=/usr/share/man \
    --infodir=/usr/share/info --with-apachectl=/usr/sbin/apache2ctl \
    --with-apache-include=/usr/include/apache2 \
    --with-apache-modules=/usr/lib/apache2/modules \
    --with-apache-documents=/var/www/apache2-default \
    --with-apache-config=/etc/apache2 --enable-exslt \
    --with-apxs2=/usr/bin/apxs2 --with-subversion-include=/usr/include/subversion-1
  $ make
  
  You will neeed libpq-fe.h and libpq.a for compilation. Try to install development 
  packages of apache2 and postgresql.
  You will need subversion development files too.

  It's a --enable-debug options, that is useful if you want to send a bugreport.
  
  
  3.Installation
  ==============
 
  If the compilation was smooth, then you just only have to make:
  
  # make install
  
  So, you will have to add the module to Apache2. 
  
  # /usr/sbin/a2enmod mod_auth_gforge ( if Debian )
  # ln -sf /etc/apache2/mods-available/mod_auth_gforge.load /etc/apache2/mods-enabled/mod_auth_gforge.load
  # /usr/sbin/apache2ctl restart
  
  And you will be able to see in the Log of Apache, something like this
    ---  ---  ---  ---  ---  ---
  Apache/2.0.48 (Debian GNU/Linux) DAV/2 SVN/1.0.0 mod_auth_gforge/$VERSION config
  ured -- resuming normal operations
    ---  ---  ---  ---  ---  ---
  That implies that Apache2 Httpd Server is running with the mod_auth_gforge module.
  
  If you don't see DAV/2 or SVN/1.0.0, you will have to enable them too.
  
  In Debian
  # /usr/sbin/a2enmod dav
  # /usr/sbin/a2enmod dav_fs
  # /usr/sbin/a2enmod dav_svn
  In others
  # ln -sf /etc/apache2/mods-available/dav.load /etc/apache2/mods-enabled/dav.load
  # ln -sf /etc/apache2/mods-available/dav_fs.load /etc/apache2/mods-enabled/dav_fs.load
  # ln -sf /etc/apache2/mods-available/dav_fs.conf /etc/apache2/mods-enabled/dav_fs.conf
  # ln -sf /etc/apache2/mods-available/dav_svn.load /etc/apache2/mods-enabled/dav_svn.load
  # ln -sf /etc/apache2/mods-available/dav_svn.conf /etc/apache2/mods-enabled/dav_svn.conf
  
  and 
  # /usr/sbin/apache2ctl restart 
  
  So, Apache2 Httpd Server is now ready for Setting up the VirtualHost supporting
  our control access module.
  
  4.General Information About Gforge Authentication and Authorization Module
  ==========================================================================
  
	4.1.Gforge authentication instructions
	--------------------------------------
	
	Outline:
	
	-Authentication
	
	You need one database, and one (or two) tables. One table holds the 
	username and the encrypted (or plain) password. The other table holds 
	the username and the names of the roup to which the user belongs. It 
	is possible to have username, groupname and password in the same 
	table.

	groups and users databases should be used for this.
	
	-Access Logging
	
	Every authentication access is logged in the same database of the
	authentication table, but in different table.
	User name and date of the request are logged. As option, it can log
	password, ip address, and request line.
	
	
	4.2.Gforge authorization instructions
	-------------------------------------
	
	-Authorization
	
	There are two kind of accesses. The "Group" access and the "User" access.
	Each Gforge project ( group ) could have a directory containing files 
	belonging to the project. Only the admins of this project could change 
	the files inside.
	
	If project is not Active ('A' status), the only ones that could get in are
	the site admin users ( users being members of the siteadmin project ).
	
	If the project is not public, the only one that could get into ( read access )
	are projects admin ( and of course, site admins ).
	
	Each User has a directory. He is the only one who can write into it. ( Site 
	admins could write too ). If the user is not active, then the only user who 
	can get into his directory is a site admin. Each user could have a private 
	directory ( in this moments 'private' ), he is the only one that can read 
	and/or write there.
	
	All users could read each user directories ( and files ) but private.
	
	A typical DocumentRoot of the WebDav system looks like this:
	( find -type d from /var/lib/gforge/upload )
		./groups
		./groups/newsadmin
		./groups/newsadmin/directory1
		./groups/project1/directory1
		./users
		./users/kikov2
		./users/kikov2/folder1
		./users/kikov2/private
		./users/kikov2/private/private_dir
		
	There exists another way to organize the tree. I have called it "First Letter".
	This should be configured in Apache Config, and in tools for maintenance.
	( find -type d from /var/lib/gforge/upload )
		./groups
		./groups/n
		./groups/n/newsadmin
		./groups/n/newsadmin/directory1
		./groups/p
		./groups/p/project1
		./users
		./users/k
		./users/k/kikov2
		./users/k/kikov2/folder1
		./users/k/kikov2/private/
		./users/k/kikov2/private/private_dir
	
	Each directory could contains files.
	The owner of ALL the tree is www-data. Permissions are controlled by the auth 
	module.
	
	Module Directives: See the code. At the moment, the same of
	libapache-mod-pgsql, plus:
	- GforgeSysPath
		The root of the path supporting the directory structure, although
		it's not used yet. It should contain the DocumentRoot of the
		VirtualHost containing the SVN repositories
	
	- GforgeGroupsRoot 
		The root of the groups directory. It's the relative path to the 
		DocumentRoot containing the groups directories
	
	- GforgeUsersRoot 
		The root of the users directory. It's the relative path to the 
		DocumentRoot containing users directories
	
	- FirstLetter
		If true it checks the directory to be like this:
		$GforgeUsersRoot/a/abel
		$GforgeUsersRoot/j/john
		
		$GforgeGroupsRoot/m/myProject
		$GforgeGroupsRoot/y/yourProject

	- GforgeAuthClause	
		It's a SQL Query that allow an extra check to restrict the access
		If the query result is empty, then the access will be denied.
		If the query result is not empty, the rest of the checks will occur
		You can use params in the SQL:
		$G -> unix_group_name extracted from directory
		$U -> user_name who is accessing
		$u -> user_name extracted from directory
		$A -> Access Method
			WRITE for write access
			READ for read access
	
	- GforgeReadClause and GforgeWriteClause
		It's a part of a SQL that allow an extra check based on flags.
		The Query that is executed is this:
		"SELECT user_group_id FROM users,groups,user_group "
		"WHERE user_group.group_id=groups.group_id AND "
		"user_group.user_id=users.user_id AND "
		"users.user_name = '%s' AND "
		"groups.unix_group_name = '%s' AND "
		"user_group.%s", user_name, unix_grop_name, clause
		
		The last param is changed by the string you put in
		the directive.
		To see when they are executed, see the following TREE
		
	- GforgeAnonClause
		It's a part of a SQL that allow an extra check on public
		projects, where there is a restriction ( like enable_anoncvs )

		"SELECT group_id FROM groups,users "
		"WHERE groups.unix_grop_name = '%s' AND "
		"users.user_name = '%s' AND "
		"%s", real_group, user_name, clause

	- Auth_PG_cache_passwords
		It will make use of some tables of 50 Elements to cache
		results of SQL queries.
	
	Access Checking for Groups Dir actually implemented
	
		1) Check if the Project exists:
		 1.a) If exists, go to 2
		 1.b) If doesn't exist, relay in another Auth system, EXIT
		2) Check if the user is Site_Admin
		 2.a) If Site_Admin, AUTH_GRANTED
		 2.b) If not, go to 3
		3) Check if Project is active
		 3.a) If deactive, FORBIDDEN
		 3.b) If active, go to 4
		4) Check if the Project is public
		 4.a) If public, go to 5
		 4.b) If isn't public, Check if the user is in the group
		   4.b.1) If he is, 5
		   4.b.2) If he isn't, FORBIDDEN
		5) Check the General CLAUSE
		6) Check if User is a group admin
		 6.a) If he is, AUTH_GRANTED
		 6.b) If he isn't, go to 7
		7) Check Access Kind
		 7.a) Read, is_public?
		  7.a.1) Yes, Return ANON_CLUASE
		  7.a.2) No, READ_CLAUSE -> return READ_CLAUSE
		 7.b) Write. Return WRITE_CLAUSE
		 7.c) Unknown Access Type -> HTTP_FORBIDDEN
		7)Check Access Kind 
		 7.a) Is Member? 
		  7.a.1) Yes 
		   7.a.1.a) Read Access? -> Return READ_CLAUSE 
		   7.a.1.b) Write Access? -> Return WRITE_CLAUSE 
		  7.a.2) No, 
		   7.a.2.1) Check if public group AND READ access
		    7.a.2.1.a) Yes. Return ANON_CLAUSE 
		    7.a.2.1.b) No. HTTP_FORBIDDEN

		default

	
	Access Checking for Users Dir actually implemented
		1) Check if the User Exists
		1.a) If exist, go on
		1.b) If doesn't exist, relay in another Auth system
		2) Check if the user is Active
		2.a) If is active, go on
		2.b) If not active, check if user is site admin
		2.b.1) If site admin, AUTH_GRANTED
		2.b.2) If not, FORBIDDEN
		3) Check if directory is private
		3.a) If is private
		3.a.1) Check if user != userdir
		3.a.1.a) if !=, then FORBIDDEN
		3.a.1.b) If ==, then go on
		3.b) If not, go on
		4) Check the Authz Method
		4.a) If READ, go on
		4.b) If WRITE
		4.b.1) Check if user == userdir
		4.b.1.a) If it is, then go on
		4.b.1.b) If not, FORBIDDEN
		4.c) DECLINED
		5) AUTH_GRANTED



  5.Configuration
  ===============
  
  A template file in $sources/etc/gforge/httpd.d/17webdav file is provided
  
  Comments about the configuration of Apache
  
  This is an example of a VirtualHost with Access Control.

  Example Apache Config File
  ---  ---  ---  ---  ---  ---
  #
  # Upload host
  #
  <VirtualHost 192.168.3.17:80>
    ServerName webdav.vikinga.ladies
    DocumentRoot  /var/lib/gforge/upload
    DAVLockDB     /var/lib/gforge/tmp/DAVLockDB
  
    <Location />
          GforgeSysPath 	/var/lib/gforge/upload # Actually not used, but
				# should have a string
				# QUITE IMPORTANT.
	  GforgeGroupsRoot	/groups
	  GforgeUsersRoot	/users

          DAV On
          AuthType              basic
          AuthName              "Gforge User Authentication"

          Auth_PG_host          localhost
          Auth_PG_database      gforge
          Auth_PG_port          5432
          Auth_PG_user          gforge
          Auth_PG_pwd           xxxxxxxxx
          Auth_PG_pwd_table     users
          Auth_PG_pwd_field     unix_pw
          Auth_PG_uid_field     user_name
          Auth_PG_encrypted     on
          Auth_PG_hash_type     CRYPT
          Auth_PG_authoritative on

          Require valid-user
    </Location>

    LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
    CustomLog "|/usr/sbin/cronolog /var/log/gforge/%Y/%m/%d/gforge.log" gforge
    
    # Ensure that we don't try to use SSL on SSL Servers
    <IfModule apache_ssl.c>
    	  SSLDisable
    </IfModule>
  </VirtualHost>
  ---  ---  ---  ---  ---  ---
  
  This Virtual Host is for a box called "vikinga.ladies"

  In /var/lib/gforge/upload there should be directories with unix_group_names
  names of groups. A set of scripts are provided to make such a structure.


  These scripts are create_users.php and create_groups.php that are used in this way:

  # /usr/lib/gforge/bin/create_users.php -d include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
    /var/lib/gforge/upload
  # /usr/lib/gforge/bin/create_groups.php -d include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
    /var/lib/gforge/upload
    
  There is a option -f, that means First Letters. This option was previously explained.

  You may want to use a cronjob file.
  ---  ---  ---  ---  ---  ---
  15 6 * * * www-data [ -x /usr/lib/gforge/bin/create_users.php ] && \
    /usr/lib/gforge/bin/create_users.php -d \
    include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
    /var/lib/gforge/upload -f> /dev/null 2>&1
  35 6 * * * www-data [ -x /usr/lib/gforge/bin/create_groups.php ] && \
    /usr/lib/gforge/bin/create_groups.php -d \
    include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
    /var/lib/gforge/upload -f> /dev/null 2>&1
  ---  ---  ---  ---  ---  ---
  
  These are the permissions that I have set in /var/lib/gforge/upload
    drwx------    2 www-data www-data        6 Feb 18 16:56 groups
    drwx------    2 www-data www-data        6 Feb 18 16:56 users

  Use a webdav brownser like Konqueror to explore it: webdav://username@webdav.YourSite

  5.1. Working with SUBVERSION
  ----------------------------
  
  This module could be used too with Subversion. When working with subversion,
  the system haven't direct access to the datas in it, so it's a bit more complex to
  do maintenance tasks such as automatic group and user directories creation.
  
  So I have provide a script to automate a bit the admin tasks.
  
  These steps are required in the installation of a SVN repository
  
  1 )In the installation, you have to create a SVN repository. 
  
  # svnadmin create /var/lib/gforge/uploadsvn
  # chown www-data.www-data -R /var/lib/gforge/uploadsvn
  
  2) You have now to create group and users directories.
  
  # /usr/lib/gforge/bin/create_users.php -d include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
	/var/lib/gforge/upload -f
  # /usr/lib/gforge/bin/create_groups.php -d include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
          /var/lib/gforge/upload -f
  # chown www-data.www-data -R /var/lib/gforge/upload
  
  3) You have to import them in the SVN repository
  # svn import /var/lib/gforge/upload file:///var/lib/gforge/uploadsvn
  
  4) Now, we're going to prepare the working copy. It all went smooth, we can make:
  
  # rm -rf /var/lib/gforge/upload
  # svn checkout file:///var/lib/gforge/uploadsvn /var/lib/gforge/upload
  # chown www-data.www-data -R /var/lib/gforge/upload
  
  In this moments, we can add a file to /var/lib/gforge/upload, and commit. Creation of
  group and users directory should be done in a cronjob. You can use create_groups.php and 
  create_users.php for this.
  
  
  For maintenance, if you have to fix something, you will do:
  
  # cd /var/lib/gforge/upload && svn update
  # ( ... fix ... )
  # cd /var/lib/gforge/upload && svn commit
  
  
  So, you will need a cron file like this
  ---  ---  ---  ---  ---  ---  ---
  # Recreate groups and users directories
  0 6 * * * www-data cd /var/lib/gforge/upload && svn update
  15 6 * * * www-data [ -x /usr/lib/gforge/bin/create_users.php ] && \
    /usr/lib/gforge/bin/create_users.php -d \
    include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
    /var/lib/gforge/upload -f> /dev/null 2>&1
  35 6 * * * www-data [ -x /usr/lib/gforge/bin/create_groups.php ] && \
    /usr/lib/gforge/bin/create_groups.php -d \
    include_path=/usr/share/gforge/:/usr/share/gforge/www/include \
    /var/lib/gforge/upload -f> /dev/null 2>&1
  55 6 * * * www-data [ -x /usr/lib/gforge/bin/committree.sh ] && \
    /usr/lib/gforge/bin/committree.sh /var/lib/gforge/upload > /dev/null 2>&1
  ---  ---  ---  ---  ---  ---  ---

  Example Apache Config File for SVN
  ---  ---  ---  ---  ---  ---  ---
  #
  # Upload host with SVN
  #
  <VirtualHost 192.168.3.17:80>
    ServerName webdav.vikinga.ladies
    DocumentRoot  /var/lib/gforge/upload
    DAVLockDB     /var/lib/gforge/tmp/DAVLockDB
  
    <Location />
          GforgeSysPath 	/var/lib/gforge/upload # Actually not used, but
				# should have a string
				# QUITE IMPORTANT.
	  GforgeGroupsRoot	/groups
	  GforgeUsersRoot	/users

          DAV svn
	  SVNPath /var/lib/gforge/uploadsvn
 	# And optionally if you want: SVNAutoversioning on,if you want users 
	#  can add files  ( and new versions ) from the brownser
          AuthType              basic
          AuthName              "Gforge User Authentication"

          Auth_PG_host          localhost
          Auth_PG_database      gforge
          Auth_PG_port          5432
          Auth_PG_user          gforge
          Auth_PG_pwd           xxxxxxxxx
          Auth_PG_pwd_table     users
          Auth_PG_pwd_field     unix_pw
          Auth_PG_uid_field     user_name
          Auth_PG_encrypted     on
          Auth_PG_hash_type     CRYPT
          Auth_PG_authoritative on

          Require valid-user
    </Location>

    LogFormat "%h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" gforge
    CustomLog "|/usr/sbin/cronolog /var/log/gforge/%Y/%m/%d/gforge.log" gforge
    # Ensure that we don't try to use SSL on SSL Servers
    <IfModule apache_ssl.c>
	  SSLDisable
    </IfModule>
  </VirtualHost>
  ---  ---  ---  ---  ---  ---  ---

  There exits another way. You may want having separated repositories by each project.
  You should use SVNParentPath instead SVNPath. 
  With SVNParentPath, GforgeGroupsRoot should be the same as Location. It's not possible
  to have First_Letter + SVNParentPath.


  Aditional Notes:
  It's quite important to not overlap DocumentRoot and SVNPath ( or SVNParentPath )!!!
  This is explained in Subversion Faq 
  ( http://subversion.tigris.org/project_faq.html#301-error )

  6.Installation Summary
  ======================
    1) Install all modules in apache: dav, dav_fs, svn, mod_auth_gforge. You can
    	use the utility a2enmod provided with Apache2 Httpd Webserver.
    2) Choose between SVN or Not, if SVN, choose between Autoversioning or not.
    3) Choose between First Letter or not.
    3) Fill the VirtualHost with your datas in Apache. Setup your DNS server!
    4) If your using SVN, prepare the repository.
    5) Create the main skeleton of /groups and /users with create_users.php and 
       create_groups.php. REMEMBER to use the -f option if you have choosen the
       First Letter option.
    6) If you chose the SVN, commit the new changes
    7) Setup the cronjobs scripts. Test them manually, and adjust the paths.

    8) Take care of Permissions. This should work with 700 for directories and
       600 for files for user www-data ( the one used by Apache2 ).
       
  7.Tests
  =======
  I propose some test to see if everything is working OK.

  8.Notes for Fedora Core 3
  =========================
  You can have two problems with FC3 apache default configuration.
  1) First, disable ( or remove ) the filename /etc/httpd/conf.d/welcome.conf. This will
     prevent showing something different than default FC3 test page when no index.html is
     found
  2) Options Indexes. Don't forget to include this if you want to retrieve the 
     directory listing. 
