1
0
mirror of https://github.com/til-schneider/slim-wiki.git synced 2025-08-05 08:07:35 +02:00

Showing better error message if write permissions are missing

This commit is contained in:
til-schneider
2015-12-24 15:04:33 +01:00
parent 51787c25ac
commit e13a759294
5 changed files with 79 additions and 20 deletions

View File

@@ -4,6 +4,9 @@ $i18n = array(
'error.noJavaScript' => 'Bitte aktivieren Sie JavaScript in den Einstellungen Ihres Browser um diese Seite verwenden zu können.',
'error.browserNotSupported' => 'Ihr Browser wird nicht unterstützt. Bitte verwenden Sie einen aktuellen Browser.',
'error.errorLogged' => 'Es ist ein Fehler aufgetreten. Bitte prüfen Sie die Log-Datei.',
'error.editingArticleFailed' => 'Der Artikel kann nicht bearbeitet werden.',
'error.missingWritePermissions.article' => 'Der Server hat keine Schreibrechte für die Artikel-Datei:',
'error.missingWritePermissions.backup' => 'Der Server hat keine Schreibrechte für die Backup-Datei:',
'button.cancel' => 'Abbrechen',
'button.back' => 'Zurück',
'button.edit' => 'Bearbeiten',

View File

@@ -4,6 +4,9 @@ $i18n = array(
'error.noJavaScript' => 'Please activate JavaScript in the settings of your browser in order to use this site.',
'error.browserNotSupported' => 'Your browser is not supported. Please use an up-to-date browser.',
'error.errorLogged' => 'An error has occurred. Please have a look to the log file.',
'error.editingArticleFailed' => 'Editing article failed.',
'error.missingWritePermissions.article' => 'The server has no write permissions for the article file:',
'error.missingWritePermissions.backup' => 'The server has no write permissions for the backup file:',
'button.cancel' => 'Cancel',
'button.back' => 'Back',
'button.edit' => 'Edit',

View File

@@ -61,19 +61,24 @@ $mode = $data['mode'];
if ($mode != 'view') {
// Show an error message if JavaScript is off or if the browser is not supported.
// NOTE: In view mode we don't show an error. Instead, syntax highlighting will be off for unsupported browsers.
?><div id="fatal-error-message"><div><?php echo $i18n['error.noJavaScript']; ?></div><a class="btn btn-default" href="<?php echo $data['requestPath']; ?>"><?php echo $i18n['button.back']; ?></a></div>
<script type="text/javascript">
(function() {
var errElem = document.getElementById('fatal-error-message');
if (slimwiki.supportedBrowser) {
errElem.parentNode.removeChild(errElem);
} else {
errElem.firstChild.innerHTML = <?php echo json_encode($i18n['error.browserNotSupported']); ?>;
}
})();
</script>
<div id="error-alert"><div class="alert alert-warning"><?php echo $i18n['error.errorLogged']; ?></div></div>
?><div id="fatal-error-message"><div><?php echo ($mode == 'error') ? $data['fatalErrorMessage'] : $i18n['error.noJavaScript']; ?></div>
<a class="btn btn-default" href="<?php echo $data['requestPath']; ?>"><?php echo $i18n['button.back']; ?></a>
</div><?php
if ($mode != 'error') { ?>
<script type="text/javascript">
(function() {
var errElem = document.getElementById('fatal-error-message');
if (slimwiki.supportedBrowser) {
errElem.parentNode.removeChild(errElem);
} else {
errElem.firstChild.innerHTML = <?php echo json_encode($i18n['error.browserNotSupported']); ?>;
}
})();
</script>
<div id="error-alert"><div class="alert alert-warning"><?php echo $i18n['error.errorLogged']; ?></div></div>
<?php
}
}
if ($mode == 'edit') {
@@ -151,7 +156,7 @@ if ($mode == 'edit') {
?></div><?php // id="main-wrapper" ?>
<?php if ($mode != 'view') { ?>
<?php if ($mode == 'edit' || $mode == 'createUser') { ?>
<!-- build:js client/edit.js -->
<script src="client/libs/CodeMirror/lib/codemirror.js"></script>
<script src="client/libs/CodeMirror/addon/mode/overlay.js"></script> <!-- Allow language-in-language -->
@@ -169,13 +174,15 @@ if ($mode == 'edit') {
<script src="client/js/app-edit.js"></script>
<!-- endbuild -->
<?php } // if ($mode != 'view') ?>
<?php } // if ($mode == 'edit' || $mode == 'createUser') ?>
<?php if ($mode != 'error') { ?>
<!-- build:js client/view.js -->
<script src="client/libs/highlightjs/highlight.pack.js"></script>
<script src="client/js/app-view.js"></script>
<!-- endbuild -->
<?php } // if ($mode != 'error') ?>
</body>
</html>

View File

@@ -36,6 +36,32 @@ class EditorService {
}
}
public function checkForError($articleFilename) {
function canWriteFileOrParent($filename) {
if ($filename == '') {
return false;
} else if (file_exists($filename)) {
return is_writable($filename);
} else {
return canWriteFileOrParent(dirname($filename));
}
}
$articleFullFilename = $this->context->getArticleBaseDir() . $articleFilename;
if (! canWriteFileOrParent($articleFullFilename)) {
return $this->context->getI18n()['error.missingWritePermissions.article']
. ' <code>' . $articleFullFilename . '</code>';
}
$backupFullFilename = $this->context->getDataBaseDir() . $this->getBackupFilename($articleFilename);
if (! canWriteFileOrParent($backupFullFilename)) {
return $this->context->getI18n()['error.missingWritePermissions.backup']
. ' <code>' . $backupFullFilename . '</code>';
}
return null;
}
public function saveArticle($articleFilename, $markdownText) {
$this->assertLoggedIn();
@@ -43,23 +69,26 @@ class EditorService {
throw new Exception("Invalid article filename: '$articleFilename'");
}
// Set timezone
$this->context->getConfig();
// Write article file
$articleFullFilename = $this->context->getArticleBaseDir() . $articleFilename;
$articleDir = dirname($articleFullFilename);
if (! file_exists($articleDir)) {
mkdir($articleDir, 0777, true);
}
if (! is_writable(file_exists($articleFullFilename) ? $articleFullFilename : $articleDir)) {
throw new Exception("No write permissions for article file");
}
file_put_contents($articleFullFilename, $markdownText);
// Write backup file (one per day)
$backupFullFilename = $this->context->getDataBaseDir() . 'backup/' . $articleFilename . date('_Y-m-d') . '.gz';
$backupFullFilename = $this->context->getDataBaseDir() . $this->getBackupFilename($articleFilename);
$backupDir = dirname($backupFullFilename);
if (! file_exists($backupDir)) {
mkdir($backupDir, 0777, true);
}
if (! is_writable(file_exists($backupFullFilename) ? $backupFullFilename : $backupDir)) {
throw new Exception("No write permissions for backup file");
}
$fp = gzopen ($backupFullFilename, 'w9');
gzwrite ($fp, $markdownText);
gzclose($fp);
@@ -67,6 +96,13 @@ class EditorService {
return $this->context->getRenderService()->renderMarkdown($markdownText, true);
}
private function getBackupFilename($articleFilename) {
// Set timezone
$this->context->getConfig();
return 'backup/' . $articleFilename . date('_Y-m-d') . '.gz';
}
public function createUserConfig($user, $pass) {
$type = 'sha256';
$salt = uniqid(mt_rand(), true);

View File

@@ -58,8 +58,8 @@ class Main {
try {
$responseData['result'] = call_user_func_array(array($object, $methodName), $requestData['params']);
} catch (Exception $exc) {
$msg = "Calling RPC $objectName.$methodName failed";
error_log($msg . ': ' . $exc->getMessage());
$msg = "Calling RPC $objectName.$methodName failed: " . $exc->getMessage();
error_log($msg);
$responseData['error'] = array( 'code' => -32000, 'message' => $msg );
}
}
@@ -102,10 +102,20 @@ class Main {
} else {
$config = $this->context->getConfig();
$fatalErrorMessage = null;
if ($mode == 'edit') {
$fatalErrorMessage = $this->context->getEditorService()->checkForError($articleFilename);
if ($fatalErrorMessage != null) {
$fatalErrorMessage = $this->context->getI18n()['error.editingArticleFailed'] . '<br/>' . $fatalErrorMessage;
$mode = 'error';
}
}
$data = array();
$data['baseUrl'] = $baseUrl;
$data['basePath'] = $basePath;
$data['mode'] = $mode;
$data['fatalErrorMessage'] = $fatalErrorMessage;
foreach (array('wikiName', 'footerHtml') as $key) {
$data[$key] = $config[$key];