Revise permissions system to support read, write, and delete
This commit is contained in:
parent
09e05d14a0
commit
d13ba0ee2d
|
@ -32,7 +32,7 @@
|
||||||
<length>128</length>
|
<length>128</length>
|
||||||
</field>
|
</field>
|
||||||
<field>
|
<field>
|
||||||
<name>is_writeable</name>
|
<name>permissions</name>
|
||||||
<type>integer</type>
|
<type>integer</type>
|
||||||
<notnull>true</notnull>
|
<notnull>true</notnull>
|
||||||
<length>1</length>
|
<length>1</length>
|
||||||
|
|
|
@ -32,10 +32,6 @@ $(document).ready(function() {
|
||||||
alert("remove");
|
alert("remove");
|
||||||
// TODO Remove corresponding row
|
// TODO Remove corresponding row
|
||||||
});
|
});
|
||||||
$('#toggle-private-advanced').live('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
$('#private-advanced').toggle();
|
|
||||||
});
|
|
||||||
$('#expire').datepicker({
|
$('#expire').datepicker({
|
||||||
dateFormat:'MM d, yy',
|
dateFormat:'MM d, yy',
|
||||||
altField: "#expire_time",
|
altField: "#expire_time",
|
||||||
|
@ -69,8 +65,8 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function createShareDialog(files) {
|
function createShareDialog(fileNames) {
|
||||||
var html = "<div id='dialog' title='Share "+files+"' align='center'>";
|
var html = "<div id='dialog' align='center'>";
|
||||||
html += "<label><input type='radio' name='share_type' value='private' checked='checked' /> Private</label>";
|
html += "<label><input type='radio' name='share_type' value='private' checked='checked' /> Private</label>";
|
||||||
html += "<label><input type='radio' name='share_type' value='public' /> Public</label>";
|
html += "<label><input type='radio' name='share_type' value='public' /> Public</label>";
|
||||||
html += "<br />";
|
html += "<br />";
|
||||||
|
@ -78,13 +74,12 @@ function createShareDialog(files) {
|
||||||
html += "<label>Share with <input placeholder='User or Group' class='uid_shared_with' /></label>";
|
html += "<label>Share with <input placeholder='User or Group' class='uid_shared_with' /></label>";
|
||||||
html += "<button id='hey' class='add-uid_shared_with fancybutton'>+</button>";
|
html += "<button id='hey' class='add-uid_shared_with fancybutton'>+</button>";
|
||||||
html += "<br />";
|
html += "<br />";
|
||||||
html += "<a id='toggle-private-advanced'>Advanced</a>";
|
html += "<div id='permissions'style='text-align: left'>";
|
||||||
|
html += "Permissions"
|
||||||
html += "<br />";
|
html += "<br />";
|
||||||
html += "<div id='private-advanced' style='display: none; text-align: left'>";
|
html += "<label><input type='checkbox' name='share_permissions' value='0' checked='checked' disabled='disable' /> Read</label><br />";
|
||||||
html += "<label><input type='checkbox' name='share_permissions' value='read' checked='checked' disabled='disable' /> Read</label><br />";
|
html += "<label><input type='checkbox' name='share_permissions' value='1' /> Write</label><br />";
|
||||||
html += "<label><input type='checkbox' name='share_permissions' value='write' /> Write</label><br />";
|
html += "<label><input type='checkbox' name='share_permissions' value='2' /> Delete</label><br />";
|
||||||
html += "<label><input type='checkbox' name='share_permissions' value='rename' /> Rename</label><br />";
|
|
||||||
html += "<label><input type='checkbox' name='share_permissions' value='delete' /> Delete</label><br />";
|
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
html += "<div id='public' style='display: none'>";
|
html += "<div id='public' style='display: none'>";
|
||||||
|
@ -95,6 +90,8 @@ function createShareDialog(files) {
|
||||||
html += "<button class='submit fancybutton'>Share</button>";
|
html += "<button class='submit fancybutton'>Share</button>";
|
||||||
html += "<div>";
|
html += "<div>";
|
||||||
$(html).dialog({
|
$(html).dialog({
|
||||||
|
title: "Share " + fileNames,
|
||||||
|
modal: true,
|
||||||
close: function(event, ui) {
|
close: function(event, ui) {
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ OC_HOOK::connect("OC_FILESYSTEM","post_rename", "OC_SHARE", "renameItem");
|
||||||
*/
|
*/
|
||||||
class OC_SHARE {
|
class OC_SHARE {
|
||||||
|
|
||||||
|
const WRITE = 1;
|
||||||
|
const DELETE = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO notify user a file is being shared with them?
|
* TODO notify user a file is being shared with them?
|
||||||
* Share an item, adds an entry into the database
|
* Share an item, adds an entry into the database
|
||||||
|
@ -101,7 +104,7 @@ class OC_SHARE {
|
||||||
$source = $folders['source'].substr($oldTarget, strlen($folders['target']));
|
$source = $folders['source'].substr($oldTarget, strlen($folders['target']));
|
||||||
$item = self::getItem($folders['target']);
|
$item = self::getItem($folders['target']);
|
||||||
$query = OC_DB::prepare("INSERT INTO *PREFIX*sharing VALUES(?,?,?,?,?)");
|
$query = OC_DB::prepare("INSERT INTO *PREFIX*sharing VALUES(?,?,?,?,?)");
|
||||||
$query->execute(array($item[0]['uid_owner'], OC_USER::getUser(), $source, $newTarget, $item[0]['is_writeable']));
|
$query->execute(array($item[0]['uid_owner'], OC_USER::getUser(), $source, $newTarget, $item[0]['permissions']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +114,7 @@ class OC_SHARE {
|
||||||
*/
|
*/
|
||||||
public static function getItem($target) {
|
public static function getItem($target) {
|
||||||
$target = self::cleanPath($target);
|
$target = self::cleanPath($target);
|
||||||
$query = OC_DB::prepare("SELECT uid_owner, source, is_writeable FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with = ? LIMIT 1");
|
$query = OC_DB::prepare("SELECT uid_owner, source, permissions FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with = ? LIMIT 1");
|
||||||
return $query->execute(array($target, OC_USER::getUser()))->fetchAll();
|
return $query->execute(array($target, OC_USER::getUser()))->fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +123,7 @@ class OC_SHARE {
|
||||||
* @return An array with all items the user is sharing
|
* @return An array with all items the user is sharing
|
||||||
*/
|
*/
|
||||||
public static function getMySharedItems() {
|
public static function getMySharedItems() {
|
||||||
$query = OC_DB::prepare("SELECT uid_shared_with, source, is_writeable FROM *PREFIX*sharing WHERE uid_owner = ?");
|
$query = OC_DB::prepare("SELECT uid_shared_with, source, permissions FROM *PREFIX*sharing WHERE uid_owner = ?");
|
||||||
return $query->execute(array(OC_USER::getUser()))->fetchAll();
|
return $query->execute(array(OC_USER::getUser()))->fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,32 +188,33 @@ class OC_SHARE {
|
||||||
return $result[0]['source'];
|
return $result[0]['source'];
|
||||||
} else {
|
} else {
|
||||||
$folders = self::getParentFolders($target);
|
$folders = self::getParentFolders($target);
|
||||||
if ($folders == false) {
|
if ($folders == true) {
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return $folders['source'].substr($target, strlen($folders['target']));
|
return $folders['source'].substr($target, strlen($folders['target']));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the user has write permission for the item at the specified target location
|
* Get the user's permissions for the item at the specified target location
|
||||||
* @param $target The target location of the item
|
* @param $target The target location of the item
|
||||||
* @return True if the user has write permission or false if read only
|
* @return The permissions, use bitwise operators to check against the constants WRITE and DELETE
|
||||||
*/
|
*/
|
||||||
public static function isWriteable($target) {
|
public static function getPermissions($target) {
|
||||||
$target = self::cleanPath($target);
|
$target = self::cleanPath($target);
|
||||||
$userAndGroups = self::getUserAndGroups();
|
$userAndGroups = self::getUserAndGroups();
|
||||||
$query = OC_DB::prepare("SELECT is_writeable FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with IN(".substr(str_repeat(",?", count($userAndGroups)), 1).") LIMIT 1");
|
$query = OC_DB::prepare("SELECT permissions FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with IN(".substr(str_repeat(",?", count($userAndGroups)), 1).") LIMIT 1");
|
||||||
$result = $query->execute(array_merge(array($target), $userAndGroups))->fetchAll();
|
$result = $query->execute(array_merge(array($target), $userAndGroups))->fetchAll();
|
||||||
if (count($result) > 0) {
|
if (count($result) > 0) {
|
||||||
return $result[0]['is_writeable'];
|
return $result[0]['permissions'];
|
||||||
} else {
|
} else {
|
||||||
// Check if the folder is writeable
|
$folders =self::getParentFolders($target);
|
||||||
$folders = OC_SHARE::getParentFolders($target);
|
if ($folders == true) {
|
||||||
$result = $query->execute(array_merge(array($target), $userAndGroups))->fetchAll();
|
$result = $query->execute(array_merge(array($folders), $userAndGroups))->fetchAll();
|
||||||
if (count($result) > 0) {
|
if (count($result) > 0) {
|
||||||
return $result[0]['is_writeable'];
|
return $result[0]['permissions'];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -245,18 +249,18 @@ class OC_SHARE {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change write permission for the specified item and user
|
* Change the permissions for the specified item and user
|
||||||
*
|
*
|
||||||
* You must construct a new shared item to change the write permission of a file inside a shared folder if the write permission differs from the folder
|
* You must construct a new shared item to change the permissions of a file inside a shared folder if the permissions differ from the folder
|
||||||
*
|
*
|
||||||
* @param $source The source location of the item
|
* @param $source The source location of the item
|
||||||
* @param $uid_shared_with Array of users to change the write permission for
|
* @param $uid_shared_with The user to change the permissions for
|
||||||
* @param $is_writeable True if the user has write permission or false if read only
|
* @param $permissions The permissions, use the constants WRITE and DELETE
|
||||||
*/
|
*/
|
||||||
public static function setIsWriteable($source, $uid_shared_with, $is_writeable) {
|
public static function setPermissions($source, $uid_shared_with, $permissions) {
|
||||||
$source = self::cleanPath($source);
|
$source = self::cleanPath($source);
|
||||||
$query = OC_DB::prepare("UPDATE *PREFIX*sharing SET is_writeable = ? WHERE SUBSTR(source, 1, ?) = ? AND uid_shared_with = ? AND uid_owner = ?");
|
$query = OC_DB::prepare("UPDATE *PREFIX*sharing SET permissions = ? WHERE SUBSTR(source, 1, ?) = ? AND uid_shared_with = ? AND uid_owner = ?");
|
||||||
$query->execute(array($is_writeable, strlen($source), $source, $uid_shared_with, OC_USER::getUser()));
|
$query->execute(array($permissions, strlen($source), $source, $uid_shared_with, OC_USER::getUser()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -59,7 +59,7 @@ class OC_FILESTORAGE_SHARED extends OC_FILESTORAGE {
|
||||||
} else {
|
} else {
|
||||||
$source = $this->getSource($path);
|
$source = $this->getSource($path);
|
||||||
if ($source) {
|
if ($source) {
|
||||||
if (OC_SHARE::isWriteable($this->datadir.$path)) {
|
if ($this->is_writeable($path)) {
|
||||||
$storage = OC_FILESYSTEM::getStorage($source);
|
$storage = OC_FILESYSTEM::getStorage($source);
|
||||||
return $storage->mkdir($this->getInternalPath($source));
|
return $storage->mkdir($this->getInternalPath($source));
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ class OC_FILESTORAGE_SHARED extends OC_FILESTORAGE {
|
||||||
|
|
||||||
public function getFolderSize($path) {
|
public function getFolderSize($path) {
|
||||||
if ($path == "" || $path == "/") {
|
if ($path == "" || $path == "/") {
|
||||||
$dbpath = OC_USER::getUser()."/files/Share/";
|
$dbpath = $this->datadir;
|
||||||
} else {
|
} else {
|
||||||
$source = $this->getSource($path);
|
$source = $this->getSource($path);
|
||||||
$dbpath = $this->getInternalPath($source);
|
$dbpath = $this->getInternalPath($source);
|
||||||
|
@ -267,10 +267,10 @@ class OC_FILESTORAGE_SHARED extends OC_FILESTORAGE {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function is_writeable($path) {
|
public function is_writeable($path) {
|
||||||
if ($path == "" || $path == "/") {
|
if ($path == "" || $path == "/" || OC_SHARE::getPermissions($this->datadir.$path) & OC_SHARE::WRITE) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return OC_SHARE::isWriteable($this->datadir.$path);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,44 +362,70 @@ class OC_FILESTORAGE_SHARED extends OC_FILESTORAGE {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO OC_SHARE::getPermissions()
|
|
||||||
public function file_put_contents($path, $data) {
|
public function file_put_contents($path, $data) {
|
||||||
|
if ($this->is_writeable($path)) {
|
||||||
$source = $this->getSource($path);
|
$source = $this->getSource($path);
|
||||||
if ($source) {
|
if ($source) {
|
||||||
$storage = OC_FILESYSTEM::getStorage($source);
|
$storage = OC_FILESYSTEM::getStorage($source);
|
||||||
return $storage->file_put_contents($this->getInternalPath($source), $data);
|
return $storage->file_put_contents($this->getInternalPath($source), $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function unlink($path) {
|
public function unlink($path) {
|
||||||
// The file will be removed from the database, but won't be touched on the owner's filesystem
|
|
||||||
$target = $this->datadir.$path;
|
$target = $this->datadir.$path;
|
||||||
// If file is inside a shared folder
|
// If the user has delete permission for the item, the source item will be deleted
|
||||||
|
if (OC_SHARE::getPermissions($target) & OC_SHARE::DELETE) {
|
||||||
|
$source = $this->getSource($path);
|
||||||
|
if ($source) {
|
||||||
|
$storage = OC_FILESYSTEM::getStorage($source);
|
||||||
|
return $storage->unlink($this->getInternalPath($source));
|
||||||
|
}
|
||||||
|
// The item will be removed from the database, but won't be touched on the owner's filesystem
|
||||||
|
} else {
|
||||||
|
// Check if the item is inside a shared folder
|
||||||
if (OC_SHARE::getParentFolders($target)) {
|
if (OC_SHARE::getParentFolders($target)) {
|
||||||
// If entry for file already exists
|
// If entry for item already exists
|
||||||
if (OC_SHARE::getItem($target)) {
|
if (OC_SHARE::getItem($target)) {
|
||||||
OC_SHARE::setTarget($target, "/");
|
OC_SHARE::setTarget($target, "/");
|
||||||
} else {
|
} else {
|
||||||
OC_SHARE::pullOutOfFolder($target, "/");
|
OC_SHARE::pullOutOfFolder($target, "/");
|
||||||
|
// If this is a folder being deleted, call setTarget in case there are any database entries inside the folder
|
||||||
|
if (self::is_dir($path)) {
|
||||||
|
OC_SHARE::setTarget($target, "/");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Delete the database entry
|
||||||
} else {
|
} else {
|
||||||
OC_SHARE::unshareFromMySelf($target);
|
OC_SHARE::unshareFromMySelf($target);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rename($path1, $path2) {
|
public function rename($path1, $path2) {
|
||||||
// The file will be renamed in the database, but won't be touched on the owner's filesystem
|
// If the user has write permission for the item, the source item will be renamed
|
||||||
|
if ($this->is_writeable($path1)) {
|
||||||
|
$source = $this->getSource($path1);
|
||||||
|
if ($source) {
|
||||||
|
$storage = OC_FILESYSTEM::getStorage($source);
|
||||||
|
return $storage->rename($path1, $path2);
|
||||||
|
}
|
||||||
|
// The item will be renamed in the database, but won't be touched on the owner's filesystem
|
||||||
|
} else {
|
||||||
$oldTarget = $this->datadir.$path1;
|
$oldTarget = $this->datadir.$path1;
|
||||||
$newTarget = $this->datadir.$path2;
|
$newTarget = $this->datadir.$path2;
|
||||||
if (OC_SHARE::getItem($oldTarget)) {
|
if (OC_SHARE::getItem($oldTarget)) {
|
||||||
OC_SHARE::setTarget($oldTarget, $newTarget);
|
OC_SHARE::setTarget($oldTarget, $newTarget);
|
||||||
|
// There is no entry in the database for the item, it must be inside a shared folder
|
||||||
} else {
|
} else {
|
||||||
OC_SHARE::pullOutOfFolder($oldTarget, $newTarget);
|
OC_SHARE::pullOutOfFolder($oldTarget, $newTarget);
|
||||||
|
// If this is a folder being renamed, call setTarget in case there are any database entries inside the folder
|
||||||
if (self::is_dir($path1)) {
|
if (self::is_dir($path1)) {
|
||||||
OC_SHARE::setTarget($oldTarget, $newTarget);
|
OC_SHARE::setTarget($oldTarget, $newTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +433,7 @@ class OC_FILESTORAGE_SHARED extends OC_FILESTORAGE {
|
||||||
if ($path2 == "" || $path2 == "/") {
|
if ($path2 == "" || $path2 == "/") {
|
||||||
// TODO Construct new shared item or should this not be allowed?
|
// TODO Construct new shared item or should this not be allowed?
|
||||||
} else {
|
} else {
|
||||||
if ($this->is_writeable($path)) {
|
if ($this->is_writeable($path2)) {
|
||||||
$tmpFile = $this->toTmpFile($path1);
|
$tmpFile = $this->toTmpFile($path1);
|
||||||
return $this->fromTmpFile($tmpFile, $path2);
|
return $this->fromTmpFile($tmpFile, $path2);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue