blob: d6e84dd3251c6b19d18a3a928a2a4c748240d608 [file] [log] [blame]
<?xml version="1.0"?>
<!--
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* 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>
<properties>
<title>Turbine Services - Torque Security Service</title>
</properties>
<body>
<section name="Torque Security Service">
<p>
This is an implementation of a Security Service which uses <a
href="http://db.apache.org/torque/">Torque</a> generated
peers to access the required security information.
</p>
<p>
Older versions of the Security Service used hard coded Peers to access
the security information. The current version can access arbitrary peers
to retrieve the information and can be adapted to a pre-existing schema and
use peer classes from outside Turbine.
</p>
</section>
<section name="Configuring the Security Service">
<p>
You need to configure Turbine to use the Torque Security Service:
</p>
<source><![CDATA[
services.SecurityService.classname = org.apache.turbine.services.security.torque.TorqueSecurityService
]]></source>
<p>
You must also tell the Security Service to use the Torque UserManager
implementation:
</p>
<source><![CDATA[
services.SecurityService.user.manager = org.apache.turbine.services.security.torque.TorqueUserManager
]]></source>
<p>
See the <a href="security-service.html">Security Service</a> page
for details of these and other properties that may also need to be configured.
</p>
</section>
<section name="Using the supplied Peer classes">
<p>
When you start with the Security Service, you should use the Turbine
supplied Peer classes to familiarize yourself with the workings of the
Torque Security Service. Once you understand how the peer classes are
accessed, you can customize to your own Peer classes. Turbine supplies
the following peer classes and objects to retrieve data:
<table>
<tr>
<th>Object type</th>
<th>Function</th>
<th>Class</th>
</tr>
<tr>
<td rowspan="3">User</td>
<td>Implementation</td>
<td>org.apache.turbine.services.security.torque.TorqueUser</td>
</tr>
<tr>
<td>Peer</td>
<td>org.apache.turbine.services.security.torque.om.TurbineUserPeer</td>
</tr>
<tr>
<td>Persistent object</td>
<td>org.apache.turbine.services.security.torque.om.TurbineUser</td>
</tr>
<tr>
<td rowspan="3">Group</td>
<td>Implementation</td>
<td>org.apache.turbine.services.security.torque.TorqueGroup</td>
</tr>
<tr>
<td>Peer</td>
<td>org.apache.turbine.services.security.torque.om.TurbineGroupPeer</td>
</tr>
<tr>
<td>Persistent object</td>
<td>org.apache.turbine.services.security.torque.om.TurbineGroup</td>
</tr>
<tr>
<td rowspan="3">Role</td>
<td>Implementation</td>
<td>org.apache.turbine.services.security.torque.TorqueRole</td>
</tr>
<tr>
<td>Peer</td>
<td>org.apache.turbine.services.security.torque.om.TurbineRolePeer</td>
</tr>
<tr>
<td>Persistent object</td>
<td>org.apache.turbine.services.security.torque.om.TurbineRole</td>
</tr>
<tr>
<td rowspan="3">Permission</td>
<td>Implementation</td>
<td>org.apache.turbine.services.security.torque.TorquePermission</td>
</tr>
<tr>
<td>Peer</td>
<td>org.apache.turbine.services.security.torque.om.TurbinePermissionPeer</td>
</tr>
<tr>
<td>Persistent object</td>
<td>org.apache.turbine.services.security.torque.om.TurbinePermission</td>
</tr>
</table>
If you retrieve objects from the Torque Security Service, you will always
get the object classes in the "Implementation" rows. The Torque Security
Service will use the peers described in the "Peer" rows and internally
the implementation objects will use the objects from the "Persistent"
rows. As you will see later, you can reconfigure the "Peer" and
"Persistent" objects.
</p>
</section>
<section name="Turbine supplied table schema">
<p>
The Peers and objects supplied with the Torque Security Service were generated
from a Torque Schema. Its definition is <a href="/services/torque-security-schema.html">shown here</a>.
</p>
<p>
Turbine uses the following configuration for accessing the Torque
schema. If you just want to use the default Peers, you don't need any
of the following configuration, these are the defaults:
</p>
<source><![CDATA[
# This is the Peer class used to access the user peer (org.apache.turbine.services.security.torque.om.TurbineUserPeer)
services.SecurityService.torque.userPeer.class = org.apache.turbine.services.security.torque.om.TurbineUserPeer
# The columns in the peer used to retrieve information. These are the names of the constants
# in the configured peer
services.SecurityService.torque.userPeer.column.name = LOGIN_NAME
services.SecurityService.torque.userPeer.column.id = USER_ID
services.SecurityService.torque.userPeer.column.password = PASSWORD_VALUE
services.SecurityService.torque.userPeer.column.firstname = FIRST_NAME
services.SecurityService.torque.userPeer.column.lastname = LAST_NAME
services.SecurityService.torque.userPeer.column.email = EMAIL
services.SecurityService.torque.userPeer.column.confirm = CONFIRM_VALUE
services.SecurityService.torque.userPeer.column.createdate = CREATED
services.SecurityService.torque.userPeer.column.lastlogin = LAST_LOGIN
services.SecurityService.torque.userPeer.column.objectdata = OBJECTDATA
# These are the objects returned by the configured user peer (org.apache.turbine.services.security.torque.om.TurbineUser)
services.SecurityService.torque.user.class = org.apache.turbine.services.security.torque.om.TurbineUser
# These bean properties are queried from the returned object to retrieve the
# information
services.SecurityService.torque.user.property.name = UserName
services.SecurityService.torque.user.property.id = UserId
services.SecurityService.torque.user.property.password = Password
services.SecurityService.torque.user.property.firstname = FirstName
services.SecurityService.torque.user.property.lastname = LastName
services.SecurityService.torque.user.property.email = Email
services.SecurityService.torque.user.property.confirm = Confirmed
services.SecurityService.torque.user.property.createdate = CreateDate
services.SecurityService.torque.user.property.lastlogin = LastLogin
services.SecurityService.torque.user.property.objectdata = Objectdata
# This is the Peer class used to access the Group Peer (org.apache.turbine.services.security.torque.om.TurbineGroupPeer)
services.SecurityService.torque.groupPeer.class = org.apache.turbine.services.security.torque.om.TurbineGroupPeer
# The columns in the peer used to retrieve information. These are the names of the constants
# in the configured peer
services.SecurityService.torque.groupPeer.column.name = GROUP_NAME
services.SecurityService.torque.groupPeer.column.id = GROUP_ID
# These are the objects returned by the configured group peer (org.apache.turbine.services.security.torque.om.TurbineGroup)
services.SecurityService.torque.group.class = org.apache.turbine.services.security.torque.om.TurbineGroup
# These bean properties are queried from the returned object to retrieve the
# information
services.SecurityService.torque.group.property.name = Name
services.SecurityService.torque.group.property.id = GroupId
# This is the Peer class used to access the Role Peer (org.apache.turbine.services.security.torque.om.TurbineRolePeer)
services.SecurityService.torque.rolePeer.class = org.apache.turbine.services.security.torque.om.TurbineRolePeer
# The columns in the peer used to retrieve information. These are the names of the constants
# in the configured peer
services.SecurityService.torque.rolePeer.column.name = ROLE_NAME
services.SecurityService.torque.rolePeer.column.id = ROLE_ID
# These are the objects returned by the configured role peer (org.apache.turbine.services.security.torque.om.TurbineRole)
services.SecurityService.torque.role.class = org.apache.turbine.services.security.torque.om.TurbineRole
# These bean properties are queried from the returned object to retrieve the
# information
services.SecurityService.torque.role.property.name = Name
services.SecurityService.torque.role.property.id = RoleId
# This is the Peer class used to access the Permission Peer (org.apache.turbine.services.security.torque.om.TurbinePermissionPeer)
services.SecurityService.torque.permissionPeer.class = org.apache.turbine.services.security.torque.om.TurbinePermissionPeer
# The columns in the peer used to retrieve information. These are the names of the constants
# in the configured peer
services.SecurityService.torque.permissionPeer.column.name = PERMISSION_NAME
services.SecurityService.torque.permissionPeer.column.id = PERMISSION_ID
# These are the objects returned by the configured permission peer (org.apache.turbine.services.security.torque.om.TurbinePermission)
services.SecurityService.torque.permission.class = org.apache.turbine.services.security.torque.om.TurbinePermission
# These bean properties are queried from the returned object to retrieve the
# information
services.SecurityService.torque.permission.property.name = Name
services.SecurityService.torque.permission.property.id = PermissionId
]]></source>
<p>
The column names and the bean properties do not always match, because
you can change the name of the bean property with the javaName
attribute in the Torque XML file.
</p>
<p>
If you omit the class definition of the object classes
(<i>torque.user.class</i>, <i>torque.group.class</i>, <i>torque.role.class</i>,
<i>torque.permission.class</i>), the bean property OMClass in the peer is
consulted which should return the default class that this peer
returns.
</p>
</section>
<section name="Configuring Torque Security Service to use your own peer classes">
<p>
The most interesting application for this is to extend some of the tables
with more columns for additional data. In this example, the User table gets
extended by two more columns called "TELEPHONE" and "FAX".
</p>
<p>
At first we create a new torque schema:
</p>
<source><![CDATA[
<table name="CUSTOM_USER" idMethod="idbroker">
<column name="USER_ID" required="true" primaryKey="true" type="INTEGER"/>
<column name="LOGIN_NAME" required="true" size="64" type="VARCHAR" javaName="UserName"/>
<column name="PASSWORD_VALUE" required="true" size="16" type="VARCHAR" javaName="Password"/>
<column name="FIRST_NAME" required="true" size="64" type="VARCHAR"/>
<column name="LAST_NAME" required="true" size="64" type="VARCHAR"/>
<column name="EMAIL" size="64" type="VARCHAR"/>
<column name="CONFIRM_VALUE" size="16" type="VARCHAR" javaName="Confirmed"/>
<column name="MODIFIED" type="TIMESTAMP"/>
<column name="CREATED" type="TIMESTAMP" javaName="CreateDate"/>
<column name="LAST_LOGIN" type="TIMESTAMP"/>
<column name="OBJECTDATA" type="VARBINARY"/>
<column name="TELEPHONE" size="32" type="VARCHAR" javaName="Phone" />
<column name="FAX" size="32" type="VARCHAR"/>
<unique>
<unique-column name="LOGIN_NAME"/>
</unique>
]]></source>
<p>
Note a few things:
<ul>
<li>This schema is the same as the TURBINE_USER schema from Turbine with the addition of
two columns. This is especially important with regard to the "javaName" attributes which configure
the name of the property for this column in the persistent objects.</li>
<li>The "TELEPHONE" column has its property name set to "Phone".</li>
</ul>
</p>
<p>
The Torque schema now gets translated into two java classes:
<i>CustomUserPeer</i> for accessing the tables and <i>CustomUser</i> as objects
returned by the Peer.
</p>
<p>
Now we configure the Torque Security Service to for using this peer as UserPeer:
</p>
<source><![CDATA[
# This is the Peer class used to access the user peer (org.apache.turbine.services.security.torque.om.TurbineUserPeer)
services.SecurityService.torque.userPeer.class = CustomUserPeer
]]></source>
<p>
Please note that we neither configure any column or property
properties nor do we configure
<i>services.SecurityService.torque.user.class</i>. So the Torque Security
Service will query the <i>CustomPeer</i> for the class of the returned
objects. Now Turbine uses your supplied Custom User Peer for querying
User information. However you can't access your custom columns
(yet)...
</p>
<p>
Accessing your custom columns can be done in two ways. A simple and a complex:
</p>
<p>
The simple way:
</p>
<source><![CDATA[
User user = TurbineSecurity.getUser("test");
String phone = ((CustomUser) (((TorqueUser) user).getPersistentObj())).getPhone();
/* Better readable: */
User u2 = TurbineSecurity.getUser("test2");
TorqueUser tu2 = (TorqueUser) u2;
CustomUser cu = (CustomUser) u2.getPersistentObj();
String fax = cu.getFax();
]]></source>
<p>
Ugly, isn't it? If you get a class cast exception somewhere on the
way, don't worry. Then you misconfigured either the Torque Security
Service (CCE when doing tu2 = (TorqueUser) u2) or the peer (CCE when doing
cu = (CustomUser) u2.getPersistentObj()).
</p>
<p>
The elegant way:
</p>
<source><![CDATA[
public class ExtendedUser extends TorqueUser
{
public ExtendedUser()
{
super();
}
public ExtendedUser(Persistent obj)
{
super(obj);
}
public String getPhone()
{
return ((CustomUser) getPersistentObj()).getPhone();
}
public void setPhone(String phone)
{
((CustomUser) getPersistentObj()).setPhone(phone);
}
public String getFax()
{
return ((CustomUser) getPersistentObj()).getFax();
}
public void setFax(String fax)
{
((CustomUser) getPersistentObj()).setFax(fax);
}
}
TurbineResources.properties:
services.SecurityService.user.class = ExtendedUser
And then:
ExtendedUser eu = (ExtendedUser) TurbineSecurity.getUser("test");
String phone = eu.getPhone();
]]></source>
</section>
<section name="Advanced customization">
<p>
Consider the following schema:
</p>
<source><![CDATA[
<table name="CUSTOM_ROLE" idMethod="idbroker">
<column name="CUSTOM_ID" required="true" primaryKey="true" type="INTEGER"/>
<column name="NAME_OF_ROLE" required="true" size="64" type="VARCHAR"/>
<unique>
<unique-column name="NAME_OF_ROLE"/>
</unique>
</table>
]]></source>
<p>
If you want to use this as the role peer, you can configure the Torque Security Service like this:
</p>
<source><![CDATA[
services.SecurityService.torque.rolePeer.class = CustomRolePeer
# The columns in the peer used to retrieve information. These are the names of the constants
# in the configured peer
services.SecurityService.torque.rolePeer.column.name = NAME_OF_ROLE
services.SecurityService.torque.rolePeer.column.id = CUSTOM_ID
# These are the objects returned by the configured role peer (org.apache.turbine.services.security.torque.om.TurbineRole)
services.SecurityService.torque.role.class = CustomRole
# These bean properties are queried from the returned object to retrieve the
# information
services.SecurityService.torque.role.property.name = NameOfRole
services.SecurityService.torque.role.property.id = CustomId
]]></source>
<p>
Of course you must assure that the necessary foreign key relations in
the database are still valid. With some databases, e.g. MySQL this is
not a big concern, because they don't support foreign keys at all.
</p>
</section>
</body>
</document>