2023-03-02 23:01:23 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
use GuzzleHttp\Client;
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
|
2023-03-02 23:29:39 +00:00
|
|
|
use App\Models\Site;
|
|
|
|
use App\Models\SiteVersion;
|
|
|
|
|
2023-03-02 23:01:23 +00:00
|
|
|
class VersionController extends Controller
|
|
|
|
{
|
2023-03-03 04:22:52 +00:00
|
|
|
private const CACHE_TIME = 86400; // Time to cache version
|
2023-03-02 23:05:55 +00:00
|
|
|
|
2023-03-03 04:22:52 +00:00
|
|
|
private const GL_PROJECT = 2; // Gitlab project number
|
|
|
|
private const GL_URL = 'https://dev.dege.au/api/v4'; // Gitlab URL
|
2023-03-02 23:05:55 +00:00
|
|
|
|
2023-03-03 04:22:52 +00:00
|
|
|
private const VERSION_REGEX = '/^v([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)-([a-z]{3})-([a-z0-9]{8})$/';
|
2023-03-02 23:05:55 +00:00
|
|
|
|
|
|
|
public function main(Request $request,string $version=NULL) {
|
|
|
|
// Our version is in the format of either:
|
|
|
|
// v1.2.3-xxx-abcdef01
|
|
|
|
Log::info(sprintf('Connection from [%s] reporting version [%s]',$this->getUserIpAddr(),$version));
|
|
|
|
|
|
|
|
$matches = [];
|
|
|
|
if (preg_match(self::VERSION_REGEX,$version,$matches)) {
|
2023-03-03 01:15:20 +00:00
|
|
|
$so = Site::firstOrCreate([
|
|
|
|
'ip_address'=>$this->getUserIpAddr()
|
|
|
|
]);
|
|
|
|
|
|
|
|
$vo = new SiteVersion;
|
|
|
|
$vo->version = $version;
|
|
|
|
$so->versions()->save($vo);
|
|
|
|
|
2023-03-02 23:05:55 +00:00
|
|
|
// If xxx is "dev" we are a development version
|
|
|
|
switch($matches[3]) {
|
|
|
|
case 'dev':
|
|
|
|
$current = Cache::remember('dev',self::CACHE_TIME,function() {
|
|
|
|
$client = new Client;
|
|
|
|
$url = sprintf('%s/projects/%d/repository/commits',self::GL_URL,self::GL_PROJECT);
|
|
|
|
|
|
|
|
$response = $client->request('GET',$url,['form_params'=>['ref_name'=>'BRANCH-2.0','order'=>'default']]);
|
|
|
|
|
|
|
|
if ($response->getStatusCode() === 200) {
|
|
|
|
$result = collect(json_decode($response->getBody()));
|
|
|
|
|
|
|
|
return $result->first();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
});
|
|
|
|
|
|
|
|
if ($current) {
|
|
|
|
$repository = sprintf('v%s-rel-%s',$matches[1],$current->short_id);
|
|
|
|
|
|
|
|
// Find the tag associated with version $matches[1] and see if it is more recent than $matches[4]
|
2023-03-03 04:22:52 +00:00
|
|
|
$response = ($matches[4] === $current->short_id)
|
|
|
|
? ['action'=>'current','version'=>$repository]
|
|
|
|
: ['action'=>'upgrade','version'=>sprintf('v%s-%s-%s',$matches[1],$matches[3],$current->short_id)];
|
2023-03-02 23:05:55 +00:00
|
|
|
|
|
|
|
} else
|
2023-03-03 04:31:18 +00:00
|
|
|
$response = ['action'=>'unable','version'=>'vn.n.n-dev-hhhhhhhh'];
|
2023-03-02 23:29:39 +00:00
|
|
|
|
|
|
|
break;
|
2023-03-02 23:05:55 +00:00
|
|
|
|
|
|
|
case 'rel':
|
|
|
|
$current = Cache::remember('dev',self::CACHE_TIME,function() {
|
|
|
|
$client = new Client;
|
|
|
|
$url = sprintf('%s/projects/%d/repository/tags',self::GL_URL,self::GL_PROJECT);
|
|
|
|
|
|
|
|
// Find the tag associated with version $matches[1] and see if there is a more recent version number
|
|
|
|
$response = $client->request('GET',$url,['form_params'=>['ref_name'=>'master','sort'=>'desc']]);
|
|
|
|
|
|
|
|
if ($response->getStatusCode() === 200) {
|
|
|
|
$result = collect(json_decode($response->getBody()));
|
|
|
|
|
|
|
|
return $result->first();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
});
|
|
|
|
|
|
|
|
if ($current) {
|
|
|
|
$repository = sprintf('v%s-rel-%s',$current->name,$current->commit->short_id);
|
|
|
|
|
|
|
|
// If $matches[1] is smaller, "upgrade available"
|
|
|
|
if ($matches[1] < $current->name)
|
2023-03-03 04:22:52 +00:00
|
|
|
$response = ['action'=>'upgrade','version'=>$repository];
|
2023-03-02 23:05:55 +00:00
|
|
|
|
|
|
|
// If $matches[1] is the same, validate that $matches[4] is current and the same and if not, error
|
|
|
|
elseif ($matches[1] === $current->name)
|
2023-03-03 04:22:52 +00:00
|
|
|
$response = ($matches[4] === $current->commit->short_id) ? ['action'=>'current','version'=>$repository] : ['action'=>'mismatch','version'=>$repository];
|
2023-03-02 23:05:55 +00:00
|
|
|
|
|
|
|
// if $matches[1] is higher, abort
|
|
|
|
else
|
2023-03-03 04:22:52 +00:00
|
|
|
$response = ['action'=>'unknown','version'=>$repository];
|
2023-03-02 23:05:55 +00:00
|
|
|
|
|
|
|
} else
|
2023-03-03 04:31:18 +00:00
|
|
|
$response = ['action'=>'unable','version'=>'vn.n.n-rel-hhhhhhhh'];
|
2023-03-02 23:29:39 +00:00
|
|
|
|
|
|
|
break;
|
2023-03-02 23:05:55 +00:00
|
|
|
}
|
2023-03-02 23:29:39 +00:00
|
|
|
|
|
|
|
$vo->response = $response;
|
|
|
|
$vo->save();
|
|
|
|
|
|
|
|
return $response;
|
2023-03-02 23:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the current version
|
2023-03-03 04:31:18 +00:00
|
|
|
return ['action'=>'invalid','version'=>'vn.n.n-xxxx-hhhhhhhh'];
|
2023-03-02 23:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getUserIpAddr(): string
|
|
|
|
{
|
|
|
|
if (isset($_SERVER['HTTP_CLIENT_IP']))
|
|
|
|
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
|
2023-03-02 23:29:39 +00:00
|
|
|
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
|
|
|
$ips = preg_split('/,\s*/',$_SERVER['HTTP_X_FORWARDED_FOR']);
|
|
|
|
$ipaddress = $ips[0];
|
|
|
|
}
|
2023-03-02 23:05:55 +00:00
|
|
|
else if(isset($_SERVER['HTTP_X_FORWARDED']))
|
|
|
|
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
|
|
|
|
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
|
|
|
|
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
|
|
|
|
else if(isset($_SERVER['HTTP_FORWARDED']))
|
|
|
|
$ipaddress = $_SERVER['HTTP_FORWARDED'];
|
|
|
|
else if(isset($_SERVER['REMOTE_ADDR']))
|
|
|
|
$ipaddress = $_SERVER['REMOTE_ADDR'];
|
|
|
|
else
|
|
|
|
$ipaddress = 'UNKNOWN';
|
|
|
|
|
|
|
|
return $ipaddress;
|
|
|
|
}
|
2023-03-02 23:01:23 +00:00
|
|
|
}
|