Java tutorial
package com.fbr.services; /* * *********************************************************** * Copyright (c) 2013 VMware, Inc. All rights reserved. * *********************************************************** */ import com.fbr.Constants.ResourceType; import com.fbr.Dao.SQL.Authorization.AuthorizationMappingDao; import com.fbr.Dao.SQL.Authorization.Entities.AuthorizationMappingDbType; import com.fbr.Dao.SQL.License.Entities.RoleType; import com.fbr.Dao.SQL.License.Entities.UserDbType; import com.fbr.Dao.SQL.License.UserDao; import com.fbr.Dao.SQL.Security.Entities.SessionDbType; import com.fbr.Dao.SQL.Security.SessionDao; import com.fbr.RestException.CustomExceptions.AuthorizationException; import com.fbr.RestException.CustomExceptions.BadRequestException; import com.fbr.RestException.CustomExceptions.RestException; import com.fbr.RestException.ErrorCode; import com.fbr.RestException.ErrorType; import com.fbr.Utilities.LoggerUtil; import com.fbr.domain.Security.LoginResponse; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.MultiValueMap; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.*; import java.util.Map.Entry; @Service public class SecurityService { @Autowired UserService userService; @Autowired SessionDao sessionDao; @Autowired UserDao userDao; @Autowired LicenseService licenseService; @Autowired AuthorizationMappingDao authorizationMappingDao; @Value("${session.idle_timeout:30}") private int idle_session_timeout; private static final Logger logger = Logger.getLogger(SecurityService.class); private static final String[] LOGIN_EXCEPTION_VALUES = new String[] { "/feedback-review/login", "/feedback-review/license/register", "/feedback-review/contactUs" }; private static final Set<String> LOGIN_EXCEPTION_URIS = new HashSet<String>( Arrays.asList(LOGIN_EXCEPTION_VALUES)); @Transactional public HttpStatus checkAuthenticationAndAuthorization(HttpServletRequest httpRequest) { logger.debug("Request uri is {}" + httpRequest.getRequestURI()); if (!LOGIN_EXCEPTION_URIS.contains(httpRequest.getRequestURI())) { String sessionId = httpRequest.getHeader("sessionId"); Enumeration<String> headers = httpRequest.getHeaderNames(); if (headers != null) { logger.debug("Headers are"); while (headers.hasMoreElements()) { logger.debug(headers.nextElement()); } } if (sessionId != null) { Date idleExpirationDate = DateUtils.addMinutes(new Date(), -idle_session_timeout); SessionDbType sessionDbType = sessionDao.validateSessionId(sessionId, idleExpirationDate); if (sessionDbType == null) { logger.debug("Session " + sessionId + " was not found in the database"); return HttpStatus.UNAUTHORIZED; } logger.debug("Session " + sessionId + " is validated"); sessionDbType.setLastAccessTime(new Date()); sessionDao.update(sessionDbType); if (!isAuthorizedForApi(httpRequest.getMethod(), httpRequest.getRequestURI(), httpRequest.getQueryString(), sessionDbType)) { logger.debug(httpRequest.getMethod() + " on " + httpRequest.getRequestURI() + " for this user is not authorized"); return HttpStatus.FORBIDDEN; } logger.debug("Session " + sessionId + "is Authorized"); } else { logger.debug("sessionId was not found in the header"); return HttpStatus.UNAUTHORIZED; } } return HttpStatus.OK; } public UserDbType getUserDbType(String sessionId) { try { if (!StringUtils.isBlank(sessionId)) { return sessionDao.getUserDbType(sessionId); } throw new AuthorizationException("session id is empty or not given"); } catch (Exception e) { logger.debug(LoggerUtil.getStackTrace(e)); throw new AuthorizationException("session id is wrong"); } } @Transactional public String createLogin(final MultiValueMap<String, String> credentials, LoginResponse loginResponse) { UserDbType userDbType = null; String password = ""; UUID uuid = null; boolean isAppUser = false; final Map<String, String> credentialsMap = credentials.toSingleValueMap(); for (Entry<String, String> nameValuePair : credentialsMap.entrySet()) { if (nameValuePair.getKey().equals("username")) { logger.debug("Username given is {0}" + nameValuePair.getValue()); userDbType = userService.findUserName(nameValuePair.getValue()); } else if (nameValuePair.getKey().equals("password")) { logger.debug("password given is {0}" + nameValuePair.getValue()); password = nameValuePair.getValue(); } else if (nameValuePair.getKey().equals("uuid")) { logger.debug("uuid given is {0}" + nameValuePair.getValue()); uuid = UUID.fromString(nameValuePair.getValue()); isAppUser = true; } } if (isAppUser) { userDbType = licenseService.validateUUID(uuid); logger.debug("uuid " + uuid + " validated"); } else { userService.validatePassword(userDbType, password); logger.debug("password is validated"); } int companyId = userDbType.getCompanyDbType().getCompanyId(); loginResponse.setCompanyId(companyId); loginResponse.setRole(userDbType.getRole()); SessionDbType sessionDbType = new SessionDbType(); Date now = new Date(); sessionDbType.setCreationTime(now); sessionDbType.setLastAccessTime(now); sessionDbType.setUserDbType(userDbType); sessionDao.add(sessionDbType); return sessionDbType.getId(); } @Transactional public void deleteLogin(String sessionId) { if (StringUtils.isEmpty(sessionId)) { throw new AuthorizationException("sessionId could not be found"); } logger.debug("session id given is {0}" + sessionId); if (sessionDao.delete(sessionId) == 1) { logger.debug("Session id " + sessionId + " is successfully deleted"); } } private boolean isUriTokenMatch(UserDbType userDbType, String uriToken, String givenUriToken, String beforeToken) { if (StringUtils.equalsIgnoreCase(uriToken, givenUriToken)) { return true; } if (uriToken.startsWith("{") && uriToken.endsWith("}")) { if (beforeToken != null && beforeToken.equalsIgnoreCase("company")) { return userService.validateCompanyId(userDbType, Integer.parseInt(givenUriToken)); } else if (beforeToken != null && beforeToken.equalsIgnoreCase("branch")) { return userService.validateBranchId(userDbType, Integer.parseInt(givenUriToken)); } logger.debug("Escaping the placeholder"); return true; } return false; } private String findPath(String uri) { String uris[] = uri.split("\\?"); uri = uris[0]; uri = uri.concat("/"); uri = "/".concat(uri); uri = uri.replaceAll("/+", "/"); return uri; } private void printStrings(String[] strings) { logger.debug("Tokens ====="); for (String str : strings) { logger.debug("Token - " + str); } } private boolean isPathMatch(UserDbType userDbType, String uri, String givenUri) { logger.debug("stored uri path is " + uri); logger.debug("given uri path is " + givenUri); String[] uriTokens = uri.split("/"); String[] givenUriTokens = givenUri.split("/"); String beforeToken = null; if ((uriTokens.length + 1) != givenUriTokens.length) { logger.debug("Tokens lengths did not match"); return false; } if (givenUriTokens.length == 0) { return false; } int i = 1, j = 2; // uri in the database does not consist of 'feedback-review' for (; i < uriTokens.length; i++, j++) { if (!isUriTokenMatch(userDbType, uriTokens[i], givenUriTokens[j], beforeToken)) { logger.debug("Tokens -" + uriTokens[i] + "," + givenUriTokens[j] + "- did not match"); return false; } else { beforeToken = uriTokens[i]; } } if (i == uriTokens.length && j == givenUriTokens.length) { return true; } return false; } public Map<String, String> splitQuery(String queryString) throws UnsupportedEncodingException { final Map<String, String> query_pairs = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); final String[] pairs = queryString.split("&"); for (String pair : pairs) { final int idx = pair.indexOf("="); final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair; final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; query_pairs.put(key, value); } return query_pairs; } private boolean isQueryStringMatch(UserDbType userDbType, int roleType, String queryString, String givenQueryString) { Map<String, String> queryStringMap = null; Map<String, String> givenQueryStringMap = null; logger.debug("query string - " + queryString); logger.debug("given query string - " + givenQueryString); try { queryStringMap = splitQuery(queryString); givenQueryStringMap = splitQuery(givenQueryString); } catch (Exception e) { throw new BadRequestException(e.getMessage()); } if (queryStringMap.get("branch") != null) { String branchId = givenQueryStringMap.get("branch"); logger.debug("branchId is - " + branchId); if (branchId == null && !userService.validateRole(roleType, RoleType.CompanyOwner)) { throw new RestException(new ErrorType(ResourceType.USER, ErrorCode.INVALID_ROLE, "This user " + " Can not perform this action")); } int branchIdInt = Integer.parseInt(branchId); return userService.validateBranchId(userDbType, branchIdInt); } return false; } private boolean isUriMatch(UserDbType userDbType, int roleType, String uri, String givenUri, String givenQueryString) { String uriPath = findPath(uri); String givenUriPath = findPath(givenUri); if (!isPathMatch(userDbType, uriPath, givenUriPath)) { logger.debug("Path authorization failed"); return false; } String[] queryStrings = uri.split("\\?"); if (queryStrings.length == 2 && roleType == RoleType.BranchManager.getRoleValue()) { if (!isQueryStringMatch(userDbType, roleType, queryStrings[1], givenQueryString)) { logger.debug("Query string authorization failed"); return false; } } return true; } public boolean isAuthorizedForApi(String method, String uri, String queryString, SessionDbType sessionDbType) { UserDbType userDbType = sessionDbType.getUserDbType(); int roleType = userDbType.getRole(); logger.debug("User name for the session id given is " + userDbType.getUsername()); logger.debug("Password for the session id given is " + userDbType.getPassword()); List<AuthorizationMappingDbType> authorizationMappingDbTypeList = authorizationMappingDao.findAll(); String userName = userDbType.getUsername(); logger.debug("Role of the user - " + userName + " is - " + roleType); for (AuthorizationMappingDbType authorizationMappingDbType : authorizationMappingDbTypeList) { if (method.equalsIgnoreCase(authorizationMappingDbType.getMethod()) && isUriMatch(userDbType, roleType, authorizationMappingDbType.getUri(), uri, queryString)) { if (userService.validateRole(roleType, authorizationMappingDbType.getRoleType())) { return true; } } } return false; } }