Permalink
Browse files

Created Freemarker tags for Apache Shiro, these mirror the JSP tags

provided by Shiro itself. See README.md for usage.
  • Loading branch information...
jagregory committed Jul 7, 2011
0 parents commit b876e1a2b72d9294a1cacedb5b22316eb0441881
@@ -0,0 +1,3 @@
+target
+.idea
+*.iml
@@ -0,0 +1,23 @@
+# Apache Shiro tags for Freemarker
+
+[Apache Shiro](http://shiro.apache.org/) comes with some [handy JSP tags](http://shiro.apache.org/jsp-tag-library.html) for doing things like only showing content for anonymous users, logged in users, etc... I'm using [Freemarker](http://freemarker.sourceforge.net/) and didn't want to take a dependency on JSP just for Shiro, so I rewrote the tags for Freemarker.
+
+## Install
+
+Either download the [dist/shiro-freemarker-tags-0.1-SNAPSHOT.jar](/jagregory/shiro-freemarker-tags/raw/master/dist/shiro-freemarker-tags-0.1-SNAPSHOT.jar) or take all the java files and stick them in your project. Simple.
+
+If there's enough demand, I could put this up on Maven.
+
+## Usage
+
+Declare a shared variable called "shiro", and assign it to an instance of the ShiroTags class.
+
+ cfg.setSharedVariable("shiro", new ShiroTags());
+
+You should then be able to use the tags in your Freemarker templates.
+
+ <@shiro.guest>Hello guest!</@shiro.guest>
+
+## License
+
+Do what you want with it, just don't blame me if it breaks anything.
Binary file not shown.
32 pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>shiro-freemarker-tags</artifactId>
+ <groupId>com.jagregory</groupId>
+ <version>0.1-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-all</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.freemarker</groupId>
+ <artifactId>freemarker</artifactId>
+ <version>2.3.18</version>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Maven2 Repository</name>
+ <url>http://repo1.maven.org/maven2/</url>
+ </repository>
+ </repositories>
+</project>
@@ -0,0 +1,44 @@
+package com.jagregory.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * JSP tag that renders the tag body only if the current user has executed a <b>successful</b> authentication attempt
+ * <em>during their current session</em>.
+ *
+ * <p>This is more restrictive than the {@link UserTag}, which only
+ * ensures the current user is known to the system, either via a current login or from Remember Me services,
+ * which only makes the assumption that the current user is who they say they are, and does not guarantee it like
+ * this tag does.
+ *
+ * <p>The logically opposite tag of this one is the {@link NotAuthenticatedTag}
+ *
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.AuthenticatedTag}</p>
+ *
+ * @since 0.2
+ */
+public class AuthenticatedTag extends SecureTag {
+ private static final Logger log = Logger.getLogger("AuthenticatedTag");
+
+ @Override
+ public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+ if (getSubject() != null && getSubject().isAuthenticated()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Subject exists and is authenticated. Tag body will be evaluated.");
+ }
+
+ renderBody(env, body);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Subject does not exist or is not authenticated. Tag body will not be evaluated.");
+ }
+ }
+ }
+}
@@ -0,0 +1,42 @@
+package com.jagregory.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * JSP tag that renders the tag body if the current user <em>is not</em> known to the system, either because they
+ * haven't logged in yet, or because they have no 'RememberMe' identity.
+ *
+ * <p>The logically opposite tag of this one is the {@link UserTag}. Please read that class's JavaDoc as it explains
+ * more about the differences between Authenticated/Unauthenticated and User/Guest semantic differences.
+ *
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.GuestTag}</p>
+ *
+ * @since 0.9
+ */
+public class GuestTag extends SecureTag {
+ private static final Logger log = Logger.getLogger("AuthenticatedTag");
+
+ @Override
+ public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+ if (getSubject() == null || getSubject().getPrincipal() == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Subject does not exist or does not have a known identity (aka 'principal'). " +
+ "Tag body will be evaluated.");
+ }
+
+ renderBody(env, body);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Subject exists or has a known identity (aka 'principal'). " +
+ "Tag body will not be evaluated.");
+ }
+ }
+ }
+}
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package com.jagregory.shiro.freemarker;
+
+import org.apache.shiro.subject.Subject;
+
+
+/**
+ * Displays body content if the current user has any of the roles specified.
+ *
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.HasAnyRolesTag}</p>
+ *
+ * @since 0.2
+ */
+public class HasAnyRolesTag extends RoleTag {
+ // Delimeter that separates role names in tag attribute
+ private static final String ROLE_NAMES_DELIMETER = ",";
+
+ protected boolean showTagBody(String roleNames) {
+ boolean hasAnyRole = false;
+ Subject subject = getSubject();
+
+ if (subject != null) {
+ // Iterate through roles and check to see if the user has one of the roles
+ for (String role : roleNames.split(ROLE_NAMES_DELIMETER)) {
+ if (subject.hasRole(role.trim())) {
+ hasAnyRole = true;
+ break;
+ }
+ }
+ }
+
+ return hasAnyRole;
+ }
+}
@@ -0,0 +1,12 @@
+package com.jagregory.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.HasPermissionTag}</p>
+ *
+ * @since 0.1
+ */
+public class HasPermissionTag extends PermissionTag {
+ protected boolean showTagBody(String p) {
+ return isPermitted(p);
+ }
+}
@@ -0,0 +1,10 @@
+package com.jagregory.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.HasRoleTag}</p>
+ */
+public class HasRoleTag extends RoleTag {
+ protected boolean showTagBody(String roleName) {
+ return getSubject() != null && getSubject().hasRole(roleName);
+ }
+}
@@ -0,0 +1,10 @@
+package com.jagregory.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.LacksPermissionTag}</p>
+ */
+public class LacksPermissionTag extends PermissionTag {
+ protected boolean showTagBody(String p) {
+ return !isPermitted(p);
+ }
+}
@@ -0,0 +1,11 @@
+package com.jagregory.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.LacksRoleTag}</p>
+ */
+public class LacksRoleTag extends RoleTag {
+ protected boolean showTagBody(String roleName) {
+ boolean hasRole = getSubject() != null && getSubject().hasRole(roleName);
+ return !hasRole;
+ }
+}
@@ -0,0 +1,32 @@
+package com.jagregory.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * Freemarker tag that renders the tag body only if the current user has <em>not</em> executed a successful authentication
+ * attempt <em>during their current session</em>.
+ *
+ * <p>The logically opposite tag of this one is the {@link org.apache.shiro.web.tags.AuthenticatedTag}.
+ *
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.NotAuthenticatedTag}</p>
+ */
+public class NotAuthenticatedTag extends SecureTag {
+ static final Logger log = Logger.getLogger("NotAuthenticatedTag");
+
+ @Override
+ public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+ if (getSubject() == null || !getSubject().isAuthenticated()) {
+ log.debug("Subject does not exist or is not authenticated. Tag body will be evaluated.");
+ renderBody(env, body);
+ } else {
+ log.debug("Subject exists and is authenticated. Tag body will not be evaluated.");
+ }
+ }
+}
@@ -0,0 +1,42 @@
+package com.jagregory.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModelException;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.PermissionTag}</p>
+ */
+public abstract class PermissionTag extends SecureTag {
+ String getName(Map params) {
+ return getParam(params, "name");
+ }
+
+ @Override
+ protected void verifyParameters(Map params) throws TemplateModelException {
+ String permission = getName(params);
+
+ if (permission == null || permission.length() == 0) {
+ throw new TemplateModelException("The 'name' tag attribute must be set.");
+ }
+ }
+
+ @Override
+ public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+ String p = getName(params);
+
+ boolean show = showTagBody(p);
+ if (show) {
+ renderBody(env, body);
+ }
+ }
+
+ protected boolean isPermitted(String p) {
+ return getSubject() != null && getSubject().isPermitted(p);
+ }
+
+ protected abstract boolean showTagBody(String p);
+}
Oops, something went wrong.

0 comments on commit b876e1a

Please sign in to comment.