/* * Aipo is a groupware program developed by TOWN, Inc. * Copyright (C) 2004-2015 TOWN, Inc. * http://www.aipo.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.aimluck.eip.modules.actions; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Date; import javax.servlet.http.Cookie; import org.apache.jetspeed.om.security.JetspeedUser; import org.apache.jetspeed.services.JetspeedSecurity; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.services.resources.JetspeedResources; import org.apache.jetspeed.services.rundata.JetspeedRunData; import org.apache.jetspeed.services.security.AccountExpiredException; import org.apache.jetspeed.services.security.CredentialExpiredException; import org.apache.jetspeed.services.security.FailedLoginException; import org.apache.jetspeed.services.security.LoginException; import org.apache.jetspeed.services.security.nosecurity.FakeJetspeedUser; import org.apache.jetspeed.util.template.JetspeedLink; import org.apache.jetspeed.util.template.JetspeedLinkFactory; import org.apache.turbine.modules.ActionEvent; import org.apache.turbine.services.localization.Localization; import org.apache.turbine.services.template.TurbineTemplate; import org.apache.turbine.util.RunData; import com.aimluck.commons.field.ALStringField; import com.aimluck.eip.common.ALEipConstants; import com.aimluck.eip.common.ALEipInformation; import com.aimluck.eip.common.ALEipUser; import com.aimluck.eip.services.config.ALConfigHandler.Property; import com.aimluck.eip.services.config.ALConfigService; import com.aimluck.eip.services.eventlog.ALEventlogFactoryService; import com.aimluck.eip.util.ALCellularUtils; import com.aimluck.eip.util.ALCommonUtils; import com.aimluck.eip.util.ALEipUtils; import com.aimluck.eip.util.ALLocalizationUtils; import com.aimluck.eip.util.ALTimelineUtils; /** * ログイン処理用のクラスです。 <br /> * */ public class ALJLoginUser extends ActionEvent { private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(ALJLoginUser.class.getName()); public static String KEY_MYGROUP = "mygroup"; @Override @SuppressWarnings("deprecation") public void doPerform(RunData rundata) throws Exception { JetspeedRunData data = (JetspeedRunData) rundata; String username = data.getParameters().getString("username", ""); String password = data.getParameters().getString("password", ""); // セッションハイジャック対策 // 携帯の場合、URLからのログインはログイン画面にリダイレクト if (ALCellularUtils.isCellularPhone(data) && (username != null) && (password != null) && (data.getRequest().getMethod() == "GET")) { String externalLoginUrl = ALConfigService.get(Property.EXTERNAL_LOGIN_URL); if (!"".equals(externalLoginUrl)) { // ログイン画面へリダイレクト data.setRedirectURI(externalLoginUrl); } data.getResponse().sendRedirect(data.getRedirectURI()); } // Cookieでセッションを管理していなければエラー画面を表示 else if (!data.getRequest().isRequestedSessionIdFromCookie()) { data.setScreenTemplate("CookieError"); return; } // 入力されたユーザ名を検証する. ALStringField tmpname = new ALStringField(); tmpname.setTrim(true); tmpname.setNotNull(true); tmpname.setCharacterType(ALStringField.TYPE_ASCII); tmpname.limitMaxLength(16); tmpname.setValue(username); boolean valid = tmpname.validate(new ArrayList<String>()); // 携帯の簡単ログインについては、後でusername, passwordを取得 if (ALCellularUtils.isCellularPhone(data) && (data.getParameters().getString("key", "").trim() != null)) { valid = true; } int length = username.length(); for (int i1 = 0; i1 < length; i1++) { if (isSymbol(username.charAt(i1))) { // 使用されているのが妥当な記号であるかの確認 if (!(username.charAt(i1) == "_".charAt(0) || username.charAt(i1) == "-".charAt(0) || username.charAt(i1) == "." .charAt(0))) { valid = false; break; } } } if (!valid) { // username = ""; data.setUser(JetspeedSecurity.getAnonymousUser()); data.setMessage(ALLocalizationUtils.getl10n("LOGINACTION_NO_USERID_PW")); // data.setScreenTemplate(JetspeedResources.getString("logon.disabled.form")); data.getUser().setHasLoggedIn(Boolean.FALSE); return; } // ここから if (ALCellularUtils.isSmartPhone(data) && "admin".equals(username)) { data.setUser(JetspeedSecurity.getAnonymousUser()); data.setMessage(ALLocalizationUtils.getl10n("LOGINACTION_LOGIN_ONLY_PC")); data.getUser().setHasLoggedIn(Boolean.FALSE); return; } if ("admin".equals(username) && "T".equals(ALConfigService.get(Property.FIRST_ADMIN_LOGIN))) { // アップデート時には自動投稿しない if (!ALTimelineUtils.hasTimelinePost()) { // ID=2 をガイドユーザーとする ALTimelineUtils.postTimeline(data, 2); } ALConfigService.put(Property.FIRST_ADMIN_LOGIN, "F"); } boolean newUserApproval = JetspeedResources.getBoolean("newuser.approval.enable", false); String secretkey = data.getParameters().getString("secretkey", null); if (secretkey != null) { // its the first logon - we are verifying the secretkey // handle the buttons on the ConfirmRegistration page String button1 = data.getParameters().getString("submit1", null); if (button1 != null && button1.equalsIgnoreCase("Cancel")) { data.setScreenTemplate(TurbineTemplate.getDefaultScreen()); return; } // check to make sure the user entered the right confirmation key // if not, then send them to the ConfirmRegistration screen JetspeedUser user = JetspeedSecurity.getUser(username); if (user == null) { logger.warn("JLogin User: Unexpected condition : user is NULL"); return; } String confirm_value = user.getConfirmed(); if (!secretkey.equals(confirm_value) && !confirm_value.equals(JetspeedResources.CONFIRM_VALUE)) { if (newUserApproval) { data.setMessage(Localization.getString( rundata, "JLOGINUSER_KEYNOTVALID")); // data.setScreenTemplate("NewUserAwaitingAcceptance"); return; } else { if (user.getConfirmed().equals( JetspeedResources.CONFIRM_VALUE_REJECTED)) { data.setMessage(Localization.getString( rundata, "JLOGINUSER_KEYNOTVALID")); // data.setScreenTemplate("NewUserRejected"); return; } else { data.setMessage(Localization.getString( rundata, "JLOGINUSER_KEYNOTVALID")); // data.setScreenTemplate("ConfirmRegistration"); return; } } } user.setConfirmed(JetspeedResources.CONFIRM_VALUE); data.setMessage(Localization.getString(rundata, "JLOGINUSER_WELCOME")); JetspeedSecurity.saveUser(user); } JetspeedUser user = null; try { if (ALCellularUtils.isCellularPhone(data)) { String key = data.getParameters().getString("key", "").trim(); if (key != null && key.length() > 0 && key.contains("_")) { username = key.substring(0, key.lastIndexOf("_")); String base64value = key.substring(key.lastIndexOf("_") + 1); ALEipUser eipuser = ALEipUtils.getALEipUser(username); if (eipuser != null) { if (!(ALCellularUtils.getCheckValueForCellLogin(username, eipuser .getUserId() .toString())).equals(base64value)) { username = ""; } } else { username = ""; } } String celluid = ALCellularUtils.getCellularUid(rundata); if (!"".equals(celluid)) { password = ALEipConstants.KEY_CELLULAR_UID + celluid; } } user = JetspeedSecurity.login(username, password); rundata.getSession().setAttribute( ALEipConstants.LAST_PASSWORD_LOGIN, new Date()); JetspeedSecurity.saveUser(user); // 運営からのお知らせ用のクッキ−削除 if (rundata.getRequest().getCookies() != null) { for (Cookie cookie : rundata.getRequest().getCookies()) { String cookieName = cookie.getName(); if (cookieName.startsWith(ALEipInformation.INFORMATION_COOKIE_PREFIX)) { cookie.setMaxAge(0); cookie.setPath("/"); cookie.setValue("true"); data.getResponse().addCookie(cookie); } } } int loginUserId = Integer.parseInt(user.getUserId()); ALEventlogFactoryService.getInstance().getEventlogHandler().logLogin( loginUserId); } catch (LoginException e) { /* * data.setScreenTemplate( * JetspeedResources.getString(TurbineConstants.TEMPLATE_LOGIN)); */ String message = e.getMessage() != null ? e.getMessage() : e.toString(); data.setMessage(message); data.setUser(JetspeedSecurity.getAnonymousUser()); data.getUser().setHasLoggedIn(Boolean.FALSE); if (e instanceof FailedLoginException) { if (ALEipConstants.USER_STAT_DISABLED.equals(message)) { data.setMessage(Localization.getString( rundata, "JLOGINUSER_ACCOUNT_DISABLED")); return; } else if (ALEipConstants.USER_STAT_NUTRAL.equals(message)) { data.setMessage(ALLocalizationUtils .getl10n("LOGINACTION_INVALIDATION_USER")); return; } if (!disableCheck(data)) { logger.info("JLoginUser: Credential Failure on login for user: " + username); data.setMessage(Localization.getString( rundata, "PASSWORDFORM_FAILED_MSG")); } } else if (e instanceof AccountExpiredException) { logger.info("JLoginUser: Account Expired for user " + username); } else if (e instanceof CredentialExpiredException) { logger.info("JLoginUser: Credentials expired for user: " + username); /* * data.setScreenTemplate( JetspeedResources.getString( * JetspeedResources.CHANGE_PASSWORD_TEMPLATE, "ChangePassword")); */ data.setMessage(Localization.getString( rundata, "PASSWORDFORM_EXPIRED_MSG")); data.getParameters().setString("username", username); } return; } catch (Throwable other) { // data.setScreenTemplate( // JetspeedResources.getString(TurbineConstants.TEMPLATE_ERROR)); String message = other.getMessage() != null ? other.getMessage() : other.toString(); data.setMessage(message); data.setStackTrace( org.apache.turbine.util.StringUtils.stackTrace(other), other); JetspeedUser juser = new FakeJetspeedUser(JetspeedSecurity.getAnonymousUserName(), false); data.setUser(juser); return; } // check for being confirmed before allowing someone to finish logging in if (data.getUser().hasLoggedIn()) { if (JetspeedSecurity.isDisableAccountCheckEnabled()) { // dst: this needs some refactoring. I don't believe this api is // necessary JetspeedSecurity.resetDisableAccountCheck(data .getParameters() .getString("username", "")); } String confirmed = data.getUser().getConfirmed(); if (confirmed == null || !confirmed.equals(JetspeedResources.CONFIRM_VALUE)) { if (confirmed != null && confirmed.equals(JetspeedResources.CONFIRM_VALUE_REJECTED)) { data.setMessage(Localization.getString( rundata, "JLOGINUSER_KEYNOTVALID")); // data.setScreenTemplate("NewUserRejected"); data.getUser().setHasLoggedIn(Boolean.FALSE); return; } else { data.setMessage(Localization.getString( rundata, "JLOGINUSER_CONFIRMFIRST")); // data.setScreenTemplate("ConfirmRegistration"); data.getUser().setHasLoggedIn(Boolean.FALSE); return; } } // user has logged in successfully at this point boolean automaticLogonEnabled = JetspeedResources.getBoolean("automatic.logon.enable", false); if (automaticLogonEnabled) { // Does the user want to use this facility? boolean userRequestsRememberMe = data.getParameters().getBoolean("rememberme", false); if (userRequestsRememberMe) { // save cookies on the users machine. int maxage = JetspeedResources.getInt("automatic.logon.cookie.maxage", -1); String comment = JetspeedResources.getString("automatic.logon.cookie.comment", ""); String domain = JetspeedResources.getString("automatic.logon.cookie.domain"); String path = JetspeedResources.getString("automatic.logon.cookie.path", "/"); if (domain == null || "".equals(domain)) { String server = data.getServerName(); domain = "." + server; } String loginCookieValue = null; if (JetspeedResources.getString( "automatic.logon.cookie.generation", "everylogon").equals("everylogon")) { loginCookieValue = "" + Math.random(); data.getUser().setPerm("logincookie", loginCookieValue); JetspeedSecurity.saveUser(data.getJetspeedUser()); } else { loginCookieValue = (String) data.getUser().getPerm("logincookie"); if (loginCookieValue == null || loginCookieValue.length() == 0) { loginCookieValue = "" + Math.random(); data.getUser().setPerm("logincookie", loginCookieValue); JetspeedSecurity.saveUser(data.getJetspeedUser()); } } Cookie userName = new Cookie("username", data.getUser().getUserName()); Cookie loginCookie = new Cookie("logincookie", loginCookieValue); userName.setMaxAge(maxage); userName.setComment(comment); // userName.setDomain(domain); userName.setPath(path); loginCookie.setMaxAge(maxage); loginCookie.setComment(comment); // loginCookie.setDomain(domain); loginCookie.setPath(path); data.getResponse().addCookie(userName); data.getResponse().addCookie(loginCookie); String lastloginValue = ALCommonUtils.encodeBase64(ALCommonUtils.encrypt(JetspeedResources .getString("aipo.cookie.encryptKey", "secureKey"), new Date() .getTime() + "")); if (lastloginValue != null) { Cookie lastlogin = new Cookie("lastlogin", lastloginValue); lastlogin.setMaxAge(maxage); lastlogin.setComment(comment); // lastlogin.setDomain(domain); lastlogin.setPath(path); data.getResponse().addCookie(lastlogin); } } } JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata); String redirectUrl = data.getParameters().getString("redirect", ""); if (redirectUrl != null && !"".equals(redirectUrl)) { data.setRedirectURI(redirectUrl); data.getResponse().sendRedirect(redirectUrl); JetspeedLinkFactory.putInstance(jsLink); jsLink = null; return; } if (ALCellularUtils.isCellularPhone(data)) { rundata.setRedirectURI(jsLink.getPortletById("").addQueryData( JetspeedResources.PATH_ACTION_KEY, "controls.Restore").toString()); rundata.getResponse().sendRedirect(rundata.getRedirectURI()); JetspeedLinkFactory.putInstance(jsLink); jsLink = null; return; } String client = ALEipUtils.getClient(rundata); String peid = data.getParameters().getString("js_peid"); if (peid == null) { peid = (String) data.getUser().getTemp("js_peid"); } if (peid == null && "IPHONE".equals(client)) { String firstPortletId = ALEipUtils.getFirstPortletId(data.getUser().getUserName()); String url = jsLink.getPortletById(firstPortletId).addQueryData( "action", "controls.Maximize").toString(); data.setRedirectURI(url); data.getResponse().sendRedirect(url); JetspeedLinkFactory.putInstance(jsLink); jsLink = null; return; } } else { disableCheck(data); } } /** * * 指定したchar型文字が記号であるかを判断します。 * * @param ch * @return */ protected boolean isSymbol(char ch) { byte[] chars; try { chars = (Character.valueOf(ch).toString()).getBytes("shift_jis"); } catch (UnsupportedEncodingException ex) { return false; } if (chars == null || chars.length == 2 || Character.isDigit(ch) || Character.isLetter(ch)) { return false; } else { return true; } } @SuppressWarnings("deprecation") private boolean disableCheck(JetspeedRunData data) { boolean disabled = false; // disable user after a configurable number of strikes if (JetspeedSecurity.isDisableAccountCheckEnabled()) { disabled = JetspeedSecurity.checkDisableAccount(data.getParameters().getString( "username", "")); if (disabled) { data.setMessage(Localization.getString( data, "JLOGINUSER_ACCOUNT_DISABLED")); data.setScreenTemplate(JetspeedResources .getString("logon.disabled.form")); data.getUser().setHasLoggedIn(Boolean.FALSE); } } return disabled; } }