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