package org.maachang.comet.httpd.engine.auth ;

import java.util.HashSet;

import org.maachang.comet.httpd.HttpdHeaders;
import org.maachang.comet.httpd.HttpdRequest;
import org.maachang.comet.httpd.engine.HttpdDef;
import org.maachang.util.Base64;

/**
 * HTTPD-認証:Basic.
 *
 * @version 2007/08/19
 * @author  masahito suzuki
 * @since   MaachangComet 1.00
 */
public class HttpdAuthBasic {
    
    /**
     * 認証タイプ.
     */
    public static final String AUTH_TYPE_BY_BASIC = "basic" ;
    
    /**
     * コンストラクタ.
     */
    private HttpdAuthBasic() {
        
    }
    
    /**
     * 送信用認証情報を生成.
     * <BR><BR>
     * 送信用認証情報を生成します.
     * <BR>
     * @param element 対象の認証要素を設定します.
     * @return String 送信用認証内容が返されます.
     */
    public static final String getSendAuth( HttpdAuthElement element ) {
        StringBuilder buf = new StringBuilder() ;
        buf.append( HttpdDef.AUTH_TYPE_BASIC ).
            append( " realm=" ).
            append( "\"" ).
            append( element.getRealm() ).
            append( "\"" ) ;
        return buf.toString() ;
    }
    
    /**
     * 受信内容を元に認証処理.
     * <BR><BR>
     * 受信内容を元に認証処理を行います.
     * <BR>
     * @param request 対象のリクエストを設定します.
     * @param element 対象の認証要素を設定します.
     * @param users 対象のユーザ管理内容を設定します.
     * @param headerParams 対象のHTTPヘッダパラメータを設定します.
     * @return boolean [true]が返された場合、認証成功です.
     */
    public static final boolean isAuth( HttpdRequest request,HttpdAuthElement element,HttpdAuthUsers users,HttpdHeaders headerParams ) {
        boolean ret = false ;
        try{
            int pnt ;
            String params = null ;
            if( ( params = ( String )headerParams.getHeader( HttpdDef.VALUE_AUTH ) ) != null ){
                if( ( pnt = params.indexOf( HttpdDef.AUTH_TYPE_BASIC ) ) != -1 ){
                    params = params.substring( pnt+HttpdDef.AUTH_TYPE_BASIC.length(),params.length() ).trim() ;
                    if( params.length() > 0 ){
                        HashSet userset = element.getUsers() ;
                        String userPasswd = new String( Base64.decode( params ) ) ;
                        // パスワードが指定されていない場合.
                        if( ( pnt = userPasswd.indexOf( ":" ) ) == -1 ) {
                            String user = userPasswd ;
                            if( users == null || userset == null ||
                                users.isUser( user ) == false ) {
                                ret = false ;// ユーザが存在しない場合.
                            }
                            else if( userset.size() > 0 && userset.contains( user ) == false ) {
                                ret = false ;// ユーザマスク内に存在しない.
                            }
                            else {
                                String[] checkPasswd = users.getPassword( user ) ;
                                if( checkPasswd != null ) {
                                    int clen = checkPasswd.length ;
                                    for( int i = 0 ; i < clen ; i ++ ) {
                                        if( checkPasswd[ i ] == null || checkPasswd[ i ].length() <= 0 ) {
                                            ret = true ;// パスワードが一致.
                                            // 認証ユーザと認証パスワードをリクエストにセット.
                                            HttpdAuthManager.setSuccessAuth( request,user,checkPasswd[ i ] ) ;
                                            break ;
                                        }
                                    }
                                }
                            }
                        }
                        // パスワードが指定されている場合.
                        else {
                            String user = userPasswd.substring( 0,pnt ) ;
                            String passwd = userPasswd.substring( pnt+1,userPasswd.length() ) ;
                            if( users == null || userset == null ||
                                users.isUser( user ) == false ) {
                                ret = false ;// ユーザが存在しない場合.
                            }
                            else if( userset.size() > 0 && userset.contains( user ) == false ) {
                                ret = false ;// ユーザマスク内に存在しない.
                            }
                            else {
                                String[] checkPasswd = users.getPassword( user ) ;
                                if( checkPasswd != null ) {
                                    int clen = checkPasswd.length ;
                                    for( int i = 0 ; i < clen ; i ++ ) {
                                        if( ( passwd == null || passwd.length() <= 0 ) &&
                                            ( checkPasswd[ i ] == null || checkPasswd[ i ].length() <= 0 ) ) {
                                            ret = true ;// パスワードが一致.
                                            // 認証ユーザと認証パスワードをリクエストにセット.
                                            HttpdAuthManager.setSuccessAuth( request,user,checkPasswd[ i ] ) ;
                                            break ;
                                        }
                                        else if( ( checkPasswd[ i ] != null && checkPasswd[ i ].length() > 0 ) &&
                                            ( checkPasswd[ i ].equals( passwd ) == true ) ) {
                                            ret = true ;// パスワードが一致.
                                            // 認証ユーザと認証パスワードをリクエストにセット.
                                            HttpdAuthManager.setSuccessAuth( request,user,checkPasswd[ i ] ) ;
                                            break ;
                                        }
                                        else {
                                            ret = false ;
                                        }
                                    }
                                }
                            }
                        }
                        
                    }
                }
            }
        }catch( Exception e ) {
            ret = false ;
        }
        return ret ;
    }
}

