/* * * * Copyright (c) 2016. David Sowerby * * * * 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. * */ package uk.q3c.krail.core.navigate.sitemap; import com.google.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import uk.q3c.krail.core.guice.vsscope.VaadinSessionScoped; import uk.q3c.krail.core.i18n.CurrentLocale; import uk.q3c.krail.core.i18n.Translate; import uk.q3c.krail.core.shiro.PageAccessController; import uk.q3c.krail.core.shiro.SubjectProvider; import uk.q3c.util.NodeModifier; import javax.annotation.Nonnull; import java.text.Collator; import java.util.Comparator; import static com.google.common.base.Preconditions.checkNotNull; public class UserSitemapNodeModifier implements NodeModifier<MasterSitemapNode, UserSitemapNode> { private static Logger log = LoggerFactory.getLogger(UserSitemapNodeModifier.class); private final SubjectProvider subjectProvider; private final PageAccessController pageAccessController; private final Collator collator; private final Translate translate; private MasterSitemap masterSitemap; @Inject public UserSitemapNodeModifier(SubjectProvider subjectProvider, CurrentLocale currentLocale, PageAccessController pageAccessController, Translate translate) { super(); this.subjectProvider = subjectProvider; this.pageAccessController = pageAccessController; this.collator = Collator.getInstance(currentLocale.getLocale()); this.translate = translate; } /** * * Checks each node to ensure that the Subject has permission to view, and if so, adds it to this tree. Note that * if a node is redirected, its pageAccessControl attribute will have been modified to be the same as the redirect * target by the SitemapChecker. * <p/> * Nodes which have a null label key are ignored, as they cannot be displayed. The logout page is never loaded. The * login page is only shown if the user is not authenticated.<br> * <br> * The label and collation key for the node are created using {@link CurrentLocale}, which may be different for * different users; so both this class and CurrentLocale are {@link VaadinSessionScoped} * * {@link #setMasterSitemap} must be called first * * @param masterNode the MasterSitemapNode that the UserSitemapNode must reference * * @return created UserSitemapNode with reference to {@code masterNode} */ @Override public UserSitemapNode create(UserSitemapNode parentUserNode, @Nonnull MasterSitemapNode masterNode) { checkNotNull(masterNode); log.debug("creating a node for master node {}", masterNode); // if there is no labelKey (usually when page is redirected), cannot be shown if (masterNode.getLabelKey() == null) { return null; } // if the subject is already authenticated, don't show the login page if (subjectProvider.get() .isAuthenticated()) { if (masterNode.equals(masterSitemap.standardPageNode(StandardPageKey.Log_In))) { log.debug("User has already authenticated, do not show the login node"); return null; } } if (pageAccessController.isAuthorised(subjectProvider.get(), masterSitemap, masterNode)) { log.debug("User is authorised for page {}, creating a node for it", masterSitemap.uri(masterNode)); UserSitemapNode userNode = new UserSitemapNode(masterNode); userNode.setLabel(translate.from(masterNode.getLabelKey())); userNode.setCollationKey(collator.getCollationKey(userNode.getLabel())); return userNode; } else { log.debug("User is NOT authorised for page {}, returning null", masterSitemap.uri(masterNode)); return null; } } @Override public MasterSitemapNode sourceNodeFor(@Nonnull UserSitemapNode target) { return target.getMasterNode(); } /** * Not used in this implementation */ @Override public void setLeaf(@Nonnull UserSitemapNode targetNode) { } /** * Not used in this implementation */ @Override public void forceSetLeaf(@Nonnull UserSitemapNode targetNode) { } /** * Not used in this implementation */ @Override public void setCaption(@Nonnull UserSitemapNode targetNode, String caption) { } @Override public boolean attachOnCreate() { return false; } /** * Not used in this implementation */ @Override public void sortChildren(UserSitemapNode parentNode, @Nonnull Comparator<UserSitemapNode> comparator) { } public void setMasterSitemap(MasterSitemap masterSitemap) { this.masterSitemap = masterSitemap; } }