Warning: chmod(): Operation not permitted in /var/www/hopeinstoughton_www/wp-content/plugins/simple-universal-google-analytics/main.php on line 8 [0] in function chmod in /var/www/hopeinstoughton_www/wp-content/plugins/simple-universal-google-analytics/main.php on line 8 [1] in function include_once in /var/www/hopeinstoughton_www/wp-settings.php on line 560 [2] in function require_once in /var/www/hopeinstoughton_www/wp-config.php on line 85 [3] in function require_once in /var/www/hopeinstoughton_www/wp-load.php on line 50 [4] in function require_once in /var/www/hopeinstoughton_www/wp-blog-header.php on line 13 [5] in function require in /var/www/hopeinstoughton_www/index.php on line 17
| Server IP : 94.177.8.99 / Your IP : 216.73.217.165 Web Server : Apache/2.4.58 (Ubuntu) System : Linux aries 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64 User : www-data ( 33) PHP Version : 8.1.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/hopeinstoughton_vote/modules/update/model/ |
Upload File : |
<?php
// updates indexs are cached for an hour
class update_model extends Model {
public $CATALOGS;
public function __construct() {
parent::__construct();
$this->CATALOGS = [];
}
public function CustomFields($rep) {
$rep->pagesize(25);
$col = $rep->AddColumn();
$col->name('update')
->width(80)
->caption('Update?') // is an upadte Available?
->render([$this, '__field_update']);
}
public function __field_update($value, $item) {
$module = strtolower($item['module']);
$display = '-';
$value = 0;
foreach($this->CATALOGS as $key => $catalog) {
if (isset($catalog['index'][$module])) {
$current = $catalog['content'][$catalog['index'][$module]];
if (version_compare($current['ver'], $item['version']) > 0) {
$display = "<a href=\"/admin/update/{$module}\" class=\"json-request\">{$current['ver']}</a>";
} else {
$display = $current['ver']; // older or same version is in the repo.
}
$value = $current['ver'];
$elements = explode('.', $value . '.0.0.0');
$value = intval($elements[0], 10) * 100000
+ intval($elements[1], 10) * 1000
+ intval($elements[2], 10);
break;
}
}
return [
'disp' => $display,
'val' => $value
];
}
public function asDate() {
$last = 0;
foreach($this->CATALOGS as $catalog) {
$ct = $catalog['time'] ?? 0;
if ($ct > $last) $last = $ct;
}
return !$last ? '(never)' : gmdate('Y-m-d H:i', $last);
}
public function checkCatalog($repolist, $refresh = FALSE) {
$hosts = preg_split('~\s+~ims', trim($repolist));
foreach($hosts as $host) {
$this->checkUpdateCatalog($host, $refresh); // make sure the local copy of the catalog has not expired
}
}
public function checkUpdateCatalog($hostname, $refresh = FALSE) {
$key = md5(strtolower($hostname));
$filename = HOME . '/storage/' . $key . '.json';
if (file_exists($filename)) {
$data = json_decode(file_get_contents($filename), TRUE);
} else {
$data = [
'expiry' => 0,
'url' => $hostname,
'content' => [],
];
}
if ($data['expiry'] < time() || $refresh) {
$data = $this->_loadCatalog($hostname);
file_put_contents($filename, json_encode($data, JSON_UNESCAPED_SLASHES));
}
// create index
$indexlist = [];
foreach($data['content'] as $index => $item) {
$indexlist[strtolower(trim($item['name']))] = $index;
}
$data['index'] = $indexlist;
$this->CATALOGS[$key] = $data;
}
protected function _loadCatalog($hostname) {
// grab the file from host
$c = new CurlObject;
$body = $c->url($hostname . '/content')
->redirect(1)
->Execute()
->Body();
// set new expiry
return [
'time' => time(),
'expiry' => time() + 3600,
'url' => $hostname,
'content' => json_decode($body, TRUE),
];
// return structure
}
private function backupModule($modulename, $backupname) {
$safename = escapeshellarg($backupname);
`rm $safename`;
$zipname = '/usr/bin/zip';
$safedir = escapeshellarg(HOME . '/modules');
if (!file_exists($zipname)) {
return "Unable to locate $zipname";
}
$output = $return_code = '';
exec("(cd $safedir && $zipname -r $safename $modulename) 2>&1", $output, $return_code);
return !$return_code;
}
private function getRealName($modulename) {
$module = strtolower(trim($modulename));
foreach($this->CATALOGS as $key => $catalog) {
if (isset($catalog['index'][$module])) {
$current = $catalog['content'][$catalog['index'][$module]];
return [ $current['name'], $catalog['url'] . '/repository/' . $current['name'] . '@' . $current['ver'] . '.zip', $current ];
}
}
return [NULL, NULL, NULL];
}
public function performUpdate($module) {
// get real basename and filename
[ $modulename, $filename ] = $this->getRealName($module);
if (is_null($modulename) || $modulename == '' || $modulename == '.') {
return "Unrecognized module name: $module";
}
$dir = HOME . '/modules';
$backupname = $dir . '/' . $modulename . '@old.zip';
$ok = $this->backupModule($modulename, $backupname);
if (is_string($ok)) return $ok;
if (!$ok) {
return "Unable to create backup file {$backupname}. Please check directory ownership";
}
// download
return $this->downloadAndInstall($module);
}
protected function downloadAndInstall($module) {
[ $modulename, $filename ] = $this->getRealName($module);
if (is_null($modulename) || $modulename == '' || $modulename == '.') {
return "Unrecognized module name: $module";
}
$dir = HOME . '/modules';
// download
$c = new CurlObject;
$body = $c ->url($filename)
->Redirect(1)
->Execute()
->Body();
$status = $c->Status();
if (intval($status / 100) != 2) {
return "Unable to download module: $module [$status]";
}
$newfile = $dir . '/' . $modulename . '@new.zip';
// to do: make sure file exists
// to do: file integrity
file_put_contents($newfile, $body);
$safedir = escapeshellarg($dir);
`cd $safedir && mv $modulename .{$modulename}`;
$zipname = '/usr/bin/unzip';
$safename = escapeshellarg($newfile);
exec("(cd $safedir && $zipname $safename) 2>&1", $output, $return_code);
`rm $safename`;
`cd $safedir && rm -rf .{$modulename}`;
return TRUE;
}
public function performInstallation($modulename) {
$active_theme = hook_execute('html.theme', NULL); // load the default theme
if (method_exists($active_theme, 'themeCss')) { // get the theme css (for light or dark mode)
$css = '<style type="text/css">' . $active_theme->themeCss() . '</style>';
} else {
$css = '';
}
echo <<<BLOCK
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
$css
</head>
<body>
<pre>
Installing module "$modulename"
BLOCK;
flush();
$ok = $this->performInstall($modulename);
if ($ok) {
$GLOBALS['loader']->LoadModule($modulename, TRUE); // load only
$module_info = $GLOBALS['loader']->GetModuleInfo($modulename);
$info = $module_info['.info']; // __info()
// do we have a database section in the index file?
if (isset($info['database']) && count($info['database'])) {
echo "Performing database migration...\n";
$output = hook_execute('db.migrate', '', $this);
echo $output;
flush();
}
echo <<<BLOCK
Installation complete
<script type="application/javascript">
window.parent.postMessage('install.complete', '*');
</script>
BLOCK;
flush();
// send message to parent: delay 3s, close window
} else {
echo "Installation failed\n";
}
echo <<<BLOCK
</pre>
</body>
</html>
BLOCK;
// composer
}
public function performInstall($module) {
// generate error if module is missing
[ $modulename, $filename, $current ] = $this->getRealName($module);
if (is_null($modulename) || $modulename == '' || $modulename == '.') {
echo "Unrecognized module name: $module\n";
flush();
return FALSE;
}
// install modulename
$res = $this->downloadAndInstall($module);
if (is_string($res)) {
echo "$res\n";
flush();
return FALSE;
}
$modules = $GLOBALS['loader']->getModuleList();
// get all dependencies - performInstall() on missing+
foreach($current['depends'] as $dependency) {
if (!$this->isModulePresent($modules, $dependency)) {
echo "... Installing dependency \"$dependency\"\n";
flush();
$res = $this->downloadAndInstall($dependency);
if (is_string($res)) {
echo "$res\n";
flush();
return FALSE;
}
}
}
return TRUE;
}
protected function isModulePresent($modules, $modulename) {
if (isset($modules[$modulename])) {
$primary_file = HOME . '/modules/' . $modulename . '/index.php';
return file_exists($primary_file);
} else {
return FALSE;
}
}
public function DataTable_Installable() {
$modules = $GLOBALS['loader']->getModuleList(); // installed modules
$data = [];
foreach($this->CATALOGS as $hash => $hostinfo) {
foreach($hostinfo['content'] as $module) {
$module_abbr = $module['name'];
if (!$this->isModulePresent($modules, $module_abbr)) { // is the module loaded?
$data[] = [
'module' => [
'disp' => "<a class=\"json-request\" href=\"/admin/update/install/{$module_abbr}\">$module_abbr</a>",
'val' => $module_abbr,
],
'name' => $module['desc'],
'version' => $module['ver'],
];
}
}
};
$result = [
'columns' => [
['data' => 'module', 'width' => 120, 'render' => ['_' => 'disp', 'sort' => 'val']],
['data' => 'name', 'width' => 600],
['data' => 'version', 'width' => 120],
],
'order' => [ [ 0, 'asc'] ],
'pageLength' => 25,
'paginate' => TRUE,
'filter' => TRUE,
'info' => TRUE, // Showing x to y of z entries
'data' => $data,
];
return $result;
}
private function _getAvailableModule($modulename) {
foreach($this->CATALOGS as $hash => $hostinfo) {
foreach($hostinfo['content'] as $module) {
$module_abbr = $module['name'];
if ($module_abbr == $modulename) return $module;
}
}
return NULL;
}
public function listAvailableUpdates() {
$result = [ 'result' => 0, 'u' => [], 'dt' => 0 ];
// get list of modules
$modules = $GLOBALS['loader']->getModuleList();
// fetch list of modules needing updating
foreach($modules as $modulename => $module_info) {
$current_version = $module_info['.info']['version'];
$available = $this->_getAvailableModule($modulename);
if (!is_null($available)) {
$new_version = $available['ver'];
if (version_compare($current_version, $new_version) < 0) {
$result['u'][] = [ 'n' => $modulename, 'v' => $new_version ];
}
}
}
// last update time
foreach($this->CATALOGS as $hash => $hostinfo) {
if (!$result['dt'] || $hostinfo['time'] < $result['dt']) {
$result['dt'] = $hostinfo['time'];
}
}
// and php version
return $result;
}
private function decryptData($privkey, $data) {
$info = openssl_pkey_get_details($privkey);
$blocksize = intval($info['bits'] / 8);
$output = '';
foreach(str_split($data, $blocksize) as $chunk) {
$decrypted_data = '';
openssl_private_decrypt($chunk, $decrypted_data, $privkey, OPENSSL_PKCS1_PADDING);
if ($decrypted_data == '') return FALSE; // corrupted
$output .= $decrypted_data;
}
return $output;
}
public function Decrypt($payload) { // base64 encoded payload
$payload = base64_decode(str_pad(strtr($payload, '-_', '+/'), strlen($payload) % 4, '=', STR_PAD_RIGHT));
$settings = $this->SettingGet('config.module_info', NULL);
$priv_key = isset($settings['key']) ? $settings['key'] : '';
$priv_key = openssl_pkey_get_private($priv_key);
return $this->decryptData($priv_key, $payload);
}
// decrypt the payload - get userid
public function extractLogin($auth) {
$payload = $this->Decrypt($auth);
var_dump($payload);
}
}