    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        /** コネクションにアプリケーション情報を追記するかどうか指定 */
    090        public static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
    091
    092        // 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
    093        static {
    094                Cleanable clr = new Cleanable() {
    095                        public void clear() {
    096                                UserInfoFactory.clear();
    097                        }
    098                };
    099
    100                SystemManager.addCleanable( clr );
    101        }
    102
    103        private static final Object lock = new Object();
    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[] args;
    146//              String[][] vals;
    147
    148//              if( roles == null || roles.length() == 0 ) {
    149//                      args = new String[] { SYSTEM_ID,userID };
    150//                      synchronized( lock ) {
    151//                              vals = DBUtil.dbExecute( query,args,appInfo,dbid );
    152//                      }
    153//              }
    154//              // 4.0.0.0 (2007/10/31)
    155//              else {
    156//                      args = new String[] { SYSTEM_ID,userID,roles };
    157//                      synchronized( lock ) {
    158//                              vals = DBUtil.dbExecute( queryRole,args,appInfo,dbid );
    159//                      }
    160//              }
    161
    162                String[][] vals;
    163                if( "LDAP".equalsIgnoreCase( srcType ) ) {
    164                        vals = getValsByLdap( userID, roles );
    165                }
    166                else {
    167                        vals = getVals( userID, roles, appInfo );
    168                }
    169
    170                final UserInfo info ;
    171                int len = vals.length ; // システムID ** を含む。
    172                if( len >= 1 && vals[0].length >= 5 ) {
    173                        // システムIDでソートされる。SYSTEM_ID="**"は最初に現れるので、最後を取得
    174                        info = new UserInfo(
    175                                                                userID          ,                       // userID
    176                                                                vals[len-1][1]  ,               // lang
    177                                                                vals[len-1][2]  ,               // jname
    178                                                                vals[len-1][3]  ,               // roles
    179                                                                vals[len-1][4]  ,               // droles // 4.4.0.0 (2009/08/02)
    180                                                                SYSTEM_ID               ,               // systemId
    181                                                                ipAddress               ,               // ipAddress
    182                                                                appInfo                 ) ;             // ApplicationInfo
    183                }
    184                else {
    185                        String errMsg = "UserInfo のデータ(USERID,LANG,NAME,ROLES,DROLES)が取得できません。"
    186                                                + " Key [" + userID + "]"
    187                                                + " SQL [" + query + "]" ;
    188                        LogWriter.log( errMsg );
    189                        throw new HybsSystemException( errMsg );
    190                }
    191
    192                return info ;
    193        }
    194
    195        /**
    196         * UserInfoFactoryをクリアします。
    197         *
    198         * @og.rev 5.2.0.0 (2010/09/01) LDAP対応
    199         *
    200         */
    201        public static void clear() {
    202                synchronized( lock ) {
    203                        dbid = StringUtil.nval(
    204                                                                        HybsSystem.sys( "RESOURCE_USER_DBID" ) ,
    205                                                                        HybsSystem.sys( "RESOURCE_DBID" )
    206                                                                ) ;
    207                        query = HybsSystem.sys( "RESOURCE_USER_SQL" );
    208                        queryRole = HybsSystem.sys( "RESOURCE_USER_ROLE_SQL" );
    209
    210                        // 5.2.0.0 (2010/09/01) LDAP対応
    211                        srcType                 = HybsSystem.sys( "RESOURCE_USER_SRC_TYPE" );
    212                        ldapClm                 = StringUtil.csv2Array( HybsSystem.sys( "RESOURCE_USER_LDAP_CLM" ) );
    213                        ldapFilter              = HybsSystem.sys( "RESOURCE_USER_LDAP_FILTER" );
    214                        ldapRoleFilter  = HybsSystem.sys( "RESOURCE_USER_ROLE_LDAP_FILTER" );
    215
    216                        searchScope             = HybsSystem.sys( "LDAP_SEARCH_SCOPE" );
    217                        initctx                 = HybsSystem.sys( "LDAP_INITIAL_CONTEXT_FACTORY" );
    218                        providerURL     = HybsSystem.sys( "LDAP_PROVIDER_URL" );
    219                        entrydn                 = HybsSystem.sys( "LDAP_ENTRYDN" );
    220                        password                = HybsSystem.sys( "LDAP_PASSWORD" );
    221                        searchbase              = HybsSystem.sys( "LDAP_SEARCH_BASE" );
    222                }
    223        }
    224
    225        /**
    226         * DBからユーザーリソースの情報を取得します。
    227         *
    228         * @og.rev 5.2.0.0 (2010/09/01) 新規作成
    229         *
    230         * @param       userId  ユーザーID
    231         * @param       roles   ロール
    232         * @param       appInfo DB接続情報
    233         *
    234         * @return ユーザーリソース情報
    235         */
    236        private static String[][] getVals( final String userId, final String roles, final ApplicationInfo appInfo ) {
    237                String[] args;
    238                String[][] rtn = null;
    239
    240                if( roles == null || roles.length() == 0 ) {
    241                        args = new String[] { SYSTEM_ID,userId };
    242                        synchronized( lock ) {
    243                                rtn = DBUtil.dbExecute( query,args,appInfo,dbid );
    244                        }
    245                }
    246                // 4.0.0.0 (2007/10/31)
    247                else {
    248                        args = new String[] { SYSTEM_ID,userId,roles };
    249                        synchronized( lock ) {
    250                                rtn = DBUtil.dbExecute( queryRole,args,appInfo,dbid );
    251                        }
    252                }
    253
    254                return rtn;
    255        }
    256
    257        /**
    258         * LDAPからユーザーリソースの情報を取得します。
    259         *
    260         * @og.rev 5.2.0.0 (2010/09/01) 新規作成
    261         *
    262         * @param       userId  ユーザーID
    263         * @param       roles   ロール
    264         *
    265         * @return ユーザーリソース情報
    266         */
    267        private static String[][] getValsByLdap( final String userId, final String roles ) {
    268                LDAPSearch serch = new LDAPSearch();
    269                serch.setSearchScope( searchScope ) ;
    270                serch.setInitctx( initctx ) ;
    271                serch.setProviderURL( providerURL ) ;
    272                serch.setSearchbase( searchbase ) ;
    273                if( entrydn != null  ) { serch.setEntrydn( entrydn ) ; }
    274                if( password != null ) { serch.setPassword( password ) ; }
    275                serch.setAttributes( ldapClm ) ;
    276                serch.init();
    277
    278                String filter = ( roles == null || roles.length() == 0 ) ? ldapFilter : ldapRoleFilter;
    279                String[] args = ( roles == null || roles.length() == 0 ) ? new String[] { SYSTEM_ID,userId } : new String[] { SYSTEM_ID,userId,roles };
    280                filter = MessageFormat.format( filter,(Object[])args );
    281
    282                List<String[]> list = serch.search( filter );
    283
    284                String[][] rtn = null;
    285                if( list.size() > 0 ) {
    286                        rtn = new String[1][];
    287                        rtn[0] = list.get( 0 );
    288                        rtn[0][1] = StringUtil.nval( rtn[0][1], "ja" );                 // 言語のデフォルト値は、'ja'
    289                        rtn[0][2] = StringUtil.nval( rtn[0][2], rtn[0][0] );    // 名称のデフォルト値は、ユーザーID
    290                        rtn[0][3] = StringUtil.nval( rtn[0][3], ldapClm[3] );   // ロールズの初期値は、ロールに設定された項目名
    291                        rtn[0][4] = StringUtil.nval( rtn[0][4], "" );
    292                }
    293
    294                return rtn;
    295        }
    296}