001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.resource; 017 018import java.text.MessageFormat; 019import java.util.List; 020 021import org.opengion.hayabusa.common.HybsSystem; 022import org.opengion.hayabusa.common.HybsSystemException; 023import org.opengion.hayabusa.common.SystemManager; 024import org.opengion.fukurou.util.LogWriter; 025import org.opengion.fukurou.util.Cleanable; 026import org.opengion.fukurou.util.StringUtil; 027import org.opengion.fukurou.util.ApplicationInfo; 028import org.opengion.fukurou.db.DBUtil; 029 030/** 031 * systemId に対応したユーザー情報を作成するファクトリクラスです。 032 * 033 * UserInfoオブジェクトは,キャッシュせずに、要求都度、データベースを検索します。 034 * これは、ユーザー登録が、他システムより行われる可能性を考慮している為です。 035 * ユーザーオブジェクトの要求は、基本的にログイン時のみで、その後セッションに 036 * キープされます。 037 * 038 * 検索するカラムには、必ず、USERID,LANG,NAME,ROLES,DROLES がこの順番で含まれており、 039 * 絞込み条件(?パラメータ)として、SYSTEM_ID,USERID がこの順番で指定される必要があります。 040 * (カラム名は関係ありません。並び順と意味が重要です。) 041 * また、検索順(ORDER BY)は、優先順位の低い順に検索してください。使用するのは、一番最後に 042 * 検索された行を使用します。 043 * ユーザーリソースは、RESOURCE_USER_DBID で指定のデータベースから取得します。 044 * 未定義の場合は、RESOURCE_DBID から、それも未定義の場合は デフォルトの接続先を 045 * 使用します。 046 * 047 * SYSTEM_ID='**' は、共通リソースです(ROLESも共通に設定する必要があります。)。 048 * これは、システム間で共通に使用されるリソース情報を登録しておきます。 049 * SYSTEM_ID は、指定のシステムIDと**を検索対象にします。**は、全システム共通の 050 * 指定のシステムIDと**と両方存在する場合は、指定のシステムIDが優先されます。 051 * 052 * ver4 では、デフォルトロールという考え方がなくなりましたので、画面のロールに、 053 * (*)を明示的に追加し、RWMODE を指定する必要があります。 054 * 055 * @og.rev 4.0.0.0 (2004/12/31) 新規作成 056 * @og.group リソース管理 057 * 058 * @version 4.0 059 * @author Kazuhiko Hasegawa 060 * @since JDK5.0, 061 */ 062public final class UserInfoFactory { 063 064 private static final String SYSTEM_ID = HybsSystem.sys( "SYSTEM_ID" ); 065 066 // ユーザーリソースの接続先を、取得します。 067 private static String dbid = StringUtil.nval( 068 HybsSystem.sys( "RESOURCE_USER_DBID" ) , 069 HybsSystem.sys( "RESOURCE_DBID" ) 070 ) ; 071 072 // ユーザーリソースのキー指定読み込みのクエリー 073 private static String query = HybsSystem.sys( "RESOURCE_USER_SQL" ); 074 private static String queryRole = HybsSystem.sys( "RESOURCE_USER_ROLE_SQL" ); 075 076 // 5.2.0.0 (2010/09/01) LDAP対応 077 private static String srcType = HybsSystem.sys( "RESOURCE_USER_SRC_TYPE" ); 078 private static String[] ldapClm = StringUtil.csv2Array( HybsSystem.sys( "RESOURCE_USER_LDAP_CLM" ) ); 079 private static String ldapFilter = HybsSystem.sys( "RESOURCE_USER_LDAP_FILTER" ); 080 private static String ldapRoleFilter= HybsSystem.sys( "RESOURCE_USER_ROLE_LDAP_FILTER" ); 081 082 private static String searchScope = HybsSystem.sys( "LDAP_SEARCH_SCOPE" ); 083 private static String initctx = HybsSystem.sys( "LDAP_INITIAL_CONTEXT_FACTORY" ); 084 private static String providerURL = HybsSystem.sys( "LDAP_PROVIDER_URL" ); 085 private static String entrydn = HybsSystem.sys( "LDAP_ENTRYDN" ); 086 private static String password = HybsSystem.sys( "LDAP_PASSWORD" ); 087 private static String searchbase = HybsSystem.sys( "LDAP_SEARCH_BASE" ); 088 089 private static final Object lock = new Object(); 090 091 /** コネクションにアプリケーション情報を追記するかどうか指定 */ 092 public static final boolean USE_DB_APPLICATION_INFO = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ; 093 094 // 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理 095 static { 096 Cleanable clr = new Cleanable() { 097 public void clear() { 098 UserInfoFactory.clear(); 099 } 100 }; 101 102 SystemManager.addCleanable( clr ); 103 } 104 105 /** 106 * デフォルトコンストラクターをprivateにして、 107 * オブジェクトの生成をさせないようにする。 108 * 109 */ 110 private UserInfoFactory() { 111 } 112 113 /** 114 * UserInfo オブジェクトを取得します。 115 * 116 * UserInfoオブジェクトは,キャッシュせずに、要求都度、データベースを検索します。 117 * これは、ユーザー登録が、他システムより行われる可能性を考慮している為です。 118 * ユーザーオブジェクトの要求は、基本的にログイン時のみで、その後セッションに 119 * キープされます。 120 * 121 * @og.rev 3.7.0.4 (2005/03/18) ゲストログイン機能追加 122 * @og.rev 4.0.0.0 (2007/10/31) ロール指定でのログイン機能追加 123 * @og.rev 4.3.4.0 (2008/12/01) GE20(ユーザー定数)へ登録するかのフラグへの対応 124 * @og.rev 4.4.0.0 (2009/08/02) データロール対応 125 * @og.rev 5.2.0.0 (2010/09/01) LDAP対応 126 * @og.rev 5.3.6.0 (2011/06/01) GE20の読み込みをUserInfo内に移動 127 * 128 * @param userID ユーザーID 129 * @param ipAddress ログイン端末のIPアドレス 130 * @param roles データロール 131 * 132 * @return UserInfoオブジェクト 133 */ 134 public static UserInfo newInstance( final String userID,final String ipAddress,final String roles ) { 135 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 136 ApplicationInfo appInfo = null ; 137 if( USE_DB_APPLICATION_INFO ) { 138 appInfo = new ApplicationInfo(); 139 // ユーザーID,IPアドレス,ホスト名 140 appInfo.setClientInfo( userID,ipAddress,null ); 141 // 画面ID,操作,プログラムID 142 appInfo.setModuleInfo( "UserInfoFactory",null,"newInstance" ); 143 } 144 145 String[][] vals; 146 if( "LDAP".equalsIgnoreCase( srcType ) ) { 147 vals = getValsByLdap( userID, roles ); 148 } 149 else { 150 vals = getVals( userID, roles, appInfo ); 151 } 152 153 final UserInfo info ; 154 int len = vals.length ; // システムID ** を含む。 155 if( len >= 1 && vals[0].length >= 5 ) { 156 // システムIDでソートされる。SYSTEM_ID="**"は最初に現れるので、最後を取得 157 info = new UserInfo( 158 userID , // userID 159 vals[len-1][1] , // lang 160 vals[len-1][2] , // jname 161 vals[len-1][3] , // roles 162 vals[len-1][4] , // droles // 4.4.0.0 (2009/08/02) 163 SYSTEM_ID , // systemId 164 ipAddress , // ipAddress 165 appInfo ) ; // ApplicationInfo 166 } 167 else { 168 String errMsg = "UserInfo のデータ(USERID,LANG,NAME,ROLES,DROLES)が取得できません。" 169 + " Key [" + userID + "]" 170 + " SQL [" + query + "]" ; 171 LogWriter.log( errMsg ); 172 throw new HybsSystemException( errMsg ); 173 } 174 175 return info ; 176 } 177 178 /** 179 * UserInfoFactoryをクリアします。 180 * 181 * @og.rev 5.2.0.0 (2010/09/01) LDAP対応 182 * 183 */ 184 public static void clear() { 185 synchronized( lock ) { 186 dbid = StringUtil.nval( 187 HybsSystem.sys( "RESOURCE_USER_DBID" ) , 188 HybsSystem.sys( "RESOURCE_DBID" ) 189 ) ; 190 query = HybsSystem.sys( "RESOURCE_USER_SQL" ); 191 queryRole = HybsSystem.sys( "RESOURCE_USER_ROLE_SQL" ); 192 193 // 5.2.0.0 (2010/09/01) LDAP対応 194 srcType = HybsSystem.sys( "RESOURCE_USER_SRC_TYPE" ); 195 ldapClm = StringUtil.csv2Array( HybsSystem.sys( "RESOURCE_USER_LDAP_CLM" ) ); 196 ldapFilter = HybsSystem.sys( "RESOURCE_USER_LDAP_FILTER" ); 197 ldapRoleFilter = HybsSystem.sys( "RESOURCE_USER_ROLE_LDAP_FILTER" ); 198 199 searchScope = HybsSystem.sys( "LDAP_SEARCH_SCOPE" ); 200 initctx = HybsSystem.sys( "LDAP_INITIAL_CONTEXT_FACTORY" ); 201 providerURL = HybsSystem.sys( "LDAP_PROVIDER_URL" ); 202 entrydn = HybsSystem.sys( "LDAP_ENTRYDN" ); 203 password = HybsSystem.sys( "LDAP_PASSWORD" ); 204 searchbase = HybsSystem.sys( "LDAP_SEARCH_BASE" ); 205 } 206 } 207 208 /** 209 * DBからユーザーリソースの情報を取得します。 210 * 211 * @og.rev 5.2.0.0 (2010/09/01) 新規作成 212 * 213 * @param userId ユーザーID 214 * @param roles ロール 215 * @param appInfo DB接続情報 216 * 217 * @return ユーザーリソース情報 218 */ 219 private static String[][] getVals( final String userId, final String roles, final ApplicationInfo appInfo ) { 220 String[] args; 221 String[][] rtn = null; 222 223 if( roles == null || roles.length() == 0 ) { 224 args = new String[] { SYSTEM_ID,userId }; 225 synchronized( lock ) { 226 rtn = DBUtil.dbExecute( query,args,appInfo,dbid ); 227 } 228 } 229 // 4.0.0.0 (2007/10/31) 230 else { 231 args = new String[] { SYSTEM_ID,userId,roles }; 232 synchronized( lock ) { 233 rtn = DBUtil.dbExecute( queryRole,args,appInfo,dbid ); 234 } 235 } 236 237 return rtn; 238 } 239 240 /** 241 * LDAPからユーザーリソースの情報を取得します。 242 * 243 * @og.rev 5.2.0.0 (2010/09/01) 新規作成 244 * 245 * @param userId ユーザーID 246 * @param roles ロール 247 * 248 * @return ユーザーリソース情報 249 */ 250 private static String[][] getValsByLdap( final String userId, final String roles ) { 251 LDAPSearch serch = new LDAPSearch(); 252 serch.setSearchScope( searchScope ) ; 253 serch.setInitctx( initctx ) ; 254 serch.setProviderURL( providerURL ) ; 255 serch.setSearchbase( searchbase ) ; 256 if( entrydn != null ) { serch.setEntrydn( entrydn ) ; } 257 if( password != null ) { serch.setPassword( password ) ; } 258 serch.setAttributes( ldapClm ) ; 259 serch.init(); 260 261 String filter = ( roles == null || roles.length() == 0 ) ? ldapFilter : ldapRoleFilter; 262 String[] args = ( roles == null || roles.length() == 0 ) ? new String[] { SYSTEM_ID,userId } : new String[] { SYSTEM_ID,userId,roles }; 263 filter = MessageFormat.format( filter,(Object[])args ); 264 265 List<String[]> list = serch.search( filter ); 266 267 String[][] rtn = null; 268 if( list.size() > 0 ) { 269 rtn = new String[1][]; 270 rtn[0] = list.get( 0 ); 271 rtn[0][1] = StringUtil.nval( rtn[0][1], "ja" ); // 言語のデフォルト値は、'ja' 272 rtn[0][2] = StringUtil.nval( rtn[0][2], rtn[0][0] ); // 名称のデフォルト値は、ユーザーID 273 rtn[0][3] = StringUtil.nval( rtn[0][3], ldapClm[3] ); // ロールズの初期値は、ロールに設定された項目名 274 rtn[0][4] = StringUtil.nval( rtn[0][4], "" ); 275 } 276 277 return rtn; 278 } 279}