/* ================================================================== * UserSecurityAspect.java - Oct 7, 2014 7:23:41 AM * * Copyright 2007-2014 SolarNetwork.net Dev Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * ================================================================== */ package net.solarnetwork.central.user.aop; import java.util.Set; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import net.solarnetwork.central.security.AuthorizationException; import net.solarnetwork.central.user.biz.UserBiz; import net.solarnetwork.central.user.dao.UserAuthTokenDao; import net.solarnetwork.central.user.dao.UserNodeDao; import net.solarnetwork.central.user.domain.UserAuthToken; import net.solarnetwork.central.user.domain.UserAuthTokenType; import net.solarnetwork.central.user.domain.UserNode; import net.solarnetwork.central.user.support.AuthorizationSupport; /** * Security enforcing AOP aspect for {@link UserBiz}. * * @author matt * @version 1.0 */ @Aspect public class UserSecurityAspect extends AuthorizationSupport { private final UserAuthTokenDao userAuthTokenDao; /** * Constructor. * * @param userNodeDao * the UserNodeDao * @param userAuthTokenDao * the UserAuthTokenDao */ public UserSecurityAspect(UserNodeDao userNodeDao, UserAuthTokenDao userAuthTokenDao) { super(userNodeDao); this.userAuthTokenDao = userAuthTokenDao; } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.getUser*(..)) && args(userId,..)") public void readUser(Long userId) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.getPendingUserNodeConfirmations(..)) && args(userId,..)") public void readUserNodeConfirmations(Long userId) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.getAllUserAuthTokens(..)) && args(userId,..)") public void readerUserAuthTokens(Long userId) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.getUserNode(..)) && args(userId,nodeId)") public void readUserNode(Long userId, Long nodeId) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.getArchivedUserNodes(..)) && args(userId)") public void readArchivedUserNodes(Long userId) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.updateUserNodeArchivedStatus(..)) && args(userId,nodeIds,..)") public void updateArchivedUserNodes(Long userId, Long[] nodeIds) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.generateUserAuthToken(..)) && args(userId,type,nodeIds)") public void generateAuthToken(Long userId, UserAuthTokenType type, Set<Long> nodeIds) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.deleteUserAuthToken(..)) && args(userId,token)") public void deleteAuthToken(Long userId, String token) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.updateUserAuthToken*(..)) && args(userId,token,..)") public void updateAuthToken(Long userId, String token) { } @Pointcut("bean(aop*) && execution(* net.solarnetwork.central.user.biz.*UserBiz.saveUserNode(..)) && args(entry)") public void updateUserNode(UserNode entry) { } @Before("readUser(userId) || readUserNodeConfirmations(userId) || readerUserAuthTokens(userId) || readArchivedUserNodes(userId)") public void userReadAccessCheck(Long userId) { requireUserReadAccess(userId); } @Before("readUserNode(userId, nodeId)") public void userNodeReadAccessCheck(Long userId, Long nodeId) { // the userReadAccessCheck method will also be called requireNodeWriteAccess(nodeId); } @Before("generateAuthToken(userId, type, nodeIds)") public void userReadAccessCheck(Long userId, UserAuthTokenType type, Set<Long> nodeIds) { requireUserWriteAccess(userId); if ( nodeIds != null ) { for ( Long nodeId : nodeIds ) { requireNodeWriteAccess(nodeId); } } } @Before("deleteAuthToken(userId, tokenId) || updateAuthToken(userId, tokenId)") public void updateAuthTokenAccessCheck(Long userId, String tokenId) { requireUserWriteAccess(userId); UserAuthToken token = userAuthTokenDao.get(tokenId); if ( token == null ) { throw new AuthorizationException(AuthorizationException.Reason.UNKNOWN_OBJECT, tokenId); } if ( userId.equals(token.getUserId()) == false ) { log.warn("Access DENIED to user {} for token {}; wrong user", userId, tokenId); throw new AuthorizationException(AuthorizationException.Reason.ACCESS_DENIED, tokenId); } } @Before("updateUserNode(entry)") public void updateUserNodeAccessCheck(UserNode entry) { if ( entry.getUser() == null ) { log.warn("Access DENIED to user node; no user ID"); throw new AuthorizationException(AuthorizationException.Reason.UNKNOWN_OBJECT, null); } requireUserWriteAccess(entry.getUser().getId()); if ( entry.getNode() == null ) { log.warn("Access DENIED to user node; no node ID"); throw new AuthorizationException(AuthorizationException.Reason.UNKNOWN_OBJECT, null); } requireNodeWriteAccess(entry.getNode().getId()); } @Before("updateArchivedUserNodes(userId, nodeIds)") public void updateArchivedUserNodesAccessCheck(Long userId, Long[] nodeIds) { if ( userId == null ) { log.warn("Access DENIED to user node; no user ID"); throw new AuthorizationException(AuthorizationException.Reason.UNKNOWN_OBJECT, null); } if ( nodeIds == null || nodeIds.length < 1 ) { log.warn("Access DENIED to user nodes; no node IDs"); throw new AuthorizationException(AuthorizationException.Reason.UNKNOWN_OBJECT, null); } requireUserWriteAccess(userId); for ( Long nodeId : nodeIds ) { requireNodeWriteAccess(nodeId); } } }