Archive March 2014

password* functions before php 5.5.0

There is noway to use password_hash and password_verify and other password* functions natively with php older than 5.5.0 . You can see frustrating indication (PHP 5 >= 5.5.0) in php documentation.

If you are not the admin of php server or you don’t want to upgrade your php server right now, you are like me solved by ircmaxell who codes with contributers one file php library password.php listed bellow. Take last version found here

Simple of use : download password.php and include it in your php page and enjoy


password.php

<?php
/**
 * A Compatibility library with PHP 5.5's simplified password hashing API.
 *
 * @author Anthony Ferrara 
 * @license http://www.opensource.org/licenses/mit-license.html MIT License
 * @copyright 2012 The Authors
 */

namespace {

if (!defined('PASSWORD_DEFAULT')) {

    define('PASSWORD_BCRYPT', 1);
    define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);

    /**
     * Hash the password using the specified algorithm
     *
     * @param string $password The password to hash
     * @param int    $algo     The algorithm to use (Defined by PASSWORD_* constants)
     * @param array  $options  The options for the algorithm to use
     *
     * @return string|false The hashed password, or false on error.
     */
    function password_hash($password, $algo, array $options = array()) {
        if (!function_exists('crypt')) {
            trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
            return null;
        }
        if (!is_string($password)) {
            trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
            return null;
        }
        if (!is_int($algo)) {
            trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
            return null;
        }
        $resultLength = 0;
        switch ($algo) {
            case PASSWORD_BCRYPT:
                // Note that this is a C constant, but not exposed to PHP, so we don't define it here.
                $cost = 10;
                if (isset($options['cost'])) {
                    $cost = $options['cost'];
                    if ($cost  31) {
                        trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
                        return null;
                    }
                }
                // The length of salt to generate
                $raw_salt_len = 16;
                // The length required in the final serialization
                $required_salt_len = 22;
                $hash_format = sprintf("$2y$%02d$", $cost);
                // The expected length of the final crypt() output
                $resultLength = 60;
                break;
            default:
                trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
                return null;
        }
        $salt_requires_encoding = false;
        if (isset($options['salt'])) {
            switch (gettype($options['salt'])) {
                case 'NULL':
                case 'boolean':
                case 'integer':
                case 'double':
                case 'string':
                    $salt = (string) $options['salt'];
                    break;
                case 'object':
                    if (method_exists($options['salt'], '__tostring')) {
                        $salt = (string) $options['salt'];
                        break;
                    }
                case 'array':
                case 'resource':
                default:
                    trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
                    return null;
            }
            if (PasswordCompatbinary_strlen($salt) < $required_salt_len) {
                trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompatbinary_strlen($salt), $required_salt_len), E_USER_WARNING);
                return null;
            } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
                $salt_requires_encoding = true;
            }
        } else {
            $buffer = '';
            $buffer_valid = false;
            if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
                $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
                if ($buffer) {
                    $buffer_valid = true;
                }
            }
            if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
                $buffer = openssl_random_pseudo_bytes($raw_salt_len);
                if ($buffer) {
                    $buffer_valid = true;
                }
            }
            if (!$buffer_valid && @is_readable('/dev/urandom')) {
                $f = fopen('/dev/urandom', 'r');
                $read = PasswordCompatbinary_strlen($buffer);
                while ($read = $raw_salt_len) {
                    $buffer_valid = true;
                }
            }
            if (!$buffer_valid || PasswordCompatbinary_strlen($buffer) < $raw_salt_len) {
                $bl = PasswordCompatbinary_strlen($buffer);
                for ($i = 0; $i < $raw_salt_len; $i++) {
                    if ($i  1,
     *    'algoName' => 'bcrypt',
     *    'options' => array(
     *        'cost' => 10,
     *    ),
     * )
     *
     * @param string $hash The password hash to extract info from
     *
     * @return array The array of information about the hash.
     */
    function password_get_info($hash) {
        $return = array(
            'algo' => 0,
            'algoName' => 'unknown',
            'options' => array(),
        );
        if (PasswordCompatbinary_substr($hash, 0, 4) == '$2y$' && PasswordCompatbinary_strlen($hash) == 60) {
            $return['algo'] = PASSWORD_BCRYPT;
            $return['algoName'] = 'bcrypt';
            list($cost) = sscanf($hash, "$2y$%d$");
            $return['options']['cost'] = $cost;
        }
        return $return;
    }

    /**
     * Determine if the password hash needs to be rehashed according to the options provided
     *
     * If the answer is true, after validating the password using password_verify, rehash it.
     *
     * @param string $hash    The hash to test
     * @param int    $algo    The algorithm used for new password hashes
     * @param array  $options The options array passed to password_hash
     *
     * @return boolean True if the password needs to be rehashed.
     */
    function password_needs_rehash($hash, $algo, array $options = array()) {
        $info = password_get_info($hash);
        if ($info['algo'] != $algo) {
            return true;
        }
        switch ($algo) {
            case PASSWORD_BCRYPT:
                $cost = isset($options['cost']) ? $options['cost'] : 10;
                if ($cost != $info['options']['cost']) {
                    return true;
                }
                break;
        }
        return false;
    }

    /**
     * Verify a password against a hash using a timing attack resistant approach
     *
     * @param string $password The password to verify
     * @param string $hash     The hash to verify against
     *
     * @return boolean If the password matches the hash
     */
    function password_verify($password, $hash) {
        if (!function_exists('crypt')) {
            trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
            return false;
        }
        $ret = crypt($password, $hash);
        if (!is_string($ret) || PasswordCompatbinary_strlen($ret) != PasswordCompatbinary_strlen($hash) || PasswordCompatbinary_strlen($ret) <= 13) {
            return false;
        }

        $status = 0;
        for ($i = 0; $i < PasswordCompatbinary_strlen($ret); $i++) {
            $status |= (ord($ret[$i]) ^ ord($hash[$i]));
        }

        return $status === 0;
    }
}

}

namespace PasswordCompatbinary {
    /**
     * Count the number of bytes in a string
     *
     * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
     * In this case, strlen() will count the number of *characters* based on the internal encoding. A
     * sequence of bytes might be regarded as a single multibyte character.
     *
     * @param string $binary_string The input string
     *
     * @internal
     * @return int The number of bytes
     */
    function _strlen($binary_string) {
           if (function_exists('mb_strlen')) {
               return mb_strlen($binary_string, '8bit');
           }
           return strlen($binary_string);
    }

    /**
     * Get a substring based on byte limits
     *
     * @see _strlen()
     *
     * @param string $binary_string The input string
     * @param int    $start
     * @param int    $length
     *
     * @internal
     * @return string The substring
     */
    function _substr($binary_string, $start, $length) {
       if (function_exists('mb_substr')) {
           return mb_substr($binary_string, $start, $length, '8bit');
       }
       return substr($binary_string, $start, $length);
   }

}

Jboss7 : useful jboss-cli commands

jboss7 offer jboss-cli (command line interface) which makes live easier for administrators.

First of all connect to jboss-cli as following

connect to jboss-cli : connect

[witr@WITR-PC]#cd $JBOSS_HOME
[witr@WITR-PC]#./bin/jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect
[standalone@localhost:9991 /]

Then, here some useful jboss-cli commands

undeploy and redeploy artifacts : deploy/undeploy

[standalone@localhost:9991 /] undeploy witr-4.2.15.war
[standalone@localhost:9991 /] deploy standalone/deployments/witr-4.2.15.war

list already deployed artifacts : deploy -l

[standalone@localhost:9991 /] deploy -l
NAME                          RUNTIME-NAME                  ENABLED STATUS 
wReport-4.0.13.war            wReport-4.0.13.war            true    OK     
witr-4.2.15.war               witr-4.2.15.war               true    OK     
witr-ws-4.0.1.jar             witr-ws-4.0.1.jar             true    OK     
[standalone@localhost:9991 /] 

handle log levels : /subsystem=logging

Add new log level “INFO” on class net.witr.home.Himmel

[standalone@localhost:9991 /] /subsystem=logging/logger=net.witr.home.Himmel:add(level=INFO)
{"outcome" => "success"}
[standalone@localhost:9991 /] 

Change log level of class net.witr.home.Himmel to “DEBUG”

[standalone@localhost:9991 /] /subsystem=logging/logger=net.witr.home.Himmel:change-log-level(level=DEBUG)
{"outcome" => "success"}
[standalone@localhost:9991 /] 

Remove log level of class net.witr.home.Himmel

[standalone@localhost:9991 /] /subsystem=logging/logger=net.witr.home.Himmel:remove
{"outcome" => "success"}
[standalone@localhost:9991 /] 

handle system properties : /system-property
Add, read and remove system property witrActive

[standalone@localhost:9991 /] /system-property=witrActive:add(value=Y)
{"outcome" => "success"}
[standalone@localhost:9991 /] /system-property=witrActive:read-resource
{
    "outcome" => "success",
    "result" => {"value" => "Y"}
}
[standalone@localhost:9991 /] /system-property=witrActive:remove
{"outcome" => "success"}

XSLT java debug

You may need some debug message to be logged in standard output

java debug class

package net.witr.xslt;

public class XslDebug {

    public static void debug(String msg){
        System.out.println(msg);
    }

}

xsl code


  ..
  
    
    
    
  
  ..

Apache POI : delete excel empty rows

POI method sheet.removeRow(), removes row cells but doesn’t clear them from excel output.
Means if you have three rows and you apply sheet.removeRow(1), you will have:
– not changed first row
– empty second row
– not changed third row

So to remove row completly you must then shift rows following.
But for some reason sheet.shiftRows() poi api method doesn’t work for me.
Code bellow do it

    public void deleteEmptyRows(){
        SXSSFSheet sheet = (SXSSFSheet)sh;
        for ( int r=sheet.getLastRowNum(); r >= 0; r-- ){
            Row row     = sheet.getRow( r );

            // if no row exists here; then nothing to do; next!
            if ( row == null )
                continue;

            int lastColumn = row.getLastCellNum();
            boolean rowToDelete = true;
            if(lastColumn > -1){
                for ( int x=0; x < lastColumn + 1; x++ ){
                    Cell cell    = row.getCell(x);
                    if ( cell != null && cell.getStringCellValue() != null){
                        String cellTrimValue = cell.getStringCellValue().trim();
                        if(!cellTrimValue.isEmpty()){
                            rowToDelete = false;
                            break;
                        }
                    }
                }
            }

            if(rowToDelete){
                if(r == sheet.getLastRowNum()){
                    sheet.removeRow(row);
                }else{
                    sheet.removeRow(row);
                    for(int j= r+1; j <= sheet.getLastRowNum(); j++){
                        Row rowToShift = sheet.getRow(j);
                        rowToShift.setRowNum(j-1);
                    }
                }
            }
        }
    }

Apache POI : delete list of excel columns / keep only list of excel columns

First you must got code from here

Remove some columns with provided headers

    public void deleteColumnsWithHeader(String columnHeader){
        SXSSFSheet sheet = (SXSSFSheet)sh;
        Row row     = sheet.getRow( 0 );
        if ( row == null ){
            return;
        }

        int lastColumn = row.getLastCellNum();

        for ( int x=lastColumn; x >= 0; x-- ){
            Cell headerCell    = row.getCell(x);
            if ( headerCell != null && headerCell.getStringCellValue() != null && 
                 headerCell.getStringCellValue().equalsIgnoreCase(columnHeader)){
                deleteColumn(x);
            }
        }
    }

Keep only columns with provided headers

    public void keepOnlyColumnsWithHeaders(List columnHeaders){
        SXSSFSheet sheet = (SXSSFSheet)sh;
        Row row     = sheet.getRow( 0 );
        if ( row == null ){
            return;
        }

        int lastColumn = row.getLastCellNum();

        for ( int x=lastColumn; x >= 0; x-- ){
            Cell headerCell    = row.getCell(x);
            if ( headerCell != null && headerCell.getStringCellValue() != null && 
                 !columnHeaders.contains(headerCell.getStringCellValue())){
                deleteColumn(x);
            }
        }
    }

Apache POI : remove excel columns

<

div>
Unfortunatly there was no method to remove excel columns in poi api.
Code bellow (found here) can help

    public void deleteColumn(SXSSFSheet sheet, int columnToDelete){        
        int maxColumn = 0;
        for ( int r=0; r  maxColumn )
                maxColumn = lastColumn;

            if ( lastColumn < columnToDelete )
                continue;

            for ( int x=columnToDelete+1; x < lastColumn + 1; x++ ){
                Cell oldCell    = row.getCell(x-1);
                if ( oldCell != null )
                    row.removeCell( oldCell );

                Cell nextCell   = row.getCell( x );
                if ( nextCell != null ){
                    Cell newCell    = row.createCell( x-1, nextCell.getCellType() );
                    cloneCell(newCell, nextCell);
                }
            }
        }
    }

    private void cloneCell( Cell cNew, Cell cOld ){
        cNew.setCellComment( cOld.getCellComment() );
        cNew.setCellStyle( cOld.getCellStyle() );

        switch ( cNew.getCellType() ){
            case Cell.CELL_TYPE_BOOLEAN:{
                cNew.setCellValue( cOld.getBooleanCellValue() );
                break;
            }
            case Cell.CELL_TYPE_NUMERIC:{
                cNew.setCellValue( cOld.getNumericCellValue() );
                break;
            }
            case Cell.CELL_TYPE_STRING:{
                cNew.setCellValue( cOld.getStringCellValue() );
                break;
            }
            case Cell.CELL_TYPE_ERROR:{
                cNew.setCellValue( cOld.getErrorCellValue() );
                break;
            }
            case Cell.CELL_TYPE_FORMULA:{
                cNew.setCellFormula( cOld.getCellFormula() );
                break;
            }
        }

    }

load css with javascript

Following javascript function loads css file if it’s not already loaded

function loadIfNotYetLoaded(cssFilePathName){
    cssLoaded = false;
    var ss = document.styleSheets;
    for (var i = 0, max = ss.length; i < max; i++) {
        var sheet = ss[i];
        if(sheet.href.indexOf(cssFilePathName) != -1){
            cssLoaded = true;
            break;
        }
    }

    if(!cssLoaded){     
        var link = document.createElement("link");
        link.rel = "stylesheet";      
        link.href = cssFilePathName;
        document.getElementsByTagName("head")[0].appendChild(link);     
    }
}

Oracle DB : Beware when specifying column max length

To create table STUDENT with single column NAME which must not excceed 6 characters, you may type the following

CREATE TABLE STUDENT
  (
    NAME VARCHAR2 (6)
  );

But this is wrong if NLS_LENGTH_SEMANTICS=BYTE (default value) : Typing VARCHAR2(6) means 6 bytes and not 6 characters.
In this case “Claude” will be accepted but not “Noémie”, because ‘é’ is encoded with 2 bytes and the sum will exceed 6 bytes.

The right way to specify column max length is as follow

CREATE TABLE STUDENT
  (
    NAME VARCHAR2 (6 CHAR)
  );

NLS_LENGTH_SEMANTICS enables you to create CHAR and VARCHAR2 columns using either byte or character length semantics. Existing columns are not affected.

NCHAR, NVARCHAR2, CLOB, and NCLOB columns are always character-based. You may be required to use byte semantics in order to maintain compatibility with existing applications.

NLS_LENGTH_SEMANTICS does not apply to tables in SYS and SYSTEM. The data dictionary always uses byte semantics.

Get and/or set NLS_LENGTH_SEMANTICS value

-- get NLS_LENGTH_SEMANTICS value
SELECT * FROM NLS_database_PARAMETERS WHERE PARAMETER = 'NLS_LENGTH_SEMANTICS';
-- set NLS_LENGTH_SEMANTICS to CHAR
ALTER system SET NLS_LENGTH_SEMANTICS=CHAR; -- restart to take effect