Pages

Monday, May 4, 2009

seamy photo gallery, securing it (part 3)

Previous part was about setting up security so that we have a admin user that could approve photos and an ordinary one. We have done basic authentication on this part we will look at handling authorization exceptions, securing our view and code based on authority.
First thing I did was adding approve and disapprove (delete the photo) methods to my photoService and make them authorized :
@Restrict("#{s:hasRole('admin')}")
public void approvePhoto(Photo p) {
logger.info("approving :" + p.getName());
p.approve();
entityManager.merge(p);
}

@Restrict("#{s:hasRole('admin')}")
public void disapprovePhoto(Photo p) {
logger.info("disapprovePhoto :" + p.getName());
entityManager.remove(getPhoto(p.getName()));
}
@Restrict annotation with the specified EL makes sure that user invoking these methods have admin right. Upon unauthorized access an authorization exception thrown which I handled in the pages.xml :
<exception class="org.jboss.seam.security.AuthorizationException">
<redirect>
<message>You don't have permission to do this</message>
</redirect>
</exception>
By doing so we will have an authorization exception message on our message component. There is a small issue I encountered however ; http://www.seamframework.org/Community/ExceptionInRedirectHandler
Next I added links to pics in the gallery that will invoke these actions. Seam has annatotions just for doing this kind of stuff on datatables. This is what my datatable looked liked : 
<rich:dataGrid value="#{photoService.frontPagePhotos}" var="foto"
columns="3" elements="9">
<h:column>
<s:div>
<s:link id="lnk_foto" view="/photo/photo.xhtml" propagation="none">
<f:param name="fotoId" value="#{foto.name}" />
<s:graphicImage id="imaj" value="#{foto.data}"
style="border: 1px solid black;" lt="image could not be found">
<s:transformImageSize width="100" maintainRatio="true" />
</s:graphicImage>
</s:link>
</s:div>
<s:div>
<h:outputLabel value="#{foto.name}" for="imaj" />
</s:div>
<s:div>
<h:commandLink value="Approve"
action="#{photoService.approvePhoto(foto)}"
rendered="#{foto.approved eq null}" />
<h:outputText value="," rendered="#{foto.approved eq null}" />
<h:commandLink value="Delete"
action="#{photoService.disapprovePhoto(foto)}"
rendered="#{s:hasRole('admin')}" />
</s:div>
</h:column>
</rich:dataGrid>
Approve and delete buttons must be rendered only with the user with the role admin #{s:hasRole('admin')} EL does that. 
The last thing I did was adding a logout method which is just :
<h:commandButton action="#{identity.logout()}" value="Logout" />

Again I encountered a litte problem with this : http://www.seamframework.org/Community/RedirectingWhereLeftAfterLogout . Thats all for now. Keep coding...

No comments:

Post a Comment