change nginx.conf

This commit is contained in:
F4ilji
2026-01-22 13:38:34 +05:00
parent 8104d0b6cd
commit c4be035890
47 changed files with 8872 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
body{background:url(../img/background_login.png) no-repeat 50% fixed;background-size:cover;color:#1b1b1b;font-family:Inter,Segoe UI,sans-serif;margin:0;min-height:100vh}.wrapper{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:hsla(0,0%,100%,.9);border-radius:14px;box-shadow:0 10px 35px rgba(0,0,0,.25);margin:2rem auto;max-width:1100px;padding:2.5rem 3rem;transition:all .3s ease}.wrapper:hover{box-shadow:0 12px 40px rgba(0,0,0,.35)}.header-content{align-items:center;display:flex;padding:10px 0;position:relative}.header-logo{height:auto;width:150px}.header-title{color:#1a1f71;font-size:30px;font-weight:700;text-align:center;width:100%}.vikon-logo{background-image:url(../img/vikon_logo.png);background-position:50%;background-repeat:no-repeat;background-size:contain;display:inline-block;height:50px;text-indent:-9999px;width:150px}@media (max-width:992px){.header-logo{display:none}.header-title{font-size:24px;text-align:center}}.btn-success{border-radius:8px;font-weight:500;letter-spacing:.3px;padding:.65rem 1.2rem;transition:all .2s ease}.btn-success:hover{background-color:#248f55;transform:translateY(-1px)}#modules-container{margin-top:1.5rem}#modules-container>ul{list-style:none;margin-bottom:1.5rem;padding-left:0}#modules-container>ul>li:first-child b{border-left:6px solid coral;color:#1a1f71;display:block;font-size:1.2rem;margin-bottom:.6rem;padding-left:12px}.checkbox{align-items:center;background:hsla(0,0%,100%,.65);border-radius:6px;box-shadow:0 1px 2px rgba(0,0,0,.05);display:flex;gap:10px;margin:4px 0;padding:6px 10px;transition:all .2s ease}.checkbox:hover{background:rgba(230,245,233,.9);transform:translateY(-1px)}.checkbox input[type=checkbox]{accent-color:#2e8048;cursor:pointer;transform:scale(1.1)}.checkbox label{color:#333;cursor:pointer;flex-grow:1;font-size:14px;line-height:1.3}.checkbox label .text-danger{font-size:.85em;margin-right:4px}.badge{border-radius:8px;font-size:.95rem;padding:.45em .75em}.footer{color:#555;font-size:13px;padding:1.5rem 0;text-align:center}#progressbar-container{margin-bottom:.75rem;margin-top:1rem}#progressbar-container .progress{border-radius:6px;height:1.3rem;overflow:hidden}#progressbar-container .progress-bar{font-size:.85rem;font-weight:500;transition:width .3s ease-in-out}.process-container{background:hsla(0,0%,100%,.85);border-radius:6px;font-size:.9rem;line-height:1.4;margin-top:.75rem;max-height:400px;overflow-y:auto;padding:.75rem 1rem}.process-container p{margin:.3rem 0}@keyframes rotate{to{transform:rotate(1turn)}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}.static-throbber{animation:rotate 2s linear infinite}.static-throbber .path{stroke-dasharray:1,150;stroke-dashoffset:0;stroke-linecap:round;animation:dash 1.5s ease-in-out infinite}
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
<?php
return array(
'no_use_template_for_routes' => array(
'/abitur/profile/index.html' => '/abitur/profile/index.html',
'/vsoko/survey/index.html' => '/vsoko/survey/index.html',
)
);
+86
View File
@@ -0,0 +1,86 @@
<?php
$selfDir = dirname(__FILE__);
ini_set('max_execution_time', '60');
ini_set('default_socket_timeout', '60');
$locationOfVikonModules = '/'; //todo new_core_after del
$domenName = 'www.ntspi.ru';
$apiDomen = 'https://db-nica.ru/';
$vikonDomainResolveBypass = 'db-nica.ru:443:62.76.112.192';
$fmDomainResolveBypass = 'file.db-nica.ru:443:62.76.112.192';
$apiDomainAuth = 'https://auth.db-nica.ru/';
$filemanagerApiDomen = 'https://file.db-nica.ru/';
$clientId = '542';
$clientSecret = '0mmk80mv8zpk7h5uhjvjsmsskvpkn9nmkywgy83vwg7tpzdw0y7rao0k9pvmn8xxwj5mgw8554nhtq6s';
$vuzId = '16775';
$vuzName = 'Нижнетагильский государственный социально-педагогический институт (филиал) "Российского государственного профессионально-педагогического университета"';
$modulesByPathDeploy = array (
2 => 'abitur',
1 => 'sveden',
6 => 'vsoko',
);
$allowedFoldersInCoreByModule = array (
2 =>
array (
0 => 'abitur',
),
1 =>
array (
0 => 'assets',
1 => 'files_zaglushka',
2 => 'common',
3 => 'struct',
4 => 'document',
5 => 'education',
6 => 'managers',
7 => 'employees',
8 => 'objects',
9 => 'paid_edu',
10 => 'budget',
11 => 'vacant',
12 => 'grants',
13 => 'inter',
14 => 'catering',
15 => 'eduStandarts',
16 => 'corruption',
17 => 'antiterrorism',
18 => 'files',
19 => 'update',
20 => 'index.html',
21 => '.vikon',
22 => '.htaccess',
),
6 =>
array (
0 => 'assets',
1 => 'general',
2 => 'structure',
4 => 'faq',
5 => 'procedures',
6 => 'results-and-reports',
7 => 'plans',
8 => 'survey',
9 => 'files',
10 => '.vikon',
11 => 'index.html',
12 => '.htaccess',
),
);
define('DEBUG_MODE', isset($_GET['debug_mode']) && $_GET['debug_mode'] || isset($_POST['debug_mode']) && $_POST['debug_mode']);
define('IS_DOMAIN_RESOLVE', isset($_COOKIE['is_resolve_domain']) ? (int) $_COOKIE['is_resolve_domain'] : 0);
define('FM_DOMAIN_RESOLVE_BYPASS', $fmDomainResolveBypass);
define('VIKON_DOMAIN_RESOLVE_BYPASS', $vikonDomainResolveBypass);
define('SVEDEN', 1);
define('ABITUR', 2);
define('VSOKO', 6);
if (DEBUG_MODE === true) {
error_reporting(E_ALL);
ini_set('display_errors','on');
} else {
error_reporting(0);
}
+353
View File
@@ -0,0 +1,353 @@
<?php
require_once 'path.php';
class Filesystem
{
public static function getExtension($path)
{
if ($path === '') {
return '';
}
$extension = pathinfo($path, PATHINFO_EXTENSION);
return strtolower($extension);
}
/**
* Выполняет безопасный scandir, убирает системные точки
*
* @param $path
* @return array|false - возращает entries внутри сканируемой папки или false, в случае отсутсвия прав (или других причин)
*/
public static function safeScandir($path)
{
if (!is_dir($path) || !is_readable($path)) {
return false;
}
$entries = scandir($path);
if ($entries === false) {
return false;
}
return array_diff($entries, Path::getSystemDots($path));
}
public static function removeZip($path, $withCheckRights)
{
if (!Path::isActionAllowedThisPath($path)) {
return false;
}
if (empty($path) || !file_exists($path)) {
return true;
}
if ($withCheckRights) {
$checks = array(
'is_file' => is_file($path),
'is_zip' => self::getExtension($path) === 'zip',
'is_writable' => is_writable($path)
);
foreach ($checks as $check) {
if (!$check) {
return false;
}
}
}
return unlink($path);
}
/**
* @param string $path
* @param bool $withRecursive
* @param int|null $moduleId - Важный параметр который дает понимание в рамках какой папки мы работаем
* Если null - работаем в рамках vikon_core, переданный moduleId - даст путь к модулю
* @return bool
*/
public static function remove($path, $withRecursive, $moduleId = null)
{
if (!Path::isActionAllowedThisPath($path, $moduleId)) {
return false;
}
if (!file_exists($path)) {
return true;
}
if (!is_dir($path)) {
return unlink($path);
}
if (!$withRecursive) {
return rmdir($path);
}
$success = true;
$entries = self::safeScandir($path);
foreach ($entries as $entry) {
$fullPath = Path::join($path, $entry);
if (is_dir($fullPath) && !is_link($fullPath)) {
if (!self::remove($fullPath, $withRecursive, $moduleId)) {
$success = false;
}
} else {
if (!unlink($fullPath)) {
$success = false;
}
}
}
if ($success) {
if (!rmdir($path)) {
$success = false;
}
}
return $success;
}
/**
* Переносит и переименовывает папку и все содержимое рекурсивно
* Перед использованием выполни Filesysyem::remove($targetDir)
*
* В случае с replaceWithRename перемещать мы можем в рамках vikon_core и в рамках модуля
*/
public static function replaceWithRename($sourceDir, $targetDir, $moduleId = null)
{
if ($moduleId === null) {
if (!Path::isBasePath(Path::getCoreRootPath(), $sourceDir)) {
return false;
}
if (!Path::isBasePath(Path::getCoreRootPath(), $targetDir)) {
return false;
}
} else {
if (
!Path::isBasePath(Path::getModuleRootPath($moduleId), $sourceDir)
&& !Path::isBasePath(Path::getCoreRootPath(), $sourceDir)
) {
return false;
}
if (
!Path::isBasePath(Path::getModuleRootPath($moduleId), $targetDir)
&& !Path::isBasePath(Path::getCoreRootPath(), $targetDir)
) {
return false;
}
}
if (!file_exists($sourceDir)) {
return false;
}
if (file_exists($targetDir)) {
return false;
}
$parentDir = dirname($targetDir);
if (!is_writable($parentDir)) {
return false;
}
if (!mkdir($targetDir, 0755, true)) {
return false;
}
$entries = self::safeScandir($sourceDir);
if (empty($entries)) {
return rmdir($sourceDir);
}
foreach ($entries as $entry) {
$item = Path::join($sourceDir, $entry);
$newPath = Path::join($targetDir, $entry);
if (is_dir($item)) {
if (!self::replaceWithRename($item, $newPath, $moduleId)) {
return false;
}
} else {
if (!rename($item, $newPath)) {
return false;
}
}
}
return rmdir($sourceDir);
}
public static function safeRenameFile($oldPath, $newPath, $moduleId = null)
{
if ($moduleId === null) {
if (!Path::isBasePath(Path::getCoreRootPath(), $oldPath)) {
return false;
}
if (!Path::isBasePath(Path::getCoreRootPath(), $newPath)) {
return false;
}
} else {
if (
!Path::isBasePath(Path::getModuleRootPath($moduleId), $oldPath)
&& !Path::isBasePath(Path::getCoreRootPath(), $oldPath)
) {
return false;
}
if (
!Path::isBasePath(Path::getModuleRootPath($moduleId), $newPath)
&& !Path::isBasePath(Path::getCoreRootPath(), $newPath)
) {
return false;
}
}
if (!file_exists($oldPath)) {
return false;
}
if (file_exists($newPath)) {
return false;
}
$newDir = dirname($newPath);
if (!file_exists($newDir)) {
return false;
}
if (!is_writable($newDir)) {
return false;
}
if (!is_writable($oldPath)) {
return false;
}
$result = rename($oldPath, $newPath);
if (!$result) {
return false;
}
return true;
}
/**
* @param string $restorePath - путь к ядру модуля которое мы будем восстанавливать
* @param array $allowedRestoreFolders - разрешенные к восстановлению папки,
* т.е папки которые прилетели из архива, будем работать только с ними
* @return bool
*/
public static function restoreUnitCoreAfterFail($restorePath, $allowedRestoreFolders, $moduleId = null)
{
if (!Path::isActionAllowedThisPath($restorePath, $moduleId)) {
return false;
}
if (!file_exists($restorePath)) {
return false;
}
$restoreEntries = self::safeScandir($restorePath);
if ($restoreEntries === false) {
return false;
}
foreach ($restoreEntries as $restoreEntry) {
$fullPathRestore = Path::join($restorePath, $restoreEntry);
$baseName = substr($restoreEntry, 0, -4);
if (
file_exists($fullPathRestore)
&& substr($restoreEntry, -4) === Path::$n_pstfx
&& in_array($baseName, $allowedRestoreFolders)
) {
self::remove($fullPathRestore, true, $moduleId);
}
if (
file_exists($fullPathRestore)
&& substr($restoreEntry, -4) === Path::$o_pstfx
&& in_array($baseName, $allowedRestoreFolders)
) {
$newPath = Path::join($restorePath, $baseName);
if (file_exists($newPath)) {
self::remove($newPath, true, $moduleId);
}
self::replaceWithRename($fullPathRestore, $newPath, $moduleId);
}
}
return true;
}
/**
* @param $pathClean - Путь к ядру модуля или главному ядру, чтобы почистить его
* @param $excludedEntries - папки и файлы которые не нужно чистить в ядре
* @param int|null $moduleId - модуль id или false - когда проверяем ядро
* @return bool|string
*/
public static function cleanUnitCore($pathClean, $excludedEntries, $moduleId = null)
{
if (!Path::isActionAllowedThisPath($pathClean, $moduleId)) {
return false;
}
$entries = self::safeScandir($pathClean);
foreach ($entries as $entry) {
$item = Path::join($pathClean, $entry);
if (in_array($entry, $excludedEntries)) {
continue;
}
if (is_dir($item) && !is_link($item)) {
if (!self::remove($item, true, $moduleId)) {
return $item;
}
} else {
if (!unlink($item)) {
return $item;
}
}
}
return true;
}
public static function safeMkdir($path, $mode, $moduleId = null)
{
if (!Path::isActionAllowedThisPath($path, $moduleId)) {
return false;
}
if (file_exists($path)) {
return true;
}
$parentDir = dirname($path);
if (!is_dir($parentDir)) {
return false;
}
if (!is_writable($parentDir)) {
return false;
}
return mkdir($path, $mode);
}
public static function safeMkfile($filename, $mode, $content = '')
{
if (file_exists($filename)) {
return true;
}
$directory = dirname($filename);
if (!is_writable($directory)) {
return false;
}
if (file_put_contents($filename, $content) === false) {
return false;
}
if (!chmod($filename, $mode)) {
return false;
}
return true;
}
public static function ensureValidDirectoryAndFileName($directory, $filename)
{
if ($directory !== null && (!is_string($directory) || !preg_match("/^[a-z]{3,4}$/", $directory))) {
return false;
}
if (!is_string($filename) || strpos($filename, '/') !== false || strpos($filename, "\\") !== false) {
return false;
}
return true;
}
}
+238
View File
@@ -0,0 +1,238 @@
<?php
function loadHeaders()
{
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
}
function sendErrorResponse($code, $message)
{
$resultBody = array(
'success' => false,
'forward_code' => $code,
'message' => $message,
);
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
die();
}
function sendSuccessResponse($message)
{
$resultBody = array(
'success' => true,
'forward_code' => 200,
'message' => $message,
);
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
die();
}
// unpackZip плохо проверяет может ли он распаковать в этой папке
// перед использованием сделай Filesystem::remove($pathToUnpack) - чтобы убедиться что проблем не будет
function unpackZip($fileName, $pathToUnpack)
{
$res = array();
$res['success'] = false;
$res['message'] = '';
if($pathToUnpack) {
if (extension_loaded('zip')) {
$zip = new ZipArchive;
if ($isOpenedZip = $zip->open($fileName)) {
$zip->extractTo($pathToUnpack);
$zip->close();
$res['success'] = true;
} else {
$res['message'] = 'Ошибка при распоковке файлов библиотеки ZIP:' . $isOpenedZip;
}
} else {
require_once dirname(__FILE__) . '/../update/zip_helper.php';
$archive = new PclZip($fileName);
$unZipResult = $archive->extract(PCLZIP_OPT_PATH, $pathToUnpack,
PCLZIP_CB_PRE_EXTRACT, 'preExtractCallback', PCLZIP_OPT_REPLACE_NEWER);
if ($unZipResult == 0) {
$res['message'] = 'Ошибка при распоковке файлов:' . $archive->errorInfo(true);
} else {
$res['success'] = true;
}
$archive->privCloseFd();
}
}
return $res;
}
function filterAccessToken($token)
{
return filter_var($token, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^[a-z0-9_\-\.]+$/i')));
}
function filterFileName($file)
{
return filter_var($file, FILTER_VALIDATE_REGEXP,
array('options' => array('regexp' => '/^[a-z0-9\+\.\,\(\)\;\#\№\-\_\«\»\!\%\=\$\@\'\&\]+$/i'))
);
}
function filterPath($file)
{
return filter_var($file, FILTER_VALIDATE_REGEXP,
array('options' => array('regexp' => '/^[a-z0-9\.\-\_\\/]+$/i'))
);
}
function filterEntry($entry)
{
return filter_var($entry, FILTER_VALIDATE_REGEXP,
array('options' => array('regexp' => '/^\/(?:[a-zA-Zа-яА-Я0-9_\-\.]+(?:\/)?)+$/'))
);
}
function filterInt($number)
{
return filter_var($number, FILTER_VALIDATE_INT);
}
function filterUrl($url)
{
return filter_var($url, FILTER_VALIDATE_URL);
}
function filterVersion($version)
{
return filter_var($version, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^[0-9\.]+$/')));
}
function filterPartName($part)
{
return filter_var($part, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^[a-z_\-]+$/i')));
}
function filterLogin($str)
{
return filter_var($str, FILTER_VALIDATE_EMAIL);
}
function filterPassword($str)
{
return filter_var($str, FILTER_SANITIZE_STRING);
}
function setResponseCode($code, $reason = null) {
$code = intval($code);
if (version_compare(phpversion(), '5.4', '>') && is_null($reason)) {
http_response_code($code);
} else {
header(trim("HTTP/1.0 $code $reason"));
}
}
function preExtractCallback($preEvent, &$preHeader)
{
if (!is_dir($preHeader['filename'])) {
if (strpos($preHeader['filename'], '.htaccess')) {
return 0;
}
if (file_exists($preHeader['filename'])) {
unlink($preHeader['filename']);
}
}
return 1;
}
class RemoteResult
{
public $curlHasError = true;
public $curlErrorTxt = '';
public $code = 0;
public $responseBody = '';
}
function remoteRequest($url, $responseAsJson = true, $postFields = false, $headers = array())
{
$result = new RemoteResult();
$ch = curl_init();
if (IS_DOMAIN_RESOLVE === 1) {
curl_setopt($ch, CURLOPT_RESOLVE, array(
VIKON_DOMAIN_RESOLVE_BYPASS,
FM_DOMAIN_RESOLVE_BYPASS,
));
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
if (is_array($postFields)) {
curl_setopt($ch, CURLOPT_POST, true);
$postVars = "";
foreach ($postFields as $key => $value) {
$postVars .= $key . '=' . $value . '&';
}
$postVars = rtrim($postVars, '&');
curl_setopt($ch, CURLOPT_POSTFIELDS, $postVars);
}
if ($headers !== array()) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$output = curl_exec($ch);
if (curl_errno($ch) > 0 || curl_error($ch)) {
$result->curlErrorTxt .= ';' . '#:' . curl_errno($ch) . 'Error:' . curl_error($ch);
} else{
$result->curlHasError = false;
$curlInfo = curl_getinfo($ch);
$result->code = (int) $curlInfo['http_code'];
$result->responseBody = ($responseAsJson) ? json_decode($output) : $output;
}
curl_close($ch);
return $result;
}
function tryExtractFmErrorMessage($remoteResultFmWhereBodyIsJson, $prefix = '')
{
$out = '';
if (property_exists($remoteResultFmWhereBodyIsJson->responseBody, 'error')) {
$out = $out . $remoteResultFmWhereBodyIsJson->responseBody->error;
}
if (
property_exists($remoteResultFmWhereBodyIsJson->responseBody, 'messages')
&& is_array($remoteResultFmWhereBodyIsJson->responseBody->messages)
) {
$message = version_compare(phpversion(), '8.0', '>=')
? implode('; ', $remoteResultFmWhereBodyIsJson->responseBody->messages)
: implode($remoteResultFmWhereBodyIsJson->responseBody->messages, '; ');
$out = $out . $message;
}
if ($out) {
$out = $prefix . 'Файловый сервер: ' . $out;
}
return $out;
}
function moduleDirIsEmptyOrEx($moduleRootPath, $flagFileOfModulePath)
{
if (is_dir($moduleRootPath)) {
if (count(Filesystem::safeScandir($moduleRootPath)) && !file_exists($flagFileOfModulePath)) {
throw new Exception(
'Ошибка при распаковке ядра модуля. Целевая директория: ' . $moduleRootPath . ' уже содержит данные. ' .
'Для запуска обновления целевая директория должна быть пуста. ' .
'Удалите или переместите существующие данные и повторите обновление.'
);
}
}
}
+218
View File
@@ -0,0 +1,218 @@
<?php
class Path
{
public static $vikonCoreFolder = 'vikon_core';
public static $functionalFolder = 'update';
public static $srcExecutor = 'src_executor.php';
public static $executorFile = 'executor.php';
private static $foldersCore = array();
private static $systemDots = array('.', '..');
public static $n_pstfx = '_new';
public static $o_pstfx = '_old';
/**
* Инициализация статических путей
* @param array $foldersCore
*/
public static function init($foldersCore)
{
self::$foldersCore = $foldersCore;
}
/**
* @param $path - Путь относительно которого необходимо вернуть систмные точки (., ..)
* @return array
*/
public static function getSystemDots($path)
{
$systemDots = array();
foreach (self::$systemDots as $systemDot) {
$systemDots[] = $systemDot;
$systemDots[] = $path.'/'.$systemDot;
}
return $systemDots;
}
/**
* Возвращает абсолютный путь к главному ядру
*
* @return string
*/
public static function getCoreRootPath()
{
return self::join(self::normalize(dirname(dirname(dirname(__FILE__)))), self::$vikonCoreFolder);
}
/**
* Возращает путь к функциональной папке главного ядра.
* Функциональная папка - папка в рамках которой проихсодит синхронизация и обновление частей и ядер
* vikon_core/update
*
* @return string
*/
public static function getFunctionalPath()
{
return self::join(self::getCoreRootPath(), self::$functionalFolder);
}
/**
* Возвращает абсолютный путь к папке модуля по его идентификатору
*
* @param string $moduleId
* @return string
*/
public static function getModuleRootPath($moduleId)
{
$parentFolderCore = self::normalize(dirname(self::getCoreRootPath()));
return self::join($parentFolderCore, self::$foldersCore[$moduleId]);
}
/**
* Возвращает абсолютный путь к папке версий
* @return string
*/
public static function getTmpVersionPath()
{
return self::join(self::getCoreRootPath(), 'tmp', 'versions');
}
/**
* @param int $moduleId Идентификатор модуля (1, 2 или 6).
* @return string|null Возвращает путь к директории модуля или null, если модуль не найден.
*/
public static function getFsPathByModule($moduleId)
{
return self::join(self::getModuleRootPath($moduleId), 'files');
}
/**
* Возращает путь к исходному коду для синхронизации ядра
*
* @return string
*/
public static function getSrcForExecutorPath()
{
return self::join(self::getFunctionalPath(), self::$srcExecutor);
}
/**
* Возвращает, является ли путь базовым для другого пути.
*/
public static function isBasePath($basePath, $ofPath)
{
$basePath = self::canonicalize($basePath);
$ofPath = self::canonicalize($ofPath);
$basePath = rtrim($basePath, '/').'/';
$ofPath = $ofPath.'/';
return 0 === strpos($ofPath, $basePath);
}
/**
* Объединяет несколько частей пути в один канонический путь
*
* @return string
*/
public static function join()
{
$paths = func_get_args();
$finalPath = null;
$wasScheme = false;
foreach ($paths as $path) {
if ('' === $path) {
continue;
}
if (null === $finalPath) {
$finalPath = $path;
$wasScheme = (strpos($path, '://') !== false);
continue;
}
$lastChar = substr($finalPath, -1);
if ('/' !== $lastChar && '\\' !== $lastChar) {
$finalPath .= '/';
}
if ($wasScheme) {
$finalPath .= $path;
} else {
$finalPath .= ltrim($path, '/');
}
$wasScheme = false;
}
if ($finalPath === null) {
return '';
}
return self::canonicalize($finalPath);
}
/**
* Преобразует путь в канонический вид (убирает '.', '..', двойные слеши)
*
* @param string $path
* @return string
*/
private static function canonicalize($path)
{
$path = self::normalize($path);
$parts = explode('/', $path);
$absolutes = array();
foreach ($parts as $part) {
if ('' === $part || '.' === $part) {
continue;
}
if ('..' === $part) {
array_pop($absolutes);
} else {
$absolutes[] = $part;
}
}
$normalized = implode('/', $absolutes);
if ('/' === substr($path, 0, 1)) {
$normalized = '/' . $normalized;
}
return $normalized;
}
/**
* Проверяет возможность дальнейшей работы с заданным путем, дальнейшие действия должны проходить в рамках
* базовых путей vikon_core, или путей к модулю ($moduleId)
*
* @param int|null $moduleId - null - vikon_core, или id модуля
*/
public static function isActionAllowedThisPath($path, $moduleId = null)
{
if ($moduleId === null && !Path::isBasePath(Path::getCoreRootPath(), $path)) {
return false;
}
if ($moduleId && !Path::isBasePath(Path::getModuleRootPath($moduleId), $path)) {
return false;
}
return true;
}
/**
* Нормализует слеши в пути
*
* @param string $path
* @return string
*/
public static function normalize($path)
{
return str_replace('\\', '/', $path);
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
$letters = 'ABCDEFGKIJKLMNPQRSTUVWXYZ23456789';
$caplen = 4;
$width = 120; $height = 20;
$font = './../assets/fonts/comic.ttf';
$fontsize = 14;
header('Content-type: image/png');
$im = imagecreatetruecolor($width, $height);
imagesavealpha($im, true);
$bg = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefill($im, 0, 0, $bg);
$captcha = '';
for ($i = 0; $i < $caplen; $i++) {
$captcha .= $letters[ rand(0, strlen($letters)-1) ];
$x = ($width - 20) / $caplen * $i + 10;
$x = rand($x, $x+4);
$y = $height - ( ($height - $fontsize) / 2 );
$curcolor = imagecolorallocate( $im, rand(0, 100), rand(0, 100), rand(0, 100) );
$angle = rand(-25, 25);
imagettftext($im, $fontsize, $angle, $x, $y, $curcolor, $font, $captcha[$i]);
}
session_start();
$_SESSION['captcha'] = $captcha;
imagepng($im);
imagedestroy($im);
+26
View File
@@ -0,0 +1,26 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/config.php';
$accessToken = filterAccessToken($_POST['access_token']);
$res = array();
try {
if (!$accessToken) {
throw new RuntimeException('Некорректный access_token');
}
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $accessToken);
$response = remoteRequest($apiDomainAuth . 'api/profile_applicant/check_access_token', true, false, $headers);
if ($response->code == 200) {
$res = $response->responseBody;
} else {
$err = 'Не удалось соединиться с удаленным сервером';
sendErrorResponse($response->code, $err);
}
} catch (Exception $e) {
setResponseCode($e->getCode());
$res['error'] = 'Ошибка при проверке токена. ' . $e->getMessage();
}
loadHeaders();
echo json_encode($res);
@@ -0,0 +1,77 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/config.php';
$res = array();
$res['success'] = true;
$res['errorID'] = array();
$res['messages'] = array();
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
$consent = filter_var($_POST['consent'], FILTER_SANITIZE_NUMBER_INT);
if($consent != true){
$res['success'] = false;
$res['messages'][] = 'Не получено согласие на обработку персональных данных.';
$res['errorID'][] = 'consent';
}
$code = filter_var($_POST['captcha'], FILTER_SANITIZE_STRING);
session_start();
if (!isset($_SESSION['captcha']) || strtoupper(trim($_SESSION['captcha'])) != strtoupper(trim($code))) {
$res['success'] = false;
$res['errorID'][] = 'captcha';
$res['messages'][] = 'Неверный код с картинки.';
}
unset($_SESSION['captcha']);
if ($res['success']) {
$res['success'] = false;
$headers = array('Accept: application/json');
$data = remoteRequest($apiDomen . 'oauth2/ClientCredentials', true,
array(
'client_id' => $clientId,
'client_secret' => $clientSecret,
'grant_type' => 'client_credentials',
), $headers
);
if ($data->code == 200) {
if (isset($data->responseBody)) {
$accessToken = $data->responseBody->access_token;
try {
$data = remoteRequest($apiDomen . 'oauth_via_app/feedbackSendMail?access_token='
. $accessToken .
'&name=' . urlencode($name) .
'&email=' . urlencode($email) .
'&subject=' . urlencode($subject) .
'&message=' . urlencode($message)
);
if ($data->code == 200) {
$res['success'] = true;
} else {
sendErrorResponse($data->code, $data->responseBody->message);
}
} catch (Exception $e) {
$res['message'] = 'Ошибка. '.$e->getMessage();
}
} else {
$res['message'] = 'Ошибка ' . $data->responseBody->message;
}
} else {
$res['message'] = $data->responseBody->message;
}
}
loadHeaders();
echo json_encode($res);
+15
View File
@@ -0,0 +1,15 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/config.php';
$response = array(
'client_id' => $clientId,
'vuz_id' => $vuzId,
'api_domain_auth' => $apiDomainAuth,
'api_domain_vikon' => $apiDomen,
'api_domain_filemanager' => $filemanagerApiDomen,
'vuz_name' => $vuzName,
);
loadHeaders();
echo json_encode($response);
+39
View File
@@ -0,0 +1,39 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/config.php';
$login = filterLogin($_POST['login']);
$password = filterPassword($_POST['password']);
$code = filterInt($_POST['code']);
$res = array();
try {
if (!$login && !$password && !$code) {
throw new RuntimeException('Переданы некорректные параметры');
}
$postFields = array(
'grant_type' => 'password',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'username' => $login,
'password' => $password,
'code' => $code,
'scope' => '',
);
$response = remoteRequest($apiDomainAuth . 'oauth/token', true, $postFields, array(
'App-Language: ' . isset($_POST['lang']) ? $_POST['lang'] : 'ru'
));
if ($response->code == 200) {
setResponseCode($response->code);
$res = $response->responseBody;
} else {
$err = 'Не удалось соединиться с удаленным сервером.';
sendErrorResponse($response->code, $err);
}
} catch (Exception $e) {
setResponseCode($e->getCode());
$res['error'] = 'Ошибка при получении токена. ' . $e->getMessage();
}
loadHeaders();
echo json_encode($res);
@@ -0,0 +1,32 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/config.php';
$refreshToken = filterAccessToken($_POST['refresh_token']);
$res = array();
try {
if (!$refreshToken) {
throw new RuntimeException('Некорректный refresh_token');
}
$postFields = array(
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $clientId,
'client_secret' => $clientSecret,
'scope' => '',
);
$response = remoteRequest($apiDomainAuth . 'oauth/token', true, $postFields);
if ($response->code == 200) {
$res = $response->responseBody;
} else {
$err = 'Не удалось соединиться с удаленным сервером';
sendErrorResponse($response->code, $err);
}
} catch (Exception $e) {
setResponseCode($e->getCode());
$res['error'] = 'Ошибка при обновлении токена. ' . $e->getMessage();
}
loadHeaders();
echo json_encode($res);
@@ -0,0 +1,74 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/config.php';
$res = array();
$res['success'] = true;
$res['errorID'] = array();
$res['messages'] = array();
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$consent = filter_var($_POST['consent'], FILTER_SANITIZE_NUMBER_INT);
if($consent != true){
$res['success'] = false;
$res['messages'][] = 'Не получено согласие на обработку персональных данных.';
$res['errorID'][] = 'consent';
}
$code = filter_var($_POST['captcha'], FILTER_SANITIZE_STRING);
session_start();
if (!isset($_SESSION['captcha']) || strtoupper(trim($_SESSION['captcha'])) != strtoupper(trim($code))) {
$res['success'] = false;
$res['errorID'][] = 'captcha';
$res['messages'][] = 'Неверный код с картинки.';
}
unset($_SESSION['captcha']);
if ($res['success']) {
$res['success'] = false;
$headers = array('Accept: application/json');
$data = remoteRequest($apiDomen . 'oauth2/ClientCredentials', true,
array(
'client_id' => $clientId,
'client_secret' => $clientSecret,
'grant_type' => 'client_credentials',
), $headers
);
if ($data->code == 200) {
if (isset($data->responseBody)) {
$accessToken = $data->responseBody->access_token;
try {
$data = remoteRequest($apiDomen . 'oauth-via-app/vsoko/feedbackSendMail?access_token='
. $accessToken .
'&name=' . urlencode($name) .
'&email=' . urlencode($email) .
'&message=' . urlencode($message)
);
if ($data->code == 200) {
$res['success'] = true;
} else {
sendErrorResponse($data->code, $data->responseBody->message);
}
} catch (Exception $e) {
$res['message'] = 'Ошибка. '.$e->getMessage();
}
} else {
$res['message'] = 'Ошибка ' . $data->responseBody->message;
}
} else {
$res['message'] = $data->responseBody->message;
}
}
loadHeaders();
echo json_encode($res);
+52
View File
@@ -0,0 +1,52 @@
<?php
function isCurlExists()
{
if (in_array('curl', get_loaded_extensions())) {
return true;
} else {
return false;
}
}
function checkCurl($url, $postFields = false)
{
$error = '';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
if (is_array($postFields)) {
curl_setopt($ch, CURLOPT_POST, true);
$postVars = "";
foreach ($postFields as $key => $value) {
$postVars .= $key . '=' . $value . '&';
}
$postVars = rtrim($postVars, '&');
curl_setopt($ch, CURLOPT_POSTFIELDS, $postVars);
}
curl_exec($ch);
if (curl_errno($ch) > 0 || curl_error($ch)) {
$error = 'Curl error code: ' . curl_errno($ch) . '. Error: ' . curl_error($ch);
}
curl_close($ch);
return $error;
}
if (!isCurlExists()) {
echo '<p class="alert alert-danger">
На Вашем сервере отсутствует расширение PHP для работы с cURL.<br>
Вам следует обратиться в службу технической поддержки Вашего хостинг-провайдера с просьбой
включить PHP расширение curl.
</p>';
} else {
if (($err = checkCurl($apiDomen)) || ($err = checkCurl($apiDomen, array('post' => 42)))) {
echo '<p class="alert alert-danger">
В процессе тестирования соединения с сервером обновлений, PHP расширение cURL вернуло
следующую ошибку:<br> ' . $err .
'</p>';
}
}
@@ -0,0 +1,26 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
if (!isset($_GET['entry']) && filterEntry($_GET['entry'])) {
sendErrorResponse(422, 'Некорректный entry');
}
$entry = $_GET['entry'];
try {
$headers = array('Accept: application/json');
$result = remoteRequest($apiDomen . 'oauth2/checkEntryPoint?client_id=' . $clientId . '&entry_point=' . $entry, true, false, $headers);
if ($result->curlHasError) {
sendErrorResponse(500, 'Не удалось соединиться с сервером.' . $result->curlErrorTxt);
} else {
setResponseCode($result->code);
}
loadHeaders();
echo json_encode(array('success' => $result->responseBody->success));
} catch (Exception $e) {
sendErrorResponse(500, 'Не удалось проверить настройки безопасности.' . $e->getMessage());
}
@@ -0,0 +1,74 @@
<?php
$updateDir = dirname(__FILE__);
$rootDir = dirname($updateDir);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
require_once $updateDir . '/../internal/filesystem.php';
$errPrefix = 'Для запуска инструмента не удалось подтвердить подлинность вашего токена доступа. ';
if (!isset($_POST['access_token']) || !filterAccessToken($_POST['access_token'])) {
sendErrorResponse(422, $errPrefix . 'Токен доступа отсутствует или некорректен.');
}
$token = $_POST['access_token'];
try {
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$res = remoteRequest($apiDomen . 'pull_updates/checkAccessJson', true, false, $headers);
if ($res->curlHasError) {
sendErrorResponse(500, 'Ошибка CURL при выполнении запроса авторизации. ' . $errPrefix . $res->curlErrorTxt);
}
if ($res->code !== 200) {
$err = $errPrefix . (!empty($res->responseBody->message) ? $res->responseBody->message : 'Неизвестная ошибка.');
sendErrorResponse($res->code, $err);
}
Path::init($modulesByPathDeploy);
$payload = array(
'is_access_allowed' => true,
'err' => null
);
$message = isWritableRecrusive($rootDir);
if ($message) {
$payload['is_access_allowed'] = false;
$payload['err'] = $message;
}
loadHeaders();
setResponseCode(200);
echo json_encode(
array(
'success' => true,
'forward_code' => 200,
'payload' => $payload
)
);
die();
} catch (Exception $e) {
sendErrorResponse(500, $e->getMessage());
}
function isWritableRecrusive($dir)
{
$message = '';
if (is_dir($dir)) {
if (is_writable($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
$objectPath = Path::join($dir, $object);
$message .= isWritableRecrusive($objectPath);
}
}
} else {
$message .= 'Отсутствуют права на запись: "' . htmlspecialchars($dir) . '"<br>';
}
} else {
if (!is_writable($dir)) {
$message .= 'Отсутствуют права на запись: "' . htmlspecialchars($dir) . '"<br>';
}
}
return $message;
}
+59
View File
@@ -0,0 +1,59 @@
<?php
//todo new_core_after del
require_once dirname(__FILE__) . '/../internal/config.php';
require_once dirname(__FILE__) . '/../internal/helper.php';
require_once dirname(__FILE__) . '/../internal/filesystem.php';
if (!isset($_GET['is_access_remove_old_scripts_update'])) {
$isAccessRemoveOldScriptsUpdate = 0;
}
if (!in_array((int) $_GET['is_access_remove_old_scripts_update'], array(0, 1))) {
$isAccessRemoveOldScriptsUpdate = 0;
}
$isAccessRemoveOldScriptsUpdate = (int) $_GET['is_access_remove_old_scripts_update'];
Path::init($modulesByPathDeploy);
$vikonRootPath = Path::getCoreRootPath();
//remove executor
$executorPath = Path::join($vikonRootPath, Path::$executorFile);
if (!Filesystem::remove($executorPath, false)) {
sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . $executorPath);
}
//fail
//vikon_core-latest
$vikonCoreLatestPath = Path::join($vikonRootPath, 'vikon_core-latest');
if (!Filesystem::remove($vikonCoreLatestPath, true)) {
sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . $vikonCoreLatestPath);
}
//Удаляем старые скрипты в папке sveden/update
if ($isAccessRemoveOldScriptsUpdate) {
$svedenRoot = Path::getModuleRootPath(SVEDEN);
if (!file_exists($svedenRoot)) {
sendSuccessResponse('Временные файлы успешно удалены.');
}
$svedenFuncPath = Path::join($svedenRoot, 'update');
if (!file_exists($svedenFuncPath)) {
sendSuccessResponse('Временные файлы успешно удалены.');
}
$entriesFunc = Filesystem::safeScandir($svedenFuncPath);
if (!$entriesFunc) {
sendSuccessResponse('Временные файлы успешно удалены.');
}
$excludeEntries = array('index.php');
foreach ($entriesFunc as $entry) {
if (in_array($entry, $excludeEntries)) {
continue;
}
if (!Filesystem::remove(Path::join($svedenFuncPath, $entry), true, SVEDEN)) {
sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . Path::join($svedenFuncPath, $entry));
}
}
}
sendSuccessResponse('Временные файлы успешно удалены.');
+44
View File
@@ -0,0 +1,44 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/config.php';
require_once $selfDir . '/../internal/helper.php';
$res = array();
$res['success'] = false;
if (!isset($_POST['access_token']) || !filterAccessToken($_POST['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
try {
$headers = array(
'Accept: application/json',
'Authorization: Bearer ' . $token = $_POST['access_token'],
);
$response = remoteRequest($apiDomen . 'pull_updates/assist/updateEndedSuccessByNewCoreJson', true, array(), $headers);
if (!$response->curlHasError) {
if (200 === $response->code) {
$resultBody = array(
'success' => true,
'forward_code' => 200,
);
} else {
$resultBody = array(
'success' => false,
'forward_code' => $response->code,
'message' => !empty($response->responseBody->message )
? $response->responseBody->message
: 'Неизвестная ошибка'
);
}
} else {
throw new RuntimeException( 'CURL ' . $response->curlErrorTxt);
}
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
+1
View File
@@ -0,0 +1 @@
5.76.10.1
@@ -0,0 +1,239 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
require_once $updateDir . '/../internal/filesystem.php';
if (!isset($_GET['access_token']) || !filterAccessToken($_GET['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
if (!isset($_GET['module_id']) || !filterInt($_GET['module_id'])) {
sendErrorResponse(422, 'Некорректный module_id');
}
$moduleId = (int)$_GET['module_id'];
$token = $_GET['access_token'];
Path::init($modulesByPathDeploy);
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
sendErrorResponse(422, 'Не верно передан параметр модуля');
}
$moduleFolder = $modulesByPathDeploy[$moduleId];
$foldersNeedStay = $allowedFoldersInCoreByModule[$moduleId];
$moduleRootPath = Path::getModuleRootPath($moduleId);
$flagFileOfModulePath = Path::join($moduleRootPath, '.vikon');
try {
if ($moduleId === ABITUR) {
$headers = array('Accept-Encoding: zip, gzip', 'Authorization: Bearer ' . $token);
$zipModuleCore = remoteRequest(
$apiDomen . 'pull_updates/generateEmptyModuleCore/' . $moduleId,
false,
false,
$headers
);
if ($zipModuleCore->curlHasError) {
throw new RuntimeException('CURL ' . $zipModuleCore->curlErrorTxt);
}
if ($zipModuleCore->code !== 200) {
$zipModuleCore->responseBody = json_decode($zipModuleCore->responseBody);
$err = 'Не удается скачать файл с обновлениями. ' . (!empty($zipModuleCore->responseBody->message)
? $zipModuleCore->responseBody->message
: 'Неизвестная ошибка');
sendErrorResponse($zipModuleCore->code, $err);
}
$zipModuleCore->responseBody = json_decode($zipModuleCore->responseBody);
if ($zipModuleCore->responseBody->success === true) {
moduleDirIsEmptyOrEx($moduleRootPath, $flagFileOfModulePath);
if (!Filesystem::safeMkdir($moduleRootPath, 0755, $moduleId)) {
$err = 'Ошибка при распаковке ядра модуля. Не удалось создать папку: ' . $moduleFolder;
sendErrorResponse(500, $err);
}
$filesDirectory = Path::join($moduleRootPath, 'files');
if (!Filesystem::safeMkdir($filesDirectory, 0755, $moduleId)) {
$err = 'Ошибка при распаковке ядра модуля. Не удалось создать папку: files';
sendErrorResponse(500, $err);
}
$msg = 'Ядро модуля "' . $moduleFolder . '" успешно обновлено и синхронизировано.';
if (!Filesystem::safeMkfile($flagFileOfModulePath, 0755)) {
throw new Exception('Не удалось записать служебную информацию в директорию: ' . $flagFileOfModulePath);
}
sendSuccessResponse($msg);
}
sendSuccessResponse('Неизвестная ошибка');
}
$headers = array('Accept-Encoding: zip, gzip', 'Authorization: Bearer ' . $token);
$zipModuleCore = remoteRequest(
$apiDomen . 'pull_updates/generateEmptyModuleCore/' . $moduleId,
false,
false,
$headers
);
if ($zipModuleCore->curlHasError) {
throw new RuntimeException('CURL ' . $zipModuleCore->curlErrorTxt);
}
if ($zipModuleCore->code != 200) {
$zipModuleCore->responseBody = json_decode($zipModuleCore->responseBody);
$err = 'Не удается скачать файл с обновлениями. ' . (!empty($zipModuleCore->responseBody->message)
? $zipModuleCore->responseBody->message
: 'Неизвестная ошибка');
sendErrorResponse($zipModuleCore->code, $err);
}
moduleDirIsEmptyOrEx($moduleRootPath, $flagFileOfModulePath);
$funcPath = Path::getFunctionalPath();
$filenameZip = Path::join($funcPath, $moduleFolder . '_core-latest.zip');
if (!Filesystem::removeZip($filenameZip, true)) {
$err = 'Ошибка при распаковке ядра модуля. Архив уже существует. Недостаточно прав для его удаления';
sendErrorResponse(500, $err);
}
$dlHandler = fopen($filenameZip, 'w');
if (!fwrite($dlHandler, $zipModuleCore->responseBody)) {
$err = 'Ошибка при распаковке ядра модуля. Не удалось записать архив. Проверьте права доступа и свободное место.';
sendErrorResponse(500, $err);
}
$unpackNewModuleCorePath = Path::join($funcPath, $moduleFolder);
if (!Filesystem::remove($unpackNewModuleCorePath, true)) {
$err = 'Ошибка при распаковке ядра модуля. Временая директория уже существует и не может быть удалена.';
sendErrorResponse(500, $err);
}
if (!unpackZip($filenameZip, $funcPath)) {
$err = 'Ошибка при распаковке ядра модуля. Проверьте права доступа и свободное место.';
sendErrorResponse(500, $err);
}
Filesystem::removeZip($filenameZip, false);
// перед синхронизацией убедимся что папка модуля вообще существует
if (!Filesystem::safeMkdir($moduleRootPath, 0755, $moduleId)) {
$err = 'Ошибка обновлении ядра модуля. Не удалось создать папку модуля: ' . $moduleFolder;
sendErrorResponse(500, $err);
}
$filesDirectory = Path::join($moduleRootPath, 'files');
if (!Filesystem::safeMkdir($filesDirectory, 0755, $moduleId)) {
$err = 'Ошибка обновлении ядра модуля. Не удалось создать папку в модуле: files';
sendErrorResponse(500, $err);
}
$entriesToSync = Filesystem::safeScandir($unpackNewModuleCorePath);
$serviceInfo = array('.vikon');
$failedEntryName = null;
foreach ($entriesToSync as $entryName) {
if (in_array($entryName, $serviceInfo)) {
continue;
}
$currentEntryPath = Path::join($moduleRootPath, $entryName);
$newEntryPath = Path::join($unpackNewModuleCorePath, $entryName);
$isFile = is_file($newEntryPath);
if (file_exists($currentEntryPath)) {
$newEntryPathWithNewPostfix = Path::join($moduleRootPath, $entryName . Path::$n_pstfx);
// try del
if (!Filesystem::remove($newEntryPathWithNewPostfix, true, $moduleId)) {
$failedEntryName = $entryName;
break;
}
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($newEntryPath, $newEntryPathWithNewPostfix, $moduleId)
: Filesystem::safeRenameFile($newEntryPath, $newEntryPathWithNewPostfix, $moduleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
$currentEntryPathWithOldPostfix = Path::join($moduleRootPath, $entryName . Path::$o_pstfx);
// try del
if (!Filesystem::remove($currentEntryPathWithOldPostfix, true, $moduleId)) {
$failedEntryName = $entryName;
break;
}
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($currentEntryPath, $currentEntryPathWithOldPostfix, $moduleId)
: Filesystem::safeRenameFile($currentEntryPath, $currentEntryPathWithOldPostfix, $moduleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($newEntryPathWithNewPostfix, $currentEntryPath, $moduleId)
: Filesystem::safeRenameFile($newEntryPathWithNewPostfix, $currentEntryPath, $moduleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
} else {
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($newEntryPath, $currentEntryPath, $moduleId)
: Filesystem::safeRenameFile($newEntryPath, $currentEntryPath, $moduleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
}
}
if ($failedEntryName !== null) {
if (!Filesystem::restoreUnitCoreAfterFail($moduleRootPath, $entriesToSync, $moduleId)) {
$err = 'Ошибка при синхронизации ядра модуля. Не удалось восстановить ядро после ошибки.';
sendErrorResponse(500, $err);
} else {
$err = 'Ошибка при синхронизации ядра модуля. Не удалось синхронизировать папку/файл: ' . $failedEntryName;
sendErrorResponse(500, $err);
}
}
Filesystem::remove($unpackNewModuleCorePath, true);
$successOrPath = Filesystem::cleanUnitCore($moduleRootPath, $foldersNeedStay, $moduleId);
if (is_string($successOrPath)) {
$err = 'Ошибка проверки целостности ядра модуля. Не удалось удалить папку: ' . $successOrPath;
sendErrorResponse(500, $err);
}
if (!$successOrPath) {
$err = 'Ошибка проверки целостности ядра модуля. Нет доступа к корневой папке ядра.';
sendErrorResponse(500, $err);
}
//todo new_core_after
if ($moduleId === SVEDEN) {
$updateDirModuleCore = Path::join($moduleRootPath, 'update');
$oldUpdateFile = Path::join($moduleRootPath, 'update', 'index.php');
Filesystem::safeMkdir($updateDirModuleCore, 0755, $moduleId);
Filesystem::safeMkfile($oldUpdateFile, 0755);
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://';
$redirectPath = $locationOfVikonModules . 'vikon_core/update/index.php';
$redirectUrl = $protocol . $domenName . $redirectPath;
$indexContent = "<?php\n"
. "header('Location: " . $redirectUrl . "');\n"
. "exit;\n";
file_put_contents($oldUpdateFile, $indexContent);
}
if (!Filesystem::safeMkfile($flagFileOfModulePath, 0755)) {
throw new Exception('Не удалось записать служебную информацию в директорию: ' . $flagFileOfModulePath);
}
} catch (Exception $ex) {
sendErrorResponse(500, $ex->getMessage());
}
sendSuccessResponse('Ядро модуля "' . $moduleFolder . '" успешно обновлено и синхронизировано.');
@@ -0,0 +1,56 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
$res = array();
$res['success'] = false;
$codeSuccess = isset($_POST['code']) && filterAccessToken($_POST['code']);
$urlSuccess = isset($_POST['url']) && filterUrl($_POST['url']);
if (!$codeSuccess) {
sendErrorResponse(422, 'Некорректный авторизационный код');
}
if (!$urlSuccess) {
sendErrorResponse(422, 'Некорректный url выполнения запроса');
}
try {
$headers = array('Accept: application/json');
$data = remoteRequest($apiDomen . 'oauth2/authorize/token', true, array(
'code' => $_POST['code'],
'client_id' => $clientId,
'client_secret' => $clientSecret,
'redirect_uri' => $_POST['url'],
'grant_type' => 'authorization_code',
), $headers);
if ($data->curlHasError) {
$res['message'] = 'Не удалось соединиться с сервером.' . $data->curlErrorTxt;
setResponseCode(500);
} else {
if (isset($data->responseBody->access_token)) {
$res['access_token'] = $data->responseBody->access_token;
$res['refresh_token'] = $data->responseBody->refresh_token;
$res['success'] = true;
} else {
$message = '';
if (isset($data->responseBody->message)) {
$message = $data->responseBody->message;
} else {
$message = 'Ошибка при получении токена.';
}
$res['message'] = $message;
setResponseCode($data->code);
}
}
} catch (Exception $e) {
$res['message'] = 'Ошибка при получении ключа. ' . $e->getMessage();
setResponseCode(500);
}
loadHeaders();
echo json_encode($res);
@@ -0,0 +1,33 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
require_once $updateDir . '/../internal/filesystem.php';
if (!isset($_GET['module_id']) || !filterInt($_GET['module_id'])) {
sendErrorResponse(422, 'Отсутствует идентификатор модуля или он указан некорректно');
}
$moduleId = (int) $_GET['module_id'];
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
sendErrorResponse(422, 'Не верно передан идентификатор модуля');
}
$tmpDir = Path::getTmpVersionPath();
$result = null;
$filePath = Path::join($tmpDir, $moduleId . '.json');
if (!file_exists($filePath) || !is_readable($filePath)) {
sendErrorResponse(422, 'Не получить файл с версией');
}
$json = @file_get_contents($filePath);
if ($json === false || $json === '') {
sendErrorResponse(422, 'Не удалось получить версию');
}
$data = @json_decode($json, true);
loadHeaders();
echo json_encode(array(
'success' => true,
'message' => '',
'forward_code' => 200,
'version' => isset($data['version']) ? htmlspecialchars($data['version']) : null
));
+226
View File
@@ -0,0 +1,226 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
header('Content-Type: text/html; charset=UTF-8');
$currentVersion = file_get_contents($updateDir . '/cur_version.php');
$showNewCoreInfo = isset($_GET['first_use_new_core']) && $_GET['first_use_new_core'] == '1';
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<meta http-equiv="Cache-Control" content="no-cache">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>Полуавтоматическое обновление VIKON</title>
</head>
<body class="vikon-wrapper">
<input type="hidden" name="domen" value="<?php echo $domenName; ?>">
<input type="hidden" name="api_domen" value="<?php echo $apiDomen; ?>">
<input type="hidden" name="client_id" value="<?php echo $clientId; ?>">
<input type="hidden" name="current_version" value="<?php echo $currentVersion; ?>">
<div class="wrapper container">
<div class="main-wrapper">
<header class="header">
<div class="header-content">
<div class="header-logo vikon-logo" title="Vikon Logo">Vikon Logo</div>
<div class="header-title">Полуавтоматическое обновление VIKON</div>
</div>
<hr>
</header>
<div class="container-fluid">
<div class="form-group mb-4 d-flex justify-content-between">
<div>
<a href="/" class="btn btn-success">На главную</a>
<a href="#" class="btn btn-success" id="exit" style="display: none;">Выход</a>
</div>
<a href="https://db-nica.ru/rukovodstvo/selectFaq/43/132" target="_blank" class="btn btn-success help-button">Помощь</a>
</div>
<div class="alert alert-danger" id="message-container" style="display: none;"></div>
<div class="row" id="wait-load">
<div class="text-center">
<svg class="static-throbber" viewBox="0 0 50 50" style="width: 40px; height: 40px; margin-bottom: 10px;">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5" stroke="#007bff" />
</svg>
идет загрузка страницы
</div>
</div>
<div class="row" id="no-enter" style="display: none;">
<div class="col-sm-12 text-center">
<h3>Требуется вход</h3>
<div>
<button type="button" class="btn btn-success mb-3" id="enter-vikon">
Войти через VIKON
</button>
</div>
</div>
</div>
<?php if ($showNewCoreInfo) { ?>
<div class="row">
<div class="col-sm-12">
<div class="alert alert-info">
<p>
Переход на новую систему обновления успешно завершен! Для корректной работы системы, пожалуйста, <b>выполните полное обновление всех модулей</b>.
</p>
<p class="text-danger">Внимание! Директории модулей (/sveden, /abitur) являются точками синхронизации данных системы. Все их содержимое будет автоматически синхронизировано (перезаписано) данными из системы. Пожалуйста, убедитесь, что в этих папках нет личной информации или файлов, не относящихся к данным VIKON, чтобы избежать их потери.</p>
</div>
</div>
</div>
<?php } ?>
<div class="row" id="yes-enter" style="display: none;">
<div class="col-sm-6">
<h3>Текущая версия системы: <span class="badge bg-secondary"><?php echo $currentVersion; ?></span></h3>
<div class="settings-update" id="settings-update">
<div id="modules-container">
<!-- Модули будут вставлены здесь через JavaScript -->
</div>
<b>Настройки п/а обновления:</b>
<ul class="list-unstyled">
<li>
<div class="checkbox">
<input type="checkbox" name="is_resolve_domain" id="is_resolve_domain">
<label for="is_resolve_domain">
Использовать прямое подключение по IP-адресу к серверам VIKON
</label>
<span class="fas fa-question-circle"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Если в процессе работы у ПО не получается связаться с сервером (например, появляется сообщение об ошибке соединения), вы можете включить данную опцию. В этом режиме система будет подключаться напрямую к VIKON через IP-адрес.">
</span>
</div>
</li>
</ul>
</div>
<div class="d-none admin-mode-panel" id="admin-mode-panel">
<b>Дополнительные опции для администратора:</b>
<ul class="list-unstyled">
<li>
<div class="checkbox">
<input type="checkbox" name="no_core" id="no_core" value="no_core">
<label for="no_core">Не обновлять ядро</label>
</div>
</li>
<li>
<div class="checkbox">
<input type="checkbox" name="debug_mode" id="debug_mode" value="debug_mode">
<label for="debug_mode">Debug Mode</label>
</div>
</li>
</ul>
</div>
</div>
<div class="col-sm-6">
<h3>Наличие обновления: <span class="badge bg-warning" id="new-version">получение информации...</span></h3>
<div>
<button type="button" class="btn btn-success" id="start-update">Начать обновление</button>
</div>
<p class="alert alert-success" id="update-complete" style="display: none;"></p>
<p class="alert alert-danger" id="clear_tmp_error_layout" style="display: none;"></p>
<div class="row" id="progressbar-container" style="display: none;">
<div class="col-12">
<div class="progress">
<div id="progressbar" class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"
style="width: 0;">
</div>
</div>
</div>
</div>
<div class="alert alert-info process-container" id="process-container" style="display: none;"></div>
</div>
</div>
</div>
<?php require_once $updateDir . '/check_curl.php'; ?>
</div>
<footer class="footer">
<hr>
<div class="text-center">
<p class="copyright">
Национальный фонд поддержки инноваций в сфере образования (НФПИ)
<br>
Copyright © 2013-<?php echo date('Y') ?>
</p>
</div>
</footer>
<script>
const CURRENT_VERSION = "<?php echo $currentVersion; ?>";
const ASSETS_BASE = "./../assets/";
let PATHNAME = window.location.pathname;
PATHNAME = PATHNAME.replace(/\/+$/, '');
PATHNAME = PATHNAME.replace(/\/index.php$/, '');
const getTargetContainer = (tag) => {
return document.getElementsByTagName(tag)[0] || document.documentElement;
};
const putStyle = (filename) => {
const head = getTargetContainer('head');
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = `${PATHNAME}/${ASSETS_BASE}css/${filename}?v=${CURRENT_VERSION}`;
head.appendChild(link);
};
const loadScriptsSequentially = (filenames, index = 0) => {
return new Promise((resolve, reject) => {
if (index >= filenames.length) {
return resolve();
}
const filename = filenames[index];
const body = getTargetContainer('body');
const script = document.createElement('script');
script.src = `${PATHNAME}/${ASSETS_BASE}js/${filename}?v=${CURRENT_VERSION}`;
script.onload = () => {
loadScriptsSequentially(filenames, index + 1).then(resolve).catch(reject);
};
script.onerror = () => {
loadScriptsSequentially(filenames, index + 1).then(resolve).catch(reject);
};
body.appendChild(script);
});
};
const integrate = () => {
putStyle('update.css');
putStyle('vendor.css');
loadScriptsSequentially([
'vendor.js',
'update.js'
]).catch((е) => {
console.log('Не удалось динамически загрузить js-скрипты для работы полуавтоматического обновления')
});
};
integrate();
</script>
</div>
</body>
</html>
+31
View File
@@ -0,0 +1,31 @@
<?php
$selfDir = dirname(__FILE__);
function isWritableR($dir)
{
$message = '';
if (is_dir($dir)) {
if (is_writable($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
$message .= isWritableR($dir . DIRECTORY_SEPARATOR . $object);
}
}
} else {
$message .= 'Отсутствуют права на запись: "' . $dir . '"<br>';
}
} else if (!is_writable($dir)) {
$message .= 'Отсутствуют права на запись: "' . $dir . '"<br>';
}
return $message;
}
$messageSveden = '';
$root = dirname($selfDir);
if (file_exists($root)) {
$messageSveden = isWritableR($root);
}
if ($messageSveden) {
echo '<p class="alert alert-danger">' . $messageSveden . '</p>';
}
@@ -0,0 +1,50 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
require_once $updateDir . '/../internal/filesystem.php';
if (!isset($_GET['access_token']) || !filterAccessToken($_GET['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
$token = $_GET['access_token'];
$dlHandler = null;
try {
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$hasAccess = remoteRequest($apiDomen . 'pull_updates/checkAccessJson', true, false, $headers);
if ($hasAccess->curlHasError) {
throw new RuntimeException('CURL ' . $hasAccess->curlErrorTxt);
}
if ($hasAccess->code !== 200) {
$err = 'Не удается скачать файл с обновлениями. ' . (!empty($hasAccess->responseBody->message)
? $hasAccess->responseBody->message
: 'Неизвестная ошибка');
sendErrorResponse($hasAccess->code, $err);
}
if ($hasAccess->responseBody->success) {
$vikonRootPath = Path::getCoreRootPath();
$executorPath = Path::join($vikonRootPath, Path::$executorFile);
if (!Filesystem::remove($executorPath, false)) {
sendErrorResponse(500, 'Ошибка при генерации ядра. Не удалось удалить устаревший исполняемый скрипт: ' . $executorPath);
}
$srcForExecutorPath = Path::getSrcForExecutorPath();
$executorCode = file_get_contents($srcForExecutorPath);
if (!$executorCode || !Filesystem::safeMkfile($executorPath, 0755, $executorCode)) {
sendErrorResponse(500, 'Ошибка при генерации ядра. Не удалось создать исполняемый скрипт: ' . $executorPath);
}
sendSuccessResponse('');
}
} catch (Exception $ex) {
sendErrorResponse(500, $ex->getMessage());
}
if ($dlHandler) {
fclose($dlHandler);
}
+69
View File
@@ -0,0 +1,69 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
require_once $updateDir . '/../internal/filesystem.php';
if (!isset($_POST['access_token']) || !filterAccessToken($_POST['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
$token = $_POST['access_token'];
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$res = remoteRequest($apiDomen . 'pull_updates/checkAccessJson', true, false, $headers);
if ($res->curlHasError) {
sendErrorResponse(500, 'CURL ' . $res->curlErrorTxt);
}
if ($res->code !== 200) {
$err = 'Ошибка проверки подлинности токена. '
. (!empty($zipCore->responseBody->message) ? $zipCore->responseBody->message : 'Неизвестная ошибка');
sendErrorResponse($res->code, $err);
}
$isAccessRemoveOldScriptsUpdate = 0;
if (isset($_POST['is_access_remove_old_scripts_update']) && in_array((int) $_POST['is_access_remove_old_scripts_update'], array(0, 1))) {
$isAccessRemoveOldScriptsUpdate = (int) $_POST['is_access_remove_old_scripts_update'];
}
Path::init($modulesByPathDeploy);
$vikonRootPath = Path::getCoreRootPath();
//remove executor
$executorPath = Path::join($vikonRootPath, Path::$executorFile);
if (!Filesystem::remove($executorPath, false)) {
sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . $executorPath);
}
//fail
$vikonCoreLatestPath = Path::join($vikonRootPath, 'vikon_core-latest');
if (!Filesystem::remove($vikonCoreLatestPath, true)) {
sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . $vikonCoreLatestPath);
}
//todo new_core_after
//Удаляем старые скрипты в папке sveden/update
if ($isAccessRemoveOldScriptsUpdate) {
$svedenRoot = Path::getModuleRootPath(SVEDEN);
if (!file_exists($svedenRoot)) {
sendSuccessResponse('Временные файлы успешно удалены.');
}
$svedenFuncPath = Path::join($svedenRoot, 'update');
if (!file_exists($svedenFuncPath)) {
sendSuccessResponse('Временные файлы успешно удалены.');
}
$entriesFunc = Filesystem::safeScandir($svedenFuncPath);
if (!$entriesFunc) {
sendSuccessResponse('Временные файлы успешно удалены.');
}
$excludeEntries = array('index.php');
foreach ($entriesFunc as $entry) {
if (in_array($entry, $excludeEntries)) {
continue;
}
if (!Filesystem::remove(Path::join($svedenFuncPath, $entry), true, SVEDEN)) {
sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . Path::join($svedenFuncPath, $entry));
}
}
}
sendSuccessResponse('Временные файлы успешно удалены.');
@@ -0,0 +1,50 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
if (!isset($_POST['refresh_token']) || !filterAccessToken($_POST['refresh_token'])) {
sendErrorResponse(422, 'Некорректный code');
}
$res = array();
$res['success'] = false;
$refreshToken = filterAccessToken($_POST['refresh_token']);
try {
$headers = array('Accept: application/json');
$data = remoteRequest($apiDomen . 'oauth2/RefreshToken', true, array(
'refresh_token' => $refreshToken,
'client_id' => $clientId,
'client_secret' => $clientSecret,
'grant_type' => 'refresh_token',
), $headers);
if ($data->curlHasError) {
$res['message'] = 'Не удалось соединиться с сервером.' . $data->curlErrorTxt;
setResponseCode(500);
} else {
if (isset($data->responseBody->access_token)) {
$res['access_token'] = $data->responseBody->access_token;
$res['refresh_token'] = $data->responseBody->refresh_token;
$res['success'] = true;
} else {
$message = '';
if (isset($data->responseBody->message)) {
$message = $data->responseBody->message;
} else {
$message = 'Ошибка при получении токена.';
}
$res['message'] = $message;
setResponseCode($data->code);
}
}
} catch (Exception $e) {
$res['message'] = 'Ошибка при обновлении ключа. ' . $e->getMessage();
setResponseCode(500);
}
loadHeaders();
echo json_encode($res);
@@ -0,0 +1,44 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
if (!isset($_POST['access_token']) || !filterAccessToken($_POST['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
if (!isset($_POST['part']) || !filterPartName($_POST['part'])) {
sendErrorResponse(422, 'Некорректный part');
}
$token = $_POST['access_token'];
$part = $_POST['part'];
try {
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$post = array('part' => $part, 'is_new_core' => true);
$response = remoteRequest($apiDomen . 'pull_updates/generatePartByNewCoreJson', true, $post, $headers);
if (!$response->curlHasError) {
if (200 === $response->code) {
$resultBody = array(
'success' => true,
'operation_identity' => $response->responseBody->operation_identity,
'ttl' => $response->responseBody->ttl,
'forward_code' => 200,
);
} else {
$err = !empty($response->responseBody->message) ? $response->responseBody->message : 'Неизвестная ошибка';
sendErrorResponse($response->code, $err);
}
} else {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
@@ -0,0 +1,120 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/config.php';
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/filesystem.php';
$token = filterAccessToken(isset($_POST['access_token']) ? (string) $_POST['access_token'] : '');
$moduleId = isset($_POST['moduleId']) ? filterInt($_POST['moduleId']) : null;
$dlHandler = null;
try {
Path::init($modulesByPathDeploy);
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
throw new RuntimeException('Не верно передан параметр модуля');
}
if (!$token) {
throw new RuntimeException('Некорректный access_token');
}
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$response = remoteRequest($filemanagerApiDomen . 'sync/getNewFileInfoByModule?moduleId=' . $moduleId, true, false, $headers);
if ($response->curlHasError) {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
if (
$response->code !== 200
|| !property_exists($response->responseBody, 'file_name')
|| !property_exists($response->responseBody, 'identity')
|| !property_exists($response->responseBody, 'dir_name')
) {
$msg = 'Не удалось получить информацию о файле, котрый требуется загрузить '
. tryExtractFmErrorMessage($response, '. ');
sendErrorResponse($response->code, $msg);
}
if ($response->responseBody->file_name === null && $response->responseBody->identity === null) {
$resultBody = array(
'success' => true,
'forward_code' => 200,
'done' => true,
);
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
die();
}
$fileIdentity = $response->responseBody->identity;
$filename = $response->responseBody->file_name;
$directory = $response->responseBody->dir_name;
if (!Filesystem::ensureValidDirectoryAndFileName($directory, $filename)) {
throw new RuntimeException('Некорректные параметры сохранения: недопустимое имя директории или файла.');
}
$headers = array('Accept-Encoding: zip, gzip', 'Authorization: Bearer ' . $token);
$binFile = remoteRequest(
$filemanagerApiDomen . 'sync/downloadFileBinary?identity=' . $fileIdentity,
false,
false,
$headers
);
if ($binFile->curlHasError) {
throw new RuntimeException('CURL ' . $binFile->curlErrorTxt);
}
if ($binFile->code !== 200) {
$binFile->responseBody = json_decode($binFile->responseBody);
$message = 'Не удается скачать файл ' . $filename . tryExtractFmErrorMessage($binFile, '. ');
sendErrorResponse($binFile->code, $message);
}
$fsPathDir = Path::getFsPathByModule($moduleId);
if ($directory !== null) {
$fsPathDir = Path::join($fsPathDir, $directory);
}
if (!Filesystem::safeMkdir($fsPathDir, 0775, $moduleId)) {
throw new RuntimeException('Не удалось создать папку "' . $fsPathDir . '" на вашем сервере');
}
$fsFilePath = Path::join($fsPathDir, $filename);
$dlHandler = fopen($fsFilePath, 'w');
if ($dlHandler == false || !fwrite($dlHandler, $binFile->responseBody)) {
throw new RuntimeException('Не удается записать файл ' . $fsFilePath . ' на диск', 500);
}
$headers = array('Authorization: Bearer ' . $token);
$response = remoteRequest(
$filemanagerApiDomen . 'sync/markNewFileAsLoaded?identity=' . $fileIdentity . '&moduleId=' . $moduleId,
true,
false,
$headers
);
if ($response->code !== 200) {
$message = 'Не удалось пометить файл' . $filename . ' как обновленный'
. tryExtractFmErrorMessage($response, '. ');
sendErrorResponse($response->code, $message);
}
$resultBody = array(
'success' => true,
'forward_code' => 200,
'message' => 'Файл ' . $filename . ' загружен',
'done' => false,
);
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
if ($dlHandler) {
fclose($dlHandler);
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
@@ -0,0 +1,131 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/config.php';
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/filesystem.php';
$token = filterAccessToken(isset($_POST['access_token']) ? (string) $_POST['access_token'] : '');
$fileIdentity = isset($_POST['fileIdentity']) && is_scalar($_POST['fileIdentity']) ? $_POST['fileIdentity'] : null;
$moduleId = isset($_POST['moduleId']) ? filterInt($_POST['moduleId']) : null;
$dlHandler = null;
Path::init($modulesByPathDeploy);
try {
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
throw new RuntimeException('Не верно передан параметр модуля');
}
if (!$token) {
throw new RuntimeException('Некорректный access_token');
}
if (!$fileIdentity) {
throw new RuntimeException('Передан невалидный идентификатор файла');
}
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$response = remoteRequest(
$filemanagerApiDomen . 'sync/getFileByIdentityInfo?identity=' . $fileIdentity,
true,
false,
$headers
);
if ($response->curlHasError) {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
if (
$response->code !== 200
|| !property_exists($response->responseBody, 'file_name')
|| !property_exists($response->responseBody, 'identity')
|| !property_exists($response->responseBody, 'dir_name')
) {
$resultBody = array(
'success' => false,
'forward_code' => $response->code == 200 ? 500 : $response->code,
'message' => (int) $response->code === 404
? 'Не удалось получить информацию об одном из синхронизируемых файлов. Файл был удален из системы после запуска процесса синхронизации. Перезапустите синхронизацию файлов.'
: 'Не удалось получить информацию о файле, котрый требуется загрузить ' . tryExtractFmErrorMessage($response, '. '),
'debug_identity' => $fileIdentity,
);
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
die();
}
$identity = $response->responseBody->identity;
$filename = $response->responseBody->file_name;
$directory = $response->responseBody->dir_name;
if (!Filesystem::ensureValidDirectoryAndFileName($directory, $filename)) {
throw new RuntimeException('Некорректные параметры сохранения: недопустимое имя директории или файла.');
}
$headers = array('Accept-Encoding: zip, gzip', 'Authorization: Bearer ' . $token);
$bin = remoteRequest(
$filemanagerApiDomen . 'sync/downloadFileBinaryForSync?identity=' . $identity . '&moduleId=' . $moduleId,
false,
false,
$headers
);
if ($bin->curlHasError) {
throw new RuntimeException('CURL ' . $bin->curlErrorTxt);
}
if ($bin->code !== 200) {
$bin->responseBody = json_decode($bin->responseBody);
$resultBody = array(
'success' => false,
'forward_code' => $bin->code,
'message' => 'Не удается скачать файл ' . $filename . tryExtractFmErrorMessage($bin, '. '),
'debug_identity' => $fileIdentity,
);
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
die();
}
$fsPathDir = Path::getFsPathByModule($moduleId);
if (!$fsPathDir) {
throw new RuntimeException('Неизвестная ошибка');
}
if ($directory !== null) {
$fsPathDir = Path::join($fsPathDir, $directory);
}
if (!Filesystem::safeMkdir($fsPathDir, 0775, $moduleId)) {
throw new RuntimeException('Не удалось создать папку "' . $fsPathDir . '" на вашем сервере');
}
$filePath = Path::join($fsPathDir, $filename);
$dlHandler = fopen($filePath, 'w');
if ($dlHandler === false) {
throw new RuntimeException('Не удается открыть файл для записи: ' . $filePath);
}
if (fwrite($dlHandler, $bin->responseBody) === false) {
throw new RuntimeException('Не удается записать файл на диск: ' . $filePath);
}
$resultBody = array(
'success' => true,
'forward_code' => 200,
'message' => 'Файл ' . $filename . ' загружен',
);
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
if ($dlHandler) {
fclose($dlHandler);
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
@@ -0,0 +1,57 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
if (!isset($_POST['access_token']) || !filterAccessToken($_POST['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
if (!isset($_POST['operation_identity']) || !filter_var($_POST['operation_identity'], FILTER_SANITIZE_STRING)) {
sendErrorResponse(422, 'Некорректный operation_identity');
}
if (!isset($_POST['part']) || !filterPartName($_POST['part'])) {
sendErrorResponse(422, 'Некорректный part');
}
$token = $_POST['access_token'];
$operationIdentity = (string) $_POST['operation_identity'];
$part = $_POST['part'];
try {
$headers = array(
'Accept: application/json',
'Authorization: Bearer ' . $token,
);
$response = remoteRequest(
$apiDomen . 'pull_updates/checkPartGenerationByNewCoreResultJson?operation_identity=' . $operationIdentity . '&part=' . $part,
true,
false,
$headers
);
if (!$response->curlHasError) {
if ($response->code === 200) {
$resultBody = array(
'success' => true,
'forward_code' => 200,
);
} else {
$resultBody = array(
'success' => false,
'forward_code' => $response->code,
'message' => !empty($response->responseBody->message ) ? $response->responseBody->message : 'Неизвестная ошибка'
);
}
} else {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
@@ -0,0 +1,229 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
require_once $updateDir . '/../internal/filesystem.php';
if (!isset($_POST['access_token']) || !filterAccessToken($_POST['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
if (!isset($_POST['operation_identity']) || !filter_var($_POST['operation_identity'], FILTER_SANITIZE_STRING)) {
sendErrorResponse(422, 'Некорректный operation_identity');
}
if (!isset($_POST['part']) || !filterPartName($_POST['part'])) {
sendErrorResponse(422, 'Некорректный part');
}
$dlHandler = null;
$token = $_POST['access_token'];
$operationIdentity = (string)$_POST['operation_identity'];
$part = $_POST['part'];
Path::init($modulesByPathDeploy);
try {
$headers = array(
'Authorization: Bearer ' . $token,
'Accept-Encoding: zip, gzip'
);
$response = remoteRequest(
$apiDomen . 'pull_updates/downloadPartByNewCoreResult?operation_identity=' . $operationIdentity . '&part=' . $part,
false,
false,
$headers
);
if (!$response->curlHasError) {
if ($response->code === 200) {
$curModuleId = 0;
foreach ($allowedFoldersInCoreByModule as $moduleId => $parts) {
if (is_array($parts) && in_array($part, $parts)) {
$curModuleId = $moduleId;
break;
}
}
$funcPath = Path::getFunctionalPath();
$filenameZip = Path::join($funcPath, $operationIdentity . '.zip');
if (!Filesystem::removeZip($filenameZip, true)) {
$err = 'Ошибка при распаковке раздела: "' . $part . '".'
. ' Базовый архив раздела уже существует, недостаточно прав для его удаления.';
sendErrorResponse(500, $err);
}
$dlHandler = fopen($filenameZip, 'w');
if (!fwrite($dlHandler, $response->responseBody)) {
$err = 'Ошибка при распаковке раздела: "' . $part . '".'
. ' Не удалось записать архив. Проверьте права доступа и свободное место.';
sendErrorResponse(500, $err);
}
$unpackPath = Path::join($funcPath, $part.'_part-latest');
if (!Filesystem::remove($unpackPath, true)) {
$err = 'Ошибка при распаковке раздела: "' . $part . '".'
. ' Временная директория уже существует и не может быть удалена.';
sendErrorResponse(500, $err);
}
if (!unpackZip($filenameZip, $unpackPath)) {
$err = 'Ошибка при распаковке раздела: ' . $part . '.'
. ' Проверьте права доступа и свободное место.';
sendErrorResponse(500, $err);
}
Filesystem::removeZip($filenameZip, false);
$errRepeir = 'Ошибка при синхронизации раздела. Не удалось восстановить часть: ' . $part;
$errSync = 'Ошибка при синхронизации раздела. Не удалось синхронизировать часть: ' . $part;
$rootModuleCore = Path::getModuleRootPath($curModuleId);
$pathCurFolderPart = Path::join($rootModuleCore, $part);
$excludedEntries = array();
if ('abitur' !== $part) {
$excludedEntries = $allowedFoldersInCoreByModule[$curModuleId];
$pathCurFolderPart = Path::join($rootModuleCore, $part);
if (file_exists($pathCurFolderPart)) {
$pathPartForSync = Path::join($unpackPath, $part);
$pathPartForSyncPostfixNew = Path::join($rootModuleCore, $part.Path::$n_pstfx);
if (!Filesystem::remove($pathPartForSyncPostfixNew, true, $curModuleId)) {
if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) {
sendErrorResponse(500, $errRepeir);
}
}
if (!Filesystem::replaceWithRename($pathPartForSync, $pathPartForSyncPostfixNew, $curModuleId)) {
if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) {
sendErrorResponse(500, $errRepeir);
}
sendErrorResponse(500, $errSync);
}
$pathCurFolderPartOldPostfix = Path::join($rootModuleCore, $part.Path::$o_pstfx);
if (!Filesystem::remove($pathCurFolderPartOldPostfix, true, $curModuleId)) {
if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) {
sendErrorResponse(500, $errRepeir);
}
sendErrorResponse(500, $errSync);
}
if (!Filesystem::replaceWithRename($pathCurFolderPart, $pathCurFolderPartOldPostfix, $curModuleId)) {
if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) {
sendErrorResponse(500, $errRepeir);
}
sendErrorResponse(500, $errSync);
}
if (!Filesystem::replaceWithRename($pathPartForSyncPostfixNew, $pathCurFolderPart, $curModuleId)) {
if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) {
sendErrorResponse(500, $errRepeir);
}
sendErrorResponse(500, $errSync);
}
} else {
$pathPartForSync = Path::join($unpackPath, $part);
if (!Filesystem::replaceWithRename($pathPartForSync, $pathCurFolderPart, $curModuleId)) {
if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) {
sendErrorResponse(500, $errRepeir);
}
sendErrorResponse(500, $errSync);
}
}
} else {
$pathCurFolderPart = $rootModuleCore;
$entrySyncFail = null;
$isRestoreFail = false;
$entriesToSync = Filesystem::safeScandir(Path::join($unpackPath, $part));
$excludedEntries = array_merge($entriesToSync, array('files', '.htaccess'));//todo подумать как от этого костыля отказаться
foreach ($entriesToSync as $entryName) {
$currentEntryPath = Path::join($pathCurFolderPart, $entryName);
$newEntryPath = Path::join($unpackPath, $part, $entryName);
$isFile = is_file($newEntryPath);
if (file_exists($currentEntryPath)) {
$newEntryPathWithNewPostfix = Path::join($pathCurFolderPart, $entryName.Path::$n_pstfx);
// try del
if (!Filesystem::remove($newEntryPathWithNewPostfix, true, $curModuleId)) {
$failedEntryName = $entryName;
break;
}
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($newEntryPath, $newEntryPathWithNewPostfix, $curModuleId)
: Filesystem::safeRenameFile($newEntryPath, $newEntryPathWithNewPostfix, $curModuleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
$currentEntryPathWithOldPostfix = Path::join($pathCurFolderPart, $entryName.Path::$o_pstfx);
// try del
if (!Filesystem::remove($currentEntryPathWithOldPostfix, true, $curModuleId)) {
$failedEntryName = $entryName;
break;
}
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($currentEntryPath, $currentEntryPathWithOldPostfix, $curModuleId)
: Filesystem::safeRenameFile($currentEntryPath, $currentEntryPathWithOldPostfix, $curModuleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($newEntryPathWithNewPostfix, $currentEntryPath, $curModuleId)
: Filesystem::safeRenameFile($newEntryPathWithNewPostfix, $currentEntryPath, $curModuleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
} else {
// try replace
$renameSuccess = !$isFile
? Filesystem::replaceWithRename($newEntryPath, $currentEntryPath, $curModuleId)
: Filesystem::safeRenameFile($newEntryPath, $currentEntryPath, $curModuleId);
if (!$renameSuccess) {
$failedEntryName = $entryName;
break;
}
}
}
}
Filesystem::remove($unpackPath, true);
$successOrPath = Filesystem::cleanUnitCore($rootModuleCore, $excludedEntries, $curModuleId);
if (is_string($successOrPath)) {
$err = 'Ошибка проверки целостности части. Не удалось удалить папку: ' . $successOrPath;
sendErrorResponse(500, $err);
}
if (!$successOrPath) {
$err = 'Ошибка проверки целостности части. Нет доступа к корневой папке части.';
sendErrorResponse(500, $err);
}
$resultBody = array('success' => true, 'forward_code' => 200, 'message' => 'Раздел ' . $part . ' успешно обновлен.');
} else {
$response->responseBody = json_decode($response->responseBody);
$resultBody = array(
'success' => false,
'forward_code' => $response->code,
'message' => !empty($response->responseBody->message ) ? $response->responseBody->message : 'неизвестная ошибка'
);
}
} else {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
if ($dlHandler != null) {
fclose($dlHandler);
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
+132
View File
@@ -0,0 +1,132 @@
<?php
//скрипт запускается оносительно vikon_core
$vikonDir = dirname(__FILE__);
require_once $vikonDir . '/internal/config.php';
require_once $vikonDir . '/internal/helper.php';
require_once $vikonDir . '/internal/filesystem.php';
if (!isset($_GET['access_token']) || !filterAccessToken($_GET['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
$token = $_GET['access_token'];
$dlHandler = null;
try {
$headers = array('Accept-Encoding: zip, gzip', 'Authorization: Bearer ' . $token);
$zipCore = remoteRequest($apiDomen . 'pull_updates/generateEmptyCore', false, false, $headers);
if ($zipCore->curlHasError) {
throw new RuntimeException('CURL ' . $zipCore->curlErrorTxt);
}
if ($zipCore->code !== 200) {
$zipCore->responseBody = json_decode($zipCore->responseBody);
$err = 'Не удается скачать файл с обновлениями. ' . (!empty($zipCore->responseBody->message)
? $zipCore->responseBody->message
: 'Неизвестная ошибка');
sendErrorResponse($zipCore->code, $err);
}
$vikonFuncPath = Path::getCoreRootPath();
$vikonZipCorePath = Path::join($vikonFuncPath, 'vikon_core-latest.zip');
if (!Filesystem::removeZip($vikonZipCorePath, true)) {
$err = 'Ошибка при распаковке ядра. Архив уже существует. Недостаточно прав для его удаления';
sendErrorResponse(500, $err);
}
$dlHandler = fopen($vikonZipCorePath, 'w');
if (!fwrite($dlHandler, $zipCore->responseBody)) {
$err = 'Ошибка при распаковке ядра модуля. Не удалось записать архив. Проверьте права доступа и свободное место.';
sendErrorResponse(500, $err);
}
if ($dlHandler) {
fclose($dlHandler);
}
$vikonUnpackNewCorePath = Path::join($vikonFuncPath, 'vikon_core-latest');
if (!Filesystem::remove($vikonUnpackNewCorePath, true)) {
$err = 'Ошибка при распаковке ядра. Временная директория уже существует и не может быть удалена.';
sendErrorResponse(500, $err);
}
$unpackResult = unpackZip($vikonZipCorePath, $vikonUnpackNewCorePath);
if (!$unpackResult['success']) {
sendErrorResponse(500, 'Ошибка при распаковке ядра. Проверьте права доступа и свободное место.');
}
Filesystem::removeZip($vikonZipCorePath, false);
$vikonRootPath = Path::getCoreRootPath();
$pathToFoldersNewCore = Path::join($vikonUnpackNewCorePath, Path::$vikonCoreFolder);
$nameFoldersForSync = Filesystem::safeScandir($pathToFoldersNewCore);
$isRestoreFail = false;
$folderSyncFail = null;
foreach ($nameFoldersForSync as $nameFolderSync) {
$curFolder = Path::join($vikonRootPath, $nameFolderSync);
$pathToNewFolder = Path::join($vikonUnpackNewCorePath, Path::$vikonCoreFolder, $nameFolderSync);
if (file_exists($curFolder)) {
$pathToNewFolderPostfix = Path::join($vikonRootPath, $nameFolderSync . Path::$n_pstfx);
// try del vikon_core/assets_new
if (!Filesystem::remove($pathToNewFolderPostfix, true)) {
$folderSyncFail = $nameFolderSync;
break;
}
// try replace vikon_core/vikon_core-latest/vikon_core/assets -> vikon_core/assets_new
if (!Filesystem::replaceWithRename($pathToNewFolder, $pathToNewFolderPostfix)) {
$folderSyncFail = $nameFolderSync;
break;
}
$pathToOldFolderPostfix = Path::join($vikonRootPath, $nameFolderSync . Path::$o_pstfx);
// try del vikon_core/assets_old
if (!Filesystem::remove($pathToOldFolderPostfix, true)) {
$folderSyncFail = $nameFolderSync;
break;
}
// try replace vikon_core/assets -> vikon_core/assets_old
if (!Filesystem::replaceWithRename($curFolder, $pathToOldFolderPostfix)) {
$folderSyncFail = $nameFolderSync;
break;
}
// vikon_core/assets_new -> vikon_core/assets
if (!Filesystem::replaceWithRename($pathToNewFolderPostfix, $curFolder)) {
$folderSyncFail = $nameFolderSync;
break;
}
} else {
// try replace vikon_core/vikon_core-latest/vikon_core/assets -> vikon_core/assets
if (!Filesystem::replaceWithRename($pathToNewFolder, $curFolder)) {
$folderSyncFail = $nameFolderSync;
break;
}
}
}
//синхронизированные папки + временная папка с версиями
$allFoldersNeedCore = array_merge($nameFoldersForSync, array('tmp'));
if ($folderSyncFail !== null) {
if (!Filesystem::restoreUnitCoreAfterFail($vikonRootPath, $allFoldersNeedCore)) {
sendErrorResponse(500, 'Ошибка при синхронизации ядра. Не удалось восстановить ядро после ошибки.');
} else {
sendErrorResponse(500, 'Ошибка при синхронизации ядра. Не удалось синхронизировать папку: ' . $folderSyncFail);
}
}
$successOrPath = Filesystem::cleanUnitCore($vikonRootPath, $allFoldersNeedCore);
if (is_string($successOrPath)) {
sendErrorResponse(500, 'Ошибка проверки целостности ядра. Не удалось удалить папку: ' . $successOrPath);
}
if (!$successOrPath) {
sendErrorResponse(500, 'Ошибка проверки целостности ядра. Нет доступа к корневой папке ядра.');
}
} catch (Exception $ex) {
sendErrorResponse(500, $ex->getMessage());
}
sendSuccessResponse('Архив с базовыми обновлениями успешно загружен.');
@@ -0,0 +1,74 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/config.php';
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/filesystem.php';
$token = filterAccessToken(isset($_POST['access_token']) ? (string) $_POST['access_token'] : '');
$moduleId = isset($_POST['moduleId']) ? filterInt($_POST['moduleId']) : null;
$dlHandler = null;
Path::init($modulesByPathDeploy);
try {
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
throw new RuntimeException('Не верно передан параметр модуля');
}
if (!$token) {
throw new RuntimeException('Некорректный access_token');
}
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$response = remoteRequest($filemanagerApiDomen . 'sync/getUsedDirNamesByModule?moduleId=' . $moduleId, true, false, $headers);
if ($response->code !== 200) {
$msg = 'Не удалось инициировать процедуру синхронизации файлов' . tryExtractFmErrorMessage($response, '. ');
sendErrorResponse($response->code, $msg);
}
if (!property_exists($response->responseBody, 'directories') || !is_array($response->responseBody->directories)) {
throw new RuntimeException('Невалидный формат ответа при запросе используемых директорий');
}
$directories = $response->responseBody->directories;
$fsRootPath = Path::getFsPathByModule($moduleId);
if (!$fsRootPath) {
throw new RuntimeException('Неизвестная ошибка');
}
$dirObjects = Filesystem::safeScandir($fsRootPath);
if (false === $dirObjects) {
$msg = 'Не удалось просканировать папку: ' . $fsRootPath;
sendErrorResponse(500, $msg);
}
$flippedKnownDirectories = array_flip($directories);
foreach ($dirObjects as $objectName) {
$objectPath = Path::join($fsRootPath, $objectName);
if (
!array_key_exists($objectName, $flippedKnownDirectories)
&& is_dir($objectPath)
) {
if (is_link($fsRootPath)) {
throw new RuntimeException(
'В синхронизируемый директории находится ссылка'
. $objectPath
. ' , которая не может быть безопасно удалена'
);
}
Filesystem::remove($objectPath, true, $moduleId);
}
}
$resultBody = array(
'success' => true,
'forward_code' => 200,
'directories' => $directories,
);
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
@@ -0,0 +1,50 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
if (!isset($_GET['access_token']) || !filterAccessToken($_GET['access_token'])) {
sendErrorResponse(422, 'Некорректный access_token');
}
if (!isset($_GET['operation_identity']) || !filter_var($_GET['operation_identity'], FILTER_SANITIZE_STRING)) {
sendErrorResponse(422, 'Некорректный operation_identity');
}
$operationIdentity = (string) $_GET['operation_identity'];
$token = $_GET['access_token'];
try {
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$response = remoteRequest(
$apiDomen . 'pull_updates/getStatusPartGenerationByNewCoreJson?operation_identity=' . $operationIdentity,
true,
false,
$headers
);
if (!$response->curlHasError) {
if (200 === $response->code) {
$resultBody = array(
'success' => true,
'status' => $response->responseBody->status,
'forward_code' => 200,
);
} else {
$resultBody = array(
'success' => false,
'forward_code' => $response->code,
'message' => !empty($response->responseBody->message ) ? $response->responseBody->message : 'неизвестная ошибка'
);
}
} else {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
} catch (Exception $ex) {
setResponseCode(!empty($response->code) ? $response->code : 500);
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
+109
View File
@@ -0,0 +1,109 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/config.php';
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/filesystem.php';
$token = filterAccessToken(isset($_POST['access_token']) ? (string) $_POST['access_token'] : '');
//через jquery нельзя послать пустой массив, если это не json.
// json посылать не будем, похоже при некоторых настройках старых серверов есть проблемы с чтением raw-body через php://input($HTTP_RAW_POST_DATA)
$isHasSubDirs = isset($_POST['isHasSubDirs']) && is_numeric($_POST['isHasSubDirs'])
? (int) $_POST['isHasSubDirs']
: null;
$knownSubDirs = isset($_POST['knownSubDirs']) && is_array($_POST['knownSubDirs'])
? $_POST['knownSubDirs']
: array();
$moduleId = isset($_POST['moduleId']) ? filterInt($_POST['moduleId']) : null;
$dlHandler = null;
Path::init($modulesByPathDeploy);
try {
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
throw new RuntimeException('Не верно передан параметр модуля');
}
if (!$token) {
throw new RuntimeException('Некорректный access_token');
}
if (null === $isHasSubDirs || ($isHasSubDirs && !$knownSubDirs) || (!$isHasSubDirs && $knownSubDirs)) {
throw new RuntimeException('Не может быть обработано. Неверные параметры запроса.');
}
$fsDirPath = Path::getFsPathByModule($moduleId);
if (!$fsDirPath) {
throw new RuntimeException('Не удалось определить модуль');
}
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$response = remoteRequest($filemanagerApiDomen . 'sync/getFileNamesFromRootDirectoryByModule?moduleId=' . $moduleId, true, false, $headers);
if ($response->curlHasError) {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
if (
$response->code !== 200
|| !property_exists($response->responseBody, 'files')
|| !is_array($response->responseBody->files)
) {
$msg = 'Не удалось получить список файлов с файлового сервера'
. tryExtractFmErrorMessage($response, '. ');
sendErrorResponse($response->code, $msg);
}
$filesByNamesFromFm = array();
foreach ($response->responseBody->files as $row) {
$filesByNamesFromFm[(string) $row->n] = $row->i;
}
$response = null;
if (!Filesystem::safeMkdir($fsDirPath, 0775, $moduleId)) {
throw new RuntimeException('Не удалось создать папку "' . $fsDirPath . '" на вашем сервере');
}
$items = Filesystem::safeScandir($fsDirPath);
if (false === $items) {
$msg = 'Не удалось просканировать существующие файлы';
sendErrorResponse(500, $msg);
}
$existingItemsByNames = array();
foreach ($items as $fName) {
$existingItemsByNames[$fName] = null;
}
$knownSubDirsByNames = array_flip($knownSubDirs);
foreach ($existingItemsByNames as $dirItem => $_) {
$fsItemPath = Path::join($fsDirPath, $dirItem);
if ((array_key_exists($dirItem, $knownSubDirsByNames) && is_dir($fsItemPath))) {
unset($existingItemsByNames[$dirItem]);
continue;
}
if (!array_key_exists((string) $dirItem, $filesByNamesFromFm)) {
//удаляем только файлы, ненужные папки были удалены в start_sync_files
if (is_file($fsItemPath)) {
unlink($fsItemPath);
}
} else {
if (!filesize($fsItemPath)) {
unset($existingItemsByNames[$dirItem]);
}
}
}
$filesForSync = array();
foreach ($filesByNamesFromFm as $fileName => $identity) {
if (!array_key_exists($fileName, $existingItemsByNames)) {
$filesForSync[] = $identity;
}
}
$resultBody = array('success' => true, 'forward_code' => 200, 'files' => $filesForSync);
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
+100
View File
@@ -0,0 +1,100 @@
<?php
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/config.php';
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/filesystem.php';
$dir = isset($_POST['dir']) && is_string($_POST['dir']) ? $_POST['dir'] : '';
$token = filterAccessToken(isset($_POST['access_token']) ? (string) $_POST['access_token'] : '');
$moduleId = isset($_POST['moduleId']) ? filterInt($_POST['moduleId']) : null;
$dlHandler = null;
Path::init($modulesByPathDeploy);
try {
if (!preg_match("/^[a-z]{3,4}$/", $dir)) {
throw new RuntimeException('Невалидное значение для синхронизируемой суб-директории');
}
if (!$token) {
throw new RuntimeException('Некорректный access_token');
}
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
throw new RuntimeException('Не верно передан параметр модуля');
}
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$url = $filemanagerApiDomen . 'sync/getFileNamesFromSubDirectoryByModule?dir=' . $dir . '&moduleId=' . $moduleId;
$response = remoteRequest($url, true, false, $headers);
if ($response->curlHasError) {
throw new RuntimeException('CURL ' . $response->curlErrorTxt);
}
if (
$response->code !== 200
|| !property_exists($response->responseBody, 'files')
|| !is_array($response->responseBody->files)
) {
$message = 'Не удалось получить список файлов с файлового сервера'
. tryExtractFmErrorMessage($response, '. ');
sendErrorResponse($response->code, $message);
}
$filesByNamesFromFm = array();
foreach ($response->responseBody->files as $row) {
$filesByNamesFromFm[(string) $row->n] = $row->i;
}
$response = null;
$fsDirPath = Path::getFsPathByModule($moduleId);
if (!$fsDirPath) {
throw new RuntimeException('Не удалось определить модуль');
}
$dirPath = Path::join($fsDirPath, $dir);
if (!Filesystem::safeMkdir($dirPath, 0775, $moduleId)) {
throw new RuntimeException('Не удалось создать папку "' . $dirPath . '" на вашем сервере');
}
$items = Filesystem::safeScandir($dirPath);
if (false === $items) {
$msg = 'Не удалось просканировать существующие файлы';
sendErrorResponse(500, $msg);
}
$existingItemsByNames = array();
foreach ($items as $fName) {
$existingItemsByNames[$fName] = null;
}
foreach ($existingItemsByNames as $subDirItem => $_) {
$filePath = Path::join($dirPath, $subDirItem);
if (!array_key_exists((string) $subDirItem, $filesByNamesFromFm)) {
if (is_dir($filePath)) {
Filesystem::remove($filePath, true);
} else {
unlink($filePath);
}
} else {
if (!filesize($filePath)) {
unset($existingItemsByNames[$subDirItem]);
}
}
}
$filesForSync = array();
foreach ($filesByNamesFromFm as $fileName => $identity) {
if (!array_key_exists($fileName, $existingItemsByNames)) {
$filesForSync[] = $identity;
}
}
$resultBody = array('success' => true, 'forward_code' => 200, 'files' => $filesForSync);
} catch (Exception $ex) {
$resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage());
}
loadHeaders();
setResponseCode(200);
echo json_encode($resultBody);
@@ -0,0 +1,80 @@
<?php
$updateDir = dirname(__FILE__);
require_once $updateDir . '/../internal/config.php';
require_once $updateDir . '/../internal/helper.php';
require_once $updateDir . '/../internal/filesystem.php';
$token = null;
if (isset($_GET['access_token'])) { //todo new_core_after del GET
$token = $_GET['access_token'];
} elseif (isset($_POST['access_token'])) {
$token = $_POST['access_token'];
}
if ($token === null || !filterAccessToken($token)) {
sendErrorResponse(422, 'Токен доступа отсутствует или некорректен');
}
$moduleId = null;
if (isset($_GET['module_id'])) { //todo new_core_after del GET
$moduleId = $_GET['module_id'];
} elseif (isset($_POST['module_id'])) {
$moduleId = $_POST['module_id'];
}
if ($moduleId === null || !filterInt($moduleId)) {
sendErrorResponse(422, 'Отсутствует идентификатор модуля или он указан некорректно');
}
if (!in_array($moduleId, array(SVEDEN, ABITUR, VSOKO))) {
sendErrorResponse(422, 'Не верно передан идентификатор модуля');
}
$version = null;
if (array_key_exists('version', $_GET)) { //todo new_core_after del GET
$version = $_GET['version'];
} elseif (array_key_exists('version', $_POST)) {
$version = $_POST['version'];
}
if ($version !== null && !filterVersion($version)) {
sendErrorResponse(422, 'Передан невалидный параметр версии последнего обновления');
}
$headers = array('Accept: application/json', 'Authorization: Bearer ' . $token);
$res = remoteRequest($apiDomen . 'pull_updates/checkAccessJson', true, false, $headers);
if ($res->curlHasError) {
sendErrorResponse(500, 'CURL ' . $res->curlErrorTxt);
}
if ($res->code !== 200) {
$err = 'Ошибка проверки подлинности токена. '
. (!empty($res->responseBody->message) ? $res->responseBody->message : 'Неизвестная ошибка');
sendErrorResponse($res->code, $err);
}
try {
$tmpPath = Path::join(Path::getCoreRootPath(), 'tmp');
if (!Filesystem::safeMkdir($tmpPath, 0755)) {
throw new RuntimeException('Не удалось создать директорию "' . $tmpPath . '" на вашем сервере');
}
$moduleVersionsPath = Path::join($tmpPath, 'versions');
if (!Filesystem::safeMkdir($moduleVersionsPath, 0755)) {
throw new RuntimeException('Не удалось создать директорию "' . $moduleVersionsPath . '" на вашем сервере');
}
$moduleVersionFilePath = Path::join($moduleVersionsPath, $moduleId . '.json');
if (!Filesystem::remove($moduleVersionFilePath, false)) {
throw new RuntimeException('Не удалось удалить файл "' . $moduleVersionFilePath . '" на вашем сервере');
}
$json = json_encode(array('version' => $version));
if (!Filesystem::safeMkfile($moduleVersionFilePath, 0755, $json)) {
throw new Exception('Не удалось записать служебную информацию в директорию: ' . $moduleVersionFilePath);
}
} catch (Exception $ex) {
sendErrorResponse(500, $ex->getMessage());
}
sendSuccessResponse('');
@@ -0,0 +1,77 @@
<?php
//todo new_core_after del file
$selfDir = dirname(__FILE__);
require_once $selfDir . '/../internal/helper.php';
require_once $selfDir . '/../internal/config.php';
$res = array();
$res['success'] = true;
$res['errorID'] = array();
$res['messages'] = array();
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$consent = filter_var($_POST['consent'], FILTER_SANITIZE_NUMBER_INT);
if($consent != true){
$res['success'] = false;
$res['messages'][] = 'Не получено согласие на обработку персональных данных.';
$res['errorID'][] = 'consent';
}
$code = filter_var($_POST['captcha'], FILTER_SANITIZE_STRING);
session_start();
if (!isset($_SESSION['captcha']) || strtoupper(trim($_SESSION['captcha'])) != strtoupper(trim($code))) {
$res['success'] = false;
$res['errorID'][] = 'captcha';
$res['messages'][] = 'Неверный код с картинки.';
}
unset($_SESSION['captcha']);
if ($res['success']) {
$res['success'] = false;
$headers = array('Accept: application/json');
$data = remoteRequest($apiDomen . 'oauth2/ClientCredentials', true,
array(
'client_id' => $clientId,
'client_secret' => $clientSecret,
'grant_type' => 'client_credentials',
), $headers
);
if ($data->code == 200) {
if (isset($data->responseBody)) {
$accessToken = $data->responseBody->access_token;
try {
$data = remoteRequest($apiDomen . 'oauth-via-app/vsoko/feedbackSendMail?access_token='
. $accessToken .
'&name=' . urlencode($name) .
'&email=' . urlencode($email) .
'&message=' . urlencode($message)
);
if ($data->code == 200) {
$res['success'] = true;
} else {
sendErrorResponse($data->code, $data->responseBody->message);
}
} catch (Exception $e) {
$res['message'] = 'Ошибка. '.$e->getMessage();
}
} else {
$res['message'] = 'Ошибка ' . $data->responseBody->message;
}
} else {
$res['message'] = $data->responseBody->message;
}
}
loadHeaders();
echo json_encode($res);
File diff suppressed because it is too large Load Diff