    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.filter;
    017
    018import org.opengion.fukurou.util.Closer;
    019import org.opengion.fukurou.util.HybsDateUtil;
    020import org.opengion.hayabusa.common.HybsSystem;
    021
    022import javax.servlet.ServletRequest;
    023import javax.servlet.http.HttpServletRequest;
    024import javax.servlet.ServletResponse;
    025import javax.servlet.ServletException;
    026import javax.servlet.ServletContext;
    027import javax.servlet.Filter;
    028import javax.servlet.FilterChain;
    029import javax.servlet.FilterConfig;
    030
    031// import java.util.Date;
    032// import java.util.Locale ;
    033// import java.text.DateFormat;
    034// import java.text.SimpleDateFormat;
    035
    036import java.io.File;                                                    // 5.7.3.2 (2014/02/28) Tomcat8 対応
    037import java.io.PrintWriter;
    038import java.io.BufferedReader;
    039import java.io.IOException;
    040import java.io.FileInputStream;
    041import java.io.InputStreamReader;
    042import java.io.UnsupportedEncodingException;
    043
    044/**
    045 * AccessStopFilter は、Filter インターフェースを継承した アクセス制御クラスです。
    046 * web.xml で filter 設定することにより、Webアプリケーションへのアクセスを制御できます。
    047 * また、SYSTEM ユーザーは、このフィルターを常に通過します。
    048 *
    049 * フィルターに対してweb.xml でパラメータを設定します。
    050 *   ・startTime:停止開始時刻
    051 *   ・stopTime :停止終了時刻
    052 *   ・filename :停止時メッセージ表示ファイル名
    053 *
    054 * 【WEB-INF/web.xml】
    055 *     &lt;filter&gt;
    056 *         &lt;filter-name&gt;AccessStopFilter&lt;/filter-name&gt;
    057 *         &lt;filter-class&gt;org.opengion.hayabusa.filter.AccessStopFilter&lt;/filter-class&gt;
    058 *         &lt;init-param&gt;
    059 *             &lt;param-name&gt;startTime&lt;/param-name&gt;
    060 *             &lt;param-value&gt;070000&lt;/param-value&gt;
    061 *         &lt;/init-param&gt;
    062 *         &lt;init-param&gt;
    063 *             &lt;param-name&gt;stopTime&lt;/param-name&gt;
    064 *             &lt;param-value&gt;070000&lt;/param-value&gt;
    065 *         &lt;/init-param&gt;
    066 *         &lt;init-param&gt;
    067 *             &lt;param-name&gt;filename&lt;/param-name&gt;
    068 *             &lt;param-value&gt;jsp/custom/stopFile.html&lt;/param-value&gt;
    069 *         &lt;/init-param&gt;
    070 *     &lt;/filter&gt;
    071 *
    072 *     &lt;filter-mapping&gt;
    073 *         &lt;filter-name&gt;AccessStopFilter&lt;/filter-name&gt;
    074 *         &lt;url-pattern&gt;/jsp/*&lt;/url-pattern&gt;
    075 *     &lt;/filter-mapping&gt;
    076 *
    077 * @og.group フィルター処理
    078 *
    079 * @version  4.0
    080 * @author   Kazuhiko Hasegawa
    081 * @since    JDK5.0,
    082 */
    083public final class AccessStopFilter implements Filter {
    084
    085        private static boolean stopFilter = false;
    086        private String startTime = "230000";            // 停止開始時刻
    087        private String stopTime  = "070000";            // 停止終了時刻
    088        private String filename  = null;                        // 停止時メッセージ表示ファイル名
    089        private int    startStop = 0;
    090
    091        private static final String  USERID_HEADER = HybsSystem.sys( "USERID_HEADER_NAME" ); // 5.10.18.0 (2019/11/29)
    092
    093        /**
    094         * フィルター処理本体のメソッドです。
    095         *
    096         * @og.rev 3.1.3.0 (2003/04/10) UTF-8 決め打ちで、stopFile.html を返送する。
    097         * @og.rev 3.1.8.0 (2003/05/16) 文字エンコードが、UTF-8 になっていないのを修正。
    098         *
    099         * @param       request         ServletRequestオブジェクト
    100         * @param       response        ServletResponseオブジェクト
    101         * @param       chain           FilterChainオブジェクト
    102         * @throws IOException 入出力エラーが発生した場合、throw されます。
    103         * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。
    104         */
    105        public void doFilter( final ServletRequest request,
    106                                                        final ServletResponse response,
    107                                                        final FilterChain chain)
    108                                                                throws IOException, ServletException {
    109
    110                if( isStop( request ) ) {
    111                        BufferedReader in = null ;
    112                        try {
    113                                response.setContentType( "text/html; charset=UTF-8" );
    114                                PrintWriter out = response.getWriter();
    115                                in = new BufferedReader( new InputStreamReader(
    116                                                                new FileInputStream( filename ) ,"UTF-8" ) );
    117                                String str ;
    118                                while( (str = in.readLine()) != null ) {
    119                                        out.println( str );
    120                                }
    121                                out.flush();
    122                        }
    123                        catch( UnsupportedEncodingException ex ) {
    124                                String errMsg = "指定されたエンコーディングがサポートされていません。[UTF-8]" ;
    125                                throw new RuntimeException( errMsg,ex );
    126                        }
    127                        catch( IOException ex ) {
    128                                String errMsg = "ストリームがオープン出来ませんでした。[" + filename + "]" ;
    129                                throw new RuntimeException( errMsg,ex );
    130                        }
    131                        finally {
    132                                Closer.ioClose( in );
    133                        }
    134                        return;
    135                }
    136
    137                chain.doFilter(request, response);
    138        }
    139
    140        /**
    141         * フィルターの初期処理メソッドです。
    142         *
    143         * フィルターに対してweb.xml で初期パラメータを設定します。
    144         *   ・startTime:停止開始時刻
    145         *   ・stopTime :停止終了時刻
    146         *   ・filename :停止時メッセージ表示ファイル名
    147         *
    148         * @og.rev 5.7.3.2 (2014/02/28) Tomcat8 対応。getRealPath( "/" ) の互換性のための修正。
    149         *
    150         * @param       filterConfig    FilterConfigオブジェクト
    151         */
    152        public void init(final FilterConfig filterConfig) {
    153
    154                ServletContext context = filterConfig.getServletContext();
    155//              String realPath = context.getRealPath( "/" );
    156                String realPath = context.getRealPath( "" ) + File.separator;   // 5.7.3.2 (2014/02/28) Tomcat8 対応
    157
    158                startTime = filterConfig.getInitParameter("startTime");
    159                stopTime  = filterConfig.getInitParameter("stopTime");
    160                filename  = realPath + filterConfig.getInitParameter("filename");
    161
    162                if( startTime == null || stopTime == null ) {
    163                        startStop = 0;
    164                }
    165                else {
    166                        startStop = startTime.compareTo( stopTime );
    167                }
    168        }
    169
    170        /**
    171         * フィルターの終了処理メソッドです。
    172         *
    173         */
    174        public void destroy() {
    175                // ここでは処理を行いません。
    176        }
    177
    178        /**
    179         * フィルターの内部状態をチェックするメソッドです。
    180         * 内部のフラグをもとに、停止/許可を求めます。
    181         *
    182         * @og.rev 3.1.8.0 (2003/05/16) 開始時刻と終了時刻を同一にしていると、画面からの制御が効かないバグを修正。
    183         * @og.rev 5.5.3.2 (2012/06/08) 通過させるユーザーに、admin を追加します。
    184         * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。
    185         * @og.rev 5.10.18.0 (2019/11/29) ヘッダ認証
    186         *
    187         * @param request ServletRequestオブジェクト
    188         *
    189         * @return      (true:停止  false:実行許可)
    190         */
    191        private boolean isStop( final ServletRequest request ) {
    192                String userID = ((HttpServletRequest)request).getRemoteUser() ;
    193                if( USERID_HEADER != null && USERID_HEADER.length() > 0 && ( userID == null || userID.length() == 0) ) {
    194                        userID = ((HttpServletRequest)request).getHeader( USERID_HEADER );
    195                }
    196
    197
    198                // 5.5.3.2 (2012/06/08) 通過させるユーザーに、admin を追加
    199//              if( "SYSTEM".equalsIgnoreCase( userID ) ) {
    200                if( "SYSTEM".equalsIgnoreCase( userID ) || "admin".equalsIgnoreCase( userID ) ) {
    201                        return false;
    202                }
    203
    204                // 4.0.0 (2005/01/31)
    205//              DateFormat formatter = new SimpleDateFormat( "HHmmss",Locale.JAPAN );
    206//              String time = formatter.format( new Date() );
    207                String time = HybsDateUtil.getDate( "HHmmss" );         // 5.5.7.2 (2012/10/09) HybsDateUtil を利用
    208
    209                boolean rtnFlag = stopFilter;
    210                if( startStop < 0 ) {
    211                        if( startTime.compareTo( time ) < 0 &&
    212                                time.compareTo( stopTime )  < 0 ) {
    213                                        rtnFlag = true;
    214                        }
    215                }
    216                else if( startStop > 0 ) {
    217                        if( startTime.compareTo( time ) < 0 ||
    218                                time.compareTo( stopTime )  < 0 ) {
    219                                        rtnFlag = true;
    220                                }
    221                }
    222                return rtnFlag;
    223        }
    224
    225        /**
    226         * フィルターの強制停止/解除を設定するメソッドです。
    227         *
    228         * @og.rev 4.0.0.0 (2005/01/31) synchronized の廃止
    229         *
    230         * @param flag (true:停止  false:実行許可)
    231         */
    232        public static void setStopFilter( final boolean flag ) {
    233                stopFilter = flag;
    234        }
    235
    236        /**
    237         * フィルターの内部状態(強制停止/解除)を取得するメソッドです。
    238         * これは、現在、アクセス制限がどうなっているかという状態ではなく、
    239         * 強制停止されているかどうかの確認メソッドです。
    240         *
    241         * @og.rev 4.0.0.0 (2007/11/29) getStopFilter() ⇒ isStopFilter() に変更
    242         *
    243         * @return      (true:停止  false:実行許可)
    244         */
    245//      public static boolean getStopFilter() {
    246        public static boolean isStopFilter() {
    247                return stopFilter;
    248        }
    249
    250        /**
    251         * 内部状態を文字列で返します。
    252         *
    253         * @return      このクラスの文字列表示
    254         */
    255        @Override
    256        public String toString() {
    257                StringBuilder sb = new StringBuilder();
    258                sb.append( "AccessStopFilter" );
    259                sb.append( "[" ).append( startTime ).append( "],");
    260                sb.append( "[" ).append( stopTime  ).append( "],");
    261                sb.append( "[" ).append( filename  ).append( "],");
    262                return (sb.toString());
    263        }
    264}