summaryrefslogtreecommitdiffstats
path: root/apps/files_texteditor
diff options
context:
space:
mode:
authorTom Needham <needham.thomas@gmail.com>2012-01-08 23:30:50 +0000
committerTom Needham <needham.thomas@gmail.com>2012-01-08 23:30:50 +0000
commitf7f19af8164aa78c3d1a143c40098e48f00145b8 (patch)
tree6dd334e2d93338ee7737eca0519636e84a4dcac2 /apps/files_texteditor
parent65c37abef9a9fb7d5c8abae644f3aedb41cbb0a0 (diff)
downloadnextcloud-server-f7f19af8164aa78c3d1a143c40098e48f00145b8.tar.gz
nextcloud-server-f7f19af8164aa78c3d1a143c40098e48f00145b8.zip
Handles file permissions. Protect against overwriting changes.
Diffstat (limited to 'apps/files_texteditor')
-rw-r--r--apps/files_texteditor/ajax/loadfile.php28
-rw-r--r--apps/files_texteditor/ajax/mtime.php49
-rw-r--r--apps/files_texteditor/ajax/savefile.php67
-rw-r--r--apps/files_texteditor/js/editor.js145
4 files changed, 154 insertions, 135 deletions
diff --git a/apps/files_texteditor/ajax/loadfile.php b/apps/files_texteditor/ajax/loadfile.php
index b06b0fa83d2..64e016be8c2 100644
--- a/apps/files_texteditor/ajax/loadfile.php
+++ b/apps/files_texteditor/ajax/loadfile.php
@@ -28,13 +28,23 @@ require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
// Set the session key for the file we are about to edit.
-$path = isset($_GET['path']) ? $_GET['path'] : false;
-
-if($path){
- $sessionname = md5('oc_file_hash_'.$path);
- $filecontents = OC_Filesystem::file_get_contents($path);
- OC_Filesystem::update_session_file_hash($sessionname,sha1(htmlspecialchars($filecontents)));
- OC_JSON::success();
+$dir = isset($_GET['dir']) ? $_GET['dir'] : '';
+$filename = isset($_GET['file']) ? $_GET['file'] : '';
+if(!empty($filename))
+{
+ $path = $dir.'/'.$filename;
+ if(OC_Filesystem::is_writeable($path))
+ {
+ $mtime = OC_Filesystem::filemtime($path);
+ $filecontents = OC_Filesystem::file_get_contents($path);
+ OC_JSON::success(array('data' => array('filecontents' => $filecontents, 'write' => 'true', 'mtime' => $mtime)));
+ }
+ else
+ {
+ $mtime = OC_Filesystem::filemtime($path);
+ $filecontents = OC_Filesystem::file_get_contents($path);
+ OC_JSON::success(array('data' => array('filecontents' => $filecontents, 'write' => 'false', 'mtime' => $mtime)));
+ }
} else {
- OC_JSON::error();
-} \ No newline at end of file
+ OC_JSON::error(array('data' => array( 'message' => 'Invalid file path supplied.')));
+} \ No newline at end of file
diff --git a/apps/files_texteditor/ajax/mtime.php b/apps/files_texteditor/ajax/mtime.php
new file mode 100644
index 00000000000..df90a68ca7a
--- /dev/null
+++ b/apps/files_texteditor/ajax/mtime.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * ownCloud - files_texteditor
+ *
+ * @author Tom Needham
+ * @copyright 2011 Tom Needham contact@tomneedham.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Init owncloud
+require_once('../../../lib/base.php');
+
+
+// Check if we are a user
+OC_JSON::checkLoggedIn();
+
+// Get the path from GET
+$path = isset($_GEt['path']) ? $_GET['path'] : '';
+
+if($path != '')
+{
+ // Find the mtime
+ $mtime = OC_Filesystem::filemtime($path);
+ if($mtime)
+ {
+ OC_JSON::success(array('data' => array('path' => $path, 'mtime' => $mtime)));
+ }
+ else
+ {
+ OC_JSON::error();
+ }
+}
+else
+{
+ OC_JSON::error();
+} \ No newline at end of file
diff --git a/apps/files_texteditor/ajax/savefile.php b/apps/files_texteditor/ajax/savefile.php
index f1a2bafc12b..1e073f3ba24 100644
--- a/apps/files_texteditor/ajax/savefile.php
+++ b/apps/files_texteditor/ajax/savefile.php
@@ -27,47 +27,36 @@ require_once('../../../lib/base.php');
// Check if we are a user
OC_JSON::checkLoggedIn();
-// Save the file data
+// Get paramteres
$filecontents = htmlspecialchars_decode($_POST['filecontents']);
-$file = $_POST['file'];
-$dir = $_POST['dir'];
-$path = $dir.'/'.$file;
-$force = isset($_POST['force']) ? $_POST['force'] : false;
-$sessionname = sha1('oc_file_hash_'.$path);
+$path = isset($_POST['path']) ? $_POST['path'] : '';
+$mtime = isset($_POST['mtime']) ? $_POST['mtime'] : '';
-function do_save($path,$filecontents){
- $sessionname = md5('oc_file_hash_'.$path);
- OC_Filesystem::update_session_file_hash($sessionname,sha1(htmlspecialchars($filecontents)));
- OC_Filesystem::file_put_contents($path, $filecontents);
-}
-// Check if file modified whilst editing?
-if(isset($_SESSION[$sessionname])){
- if(!empty($_SESSION[$sessionname])){
- // Compare to current hash of file.
- $savedfilecontents = htmlspecialchars(OC_Filesystem::file_get_contents($path));
- $hash = md5($savedfilecontents);
- $originalhash = $_SESSION[$sessionname];
- // Compare with hash taken when file was opened
- if($hash != $originalhash){
- // Someone has played with the file while you were editing
- // Force save?
- if($force){
- do_save($path, $filecontents);
- OC_JSON::success();
- } else {
- // No force
- OC_JSON::error(array('data' => array( 'message' => $l10n->t('The file has been edited since you opened it. Overwrite the file?'))));
- }
- } else {
- // No body has edited it whilst you were, so save the file
- // Update the session hash.
- do_save($path,$filecontents);
- OC_JSON::success();
- }
+if($path != '' && $mtime != '')
+{
+ // Get file mtime
+ $filemtime = OC_Filesystem::filemtime($path);
+ if($mtime != $filemtime)
+ {
+ // Then the file has changed since opening
+ OC_JSON::error();
+ }
+ else
+ {
+ // File same as when opened
+ // Save file
+ if(OC_Filesystem::is_writeable($path))
+ {
+ OC_Filesystem::file_put_contents($path, $filecontents);
+ OC_JSON::success();
+ }
+ else
+ {
+ // Not writeable!
+ OC_JSON::error(array('data' => array( 'message' => 'Insufficient permissions')));
+ }
}
} else {
- // No session value set for soem reason, just save the file.
- do_save($path,$filecontents);
- OC_JSON::success();
-} \ No newline at end of file
+ OC_JSON::error(array('data' => array( 'message' => 'File path or mtime not supplied')));
+}
diff --git a/apps/files_texteditor/js/editor.js b/apps/files_texteditor/js/editor.js
index 63e67460a3b..060c76705a1 100644
--- a/apps/files_texteditor/js/editor.js
+++ b/apps/files_texteditor/js/editor.js
@@ -77,81 +77,42 @@ function editorIsShown(){
return is_editor_shown;
}
-function updateSessionFileHash(path){
- $.get(OC.filePath('files_texteditor','ajax','loadfile.php'),
- { path: path },
- function(jsondata){
- if(jsondata.status=='failure'){
- alert('Failed to update session file hash.');
- }
- }, "json");}
-
function doFileSave(){
if(editorIsShown()){
+ // Get file path
+ var path = $('#editor').attr('data-dir')+'/'+$('#editor').attr('data-filename');
+ // Get original mtime
+ var mtime = $('#editor').attr('data-mtime');
+ // Show saving spinner
$("#editor_save").die('click',doFileSave);
$('#editor_save').after('<img id="saving_icon" src="'+OC.filePath('core','img','loading.gif')+'"></img>');
- var filecontents = window.aceEditor.getSession().getValue();
- var dir = $('#editor').attr('data-dir');
- var file = $('#editor').attr('data-filename');
- $.post(OC.filePath('files_texteditor','ajax','savefile.php'), { filecontents: filecontents, file: file, dir: dir },function(jsondata){
-
- if(jsondata.status == 'failure'){
- var answer = confirm(jsondata.data.message);
- if(answer){
- $.post(OC.filePath('files_texteditor','ajax','savefile.php'),{ filecontents: filecontents, file: file, dir: dir, force: 'true' },function(jsondata){
- if(jsondata.status =='success'){
- $('#saving_icon').remove();
- $('#editor_save').after('<p id="save_result" style="float: left">Saved!</p>')
- setTimeout(function() {
- $('#save_result').fadeOut('slow',function(){
- $(this).remove();
- $("#editor_save").live('click',doFileSave);
- });
- }, 2000);
- }
- else {
- // Save error
- $('#saving_icon').remove();
- $('#editor_save').after('<p id="save_result" style="float: left">Failed!</p>');
- setTimeout(function() {
- $('#save_result').fadeOut('slow',function(){
- $(this).remove();
- $("#editor_save").live('click',doFileSave);
- });
- }, 2000);
- }
- }, 'json');
- }
- else {
- // Don't save!
- $('#saving_icon').remove();
- // Temporary measure until we get a tick icon
- $('#editor_save').after('<p id="save_result" style="float: left">Saved!</p>');
- setTimeout(function() {
- $('#save_result').fadeOut('slow',function(){
- $(this).remove();
- $("#editor_save").live('click',doFileSave);
- });
- }, 2000);
- }
- }
- else if(jsondata.status == 'success'){
- // Success
- $('#saving_icon').remove();
- // Temporary measure until we get a tick icon
- $('#editor_save').after('<p id="save_result" style="float: left">Saved!</p>');
- setTimeout(function() {
- $('#save_result').fadeOut('slow',function(){
- $(this).remove();
- $("#editor_save").live('click',doFileSave);
- });
- }, 2000);
- }
- }, 'json');
- giveEditorFocus();
- } else {
- return;
- }
+ // Get the data
+ var filecontents = window.aceEditor.getSession().getValue();
+ // Send the data
+ $.post(OC.filePath('files_texteditor','ajax','savefile.php'), { filecontents: filecontents, path: path, mtime: mtime },function(jsondata){
+ if(jsondata.status!='success'){
+ // Save failed
+ $('#saving_icon').remove();
+ $('#editor_save').after('<p id="save_result" style="float: left">Failed to save file</p>');
+ setTimeout(function() {
+ $('#save_result').fadeOut('slow',function(){
+ $(this).remove();
+ $("#editor_save").live('click',doFileSave);
+ });
+ }, 2000);
+ } else {
+ // Save OK
+ $('#saving_icon').remove();
+ $('#editor_save').after('<p id="save_result" style="float: left">Saved</p>')
+ setTimeout(function() {
+ $('#save_result').fadeOut('slow',function(){
+ $(this).remove();
+ $("#editor_save").live('click',doFileSave);
+ });
+ }, 2000);
+ }
+ },'json');
+ }
};
function giveEditorFocus(){
@@ -162,24 +123,34 @@ function showFileEditor(dir,filename){
if(!editorIsShown()){
// Loads the file editor and display it.
var data = $.ajax({
- url: OC.filePath('files','ajax','download.php')+'?files='+encodeURIComponent(filename)+'&dir='+encodeURIComponent(dir),
+ url: OC.filePath('files_texteditor','ajax','loadfile.php'),
+ data: 'file='+encodeURIComponent(filename)+'&dir='+encodeURIComponent(dir),
complete: function(data){
- // Initialise the editor
- updateSessionFileHash(dir+'/'+filename);
- showControls(filename);
- $('table').fadeOut('slow', function() {
- $('#editor').text(data.responseText);
- // encodeURIComponenet?
- $('#editor').attr('data-dir', dir);
- $('#editor').attr('data-filename', filename);
- window.aceEditor = ace.edit("editor");
- aceEditor.setShowPrintMargin(false);
- setEditorSize();
- setSyntaxMode(getFileExtension(filename));
- OC.addScript('files_texteditor','aceeditor/theme-clouds', function(){
- window.aceEditor.setTheme("ace/theme/clouds");
+ result = jQuery.parseJSON(data.responseText);
+ if(result.status == 'success'){
+ // Save mtime
+ $('#editor').attr('data-mtime', result.data.mtime);
+ // Initialise the editor
+ showControls(filename);
+ $('table').fadeOut('slow', function() {
+ $('#editor').text(result.data.filecontents);
+ $('#editor').attr('data-dir', dir);
+ $('#editor').attr('data-filename', filename);
+ window.aceEditor = ace.edit("editor");
+ aceEditor.setShowPrintMargin(false);
+ if(result.data.write=='false'){
+ aceEditor.setReadOnly(true);
+ }
+ setEditorSize();
+ setSyntaxMode(getFileExtension(filename));
+ OC.addScript('files_texteditor','aceeditor/theme-clouds', function(){
+ window.aceEditor.setTheme("ace/theme/clouds");
+ });
});
- });
+ } else {
+ // Failed to get the file.
+ alert(result.data.message);
+ }
// End success
}
// End ajax