pla-version/app/Http/Controllers/VersionController.php

140 lines
4.3 KiB
PHP

<?php
namespace App\Http\Controllers;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\{Cache,Log};
use Illuminate\Support\Str;
use App\Models\Site;
use App\Models\SiteVersion;
class VersionController extends Controller
{
private const CACHE_TIME = 86400; // Time to cache version
private const GH_URL = 'https://api.github.com/repos'; // GitHub URL
private const GH_PROJECT = 'leenooks/phpldapadmin';
private const GH_TREE = 'master';
private const VERSION_REGEX = '/^v([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)-([a-z]{3})-([a-z0-9]{8})$/';
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)) {
$so = Site::firstOrCreate([
'ip_address'=>$this->getUserIpAddr()
]);
$vo = new SiteVersion;
$vo->version = $version;
$so->versions()->save($vo);
// 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/%s/commits/%s',self::GH_URL,self::GH_PROJECT,self::GH_TREE);
$response = $client->request('GET',$url,['form_params'=>['per_page'=>'1']]);
if ($response->getStatusCode() === 200) {
$result = collect(json_decode($response->getBody()));
return Str::limit($result->get('sha'),8,NULL);
}
return NULL;
});
if ($current) {
$repository = sprintf('v%s-rel-%s',$matches[1],$current);
// Find the tag associated with version $matches[1] and see if it is more recent than $matches[4]
$response = ($matches[4] === $current)
? ['action'=>'current','version'=>$repository]
: ['action'=>'upgrade','version'=>sprintf('v%s-%s-%s',$matches[1],$matches[3],$current)];
} else
$response = ['action'=>'unable','version'=>'vn.n.n-dev-hhhhhhhh'];
break;
case 'rel':
$current = Cache::remember('rel',self::CACHE_TIME,function() {
$client = new Client;
$url = sprintf('%s/%s/tags',self::GH_URL,self::GH_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) {
$sha = Str::limit($current->commit->sha,8,NULL);
$repository = sprintf('v%s-rel-%s',$current->name,$sha);
// If $matches[1] is smaller, "upgrade available"
if ($matches[1] < $current->name)
$response = ['action'=>'upgrade','version'=>$repository];
// If $matches[1] is the same, validate that $matches[4] is current and the same and if not, error
elseif ($matches[1] === $current->name)
$response = ($matches[4] === $sha) ? ['action'=>'current','version'=>$repository] : ['action'=>'mismatch','version'=>$repository];
// if $matches[1] is higher, abort
else
$response = ['action'=>'unknown','version'=>$repository];
} else
$response = ['action'=>'unable','version'=>'vn.n.n-rel-hhhhhhhh'];
break;
}
$vo->response = $response;
$vo->save();
return $response;
}
// Return the current version
return ['action'=>'invalid','version'=>'vn.n.n-xxxx-hhhhhhhh'];
}
public function getUserIpAddr(): string
{
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = preg_split('/,\s*/',$_SERVER['HTTP_X_FORWARDED_FOR']);
$ipaddress = $ips[0];
}
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;
}
}