Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
Imldeployment
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
IML Open Source
Imldeployment
Commits
eea7a809
Commit
eea7a809
authored
9 months ago
by
Hahn Axel (hahn)
Browse files
Options
Downloads
Patches
Plain Diff
update api/index.php
parent
652d9b45
No related branches found
No related tags found
1 merge request
!66
php8 only; added variable types; short array syntax; remove glyphicons
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
public_html/api/index.php
+256
-230
256 additions, 230 deletions
public_html/api/index.php
with
256 additions
and
230 deletions
public_html/api/index.php
+
256
−
230
View file @
eea7a809
...
...
@@ -11,245 +11,271 @@
* ----------------------------------------------------------------------
* 2020-06-16 v0.9 <axel.hahn@iml.unibe.ch>
* 2021-03-29 v1.2 <axel.hahn@iml.unibe.ch> support slashes in branch names
* 2024-09-02 v1.3 <axel.hahn@unibe.ch> php8 only; added variable types; short array syntax
* ======================================================================
*/
$bDebug
=
false
;
ini_set
(
'display_errors'
,
1
);
ini_set
(
'display_startup_errors'
,
1
);
error_reporting
(
E_ALL
);
require_once
(
"../../config/inc_projects_config.php"
);
$sDirClasses
=
__DIR__
.
'/../deployment/classes/'
;
require_once
(
$sDirClasses
.
'/project.class.php'
);
require_once
(
$sDirClasses
.
'logger.class.php'
);
$iMaxAge
=
60
;
// ----------------------------------------------------------------------
// FUNCTIONS
// ----------------------------------------------------------------------
/**
* write debug text (if enabled)
* @global boolean $bDebug
* @param string $s message
* @param string $sLevel level; one of info|
* @return boolean
*/
function
_wd
(
$s
,
$sLevel
=
'info'
){
global
$bDebug
;
if
(
$bDebug
){
echo
'<div class="debug debug-'
.
$sLevel
.
'">DEBUG: '
.
$s
.
'</div>'
;
}
return
true
;
$bDebug
=
false
;
ini_set
(
'display_errors'
,
1
);
ini_set
(
'display_startup_errors'
,
1
);
error_reporting
(
E_ALL
);
/**
* Path to deployment classes
* @var string
*/
$sDirClasses
=
__DIR__
.
'/../deployment/classes/'
;
/**
* Allowed time delta for client or server
* @var integer
*/
$iMaxAge
=
60
;
require_once
(
"../../config/inc_projects_config.php"
);
require_once
(
$sDirClasses
.
'/project.class.php'
);
require_once
(
$sDirClasses
.
'logger.class.php'
);
// ----------------------------------------------------------------------
// FUNCTIONS
// ----------------------------------------------------------------------
/**
* Write debug text (if enabled)
*
* @global boolean $bDebug
*
* @param string $s message
* @param string $sLevel level; one of info|
* @return boolean
*/
function
_wd
(
string
$s
,
string
$sLevel
=
'info'
):
bool
{
global
$bDebug
;
if
(
$bDebug
)
{
echo
"<div class=
\"
debug debug-
$sLevel
\"
>DEBUG:
$s
</div>"
;
}
/**
* abort execution with error
* @param string $s message
* @param integer $iStatus http status code to send
*/
function
_quit
(
$s
,
$iStatus
=
400
){
$aStatus
=
array
(
400
=>
'HTTP/1.0 400 Bad Request'
,
403
=>
'HTTP/1.0 403 Access denied'
,
404
=>
'HTTP/1.0 404 Not found'
,
);
header
(
$aStatus
[
$iStatus
]);
_done
(
array
(
'status'
=>
$iStatus
,
'info'
=>
$aStatus
[
$iStatus
],
'message'
=>
$s
));
return
true
;
}
/**
* Abort execution of API requestwith error
*
* @param string $s message
* @param integer $iStatus http status code to send
*/
function
_quit
(
string
$s
,
int
$iStatus
=
400
):
void
{
$aStatus
=
[
400
=>
'HTTP/1.0 400 Bad Request'
,
403
=>
'HTTP/1.0 403 Access denied'
,
404
=>
'HTTP/1.0 404 Not found'
,
];
header
(
$aStatus
[
$iStatus
]);
_done
([
'status'
=>
$iStatus
,
'info'
=>
$aStatus
[
$iStatus
],
'message'
=>
$s
]);
}
/**
* End with OK output
*
* @param array $Data array data to show as JSON
* @return void
*/
function
_done
(
array
$Data
):
void
{
echo
is_array
(
$Data
)
?
json_encode
(
$Data
,
JSON_PRETTY_PRINT
)
:
$Data
;
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 string $sProjectSecret
* @return boolean
*/
function
_checkAuth
(
string
$sProjectSecret
):
bool
{
global
$iMaxAge
;
$aReqHeaders
=
apache_request_headers
();
_wd
(
'<pre>'
.
print_r
(
$aReqHeaders
,
1
)
.
'</pre>'
);
if
(
!
isset
(
$aReqHeaders
[
'Authorization'
]))
{
_quit
(
'Access denied. Missing authorization.'
,
403
);
}
/**
* end with OK output
* @param type $Data
*/
function
_done
(
$Data
){
echo
is_array
(
$Data
)
?
json_encode
(
$Data
,
JSON_PRETTY_PRINT
)
:
$Data
;
die
();
if
(
!
isset
(
$aReqHeaders
[
'Date'
]))
{
_quit
(
'Access denied. Missing field "Date:" in the request header.'
,
403
);
}
/**
* 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 string $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
);
}
if
(
!
isset
(
$aReqHeaders
[
'Date'
])){
_quit
(
'Access denied. Missing field "Date:" in the request header.'
,
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. Maybe client or server is out of sync.'
,
403
);
}
if
(
$iAge
<-
$iMaxAge
){
_quit
(
'Access denied. Hash is '
.
$iAge
.
' sec in future but only '
.
$iMaxAge
.
' sec are allowed. Maybe client or server is out of sync.'
,
403
);
}
return
true
;
$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. Maybe client or server is out of sync.'
,
403
);
}
// ----------------------------------------------------------------------
// MAIN
// ----------------------------------------------------------------------
if
(
!
$bDebug
){
header
(
'Content-Type: application/json'
);
if
(
$iAge
<
-
$iMaxAge
)
{
_quit
(
'Access denied. Hash is '
.
$iAge
.
' sec in future but only '
.
$iMaxAge
.
' sec are allowed. Maybe client or server is out of sync.'
,
403
);
}
_wd
(
'Start: '
.
date
(
'Y-m-d H:i:s'
)
.
'<style>body{background:#eee; color:#456;}
return
true
;
}
// ----------------------------------------------------------------------
// MAIN
// ----------------------------------------------------------------------
if
(
!
$bDebug
)
{
header
(
'Content-Type: application/json'
);
}
_wd
(
'Start: '
.
date
(
'Y-m-d H:i:s'
)
.
'<style>body{background:#eee; color:#456;}
.debug{background:#ddd; margin-bottom: 2px;}
</style>'
);
_wd
(
'request uri is '
.
$_SERVER
[
"REQUEST_URI"
]);
_wd
(
'<pre>GET: '
.
print_r
(
$_GET
,
1
)
.
'</pre>'
);
// ---------- SPLIT URL
$aUriSplit
=
explode
(
'/'
,
preg_replace
(
'/\?.*$/'
,
''
,
$_SERVER
[
"REQUEST_URI"
]));
array_shift
(
$aUriSplit
);
array_shift
(
$aUriSplit
);
_wd
(
'<pre>$aUriSplit: '
.
print_r
(
$aUriSplit
,
1
)
.
'</pre>'
);
/*
/api/v1/projects/ci/build/...
$aUriSplit: Array
(
[0] => v1
[1] => projects
[2] => ci
[3] => build
)
*/
$sApiVersion
=
isset
(
$aUriSplit
[
0
])
?
$aUriSplit
[
0
]
:
false
;
$sApiItem
=
isset
(
$aUriSplit
[
1
])
?
$aUriSplit
[
1
]
:
false
;
if
(
!
$sApiVersion
){
_quit
(
'ERROR: no param for api version was found.'
);
}
if
(
!
$sApiItem
){
_quit
(
'ERROR: no param for item was found.'
);
}
switch
(
$sApiVersion
){
case
'v1'
:
switch
(
$sApiItem
){
case
'projects'
:
$oProject
=
new
project
();
$aList
=
$oProject
->
getProjects
();
_wd
(
'<pre>'
.
print_r
(
$aList
,
1
)
.
'</pre>'
);
_done
(
$aList
);
break
;;
case
'project'
:
// path /api/v1/project
$sPrjId
=
isset
(
$aUriSplit
[
2
])
?
$aUriSplit
[
2
]
:
false
;
$sPrjAction
=
isset
(
$aUriSplit
[
3
])
?
$aUriSplit
[
3
]
:
false
;
$sBranch
=
implode
(
'/'
,
array_slice
(
$aUriSplit
,
4
));
// $sParam4 = isset($aUriSplit[4]) ? $aUriSplit[4] : false;
// $sParam5 = isset($aUriSplit[5]) ? $aUriSplit[5] : false;
$sMethod
=
$_SERVER
[
'REQUEST_METHOD'
];
_wd
(
'$sPrjId = '
.
$sPrjId
);
_wd
(
'$sPrjAction = '
.
$sPrjAction
);
_wd
(
'$sBranch = '
.
$sBranch
);
$oCLog
=
new
logger
();
// try to init the given project
try
{
ob_start
();
$oProject
=
new
project
(
$sPrjId
);
// $oProject->setProjectById($sPrjId);
ob_end_clean
();
}
catch
(
Exception
$exc
)
{
_quit
(
'ERROR: project with id ['
.
$sPrjId
.
'] does not exist.'
,
404
);
}
// get secret
$aPrjCfg
=
$oProject
->
getConfig
();
$sProjectSecret
=
isset
(
$aPrjCfg
[
'api'
][
'secret'
])
?
$aPrjCfg
[
'api'
][
'secret'
]
:
false
;
if
(
!
$sProjectSecret
){
_quit
(
'Access denied. API access is disabled.'
);
}
// check authorization
_checkAuth
(
$sProjectSecret
);
// echo "OK: request was authorized successfully.\n";
$oProject
->
oUser
->
setUser
(
'api'
);
switch
(
$sPrjAction
){
case
"build"
:
if
(
$sBranch
){
$aResult
=
$oProject
->
setBranchname
(
$sBranch
);
}
$sBranchname
=
$oProject
->
getBranchname
();
$aRepodata
=
$oProject
->
getRemoteBranches
(
true
);
// ignore cache = true
if
(
!
isset
(
$aRepodata
[
$sBranchname
])){
_quit
(
'ERROR: branch not found: '
.
$sBranchname
,
404
);
}
// echo "branch is set to ".$oProject->getBranchname()."\n";
if
(
$sMethod
===
'GET'
){
$sNext
=
$oProject
->
getNextPhase
();
_done
(
array
(
'branch'
=>
$sBranchname
,
'phase'
=>
$sNext
,
'repo'
=>
$aRepodata
[
$sBranchname
]
));
}
if
(
$sMethod
===
'POST'
){
echo
"starting build() ..."
;
flush
();
echo
$oProject
->
build
();
}
break
;;
case
"phases"
:
_done
(
$oProject
->
getAllPhaseInfos
());
break
;;
default
:
_quit
(
'ERROR: Wrong action ['
.
$sApiItem
.
'].'
);
}
break
;;
default
:
_quit
(
'ERROR: item ['
.
$sApiItem
.
'] is invalid.'
);
}
break
;
default
:
_quit
(
'ERROR: Wrong (unsupported) api version.'
);
}
\ No newline at end of file
_wd
(
'request uri is '
.
$_SERVER
[
"REQUEST_URI"
]);
_wd
(
'<pre>GET: '
.
print_r
(
$_GET
,
1
)
.
'</pre>'
);
// ---------- SPLIT URL
$aUriSplit
=
explode
(
'/'
,
preg_replace
(
'/\?.*$/'
,
''
,
$_SERVER
[
"REQUEST_URI"
]));
array_shift
(
$aUriSplit
);
array_shift
(
$aUriSplit
);
_wd
(
'<pre>$aUriSplit: '
.
print_r
(
$aUriSplit
,
1
)
.
'</pre>'
);
/*
/api/v1/projects/ci/build/...
$aUriSplit: Array
(
[0] => v1
[1] => projects
[2] => ci
[3] => build
)
*/
$sApiVersion
=
isset
(
$aUriSplit
[
0
])
?
$aUriSplit
[
0
]
:
false
;
$sApiItem
=
isset
(
$aUriSplit
[
1
])
?
$aUriSplit
[
1
]
:
false
;
if
(
!
$sApiVersion
)
{
_quit
(
'ERROR: no param for api version was found.'
);
}
if
(
!
$sApiItem
)
{
_quit
(
'ERROR: no param for item was found.'
);
}
switch
(
$sApiVersion
)
{
case
'v1'
:
switch
(
$sApiItem
)
{
case
'projects'
:
$oProject
=
new
project
();
$aList
=
$oProject
->
getProjects
();
_wd
(
'<pre>'
.
print_r
(
$aList
,
1
)
.
'</pre>'
);
_done
(
$aList
);
break
;
;
case
'project'
:
// path /api/v1/project
$sPrjId
=
isset
(
$aUriSplit
[
2
])
?
$aUriSplit
[
2
]
:
false
;
$sPrjAction
=
isset
(
$aUriSplit
[
3
])
?
$aUriSplit
[
3
]
:
false
;
$sBranch
=
implode
(
'/'
,
array_slice
(
$aUriSplit
,
4
));
// $sParam4 = isset($aUriSplit[4]) ? $aUriSplit[4] : false;
// $sParam5 = isset($aUriSplit[5]) ? $aUriSplit[5] : false;
$sMethod
=
$_SERVER
[
'REQUEST_METHOD'
];
_wd
(
'$sPrjId = '
.
$sPrjId
);
_wd
(
'$sPrjAction = '
.
$sPrjAction
);
_wd
(
'$sBranch = '
.
$sBranch
);
$oCLog
=
new
logger
();
// try to init the given project
try
{
ob_start
();
$oProject
=
new
project
(
$sPrjId
);
// $oProject->setProjectById($sPrjId);
ob_end_clean
();
}
catch
(
Exception
$exc
)
{
_quit
(
'ERROR: project with id ['
.
$sPrjId
.
'] does not exist.'
,
404
);
}
// get secret
$aPrjCfg
=
$oProject
->
getConfig
();
$sProjectSecret
=
isset
(
$aPrjCfg
[
'api'
][
'secret'
])
?
$aPrjCfg
[
'api'
][
'secret'
]
:
false
;
if
(
!
$sProjectSecret
)
{
_quit
(
'Access denied. API access is disabled.'
);
}
// check authorization
_checkAuth
(
$sProjectSecret
);
// echo "OK: request was authorized successfully.\n";
$oProject
->
oUser
->
setUser
(
'api'
);
switch
(
$sPrjAction
)
{
case
"build"
:
if
(
$sBranch
)
{
$aResult
=
$oProject
->
setBranchname
(
$sBranch
);
}
$sBranchname
=
$oProject
->
getBranchname
();
$aRepodata
=
$oProject
->
getRemoteBranches
(
true
);
// ignore cache = true
if
(
!
isset
(
$aRepodata
[
$sBranchname
]))
{
_quit
(
'ERROR: branch not found: '
.
$sBranchname
,
404
);
}
// echo "branch is set to ".$oProject->getBranchname()."\n";
if
(
$sMethod
===
'GET'
)
{
$sNext
=
$oProject
->
getNextPhase
();
_done
([
'branch'
=>
$sBranchname
,
'phase'
=>
$sNext
,
'repo'
=>
$aRepodata
[
$sBranchname
]
]);
}
if
(
$sMethod
===
'POST'
)
{
echo
"starting build() ..."
;
flush
();
echo
$oProject
->
build
();
}
break
;
;
case
"phases"
:
_done
(
$oProject
->
getAllPhaseInfos
());
break
;
;
default
:
_quit
(
'ERROR: Wrong action ['
.
$sApiItem
.
'].'
);
}
break
;
;
default
:
_quit
(
'ERROR: item ['
.
$sApiItem
.
'] is invalid.'
);
}
break
;
default
:
_quit
(
'ERROR: Wrong (unsupported) api version.'
);
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment