<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" 
  "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
  <!ENTITY % cartoweb SYSTEM "../cartoweb.ent" >
  %cartoweb;
  ]>
<!-- $Id: security.xml,v 1.23 2007-07-26 15:15:13 olivier Exp $ -->
<chapter id="user.security">
  <title>Security Configuration</title>
  <sect1 id="user.security.intro">
    <title>Introduction</title>
    <para> Access to different parts of the &cartoweb; can be allowed or denied 
      according to who is currently using the application. </para>
    <para> The following concepts are used in this chapter.</para>
    <variablelist>
      <title>Security Mechanisms Concepts</title>
      <varlistentry>
        <term>User</term>
        <listitem>
          <para> Representation of a user accessing &cartoweb;. If the user is 
            not logged in, she is rerefenced as the 
            <constant>anonymous</constant> user.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>Role</term>
        <listitem>
          <para> A user can have zero or more roles associated to her. These 
            roles are used to allow or deny a permission to a resource of 
            feature. </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>Permissions</term>
        <listitem>
          <para>Permissions describe parts of the application which can be 
            allowed or denied access. A permission can have roles for which 
            access is allowed, and roles for which it is denied. </para>
        </listitem>
      </varlistentry>
    </variablelist>
  </sect1>
  <sect1 id="user.security.auth">
    <title>Auth Plugin</title>
    <para> The security system in &cartoweb; was developped to be modular and 
      to allow different authentications systems to be easily plugged-in. This 
      section describes one implementation of authentication, user password and 
      roles management, which is the auth plugin shipped with &cartoweb;. 
      </para>
    <screenshot>
      <mediaobject>
        <imageobject>
          <imagedata width="7cm" fileref="images/security.login_dialog.png" 
            format="PNG"/>
        </imageobject>
        <textobject>
          <phrase>Auth plugin login dialog</phrase>
        </textobject>
      </mediaobject>
    </screenshot>    
    <para> The auth plugin is not a core plugin. That's why you need to enable 
      it if you want to enable users to log-in. See <xref 
      linkend="user.config"/> how to enable it in the list of plugins. If it is 
      not activated the login dialog won't be available, so users will remain 
      anonymous. </para>
    <para> The next section describes the configuration file of the auth 
      plugin. It is basically the management of usernames, passwords and roles. 
      </para>
    <sect2 id="user.security.auth.users_roles">
      <title>auth.ini (Client-side)</title>
      <para> The <filename>auth.ini</filename> configuration is located in the 
        client. This file contains the list of usernames, their password and 
        the roles they belong to: </para>
      <itemizedlist>
        <listitem>
          <para> 
            authActive<indexterm><primary>authActive</primary></indexterm>: 
            boolean Whether to show the Authentication login/logout buttons. 
            (note: this is not related to the fact the authentication system 
            will be active or not) </para>
        </listitem>
        <listitem>
          <para> 
            users.USERNAME<indexterm><primary>users.USERNAME</primary></indexterm> 
            List of users and their passwords. <constant>USERNAME</constant> is 
            the name of the user for whom the password is set. Passwords values 
            are md5sums of the password. To get this value, you can type in a 
            shell: </para>
          <screen><![CDATA[echo -n 'mypassword' | md5sum]]></screen>
          <para> Example: </para>
          <programlisting><![CDATA[users.alice = e3e4faee0cc7fc55ad402f517cdaf40]]></programlisting>
        </listitem>
        <listitem>
          <para> 
            roles.USERNAME<indexterm><primary>roles.USERNAME</primary></indexterm> 
            List of roles for each user. <constant>USERNAME</constant> is 
            replaced by the user for whom the roles are set. Some roles have a 
            special meaning, see <xref 
            linkend="user.security.auth.special_roles"/> </para>
        </listitem>
      </itemizedlist>
      <para>
      It is possible to use three different locations where user and password are
      stored. There are three mechanisms built-in in &cartoweb;:
      <orderedlist>
        <listitem>
          <para>.ini file</para>
        </listitem>
        <listitem>
          <para>database</para>
        </listitem>
        <listitem>
          <para>ldap</para>
        </listitem>
      </orderedlist>
      </para>
      <para>
      The parameter <constant>securityContainer</constant> controls which backend is
      used.
      </para>
      <itemizedlist>
        <listitem>
          <para> 
            securityContainer<indexterm><primary>securityContainer</primary></indexterm>: 
            can be <constant>ini</constant> for the file storage,
            <constant>db</constant> for the dabase storage, or 
            <constant>ldap</constant> for the ldap storage.</para>
        </listitem>
      </itemizedlist>
      <para>Parameters for database and ldap storage are described below</para>
      <sect3 id="user.security.auth.users_roles.db">
        <title>database storage</title>
        <itemizedlist>
          <listitem>
            <para> 
              dbSecurityDsn<indexterm><primary>dbSecurityDsn</primary></indexterm>:
              The database connection string to be used. For instance 
              <literal>pgsql://user:password@localhost/test</literal>.
              </para>
          </listitem>
          <listitem>
            <para> 
              dbSecurityQueryUser<indexterm><primary>dbSecurityQueryUser</primary></indexterm>:
              The SQL query to perform to check a username/password pair is valid. It 
              should return a row if the pair is correct. For instance:
              <literal>"SELECT * FROM users WHERE username='%s' AND password='%s'"</literal>.
              </para>
          </listitem>
          <listitem>
          <para> 
              dbSecurityQueryRoles<indexterm><primary>dbSecurityQueryRoles</primary></indexterm>:
              The SQL query used to retrieve roles for a given user. It should return one column
              with all roles for the user each row. For instance:
              <literal>"SELECT roles FROM users WHERE username='%s'"</literal>
              </para>
          </listitem>
        </itemizedlist> 
      </sect3>
      <sect3 id="user.security.auth.users_roles.ldap">
        <title>ldap storage</title>
        <para>The following parameters are inspired from Pear::Auth_Container_LDAP</para>
        <itemizedlist>
          <listitem>
            <para> 
              host<indexterm><primary>host</primary></indexterm>:
              hostname of the server that hosts the ldap server
              <literal>localhost</literal> (default), 
              <literal>ldap.netsols.de</literal>.
              </para>
          </listitem>
          <listitem>
            <para> 
              port<indexterm><primary>port</primary></indexterm>:
              Port number on which the ldap server listens
              <literal>389</literal> (default).
              </para>
          </listitem>
          <listitem>
          <para> 
              basedn<indexterm><primary>basedn</primary></indexterm>:
              the base dn (Distinguished Name) of the ldap server
              For instance: <literal>dc=ldap,dc=netsols,dc=de</literal>
              </para>
          </listitem>
          <listitem>
          <para> 
              userattr<indexterm><primary>userattr</primary></indexterm>:
              the user attribute to search for.
              <literal>uid</literal> (default)
              </para>
          </listitem>
          <listitem>
          <para> 
              groupdn<indexterm><primary>groupdn</primary></indexterm>:
              gets prepended to basedn when searching for group.
              For instance: <literal>ou=Groups</literal>
              </para>
          </listitem>
          <listitem>
          <para> 
              groupattr<indexterm><primary>groupattr</primary></indexterm>:
              the group attribute to search for.
              <literal>cn</literal> (default)
              </para>
          </listitem>
          <listitem>
          <para> 
              groupfilter<indexterm><primary>groupfilter</primary></indexterm>:
              filter that will be added to the search filter when
              searching for a group:
              <literal><![CDATA[
              (&(groupattr=group)(memberattr=username)(groupfilter))]]>
              </literal>
              <literal>(objectClass=groupOfUniqueNames)</literal> (default).
              For instance: <literal>(objectClass=posixGroup)</literal>
              or <literal>(cn=cw*)(objectClass=posixGroup)</literal> if you 
              have groups starting with "cw" specifically set for Cartoweb.
              </para>
          </listitem>
          <listitem>
          <para> 
              memberattr<indexterm><primary>memberattr</primary></indexterm>:
              the attribute of the group object where the user dn
              may be found
              <literal>uniqueMember</literal> (default)
              </para>
          </listitem>
          <listitem>
          <para> 
              groupscope<indexterm><primary>groupscope</primary></indexterm>:
              Scope for group searching: <literal>one</literal>, 
              <literal>sub</literal> (default), or <literal>base</literal>
              </para>
          </listitem>
        </itemizedlist> 
      </sect3>
    </sect2>
    <sect2 id="user.security.auth.special_roles">
      <title>Special Role Names</title>
      <para>The auth plugin configuration described in the previous section 
        references the notion of users and roles. Basically a role can be any 
        string, the application will only use them as a way to check if a 
        feature is allowed or not. However, a set of role name have a special 
        meaning. They are described below.</para>
      <variablelist>
        <title>Special Roles</title>
        <varlistentry>
          <term>all<indexterm><primary>all</primary></indexterm></term>
          <listitem>
            <para>This role belongs to any user. It is useful in case a 
              permission should not be restricted access.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term> 
            loggedIn<indexterm><primary>loggedIn</primary></indexterm></term>
          <listitem>
            <para>This role is given to all users who have logged in the 
              application. It means they are identified to the system with a 
              username. </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term> 
            anonymous<indexterm><primary>anonymous</primary></indexterm></term>
          <listitem>
            <para>This role is given to all users not known to the application. 
              This role is attached to anyone who has not yet entered her 
              username and password. </para>
          </listitem>
        </varlistentry>
      </variablelist>

      <example id="user.security.auth.users_roles.example">
        <title>Special Role Name Usage</title>
        <programlisting><![CDATA[general.allowedRoles = loggedIn]]></programlisting>
      </example>   
    </sect2>
  </sect1>
  <sect1 id="user.security.global_permissions">
    <title>Global &cartoweb; Permissions</title>
    <para> The whole application can be denied access to anonymous users: only 
      authenticated (or a set) of users can access the application. Anonymous 
      users arriving on the main page will see a login dialog page if they have 
      no rights to view the page (if the <constant>auth</constant> plugin is 
      not loaded, they will simply see a denied page). </para>
    <para> This feature can be parametrized on the &cartoclient; in the 
      <filename>client.ini</filename> configuration file:</para>
    <itemizedlist>
      <listitem>
        <para> securityAllowedRoles = list : List of roles which are allowed to 
          access the cartoweb. Set to 'all' if no if no restriction is given. (see <xref 
            linkend="user.security.auth.special_roles"/> for typical predefined roles)
          </para>
      </listitem>
    </itemizedlist>
      <example id="user.security.global_permissions.example">
        <title>Global Permissions Usage</title>
        <programlisting><![CDATA[securityAllowedRoles = loggedIn]]></programlisting>
      </example> 
  </sect1>
  <sect1 id="user.security.plugin_permissions">
    <title>Plugin Specific Permissions</title>
    <para> The main part of permissions is set in the different plugins of 
      &cartoweb;. For instance, permissions related to which layer can be 
      viewed are set in the layer plugin configuration files, and pdf printing 
      permissions in the pdf plugin. These sections either describes the plugin 
      permissions which can be used, or make references the the corresponding 
      chapters. </para>
    <sect2 id="user.security.plugin_permissions.layers">
      <title>Layers Related Permissions</title>
      <para>It is possible to restrict which layer can be viewed by a set of 
        users. For instance, only logged in admin users can be allowed to view 
        security sensitive layers.</para>
      <para>These layer permissions are inherited by children. It means that if 
        a parent LayerGroup is not allowed to be viewed, then all the children 
        won't be visible.</para>
      <para>The permissions for layer must be activated in the 
        <filename>layers.ini</filename> &cartoclient; configuration file, and 
        are set in the metadata of the mapfile or the 
        <filename>&lt;layers&gt;.ini</filename> configuration file. The 
        concept of metadata in mapfiles and .ini file is described in <xref 
        linkend="user.layers.metadata"/>. The metadata key name which can be 
        used is called <constant>security_view</constant> and contains a coma 
        separated list of roles which are allowed to view this layer. If no 
        such metadata key is associated to a layer or layerGroup, anyone can 
        see the layer. </para>
      <para> Heres the description of the <filename>layers.ini</filename> 
        configuration file:</para>
      <itemizedlist>
        <listitem>
          <para> 
            applySecurity<indexterm><primary>applySecurity</primary></indexterm>: 
            True if the security check of layer access is activated. It might 
            have a minor impact on performances, if a large number of layer is 
            used. </para>
        </listitem>
      </itemizedlist>
      <para> Here's an example of a security metadata key used in layer of the 
        mapfile: </para>
      <programlisting><![CDATA[METADATA
    "exported_values" "security_view,some_specific_parameter"
    "security_view" "admin" 
    "some_specific_parameter" "value"
  
  "id_attribute_string" "FID|string"
  "mask_transparency" "50"
  "mask_color" "255, 255, 0"
  "area_fixed_value" "10"
END]]></programlisting>
      <para> In this example, the layer containing this metadata description 
        will only be visible for users having the <constant>admin</constant> 
        role. </para>
      <note>
        <para>Notice the usage of the <constant>exported_values</constant> 
          metadata key which lists the security related metadata key. It is 
          explained in <xref linkend="user.layers.metadata"/></para>
      </note>
      <para>Now let's look the case where the metadata key is set on a layer 
        group in the <filename>&lt;layers&gt;.ini</filename> configuration 
        file: </para>
      <programlisting><![CDATA[layers.group_admin.className = LayerGroup
layers.group_admin.children = grid_defaulthilight 
layers.group_admin.metadata.security_view = admin]]></programlisting>
      <para> In this example, the <constant>admin</constant> role is set for 
        the layerGroup called <constant>group_admin</constant>. You can notice 
        the very similar syntax as used in the mapfile. </para>
      <warning>
        <para>Don't forget to set <constant>applySecurity</constant> to True in 
          the <filename>layers.ini</filename> &cartoclient; configuration file, 
          otherwise security metadata keys won't be taken into account.</para>
      </warning>
    </sect2>
    <sect2 id="user.security.plugin_permissions.pdf">
      <title>PDF Printing Permissions</title>
      <para>The roles management in Pdf printing is explained in detail in 
        <xref linkend="user.pdf"/>. In particular, see <xref 
        linkend="user.pdf.tutorial.roles"/>. </para>
    </sect2>
  </sect1>
</chapter>
