    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}