This is an implementation of a Security Service which uses Torque generated peers to access the required security information.
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.
You need to configure Turbine to use the Torque Security Service:
services.SecurityService.classname = org.apache.turbine.services.security.torque.TorqueSecurityService
You must also tell the Security Service to use the Torque UserManager implementation:
services.SecurityService.user.manager = org.apache.turbine.services.security.torque.TorqueUserManager
See the Security Service page for details of these and other properties that may also need to be configured.
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:
Object type | Function | Class |
---|---|---|
User | Implementation | org.apache.turbine.services.security.torque.TorqueUser |
Peer | org.apache.turbine.services.security.torque.om.TurbineUserPeer | |
Persistent object | org.apache.turbine.services.security.torque.om.TurbineUser | |
Group | Implementation | org.apache.turbine.services.security.torque.TorqueGroup |
Peer | org.apache.turbine.services.security.torque.om.TurbineGroupPeer | |
Persistent object | org.apache.turbine.services.security.torque.om.TurbineGroup | |
Role | Implementation | org.apache.turbine.services.security.torque.TorqueRole |
Peer | org.apache.turbine.services.security.torque.om.TurbineRolePeer | |
Persistent object | org.apache.turbine.services.security.torque.om.TurbineRole | |
Permission | Implementation | org.apache.turbine.services.security.torque.TorquePermission |
Peer | org.apache.turbine.services.security.torque.om.TurbinePermissionPeer | |
Persistent object | org.apache.turbine.services.security.torque.om.TurbinePermission |
The Peers and objects supplied with the Torque Security Service were generated from a Torque Schema. Its definition is shown here.
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:
# 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
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.
If you omit the class definition of the object classes (torque.user.class, torque.group.class, torque.role.class, torque.permission.class), the bean property OMClass in the peer is consulted which should return the default class that this peer returns.
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".
At first we create a new torque schema:
<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>
Note a few things:
The Torque schema now gets translated into two java classes: CustomUserPeer for accessing the tables and CustomUser as objects returned by the Peer.
Now we configure the Torque Security Service to for using this peer as UserPeer:
# 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
Please note that we neither configure any column or property properties nor do we configure services.SecurityService.torque.user.class. So the Torque Security Service will query the CustomPeer 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)...
Accessing your custom columns can be done in two ways. A simple and a complex:
The simple way:
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();
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()).
The elegant way:
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();
Consider the following schema:
<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>
If you want to use this as the role peer, you can configure the Torque Security Service like this:
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
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.