<?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>Security Howto</title>
 </properties>

<body>

<section name="Turbine Security">

<p>
The Turbine Security includes a <a href="../services/security-service.html">Security Service</a> 
as well as Actions and Screens that can be extended in the Templating Services.
</p>

</section>


<!-- Start -->


<section name="Users, Groups, Roles and Permissions">

<p>
The default Relational Database schema that Turbine uses for the database security 
service, and which the TDK is generated with upon initialisation, includes the 
data structure for the managing of permissions. 
The default or core schema can be viewed at;
</p>

<p>
<ul><a href="../turbine-schema.html">Turbine Core Schema</a></ul>
</p> 

<p>
The main tables are TURBINE_GROUP, TURBINE_USER, TURBINE_ROLE and TURBINE_PERMISSION. 
The Permissions are the individual actions a user is allowed to take in the system. 
The Role is a container for the Permissions, in other words a Role can be made of 
many Permissions. User is an account that is interaction with the System and the Group 
is a something that a User would want to do something in. In the Turbine mailing lists 
it has often been described in the same way as a project. In a project you have fulfill 
a role, however a User doesnt "belong" to a project they merely have a role in that 
project ( or group ). In this manner too a User can have many Roles within the one 
Group. For instance a User may have the Role Developer in the Group, but may also have 
the Role of Administrator as well. While initially confusing at first, as there 
are no group-user or role-user containers, it is a flexible system and strong system.
</p>

</section>


<section name="Access Control Lists">

<p>
A User's interaction through the system is controlled by the Permissions they are 
able to partake in. The AccessControlLists manage this information and present it via 
RunData and User Interfaces to the application. The RunData interface through the 
getACL() method presents the AccessControlList Object.
</p>

<source>
//get the AccessControlList Object 
//from RunData
AccessControlList acl = data.getACL();

//check if the User ( from the http request )
//has permission to view the invoices
if( acl.hasPermission("viewinvoice") )
{
    data.setMessage("You have permission to view the invoices.");
    setTemplate(data, "Invoice.vm");
}
else
{
    data.setMessage("You do not have Permission to view the Invoices");
    setTemplate(data, "UnauthorizedRequest.vm");
}
</source>

<p>
This will check if the User has permission to view this in the Global Group which 
is useful for managing Anonymous Users as well as logged in Users across your 
application. If however you need stronger security, such as only allowing users that 
have logged in, and have a Role in a specific Group, the Permission will need to be 
matched to the Group and User. As an example, assume one of your groups is "Accounting" 
and the Invoice information is only to be viewed by Usersthat have a Role in Accounting 
as well as the Permission "viewinvoice", the above method would be re-written; 
</p>

<source><![CDATA[
//get the User from RunData
User user = data.getUser();

//get the AccessControlList Object 
//from RunData
AccessControlList acl = data.getACL();

//check if the User has logged in,
//has a role in the group and
//has permission to view the invoices
if( user.hasLoggedIn() &&
    acl.hasPermission("viewinvoice", "Accounting") )
{
   data.setMessage("You have permission to view the invoices.");
   setTemplate(data, "Invoice.vm");
}
else
{
   data.setMessage("You do not have Permission to view the Invoices");
   setTemplate(data, "UnauthorizedRequest.vm");
}
]]></source>

<p>
If instead the Permission could be across any of the Roles the User has, the 
method acl.hasPermission(String permission, GroupSet groups), can be used. As 
always check the Javadocs for more detail.
</p>

</section>

<section name="Templates and Logging In">

<p>
Managing Anonymous Users and Logged In Users poses problems in applications for managing 
the Secure/Strong parts of the application and the Unsecure/Weak parts of the 
application. In Turbine, the Action and Screen components make managing this process 
quite simple. Assume the only Velocity Template allowed to be viewed without being 
logged in is the actual Login.vm template. As this is the only Screen that 
needs to be Unsecure/Weak we can manage this via the parent of Login Screen.
</p>


<source>
package com.mycompany.modules.screens;

//parent which allows Users to view the screen
public class WeakScreen extends VelocityScreen
{

    //nothing to check that the User 
    //can view this screen   
    protected void doBuildTemplate( RunData data, Context context ) 
        throws Exception
    {
        //call to Super
        super.doBuildTemplate(data, context);
    }
}

package com.mycompany.modules.screens;

//the java component of the Login Velocity Template
public class Login extends WeakScreen
{

    //nothing to check that the User 
    //can view this screen   
    protected void doBuildTemplate( RunData data, Context context ) 
        throws Exception
    {
        context.put("date",new Date());

        //call to Super
        super.doBuildTemplate(data, context);
    }
}
</source>

<p>
Note that there is nothing in that method which checks that the User has logged in. 
On the other hand, for the Secure or Strong Actions and Screens we would want a 
check to ensure that the User has logged in.
</p>

<source>
package com.mycompany.modules.screens;

//Strong screen which checks for login
public class StrongScreen extends VelocityScreen
{
    //check that User has Logged in before bothering
    //to add anything to the context.   
    protected void doBuildTemplate( RunData data ) 
        throws Exception
    {
        if (data.getUser().hasLoggedIn())   
        {   
            doBuildTemplate( data, TurbineVelocity.getContext( data ) );
        }
        else
        {
            //send the User to the Login Template
            data.setMessage("Please Login first!");
            setTemplate(data,"Login.vm");
        }
    }
}

package com.mycompany.modules.screens;

//as an example use the Invoices again
public class Invoice extends StrongScreen
{
    //can view this screen   
    protected void doBuildTemplate( RunData data, Context context ) 
        throws Exception
    {
        context.put("invoice",new Invoice());

        //call to Super
        super.doBuildTemplate(data, context);
    }
}
</source>

<p>
In the latter example, before the Screen populates the Context it will check for the 
User being logged in by the doBuildTemplate(data) method in the parent. If the test 
fails, the context isnt created for the Invoice screen. Another way to manage this 
is to seperate the screens into two packages, com.mycompany.modules.screens.unsecure 
and com.mycompany.modules.screens.secure and have a Default.java Screen in each 
of the packages mimicing the above approaches.
</p>

</section>

</body>
</document>
