| <?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> |