]> source.dussan.org Git - nextcloud-server.git/commitdiff
Handles file permissions. Protect against overwriting changes.
authorTom Needham <needham.thomas@gmail.com>
Sun, 8 Jan 2012 23:30:50 +0000 (23:30 +0000)
committerTom Needham <needham.thomas@gmail.com>
Sun, 8 Jan 2012 23:30:50 +0000 (23:30 +0000)
apps/files_texteditor/ajax/loadfile.php
apps/files_texteditor/ajax/mtime.php [new file with mode: 0644]
apps/files_texteditor/ajax/savefile.php
apps/files_texteditor/js/editor.js

index b06b0fa83d2de1f1a1c04aec027bd32466d6eae2..64e016be8c277551f261f97ad6608e939c8abc9f 100644 (file)
@@ -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 (file)
index 0000000..df90a68
--- /dev/null
@@ -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
index f1a2bafc12b71fe2049b3b1d0798d60831656359..1e073f3ba24e3d47a8ef6ef4d5b953a3ed2e91c6 100644 (file)
@@ -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')));        
+}
index 63e67460a3bc0bf5e8a4619b5a66ab56f9e7a27e..060c76705a1e6db06b97ed3367dd8bb116ca88ea 100644 (file)
@@ -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