diff --git a/public_html/api/index.php b/public_html/api/index.php index 88ca9c3de1ecd428f21af603e70f8cd8d137cd4b..3e45c62185cd5115393899ec80ba6d3271fa2992 100644 --- a/public_html/api/index.php +++ b/public_html/api/index.php @@ -14,13 +14,18 @@ error_reporting(E_ALL); require_once("../../config/inc_projects_config.php"); - require_once(__DIR__.'/../deployment/classes/project.class.php'); + + $sDirClasses=__DIR__.'/../deployment/classes/'; + require_once($sDirClasses.'/project.class.php'); + + require_once($sDirClasses.'logger.class.php'); $aApiItems=array( 'project', 'projects', 'help', ); + $iMaxAge=60; // ---------------------------------------------------------------------- // FUNCTIONS @@ -66,6 +71,43 @@ die(); } + /** + * Check authorization in the http request header and age of timestamp + * On a failed check the request will be terminated + * @global int $iMaxAge max allowed age + * @param type $sProjectSecret + * @return boolean + */ + function _checkAuth($sProjectSecret){ + global $iMaxAge; + $aReqHeaders=apache_request_headers(); + _wd('<pre>'.print_r($aReqHeaders, 1).'</pre>'); + if(!isset($aReqHeaders['Authorization'])){ + _quit('Access denied. Missing authorization.', 403); + } + + $sGotHash= preg_replace('/^.*\:/', '', $aReqHeaders['Authorization']); + $sGotDate= $aReqHeaders['Date']; + $sGotMethod=$_SERVER['REQUEST_METHOD']; + $sGotReq=$_SERVER['REQUEST_URI']; + + + $sMyData="${sGotMethod}\n${sGotReq}\n${sGotDate}\n"; + $sMyHash= base64_encode(hash_hmac("sha1", $sMyData, $sProjectSecret)); + + _wd('Hash: '.$sGotHash.' -- from header'); + _wd('Hash: '.$sMyHash.' -- rebuilt'); + if($sGotHash!==$sMyHash){ + _quit('Access denied. Invalid hash.', 403); + } + + $iAge=date('U')-date('U', strtotime($sGotDate)); + _wd('Date: '.$sGotDate.' - age: '.$iAge.' sec'); + if($iAge>$iMaxAge){ + _quit('Access denied. Hash is out of date: '.$iAge. ' sec is older '.$iMaxAge.' sec', 403); + } + return true; + } // ---------------------------------------------------------------------- // MAIN // ---------------------------------------------------------------------- @@ -148,13 +190,27 @@ if(!$sProjectSecret){ _quit('Access denied. API access is disabled.'); } + + // check authorization + _checkAuth($sProjectSecret); - $aReqHeaders=apache_request_headers(); - _wd('<pre>'.print_r($aReqHeaders, 1).'</pre>'); - + echo "OK: request was authorized successfully.\n"; + switch($sPrjAction){ + case "build": + echo "build ..."; + + $oCLog = new logger(); + echo $oProject->build(); + break;; + default: + _quit('ERROR: Wrong action ['.$sApiItem.'].'); + } + break;; + default: - _quit('ERROR: Wrong item ['.$sApiItem.'].'); + // unreachable - see in_array before switch + _quit('ERROR: item ['.$sApiItem.'] is invalid.'); } break; default: diff --git a/shellscripts/api-client.sh b/shellscripts/api-client.sh index a4a6f433a16d57cef0c3bf33685239a90346c86e..4568b21aafe6282984a7379e5ce0c2493f06497e 100644 --- a/shellscripts/api-client.sh +++ b/shellscripts/api-client.sh @@ -22,32 +22,63 @@ apiHost="http://dev.ci.iml.unibe.ch:8002" apiBaseUrl="/api/v1" apiMethod=GET +line="----------------------------------------------------------------------" # ---------------------------------------------------------------------- -# MAIN +# REQ #1 - list project ids +# ---------------------------------------------------------------------- + +echo "[1] GET Request ${apiHost}${apiBaseUrl}/projects" +echo $line +curl -i \ + -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Date: ${apiTS}" \ + -H "Authorization: demo-bash-client:${myHash}" \ + -X $apiMethod \ + ${apiHost}${apiBaseUrl}/projects +echo +echo $line +echo +echo + +# ---------------------------------------------------------------------- +# REQ #2 - build ci webgui # ---------------------------------------------------------------------- # --- build url apiRequest="${apiBaseUrl}/project/${myProject}/${myAction}" -# --- generate auth -data="`date`\n${apiMethod}\n${apiRequest}" -myHash=`echo -n "$data" | openssl sha1 -hmac "${secret}" | cut -f 2 -d" "` +# --- date in http format +LANG=en_EN +# export TZ=GMT +apiTS=`date "+%a, %d %b %Y %H:%M:%S %Z"` +# --- generate data to hash: method + uri + timestamp; delimited with line break +data="${apiMethod} +${apiRequest} +${apiTS} +" -# https://stackoverflow.com/questions/356705/how-to-send-a-header-using-a-http-request-through-a-curl-call +# generate hash - split in 2 commands (piping "cut" sends additional line break) +myHash=`echo -n "$data" | openssl sha1 -hmac "${secret}" | cut -f 2 -d" "` +myHash=`echo -n "$myHash" | base64` -echo HASH: $myHash ... made from [$data] -echo REQEST: $apiRequest - $myHash +# --- send htp request +echo "[2] $apiMethod Request ${apiHost}${apiRequest}" +echo $line curl -i \ -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Date: ${apiTS}" \ -H "Authorization: demo-bash-client:${myHash}" \ -X $apiMethod \ ${apiHost}${apiRequest} rc=$? + +echo +echo $line echo rc = $rc