Monday, November 30, 2015

A tutorial on how to use the Tapestry-Security module Part 1

It often bothered me how many times I've been answering questions from my students (and Stack) this question: "How do you use Tapestry-Security?"

Actually, Tynamo already wrote a guide but some are actually having a hard time figuring it out. They are confused by the database part and how it connects to the authentication and authorization parts. So this is where I come in and since this is should be pretty long post, I'm breaking it into two parts. Also, I'd be working on the assumption readers:
  • Have working knowledge of Tapestry5
  • Can get a Tapestry5 DAO service going
  • Basic understanding how Shiro works (or at least read the tutorial); YOU NEED TO UNDERSTAND SHIRO because Tapestry-Security is based on it.
  • Are OK with me using jasypt lib for encryption; I know it's not the best so chill your titties, we need to make work first THEN we'll deal with a much stronger encryption procedure.
To get started,

Open your POM.xml file and add the Tapestry-Security and Jasypt modules as a dependency.

<dependency>  
  <groupId>org.tynamo</groupId>  
  <artifactId>tapestry-security</artifactId>  
  <version>0.6.2</version>  
</dependency> 

<dependency>  
  <groupId>org.jasypt</groupId>  
  <artifactId>jasypt</artifactId>  
  <version>1.9.2</version>  
</dependency> 

Rebuild your project after to get the module.

Once that's out of the way, we should start creating a Realm. We are making an Authorizing Realm, which authenticates subjects (or users) AND authorizes them with either Roles or Permissions. Here's a sample:

public class MySecurityRealm extends AuthorizingRealm {

    @Inject
    private UserMembershipDAO umDAO;
    
    public MiscAppRealm() {
        super(new MemoryConstrainedCacheManager());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

You then need to configure your WebSecurityManager to use this realm. The WebSecurityManager service is something that Tapestry-Security module adds. Also, don't worry about the unimplemented methods in the realm. We're going to fix that on the next post.

Monday, October 12, 2015

Tapestry5, JPA 2 and Hibernate

The documentation for Integrating JPA found on the Tapestry5 website was lacking.
  1. It doesn't tell you that you have add the Tapestry-jpa dependency in you project POM
  2. It uses EclipseLink
  3. Explicitly tell you to use JPA 2.0 NOT JPA 2.1;
So, I had a few problems to fix after reading and following the docs. With much tinkering with my Tapestry5 (5.4-beta-35) project, I figured out:
  1. To add the Tapestry-jpa dependency
    <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-jpa</artifactId> <version>5.4-beta-35</version> </dependency>
        

  2. Hibernate 4.2 instead of EclipseLink
    <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.2.20.Final</version> </dependency>
  3. Edit the persistence.xml header so it reads version=2.0 instead of 2.1. This is because my Netbeans IDE can generate the persistence.xml file but defaults to 2.1 version instead of 2.0.
And if you get a javax.persistence.PersistenceExceptionUnable to build EntityManagerFactory error during the build, you probably didn't add a hibernate.dialect property in your persistence.xml configs.

Thursday, October 8, 2015

Tapestry5, JPA, Netbeans and a FilerException

Tapestry5.4 supports JPA out of the box which is nice. Also Netbeans supports JPA, doubly nice. Now if you're using 2 or more Persistence Units, you have probably encountered a FilerException when you try to compile or run your project. This shouldn't be a problem if you're using only single Persistence Unit. I suspect the fix would be the same if you encounter the same exception.

java.lang.RuntimeException: javax.annotation.processing.FilerException: Attempt to recreate a file for type {myclass}

The {myclass} here is always an entity class.

I think, a secondary symptom of this is if all your entity classes are all in a single package. This should be the case if you're doing a standard Tapestry5 web application.

The fix to this is to edit the Persistence Unit and add a  property and explicitly declare the entity classes on the Persistence Unit.

<persistence-unit name="PayrollPU" transaction-type="RESOURCE_LOCAL">  
   <provider>org.hibernate.ejb.HibernatePersistence</provider>  
   <class>cu.ictso.miscapps.entities.Departments</class>  
   <class>cu.ictso.miscapps.entities.Employee</class>  
   <class>cu.ictso.miscapps.entities.Groups</class>  
   <class>cu.ictso.miscapps.entities.ViewAttendance</class>  
   <exclude-unlisted-classes>true</exclude-unlisted-classes>  
   <properties>  
    <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost;databaseName=DTR-Payroll2;Integrated Security=false"/>  
    <property name="javax.persistence.jdbc.user" value="PayMaster"/>  
    <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>  
    <property name="javax.persistence.jdbc.password" value="123456"/>  
    <property name="javax.persistence.schema-generation.database.action" value="create"/>  
   </properties>  
 </persistence-unit>  

Here's an example Persistence Unit.