<?xml version="1.0"?>
<!--
  Copyright 2002-2004 The Apache Software Foundation or its licensors,
  as applicable.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0 

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
  <properties>
    <title>installation</title>
  </properties>
  <body>
    <section name="Table of contents">
      <macro name="toc">
        <param name="section" value="0"/>
        <param name="fromDepth" value="0"/>
        <param name="toDepth" value="4"/>
      </macro>
    </section>
    <section name="Introduction">
      <p> PhotoXChange is a standard J2EE web application. Configuration settings are required for
        both the web application itself, and for the application server. </p>
    </section>
    <section name="Web application configuration">
      <p> To configure the web application, the following configuration settings must be done: </p>
      <table>
        <tr>
          <th>Where</th>
          <th>Parameter Name</th>
          <th>Meaning</th>
          <th>Default value</th>
        </tr>
        <tr>
          <td>
            <code>WEB-INF/classes/ org.wamblee.photos.properties</code>
          </td>
          <td>org.wamblee.photos.path</td>
          <td>Full path name of the directory where photos are stored. This directory must be
            created beforehand.</td>
          <td>A path that works on some developer's system but most likely not on yours.</td>
        </tr>
        <tr>
          <td/>
          <td>org.wamblee.photos.realm</td>
          <td>The security domain used. This must match with the JNDI name specified in
              <code>WEB-INF/jboss-web.xml</code> and it must also correspond with a security domain
            configured in the application server.</td>
          <td>PhotoXChange</td>
        </tr>
        <tr>
          <td/>
          <td>org.wamblee.photos.security.userprincipal</td>
          <td>The classname of the principal class representing the user. </td>
          <td>org.jboss.security.SimplePrincipal</td>
        </tr>
        <tr>
          <td/>
          <td>org.wamblee.photos.admingroup</td>
          <td>The name of the administrator group.</td>
          <td>administrators</td>
        </tr>
      </table>
    </section>
    <section name="Database Setup">
      <p>The only currently supported database is MySQL. </p>
      <subsection name="MySQL Setup">
        <p> The aim of the MySQL setup is to setup a database with the following properties: </p>
        <ul>
          <li>The InnoDB storage engine is used</li>
          <li>Transaction isolation level is repeatable read</li>
          <li>A single user is created with all rights</li>
        </ul>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Selecting the storage engine</strong>
          </div>
          <p> First of all, MySQL must be configured to use the InnoDB storage engine for the photos
            database. This can be done in two ways: </p>
          <ul>
            <li>Configuration setting; Edit the <code>my.cnf</code> configuration file (usually
              located in <code>/etc</code> on *nix systems and add the following lines to the
                <code>[mysqld]</code> section: <source>default-table-type = INNODB </source>
              <p>After this, restart mysql. </p>
            </li>
            <li> After creating the database tables: For every database table execute the command
                <source>alter table TABLE_NAME engine = INNODB</source> to change the storage engine
              for that table to INNODB. </li>
          </ul>
        </div>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Create the database</strong>
          </div>
          <p> Now create a MySQL database </p>
          <source> mysqladmin -u root -p create photoxchange </source>
          <p> Where <code>root</code> is the user name of the administrator and
            <code>photoxchange</code> is the name of the database. </p>
          <p> Create a user on the database by logging in as administrator </p>
          <source> mysql -u root -p photoxchange </source>
          <p> and creating a user that has access to the database </p>
          <source> grant all on * to username identified by 'password'; </source>
          <p> This creates a user that can access the database from the same host the database is
            running on. If MySQL is running on a different machine than the application server,
            consult the MySQL manuals for information on how to configure access for that user. </p>
        </div>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Transactions</strong>
          </div>
          <p> After creating the database check the transaction settings by logging on to the
            photoxchange database as administrator and executing the command </p>
          <source> show variables </source>
          <p> The value of the <code>tx_isolation</code> variable should be
            <code>REPEATABLE-READ</code>. If this not the case, set the transaction level globally
            for all databases by specifying </p>
          <source> transaction-isolation = REPEATABLE-READ </source>
          <p> In the <code>[mysqld]</code> section of the <code>my.cnf</code> file. It is also
            possible to set the transaction isolation level for one database only using </p>
          <source> SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ </source>
          <p> See the MySQL manuals for more details. </p>
        </div>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Creating the database schema</strong>
          </div>
          <p> Populate the database by executing the sql scripts provided with the delivery on the
            database. On *nix systems: </p>
          <source> mysql -u username -p photoxchange &lt; setup.sql </source>
          <p> After this, execute the command <code>show table status;</code> to check that the
            tables indeed use the InnoDB storage engine. </p>
        </div>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Populating the database</strong>
          </div>
          <p> The photos application will perform the following initializations automatically at
            startup. </p>
          <table>
            <tr>
              <th>Initialization performed</th>
              <th>When?</th>
            </tr>
            <tr>
              <td>Initialization of users with one user 'erik' and one administrator 'admin', both
                having password 'abc123'.</td>
              <td>When no users have been defined.</td>
            </tr>
            <tr>
              <td>Initialization of authorization rules. </td>
              <td>When no authorization rules exist.</td>
            </tr>
          </table>
        </div>
      </subsection>
    </section>
    <section name="Application Server Setup">
      <p> For each supported application server, a separate section is provided. </p>
      <subsection name="JBoss 4">
        <p> For JBoss, configuration amounts to configuring the datasource and the security domain,
          The name of the security domain must match that specified in <a href="#conf-web-app">configuration settings</a>. </p>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Datasource Setup</strong>
          </div>
          <p> First of all, the database driver for MySQL must be installed by copying the driver
            jar <code>mysql-connector-java-3.x.y-bin.jar</code> from the <a href="http://www.mysql.com">MySQL
              web site</a> to the <code>server/default/lib</code> directory of JBoss. </p>
          <p> Next, the datasource must be configured by copying a <a href="photos-ds.xml.sample">photos-ds.xml</a> file to the
              <code>server/default/deploy</code> directory of the application server and choosing
            the correct username and password. </p>
        </div>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Security Setup</strong>
          </div>
          <p> To configure security, add the following security domain configuration to
              <code>login-config.xml</code> in the <code>server/default/conf</code> directory of the
            server: </p>
          <source>
            &lt;application-policy name="PhotoXChange"&gt;
              &lt;authentication&gt;
                &lt;login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required"&gt;
                  &lt;module-option name="unauthenticatedIdentity"&gt;guest&lt;/module-option&gt;
                  &lt;module-option name="dsJndiName"&gt;java:/PhotoXChange&lt;/module-option&gt;
                  &lt;module-option name="principalsQuery"&gt;
                    SELECT PASSWORD FROM USERS WHERE NAME = ?;
                  &lt;/module-option&gt;
                  &lt;module-option name="rolesQuery"&gt;
                    select g.name, 'Roles' from USERS u, USER_GROUPS ug, GROUPS g 
                    where u.id = ug.user_id and ug.group_id = g.id and u.name = ?
                  &lt;/module-option&gt;
                  &lt;module-option name="hashAlgorithm"&gt;MD5&lt;/module-option&gt;
                  &lt;module-option name="hashEncoding"&gt;hex&lt;/module-option&gt;
                &lt;/login-module&gt;
              &lt;/authentication&gt;
            &lt;/application-policy&gt;   
          </source>
          <p> Note the module option <code>dsJndiName</code> which refers to the previously
            configured datasource. Also, note the module options <code>hashEncoding</code> and
              <code>hashAlgorithm</code> which specify that passwords should be stored as a base 16
            MD5 hash. </p>
        </div>
      </subsection>
      <subsection name="Glassfish 2">
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Log4j</strong>
          </div>
          <p>Since most applications and 3rd party products require log4j and glassfish by default
            does not have this, log4j support must be added as follows:</p>
          <ul>
            <li>Create a directory lib/log onder glassfish and put the log4j jar and
              log4j.properties file there. </li>
            <li>Add the fully qualified path to the log4j.jar into the classpath of Glassfish
              together with the directory that contains the log4j.properties file. You can do that
              in the web UI: Application Server/JVM Settings/Paths and the entries are separated by
              a return. Use the system path. </li>
            <li>Restart glassfish.</li>
          </ul>
        </div>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Datasource setup</strong>
          </div>
          <p> First of all, the database driver for MySQL must be installed by copying the driver
            jar mysql-connector-java-3.x.y-bin.jar from the MySQL web site to the server/default/lib
            directory of JBoss. Next, the datasource must be configured by configuring a connection
            pool and a JDBC resource with JNDI name identical to the previously configured
            datasource. The connection pool must be configured with the following properties: </p>
          <ul>
            <li><em>user</em>: The database user name.</li>
            <li><em>password</em>: The database password.</li>
            <li><em>URL</em>: For instance <code>jdbc:mysql://localhost:3306/photoxchange</code> is
              photoxchange is the name of the database. </li>
          </ul>
          <p>Configuration of the JDBC resource is straightforward.</p>
        </div>
        <div class="subsubsection">
          <div class="title">
            <strong class="title">Security setup</strong>
          </div>
          <p> To setup security, FlexibleJdbcRealm is required. This requires several steps: </p>
          <ul>
            <li>Copy the FlexibleJdbcRealm to the glassfish lib directory and restart glassfish.</li>
            <li>Edit config/login.conf of the glassfish domain to add mapping of the realm to the
              flexible JdbcRealm login module: <source> PhotoXChangeRealm {
                org.wamblee.glassfish.auth.FlexibleJdbcLoginModule required; }; </source> Here,
              PhotoXChangeRealm is the name of the configured securty realm. </li>
            <li>In glassfish administration console in security, select default principal to role
            mapping to make sure that roles and groups are identical. </li>
            <li>Configure the security realm with the following properties 
              <table><tr><th>Property</th><th>Value</th></tr><tr><td>jaas.context</td><td>PhotoXChangeRealm</td></tr><tr><td>sql.password</td><td>SELECT PASSWORD FROM USERS WHERE NAME = ?</td></tr><tr><td>sql.groups</td><td>SELECT g.name FROM USERS u, USER_GROUPS ug, GROUPS g  WHERE u.id = ug.user_id
                    and ug.group_id = g.id AND u.name = ?</td></tr><tr><td>datasource.jndi</td><td>Datasource JNDI name configured before, e.g. jdbc/PhotoXChange</td></tr><tr><td>password.encoding</td><td>MD5</td></tr><tr><td>password.seed.format</td><td>{0}</td></tr><tr><td>assign-groups</td><td>ALL</td></tr></table>
            </li>
          </ul>
        </div>
      </subsection>
    </section>
    <section name="Managing users and groups">
      <p> This release of PhotoXChange provides a rudimentary user interface for managing users and
        groups. This interface can be accessed by logging in as administrator and clicking on
        'Administration'. </p>
      <p> Alternatively, users and groups may be modified using direct SQL. The table below shows
        some common scenarios </p>
      <table>
        <tr>
          <th>Scenario</th>
          <th>Howto</th>
        </tr>
        <tr>
          <td>Changing a password</td>
          <td><code>update USERS set password = md5('password') where user = 'username'</code>. The
            MD5 encoded password can also be generated using openssl: <code>echo -n PASSWORD |
              openssl dgst -md5 -hex</code></td>
        </tr>
        <tr>
          <td>Adding a user</td>
          <td>Add a new row to the USERS table and add a new row to the USER_GROUPS table to add the
            user to a group.</td>
        </tr>
        <tr>
          <td>Adding a group</td>
          <td>Add a new row to the GROUPS table.</td>
        </tr>
        <tr>
          <td>Adding a user to a group</td>
          <td>Add an entry to the USER_GROUPS table</td>
        </tr>
      </table>
    </section>
  </body>
</document>
