/** * Copyright 2013 Sean Kavanagh - sean.p.kavanagh6@gmail.com * * 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 com.keybox.manage.action; import com.keybox.common.util.AppConfig; import com.keybox.common.util.AuthUtil; import com.keybox.manage.db.AuthDB; import com.keybox.manage.model.Auth; import com.keybox.manage.model.User; import com.keybox.manage.util.OTPUtil; import com.opensymphony.xwork2.ActionSupport; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.InterceptorRef; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.ServletResponseAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Action to auth to keybox */ @InterceptorRef("keyboxStack") public class LoginAction extends ActionSupport implements ServletRequestAware, ServletResponseAware { private static Logger loginAuditLogger = LoggerFactory.getLogger("com.keybox.manage.action.LoginAudit"); HttpServletResponse servletResponse; HttpServletRequest servletRequest; Auth auth; private final String AUTH_ERROR="Authentication Failed : Login credentials are invalid"; private final String AUTH_ERROR_NO_PROFILE="Authentication Failed : There are no profiles assigned to this account"; //check if otp is enabled boolean otpEnabled = ("required".equals(AppConfig.getProperty("oneTimePassword")) || "optional".equals(AppConfig.getProperty("oneTimePassword"))); String _csrf; @Action(value = "/login", results = { @Result(name = "success", location = "/login.jsp") } ) public String login() { _csrf = AuthUtil.generateCSRFToken(servletRequest.getSession()); return SUCCESS; } @Action(value = "/admin/menu", results = { @Result(name = "success", location = "/admin/menu.jsp") } ) public String menu() { return SUCCESS; } @Action(value = "/loginSubmit", results = { @Result(name = "input", location = "/login.jsp"), @Result(name = "change_password", location = "/admin/userSettings.action", type = "redirect"), @Result(name = "otp", location = "/admin/viewOTP.action", type = "redirect"), @Result(name = "success", location = "/admin/menu.action", type = "redirect") } ) public String loginSubmit() { String retVal = SUCCESS; String authToken = AuthDB.login(auth); //get client IP String clientIP = AuthUtil.getClientIPAddress(servletRequest); if (authToken != null) { User user = AuthDB.getUserByAuthToken(authToken); if(user!=null) { String sharedSecret = null; if (otpEnabled) { sharedSecret = AuthDB.getSharedSecret(user.getId()); if (StringUtils.isNotEmpty(sharedSecret) && (auth.getOtpToken() == null || !OTPUtil.verifyToken(sharedSecret, auth.getOtpToken()))) { loginAuditLogger.info(auth.getUsername() + " (" + clientIP + ") - " + AUTH_ERROR); addActionError(AUTH_ERROR); return INPUT; } } //check to see if admin has any assigned profiles if(!User.MANAGER.equals(user.getUserType()) && (user.getProfileList()==null || user.getProfileList().size()<=0)){ loginAuditLogger.info(auth.getUsername() + " (" + clientIP + ") - " + AUTH_ERROR_NO_PROFILE); addActionError(AUTH_ERROR_NO_PROFILE); return INPUT; } AuthUtil.setAuthToken(servletRequest.getSession(), authToken); AuthUtil.setUserId(servletRequest.getSession(), user.getId()); AuthUtil.setAuthType(servletRequest.getSession(), user.getAuthType()); AuthUtil.setTimeout(servletRequest.getSession()); //for first time login redirect to set OTP if (otpEnabled && StringUtils.isEmpty(sharedSecret)) { retVal = "otp"; } else if ("changeme".equals(auth.getPassword()) && Auth.AUTH_BASIC.equals(user.getAuthType())) { retVal = "change_password"; } loginAuditLogger.info(auth.getUsername() + " (" + clientIP + ") - Authentication Success"); } } else { loginAuditLogger.info(auth.getUsername() + " (" + clientIP + ") - " + AUTH_ERROR); addActionError(AUTH_ERROR); retVal = INPUT; } return retVal; } @Action(value = "/logout", results = { @Result(name = "success", location = "/login.action", type = "redirect") } ) public String logout() { AuthUtil.deleteAllSession(servletRequest.getSession()); return SUCCESS; } /** * Validates fields for auth submit */ public void validateLoginSubmit() { if (auth.getUsername() == null || auth.getUsername().trim().equals("")) { addFieldError("auth.username", "Required"); } if (auth.getPassword() == null || auth.getPassword().trim().equals("")) { addFieldError("auth.password", "Required"); } } public boolean isOtpEnabled() { return otpEnabled; } public void setOtpEnabled(boolean otpEnabled) { this.otpEnabled = otpEnabled; } public Auth getAuth() { return auth; } public void setAuth(Auth auth) { this.auth = auth; } public HttpServletResponse getServletResponse() { return servletResponse; } public void setServletResponse(HttpServletResponse servletResponse) { this.servletResponse = servletResponse; } public HttpServletRequest getServletRequest() { return servletRequest; } public void setServletRequest(HttpServletRequest servletRequest) { this.servletRequest = servletRequest; } public String get_csrf() { return _csrf; } public void set_csrf(String _csrf) { this._csrf = _csrf; } }