/* * 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.accessctl; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.services.resources.JetspeedResources; import org.apache.turbine.util.RunData; import org.apache.velocity.context.Context; import com.aimluck.commons.field.ALNumberField; import com.aimluck.commons.field.ALStringField; import com.aimluck.eip.accessctl.bean.AccessControlFeatureBean; import com.aimluck.eip.accessctl.util.AccessControlUtils; import com.aimluck.eip.cayenne.om.account.EipTAclPortletFeature; import com.aimluck.eip.cayenne.om.account.EipTAclRole; import com.aimluck.eip.cayenne.om.account.EipTAclUserRoleMap; import com.aimluck.eip.cayenne.om.security.TurbineUser; import com.aimluck.eip.common.ALAbstractFormData; import com.aimluck.eip.common.ALDBErrorException; import com.aimluck.eip.common.ALEipConstants; import com.aimluck.eip.common.ALEipUser; import com.aimluck.eip.common.ALPageNotFoundException; import com.aimluck.eip.modules.actions.common.ALAction; import com.aimluck.eip.orm.Database; import com.aimluck.eip.orm.query.SelectQuery; import com.aimluck.eip.services.accessctl.ALAccessControlConstants; import com.aimluck.eip.services.eventlog.ALEventlogConstants; import com.aimluck.eip.services.eventlog.ALEventlogFactoryService; import com.aimluck.eip.util.ALEipUtils; import com.aimluck.eip.util.ALLocalizationUtils; /** * アクセスコントロールのフォームデータを管理するクラスです。 <BR> * */ public class AccessControlFormData extends ALAbstractFormData { /** logger */ private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(AccessControlFormData.class.getName()); /** ロールID */ private String acl_role_id; /** ロール名 */ private ALStringField acl_role_name; /** 機能 */ private ALNumberField feature_id; /** メモ */ private ALStringField note; private ALNumberField acllist; private ALNumberField acldetail; private ALNumberField aclinsert; private ALNumberField aclupdate; private ALNumberField acldelete; private ALNumberField aclexport; /** <code>memberList</code> メンバーリスト */ private List<ALEipUser> memberList; private int defineAclType; /** 機能一覧 */ private List<AccessControlFeatureBean> portletFeatureList; /** * * @param rundata * @param context */ public void loadPortletFeatureList(RunData rundata, Context context) { portletFeatureList = AccessControlUtils.getPortletFeatureList(); } /** * * @param action * @param rundata * @param context * @throws ALPageNotFoundException * @throws ALDBErrorException */ @Override public void init(ALAction action, RunData rundata, Context context) throws ALPageNotFoundException, ALDBErrorException { super.init(action, rundata, context); } /** * 各フィールドを初期化します。 <BR> * * */ @Override public void initField() { // ロール名 acl_role_name = new ALStringField(); acl_role_name.setFieldName(ALLocalizationUtils .getl10n("ACCESSCTL_ROLE_NAME")); acl_role_name.setTrim(true); // 機能 feature_id = new ALNumberField(); feature_id.setFieldName(ALLocalizationUtils.getl10n("ACCESSCTL_ROLE_NAME")); // メモ note = new ALStringField(); note.setFieldName(ALLocalizationUtils.getl10n("ACCESSCTL_MEMO")); note.setTrim(false); acllist = new ALNumberField(); acldetail = new ALNumberField(); aclinsert = new ALNumberField(); aclupdate = new ALNumberField(); acldelete = new ALNumberField(); aclexport = new ALNumberField(); // メンバーリスト memberList = new ArrayList<ALEipUser>(); } /** * ロールの各フィールドに対する制約条件を設定します。 <BR> * * */ @Override protected void setValidator() { // ロール名必須項目 acl_role_name.setNotNull(true); // ロール名の文字数制限 acl_role_name.limitMaxLength(50); // 機能 feature_id.setNotNull(true); // メモの文字数制限 note.limitMaxLength(1000); acllist.limitValue(0, 1); acldetail.limitValue(0, 1); aclinsert.limitValue(0, 1); aclupdate.limitValue(0, 1); acldelete.limitValue(0, 1); aclexport.limitValue(0, 1); } /** * * @param rundata * @param context * @param msgList * @return * @throws ALPageNotFoundException * @throws ALDBErrorException */ @Override protected boolean setFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException { boolean res = super.setFormData(rundata, context, msgList); try { if (res) { if (ALEipConstants.MODE_UPDATE.equals(getMode())) { acl_role_id = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID); } String[] str = rundata.getParameters().getStrings("member_to"); if (str != null && str.length > 0) { SelectQuery<TurbineUser> query = Database.query(TurbineUser.class); Expression exp = ExpressionFactory.inExp(TurbineUser.LOGIN_NAME_PROPERTY, str); query.setQualifier(exp); memberList.addAll(ALEipUtils.getUsersFromSelectQuery(query)); } } } catch (Exception ex) { logger.error("AccessControlFormData.setFormData", ex); res = false; } return res; } /** * フォームに入力されたデータの妥当性検証を行います。 <BR> * * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean validate(List<String> msgList) { String tmp_acl_role_name = acl_role_name.getValue(); if (tmp_acl_role_name != null && !"".equals(tmp_acl_role_name)) { // ロール名の重複をチェックする try { SelectQuery<EipTAclRole> query = Database.query(EipTAclRole.class); if (ALEipConstants.MODE_INSERT.equals(getMode())) { Expression exp = ExpressionFactory.matchExp( EipTAclRole.ROLE_NAME_PROPERTY, tmp_acl_role_name); query.setQualifier(exp); } else if (ALEipConstants.MODE_UPDATE.equals(getMode())) { Expression exp1 = ExpressionFactory.matchExp( EipTAclRole.ROLE_NAME_PROPERTY, tmp_acl_role_name); query.setQualifier(exp1); Expression exp2 = ExpressionFactory.noMatchDbExp( EipTAclRole.ROLE_ID_PK_COLUMN, Integer.valueOf(acl_role_id)); query.andQualifier(exp2); } if (query.fetchList().size() != 0) { msgList.add(ALLocalizationUtils.getl10nFormat( "ACCESSCTL_ALERT_ALREADY_CREATED", acl_role_name.toString())); } } catch (Exception ex) { logger.error("AccessControlFormData.validate", ex); return false; } } // ロール名 acl_role_name.validate(msgList); // メモ note.validate(msgList); acllist.validate(msgList); acldetail.validate(msgList); aclinsert.validate(msgList); aclupdate.validate(msgList); acldelete.validate(msgList); aclexport.validate(msgList); // アクセス権限 if (acllist.getValue() == 0 && acldetail.getValue() == 0 && aclinsert.getValue() == 0 && aclupdate.getValue() == 0 && acldelete.getValue() == 0 && aclexport.getValue() == 0) { msgList.add(ALLocalizationUtils .getl10n("ACCESSCTL_ALERT_NO_FEATURE_SELECTED")); } // 所属メンバー if (memberList.size() == 0) { msgList.add(ALLocalizationUtils .getl10n("ACCESSCTL_ALERT_NO_MEMBER_SELECTED")); } else { try { // 同一機能の他ロールには所属できないようにする List<Integer> uids = new ArrayList<Integer>(); int msize = memberList.size(); for (int i = 0; i < msize; i++) { ALEipUser user = memberList.get(i); uids.add(Integer.valueOf((int) user.getUserId().getValue())); } SelectQuery<EipTAclRole> rolequery = Database.query(EipTAclRole.class); Expression exp11 = ExpressionFactory.matchDbExp( EipTAclRole.EIP_TACL_PORTLET_FEATURE_PROPERTY + "." + EipTAclPortletFeature.FEATURE_ID_PK_COLUMN, Integer.valueOf((int) feature_id.getValue())); Expression exp12 = ExpressionFactory.inDbExp( EipTAclRole.EIP_TACL_USER_ROLE_MAPS_PROPERTY + "." + EipTAclUserRoleMap.TURBINE_USER_PROPERTY + "." + TurbineUser.USER_ID_PK_COLUMN, uids); rolequery.setQualifier(exp11.andExp(exp12)); if (ALEipConstants.MODE_UPDATE.equals(getMode())) { Expression exp13 = ExpressionFactory.noMatchDbExp( EipTAclRole.ROLE_ID_PK_COLUMN, Integer.valueOf(acl_role_id)); rolequery.andQualifier(exp13); } List<EipTAclRole> roleList = rolequery.fetchList(); if (roleList != null && roleList.size() != 0) { msgList .add(ALLocalizationUtils.getl10n("ACCESSCTL_ALERT_OTHER_ROLE")); } } catch (Exception ex) { logger.error("AccessControlFormData.validate", ex); return false; } } return (msgList.size() == 0); } /** * ロールをデータベースから読み出します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean loadFormData(RunData rundata, Context context, List<String> msgList) { try { // オブジェクトモデルを取得 EipTAclRole aclrole = AccessControlUtils.getEipTAclRole(rundata, context); if (aclrole == null) { return false; } // ロール名 acl_role_name.setValue(aclrole.getRoleName()); List<EipTAclUserRoleMap> aclUserRoleMaps = AccessControlUtils.getEipTAclUserRoleMaps(aclrole .getRoleId() .intValue()); if (aclUserRoleMaps != null && aclUserRoleMaps.size() > 0) { EipTAclUserRoleMap rolemap = null; TurbineUser tuser = null; int size = aclUserRoleMaps.size(); for (int i = 0; i < size; i++) { rolemap = aclUserRoleMaps.get(i); tuser = rolemap.getTurbineUser(); ALEipUser user = new ALEipUser(); user.initField(); user.setUserId(tuser.getUserId().intValue()); user.setName(tuser.getLoginName()); user.setAliasName(tuser.getFirstName(), tuser.getLastName()); // 招待中ユーザでなければ追加 if (!JetspeedResources.CONFIRM_VALUE_PENDING.equals(tuser .getConfirmValue())) { memberList.add(user); } } } EipTAclPortletFeature feature = aclrole.getEipTAclPortletFeature(); feature_id.setValue(feature.getFeatureId().intValue()); defineAclType = feature.getAclType().intValue(); // メモ note.setValue(aclrole.getNote()); // アクセス権限 int tmpAclType = aclrole.getAclType(); AccessControlUtils.setupAcl( ALAccessControlConstants.VALUE_ACL_LIST, tmpAclType, acllist); AccessControlUtils.setupAcl( ALAccessControlConstants.VALUE_ACL_DETAIL, tmpAclType, acldetail); AccessControlUtils.setupAcl( ALAccessControlConstants.VALUE_ACL_INSERT, tmpAclType, aclinsert); AccessControlUtils.setupAcl( ALAccessControlConstants.VALUE_ACL_UPDATE, tmpAclType, aclupdate); AccessControlUtils.setupAcl( ALAccessControlConstants.VALUE_ACL_DELETE, tmpAclType, acldelete); AccessControlUtils.setupAcl( ALAccessControlConstants.VALUE_ACL_EXPORT, tmpAclType, aclexport); } catch (Exception ex) { logger.error("AccessControlFormData.loadFormData", ex); return false; } return true; } /** * ロールをデータベースから削除します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean deleteFormData(RunData rundata, Context context, List<String> msgList) { try { String aclroleid = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID); if (aclroleid == null || Integer.valueOf(aclroleid) == null) { // IDが空の場合 logger.debug("[AccessControlUtils] Empty ID..."); return false; } Expression exp = ExpressionFactory.matchDbExp(EipTAclRole.ROLE_ID_PK_COLUMN, aclroleid); SelectQuery<EipTAclRole> query = Database.query(EipTAclRole.class, exp); List<EipTAclRole> aclroles = query.fetchList(); if (aclroles == null || aclroles.size() == 0) { // 指定したIDのレコードが見つからない場合 logger.debug("[AccessControlUtils] Not found ID..."); return false; } SelectQuery<EipTAclUserRoleMap> EipTAclUserRoleMapSQL = Database.query(EipTAclUserRoleMap.class); EipTAclUserRoleMapSQL.andQualifier(ExpressionFactory.matchDbExp( EipTAclUserRoleMap.ROLE_ID_COLUMN, aclroleid)); List<EipTAclUserRoleMap> userRoleMaps = EipTAclUserRoleMapSQL.fetchList(); // オブジェクトを削除 Database.deleteAll(userRoleMaps); Database.delete(aclroles.get(0)); Database.commit(); // イベントログに保存 for (EipTAclRole role : aclroles) { ALEventlogFactoryService.getInstance().getEventlogHandler().log( role.getRoleId(), ALEventlogConstants.PORTLET_TYPE_ACCESSCTL, ALLocalizationUtils.getl10nFormat("ACCESSCTL_EVENTLOG_DELETE", role .getRoleName())); } } catch (Exception ex) { Database.rollback(); logger.error("AccessControlFormData.deleteFormData", ex); return false; } return true; } /** * ロールをデータベースに格納します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean insertFormData(RunData rundata, Context context, List<String> msgList) { try { Date now = Calendar.getInstance().getTime(); // 新規オブジェクトモデル EipTAclRole aclrole = Database.create(EipTAclRole.class); aclrole.setRoleName(acl_role_name.getValue()); aclrole.setNote(note.getValue()); long aclType = getAclTypeValue(); aclrole.setAclType(Integer.valueOf((int) aclType)); EipTAclPortletFeature feature = Database.get(EipTAclPortletFeature.class, Integer .valueOf((int) feature_id.getValue())); aclrole.setEipTAclPortletFeature(feature); // 作成日 aclrole.setCreateDate(now); // 更新日 aclrole.setUpdateDate(now); // userMapの登録 insertEipTAclUserRoleMap(aclrole, memberList.get(0)); // メンバー登録 int size = memberList.size(); for (int i = 1; i < size; i++) { insertEipTAclUserRoleMap(aclrole, memberList.get(i)); } // ロールを登録 Database.commit(); // イベントログに保存 ALEventlogFactoryService.getInstance().getEventlogHandler().log( aclrole.getRoleId(), ALEventlogConstants.PORTLET_TYPE_ACCESSCTL, ALLocalizationUtils.getl10nFormat("ACCESSCTL_EVENTLOG_ADD", aclrole .getRoleName())); } catch (Exception ex) { Database.rollback(); logger.error("AccessControlFormData.insertFormData", ex); return false; } return true; } /** * データベースに格納されているロールを更新します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean updateFormData(RunData rundata, Context context, List<String> msgList) { try { // オブジェクトモデルを取得 EipTAclRole aclrole = AccessControlUtils.getEipTAclRole(rundata, context); if (aclrole == null) { return false; } aclrole.setRoleName(acl_role_name.getValue()); aclrole.setNote(note.getValue()); // 更新日 aclrole.setUpdateDate(Calendar.getInstance().getTime()); long aclType = getAclTypeValue(); aclrole.setAclType(Integer.valueOf((int) aclType)); EipTAclPortletFeature feature = Database.get(EipTAclPortletFeature.class, Integer .valueOf((int) feature_id.getValue())); aclrole.setEipTAclPortletFeature(feature); // userMapの登録 int size = memberList.size(); for (int i = 0; i < size; i++) { insertEipTAclUserRoleMap(aclrole, memberList.get(i)); } // 古いEipTAclUserRoleMapの削除 deleteEipTAclUserRoleMap(rundata, context); // ロールを更新 Database.commit(); // イベントログに保存 ALEventlogFactoryService.getInstance().getEventlogHandler().log( aclrole.getRoleId(), ALEventlogConstants.PORTLET_TYPE_ACCESSCTL, ALLocalizationUtils.getl10nFormat("ACCESSCTL_EVENTLOG_UPDATE", aclrole .getRoleName())); } catch (Exception ex) { Database.rollback(); logger.error("AccessControlFormData.updateFormData", ex); return false; } return true; } private void insertEipTAclUserRoleMap(EipTAclRole aclrole, ALEipUser user) { EipTAclUserRoleMap map = Database.create(EipTAclUserRoleMap.class); int userid = (int) user.getUserId().getValue(); // ユーザーID TurbineUser tuser = Database.get(TurbineUser.class, Integer.valueOf(userid)); map.setEipTAclRole(aclrole); map.setTurbineUser(tuser); } private boolean deleteEipTAclUserRoleMap(RunData rundata, Context context) { String aclroleid = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID); if (aclroleid == null || Integer.valueOf(aclroleid) == null) { // IDが空の場合 logger.debug("[AccessControlFormData] Empty ID..."); return false; } SelectQuery<EipTAclUserRoleMap> query = Database.query(EipTAclUserRoleMap.class); Expression exp = ExpressionFactory.matchDbExp(EipTAclUserRoleMap.EIP_TACL_ROLE_PROPERTY + "." + EipTAclRole.ROLE_ID_PK_COLUMN, aclroleid); query.setQualifier(exp); List<EipTAclUserRoleMap> maps = query.fetchList(); if (maps == null || maps.size() == 0) { return true; } Database.deleteAll(maps); return true; } private long getAclTypeValue() { long aclType = acllist.getValue() * ALAccessControlConstants.VALUE_ACL_LIST + acldetail.getValue() * ALAccessControlConstants.VALUE_ACL_DETAIL + aclinsert.getValue() * ALAccessControlConstants.VALUE_ACL_INSERT + aclupdate.getValue() * ALAccessControlConstants.VALUE_ACL_UPDATE + acldelete.getValue() * ALAccessControlConstants.VALUE_ACL_DELETE + aclexport.getValue() * ALAccessControlConstants.VALUE_ACL_EXPORT; return aclType; } private boolean hasAcl(int defineAclType, int aclType) { return ((defineAclType & aclType) == aclType); } /** * ロール名を取得します。 <BR> * * @return */ public ALStringField getAclRoleName() { return acl_role_name; } public ALNumberField getFeatureId() { return feature_id; } /** * メモを取得します。 <BR> * * @return */ public ALStringField getNote() { return note; } public ALNumberField getAclList() { return acllist; } public ALNumberField getAclDetail() { return acldetail; } public ALNumberField getAclInsert() { return aclinsert; } public ALNumberField getAclUpdate() { return aclupdate; } public ALNumberField getAclDelete() { return acldelete; } public ALNumberField getAclExport() { return aclexport; } /** * グループメンバーを取得します。 * * @return */ public List<ALEipUser> getMemberList() { return memberList; } /** * * @return */ public List<AccessControlFeatureBean> getPortletFeatureList() { return portletFeatureList; } public int getDefineAclType() { return defineAclType; } public boolean hasAclList() { return hasAcl(defineAclType, ALAccessControlConstants.VALUE_ACL_LIST); } public boolean hasAclDetail() { return hasAcl(defineAclType, ALAccessControlConstants.VALUE_ACL_DETAIL); } public boolean hasAclInsert() { return hasAcl(defineAclType, ALAccessControlConstants.VALUE_ACL_INSERT); } public boolean hasAclUpdate() { return hasAcl(defineAclType, ALAccessControlConstants.VALUE_ACL_UPDATE); } public boolean hasAclDelete() { return hasAcl(defineAclType, ALAccessControlConstants.VALUE_ACL_DELETE); } public boolean hasAclExport() { return hasAcl(defineAclType, ALAccessControlConstants.VALUE_ACL_EXPORT); } }