    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.taglib;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020import org.opengion.fukurou.util.ToString;
    021
    022import static org.opengion.fukurou.util.StringUtil.nval;
    023
    024/**
    025 * IorQueryTag と IorUpdateTag にﾊﾟﾗﾒｰﾀｰを渡す為のﾀｸﾞｸﾗｽです。
    026 *
    027 * ｷｰは、SQL文のselect句／where句／group by句／order by句が指定できます。
    028 * 値は、value 属性で指定するか、なければ BODY 部に記述します。
    029 *
    030 * @og.formSample
    031 * ●形式：
    032 *     &lt;og:iorParam key="where_lk" value="{'PN':'{&#064;PN}%','TANI':'{&#064;TANI}'}" /&gt;
    033 *
    034 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    035 *
    036 * ●Tag定義：
    037 *   &lt;og:iorParam
    038 *       key              ○【TAG】ﾊﾟﾗﾒｰﾀとして渡すｷｰ情報を指定します (必須)
    039 *       value              【TAG】ﾊﾟﾗﾒｰﾀとして渡す設定値を指定します (初期値:null)
    040 *       quotCheck          【TAG】ﾘｸｴｽﾄ情報の ｼﾝｸﾞﾙｸｫｰﾄ(') 存在ﾁｪｯｸを実施するかどうか[true/false]を設定します (初期値:USE_SQL_INJECTION_CHECK[=true])
    041 *       xssCheck           【TAG】ﾘｸｴｽﾄ情報の HTMLTag開始/終了文字(&gt;&lt;) 存在ﾁｪｯｸを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true])
    042 *       caseKey            【TAG】このﾀｸﾞ自体を利用するかどうかの条件ｷｰを指定します (初期値:null)
    043 *       caseVal            【TAG】このﾀｸﾞ自体を利用するかどうかの条件値を指定します (初期値:null)
    044 *       caseNN             【TAG】指定の値が、null/ｾﾞﾛ文字列 でない場合(Not Null=NN)は、このﾀｸﾞは使用されます (初期値:判定しない)
    045 *       caseNull           【TAG】指定の値が、null/ｾﾞﾛ文字列 の場合は、このﾀｸﾞは使用されます (初期値:判定しない)
    046 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このﾀｸﾞは使用されます (初期値:判定しない)
    047 *       debug              【TAG】ﾃﾞﾊﾞｯｸﾞ情報を出力するかどうか[true/false]を指定します (初期値:false)
    048 *   &gt;   ... Body ...
    049 *   &lt;/og:iorParam&gt;
    050 *
    051 * ●使用例
    052 *     &lt;og:iorQuery
    053 *         url           = "http://･･･ "
    054 *         authURL       = "http://･･･ "
    055 *         authUserPass  = "admin:******"
    056 *         appliName     = "ﾃﾞｰﾀﾃｰﾌﾞﾙ名"
    057 *         callMethod    = "getReportInfo"
    058 *     &gt;
    059 *         &lt;og:iorParam
    060 *             key  = "select_cols"  value  = "PN,TANI,count(*) as CNT"  /&gt;
    061 *         &lt;og:iorParam
    062 *             key  = "where_lk"     value  = "{'PN':'{&#064;PN}%','TANI':'{&#064;TANI}'}"  /&gt;
    063 *     &lt;/og:iorQuery&gt;
    064 *
    065 * @og.rev 8.0.2.0 (2021/11/30) 新規作成
    066 * @og.group その他部品
    067 *
    068 * @version  8.0
    069 * @author   LEE.M
    070 * @since    JDK17.0,
    071 */
    072public class IorParamTag extends CommonTagSupport {
    073        /** このﾌﾟﾛｸﾞﾗﾑのVERSION文字列を設定します。 {@value} */
    074        private static final String VERSION = "8.0.2.0 (2021/11/30)" ;
    075        private static final long serialVersionUID = 802020211130L ;
    076
    077        /** ｷｰ情報 */
    078        private String  key                     ;
    079        /** 設定値 */
    080        private String  value           ;
    081        /** ｸｵｰﾄﾁｪｯｸ */
    082        private boolean quotCheck       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );
    083        /** XSSﾁｪｯｸ */
    084        private boolean xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );
    085
    086        /**
    087         * ﾃﾞﾌｫﾙﾄｺﾝｽﾄﾗｸﾀｰ
    088         */
    089        public IorParamTag() { super(); }       // これも、自動的に呼ばれるが、空のﾒｿｯﾄﾞを作成すると警告されるので、明示的にしておきます。
    090
    091        /**
    092         * Taglibの開始ﾀｸﾞが見つかったときに処理する doStartTag() を ｵｰﾊﾞｰﾗｲﾄﾞします。
    093         *
    094         * @return      後続処理の指示
    095         */
    096        @Override
    097        public int doStartTag() {
    098                if( useTag() ) {
    099                        useQuotCheck( quotCheck );
    100                        useXssCheck( xssCheck );
    101
    102                        value = getRequestParameter( value );
    103
    104                        if( value == null || value.isEmpty() ) {
    105                                return EVAL_BODY_BUFFERED;                                                                              // Body を評価する。( extends BodyTagSupport 時)
    106                        }
    107                }
    108                return SKIP_BODY;                                                                                                               // Body を評価しない
    109        }
    110
    111        /**
    112         * Taglibのﾀｸﾞ本体を処理する doAfterBody() を ｵｰﾊﾞｰﾗｲﾄﾞします。
    113         *
    114         * @return      後続処理の指示(SKIP_BODY)
    115         */
    116        @Override
    117        public int doAfterBody() {
    118                value = getBodyString();
    119                return SKIP_BODY;
    120        }
    121
    122        /**
    123         * Taglibの終了ﾀｸﾞが見つかったときに処理する doEndTag() を ｵｰﾊﾞｰﾗｲﾄﾞします。
    124         *
    125         * @return      後続処理の指示
    126         */
    127        @Override
    128        public int doEndTag() {
    129                debugPrint();
    130                if( useTag() ) {
    131                        final IorQueryTag iorQuery = (IorQueryTag)findAncestorWithClass( this,IorQueryTag.class );
    132                        if( iorQuery == null ) {
    133                                final String errMsg = "<b>" + getTagName() + "ﾀｸﾞは、Ior関連Tagの内側(要素)に記述してください。</b>";
    134                                throw new HybsSystemException( errMsg );
    135                        }
    136                        iorQuery.addParam( key, value );
    137                }
    138                return EVAL_PAGE;
    139        }
    140
    141        /**
    142         * ﾀｸﾞﾘﾌﾞｵﾌﾞｼﾞｪｸﾄをﾘﾘｰｽします。
    143         * ｷｬｯｼｭされて再利用されるので、ﾌｨｰﾙﾄﾞの初期設定を行います。
    144         *
    145         */
    146        @Override
    147        protected void release2() {
    148                super.release2();
    149                key                     = null;                                                                                                         // ｷｰ情報
    150                value           = null;                                                                                                         // 設定値
    151                quotCheck       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );                      // ｸｵｰﾄﾁｪｯｸ
    152                xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );                                        // XSSﾁｪｯｸ
    153        }
    154
    155        /**
    156         * 【TAG】ﾊﾟﾗﾒｰﾀとして渡すｷｰ情報を指定します。
    157         *
    158         * @og.tag
    159         * IorQueryTag と IorUpdateTag に渡すﾊﾟﾗﾒｰﾀのｷｰ情報です。
    160         * 値は、value 属性で指定するか、なければ BODY 部に記述します。
    161         *
    162         * ｷｰは、SQL文のselect句／where句／group by句／order by句が指定できます。
    163         *
    164         * 処理対象を特定するｶﾗﾑ名(select句)が指定できます。
    165         *   SQL文:  select  PN,TANI,count(*) as CNT
    166         *   使用文: key="select"  value="PN,TANI,count(*) as CNT"
    167         *
    168         * 処理対象を特定するｷｰ条件(where句)が指定できます。
    169         *   (1) SQL文:  where  PN LIKE 'GEN%'  and  TANI = 'KG'
    170         *       使用文: key="where"     value="{'PN':'GEN%','TANI':'KG'}"
    171         *   (2) SQL文:  where  DYSET &gt;= '20211101'
    172         *       使用文: key="where_ge"  value="{'DYSET':'20211101'}"
    173         *   (3) SQL文:  where  DYSET &lt;= '20211101'
    174         *       使用文: key="where_le"  value="{'DYSET':'20211101'}"
    175         *
    176         * 処理対象を特定する集計条件(group by句)が指定できます。
    177         *   SQL文:  group by  PN,TANI
    178         *   使用文: key="group by"  value="PN,TANI"
    179         *
    180         * 処理対象の並び替えを指定するｷｰﾜｰﾄﾞ(order by句)が指定できます。
    181         *   SQL文:  order by  PN,TANI
    182         *   使用文: key="order_by"  value="PN,TANI"
    183         *
    184         * @param       prmKey  ｷｰ情報
    185         */
    186        public void setKey( final String prmKey ) {
    187                key = nval( getRequestParameter( prmKey ),key );
    188                if( key == null ) {
    189                        final String errMsg = "key がｾｯﾄされていません。";
    190                        throw new HybsSystemException( errMsg );
    191                }
    192        }
    193
    194        /**
    195         * 【TAG】ﾊﾟﾗﾒｰﾀとして渡す設定値を指定します(初期値:null)。
    196         *
    197         * @og.tag
    198         * IorQueryTag と IorUpdateTag に渡すﾊﾟﾗﾒｰﾀの設定値です。
    199         * 値は、value 属性で指定するか、なければ BODY 部に記述します。
    200         * BODY 部に記述された場合は、文字列を trim() します。
    201         * 設定値は、value 属性が優先です。ここの値が、null の場合は、
    202         * BODY 要素を値として使用します。
    203         *
    204         * @param       val     設定値
    205         * @see         #setKey( String )
    206         */
    207        public void setValue( final String val ) {
    208                value = nval( getRequestParameter( val ),value );
    209        }
    210
    211        /**
    212         * 【TAG】ﾘｸｴｽﾄ情報の ｼﾝｸﾞﾙｸｫｰﾄ(') 存在ﾁｪｯｸを実施するかどうか[true/false]を設定します
    213         *        (初期値:USE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])。
    214         *
    215         * @og.tag
    216         * SQLｲﾝｼﾞｪｸｼｮﾝ対策の一つとして、暫定的ではありますが、SQLのﾊﾟﾗﾒｰﾀに
    217         * 渡す文字列にｼﾝｸﾞﾙｸｫｰﾄ(') を許さない設定にすれば、ある程度は防止できます。
    218         * 数字ﾀｲﾌﾟの引数には、 or 5=5 などのｼﾝｸﾞﾙｸｫｰﾄを使用しないｺｰﾄﾞを埋めても、
    219         * 数字ﾁｪｯｸで検出可能です。文字ﾀｲﾌﾟの場合は、必ず (')をはずして、
    220         * ' or 'A' like 'A のような形式になる為、(')ﾁｪｯｸだけでも有効です。
    221         * (') が含まれていたｴﾗｰにする(true)／かﾉｰﾁｪｯｸか(false)を指定します。
    222         * (初期値:ｼｽﾃﾑ定数のUSE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])。
    223         *
    224         * @param       flag ｸｫｰﾄﾁｪｯｸ [true:する/それ以外:しない]
    225         * @see         org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK
    226         */
    227        public void setQuotCheck( final String flag ) {
    228                quotCheck = nval( getRequestParameter( flag ),quotCheck );
    229        }
    230
    231        /**
    232         * 【TAG】ﾘｸｴｽﾄ情報の HTMLTag開始/終了文字(&gt;&lt;) 存在ﾁｪｯｸを実施するかどうか[true/false]を設定します
    233         *        (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。
    234         *
    235         * @og.tag
    236         * ｸﾛｽｻｲﾄｽｸﾘﾌﾟﾃｨﾝｸﾞ(XSS)対策の一環としてless/greater than signについてのﾁｪｯｸを行います。
    237         * (&gt;&lt;) が含まれていたｴﾗｰにする(true)／かﾉｰﾁｪｯｸか(false)を指定します。
    238         * (初期値:ｼｽﾃﾑ定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。
    239         *
    240         * @param       flag    XSSﾁｪｯｸ [true:する/false:しない]
    241         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
    242         */
    243        public void setXssCheck( final String flag ) {
    244                xssCheck = nval( getRequestParameter( flag ),xssCheck );
    245        }
    246
    247        /**
    248         * このｵﾌﾞｼﾞｪｸﾄの文字列表現を返します。
    249         * 基本的にﾃﾞﾊﾞｯｸﾞ目的に使用します。
    250         *
    251         * @return      このｸﾗｽの文字列表現
    252         * @og.rtnNotNull
    253         */
    254        @Override
    255        public String toString() {
    256                return ToString.title( this.getClass().getName() )
    257                                .println( "VERSION"             ,VERSION        )
    258                                .println( "key"                 ,key            )
    259                                .println( "value"               ,value          )
    260                                .println( "quotCheck"   ,quotCheck      )
    261                                .println( "Other..."    ,getAttributes().getAttribute() )
    262                                .fixForm().toString() ;
    263        }
    264}