Skip to content

Commit

Permalink
Merge pull request #1097 from ChurchCRM/self-update
Browse files Browse the repository at this point in the history
Self update
  • Loading branch information
crossan007 authored Oct 16, 2016
2 parents a4a64bc + 41d99c8 commit 84969cd
Show file tree
Hide file tree
Showing 13 changed files with 482 additions and 45 deletions.
68 changes: 35 additions & 33 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
#Vagrant
.vagrant/

# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/

## File-based project format:
*.ipr
*.iws

#Exclude composer vendor folders
vendor
composer.lock

# Uploaded Images
thumbnails

# SASS
.sass-cache

#skins
adminlte
font-awesome
ionicons

# Configuration files with passwords
src/Include/Config.php

target
/src/orm/model/ChurchCRM/Base/
/src/orm/model/ChurchCRM/Map/
#Vagrant
.vagrant/

# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/

## File-based project format:
*.ipr
*.iws

#Exclude composer vendor folders
vendor
composer.lock

# Uploaded Images
thumbnails

# SASS
.sass-cache

#skins
adminlte
font-awesome
ionicons

# Configuration files with passwords
src/Include/Config.php

target
/src/orm/model/ChurchCRM/Base/
/src/orm/model/ChurchCRM/Map/
/src/signatures.json
/src/integrityCheck.json
6 changes: 6 additions & 0 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<include name="**"/>
<exclude name="Images/Person/thumbnails/*.jpg"/>
<exclude name="composer.lock"/>
<exclude name="signatures.json"/>
<exclude name="Include/Config.php"/>
<exclude name="vendor/almasaeed2010/**"/>
<exclude name="vendor/components/**"/>
Expand All @@ -41,6 +42,11 @@
<exclude name="skin/adminlte/plugins/datatables/extensions/TableTools/images/psd/**"/>
</fileset>
</copy>

<echo message="Generating code signature file..."/>
<exec command = "php generateSignatures.php ${sourcedir}/churchcrm" passthru="true"/>



</target>

Expand Down
36 changes: 36 additions & 0 deletions generateSignatures.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$CRMRoot = $argv[1];
$CRMRootLen = strlen($CRMRoot);
$signatureFile = $CRMRoot."/signatures.json";
$composerFile = file_get_contents(__DIR__. "/src/composer.json");
$composerJson = json_decode($composerFile, true);

echo "Creating Signature Definition at: ".$signatureFile."\r\n";

$signatureData = new stdClass();
$signatureData->version = $composerJson["version"];
$signatureData->files = array();

$projectFiles = new RecursiveDirectoryIterator($CRMRoot);
$Iterator = new RecursiveIteratorIterator($projectFiles);
$Regex = new RegexIterator($Iterator, '/^.+\.(php|js)$/i', RecursiveRegexIterator::GET_MATCH);
foreach ($Regex as $obj )
{
$file = new stdClass();
$file->filename = substr($obj[0], $CRMRootLen+1);
$file->sha1 = sha1_file($CRMRoot."/".$file->filename);
array_push($signatureData->files, $file);
}

ksort($signatureData->files);

$signatureData->sha1 = sha1(json_encode($signatureData->files));
file_put_contents($signatureFile, json_encode($signatureData));

?>
4 changes: 4 additions & 0 deletions src/Include/HeaderNotLoggedIn.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@
<title>ChurchCRM: <?= gettext($sPageTitle) ?></title>
</head>
<body class="hold-transition login-page">

<script language="javascript" type="text/javascript">
window.CRM = {root: "<?= $sRootPath ?>"};
</script>

79 changes: 79 additions & 0 deletions src/IntegrityCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

//Include the function library
require 'Include/Config.php';
require 'Include/Functions.php';

//Set the page title
$sPageTitle = gettext('Integrity Check Results');
if (!$_SESSION['bAdmin'])
{
Redirect("index.php");
exit;
}
require 'Include/Header.php';
$integrityCheckFile = __DIR__ ."/integrityCheck.json";
$IntegrityCheckDetails = json_decode(file_get_contents($integrityCheckFile));

if ($IntegrityCheckDetails->status == "failure")
{
?>
<div class="callout callout-danger">
<h4><?= gettext("Integrity Check Failure") ?> </h4>
<p><?= gettext("The previous integrity check failed") ?></p>
<p><?= gettext("Details:")?> <?= $IntegrityCheckDetails->message ?></p>
<?php
if(count($IntegrityCheckDetails->files) > 0 )
{
?>
<p><?= gettext("Files failing integrity check:") ?>
<ul>
<?php
foreach ($IntegrityCheckDetails->files as $file)
{
?>
<li>FileName: <?= $file->filename ?>
<?php
if($file->status == "File Missing")
{
?>
<ul>
<li><?= gettext("File Missing")?></li>
</ul>
<?php
}
else
{
?>
<ul>
<li><?= gettext("Expected Hash:")?> <?= $file->expectedhash ?></li>
<li><?= gettext("Actual Hash:") ?> <?= $file->actualhash ?></li>
</ul>
<?php
}
?>
</li>
<?php
}
?>
</ul>
<?php
}
?>
</div>
<?php
}
else
{
?>
<div class="callout callout-success">
<h4><?= gettext("Integrity Check Passed") ?> </h4>
<p><?= gettext("The previous integrity check passed") ?></p>
</div>
<?php
}
?>

<?php
require 'Include/Footer.php';
?>
118 changes: 114 additions & 4 deletions src/Service/SystemService.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,24 +363,134 @@ function reportIssue($data)

function runTimerJobs()
{
global $sEnableExternalBackupTarget, $sExternalBackupAutoInterval, $sLastBackupTimeStamp;
global $sEnableIntegrityCheck, $sIntegrityCheckInterval, $sLastIntegrityCheckTimeStamp;
//start the external backup timer job
if ($sEnableExternalBackupTarget && $sExternalBackupAutoInterval > 0) //if remote backups are enabled, and the interval is greater than zero
{
try {
$now = new DateTime(); //get the current time
$previous = new DateTime($sLastBackupTimeStamp); // get a DateTime object for the last time a backup was done.
$now = new \DateTime(); //get the current time
$previous = new \DateTime($sLastBackupTimeStamp); // get a DateTime object for the last time a backup was done.
$diff = $previous->diff($now); // calculate the difference.
if (!$sLastBackupTimeStamp || $diff->h >= $sExternalBackupAutoInterval) // if there was no previous backup, or if the interval suggests we do a backup now.
{
$systemService->copyBackupToExternalStorage(); // Tell system service to do an external storage backup.
$now = new DateTime(); // update the LastBackupTimeStamp.
$now = new \DateTime(); // update the LastBackupTimeStamp.
$sSQL = "UPDATE config_cfg SET cfg_value='" . $now->format('Y-m-d H:i:s') . "' WHERE cfg_name='sLastBackupTimeStamp'";
$rsUpdate = RunQuery($sSQL);
}
} catch (Exception $exc) {
// an error in the auto-backup shouldn't prevent the page from loading...
}
}
if ($sEnableIntegrityCheck && $sIntegrityCheckInterval > 0)
{
$now = new \DateTime(); //get the current time
$previous = new \DateTime($sLastIntegrityCheckTimeStamp); // get a DateTime object for the last time a backup was done.
$diff = $previous->diff($now); // calculate the difference.
if (!$sLastIntegrityCheckTimeStamp || $diff->h >= $sIntegrityCheckInterval) // if there was no previous backup, or if the interval suggests we do a backup now.
{
$integrityCheckFile = dirname(__DIR__) . "/integrityCheck.json";
$appIntegrity = $this->verifyApplicationIntegrity();
file_put_contents($integrityCheckFile, json_encode($appIntegrity));
$now = new \DateTime(); // update the LastBackupTimeStamp.
$sSQL = "UPDATE config_cfg SET cfg_value='" . $now->format('Y-m-d H:i:s') . "' WHERE cfg_name='sLastIntegrityCheckTimeStamp'";
$rsUpdate = RunQuery($sSQL);
}
}
}

function downloadLatestRelease()
{
$release = $this->getLatestRelese();
$CRMInstallRoot = dirname(__DIR__);
$UpgradeDir = $CRMInstallRoot."/Upgrade";
$url = $release['assets'][0]['browser_download_url'];
mkdir($UpgradeDir);
file_put_contents($UpgradeDir."/".basename($url), file_get_contents($url));
$returnFile= array();
$returnFile['fileName'] = basename($url);
$returnFile['fullPath'] = $UpgradeDir."/".basename($url);
$returnFile['sha1'] = sha1_file($UpgradeDir."/".basename($url));
return $returnFile;
}

function moveDir($src,$dest) {
$files = array_diff(scandir($src), array('.', '..'));
foreach ($files as $file) {
if (is_dir("$src/$file")) {
mkdir("$dest/$file");
$this->moveDir("$src/$file","$dest/$file");
}
else
{
rename("$src/$file","$dest/$file");
}
}
return rmdir($src);
}

function doUpgrade($zipFilename,$sha1)
{
ini_set('max_execution_time',60);
$CRMInstallRoot = dirname(__DIR__);
if($sha1 == sha1_file($zipFilename))
{
$zip = new \ZipArchive();
if ($zip->open($zipFilename) == TRUE)
{
$zip->extractTo($CRMInstallRoot."/Upgrade");
$zip->close();
$this->moveDir($CRMInstallRoot."/Upgrade/churchcrm", $CRMInstallRoot);
}
unlink($zipFilename);
return "success";
}
else
{
return "hash validation failure";
}

}

function verifyApplicationIntegrity()
{
$CRMInstallRoot = dirname(__DIR__);
$signatureFile = $CRMInstallRoot."/signatures.json";
$signatureData = json_decode(file_get_contents($signatureFile));
$signatureFailures = array();

if (sha1(json_encode($signatureData->files)) == $signatureData->sha1)
{
foreach ($signatureData->files as $file)
{
if(file_exists($CRMInstallRoot."/".$file->filename))
{
$actualHash = sha1_file($CRMInstallRoot."/".$file->filename);
if ( $actualHash != $file->sha1 )
{
array_push($signatureFailures, array("filename"=>$file->filename,"status"=>"Hash Mismatch", "expectedhash"=>$file->sha1,"actualhash"=>$actualHash));
}
}
else
{
array_push($signatureFailures, array("filename"=>$file->filename,"status"=>"File Missing"));
}
}
}
else
{
return array("status"=>"failure","message"=>"Signature Definition file signature failed validation");
}

if(count($signatureFailures) > 0 )
{
return array("status"=>"failure","files"=>$signatureFailures);
}
else
{
return array("status"=>"success");
}

}

}
8 changes: 7 additions & 1 deletion src/Service/TaskService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public function __construct()

function getAdminTasks() {
requireUserGroupMembership("bAdmin");
$CRMInstallRoot = dirname(__DIR__);
$integrityCheckData = json_decode(file_get_contents($CRMInstallRoot."/integrityCheck.json"));
$sSQL = "SELECT cfg_name, IFNULL(cfg_value, cfg_default) AS value FROM config_cfg";
$rsConfig = mysql_query($sSQL); // Can't use RunQuery -- not defined yet
if ($rsConfig) {
Expand All @@ -42,7 +44,11 @@ function getAdminTasks() {
}

if ($this->latestVersion != null && $this->latestVersion["name"] != $this->installedVersion) {
array_push($tasks, $this->addTask("New Release ". $this->latestVersion["name"], $this->latestVersion["html_url"], true));
array_push($tasks, $this->addTask("New Release ". $this->latestVersion["name"], $this->baseURL."/UpgradeCRM.php", true));
}

if($integrityCheckData->status == "failure") {
array_push($tasks, $this->addTask("Application Integrity Check Failed", $this->baseURL."/IntegrityCheck.php", true));
}

return $tasks;
Expand Down
Loading

0 comments on commit 84969cd

Please sign in to comment.