Refactoring permissions. Allow guests to join session
This commit is contained in:
parent
fd60eddf2c
commit
e3e8ef5b58
@ -27,5 +27,17 @@ class Controller {
|
||||
\OCP\JSON::checkLoggedIn();
|
||||
return \OCP\User::getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do security precheck for not logged in users
|
||||
* @param bool callcheck - whether security token check is needed
|
||||
*/
|
||||
public static function preDispatchGuest($callcheck = true){
|
||||
if ($callcheck){
|
||||
\OCP\JSON::callCheck();
|
||||
}
|
||||
\OCP\JSON::checkAppEnabled('documents');
|
||||
return '(guest)';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,7 +37,11 @@
|
||||
|
||||
namespace OCA\Documents;
|
||||
|
||||
\OCP\JSON::checkLoggedIn();
|
||||
|
||||
//TODO: check if the session is related to a public share
|
||||
//\OCP\JSON::checkLoggedIn();
|
||||
|
||||
|
||||
\OCP\JSON::checkAppEnabled('documents');
|
||||
// session_write_close();
|
||||
|
||||
|
@ -14,34 +14,23 @@ namespace OCA\Documents;
|
||||
|
||||
class SessionController extends Controller{
|
||||
|
||||
public static function join($args){
|
||||
public static function joinAsGuest($args){
|
||||
$uid = self::preDispatchGuest();
|
||||
$token = @$args['token'];
|
||||
$file = File::getByShareToken($token);
|
||||
self::join($uid, $file);
|
||||
}
|
||||
|
||||
public static function joinAsUser($args){
|
||||
$uid = self::preDispatch();
|
||||
$fileId = intval(@$args['file_id']);
|
||||
$file = new File($fileId);
|
||||
self::join($uid, $file);
|
||||
}
|
||||
|
||||
protected static function join($uid, $file){
|
||||
try{
|
||||
$file = new File($fileId);
|
||||
list($ownerView, $path) = $file->getOwnerViewAndPath();
|
||||
$session = Session::getSessionByFileId($fileId);
|
||||
|
||||
//If there is no existing session we need to start a new one
|
||||
if (!$session || empty($session)){
|
||||
|
||||
$genesisPath = $ownerView->storeDocument($ownerView, $path);
|
||||
|
||||
if (!$genesisPath){
|
||||
throw new \Exception('Unable to copy document. Check permissions and make sure you have enought free space.');
|
||||
}
|
||||
|
||||
$hash = $ownerView->getHashByGenesis($genesisPath);
|
||||
$session = Session::add(
|
||||
$genesisPath,
|
||||
$hash,
|
||||
$file->getOwner(),
|
||||
$fileId
|
||||
);
|
||||
}
|
||||
|
||||
$session['permissions'] = $ownerView->getFilePermissions($path);
|
||||
$session['member_id'] = (string) Member::add($session['es_id'], $uid, Helper::getRandomColor());
|
||||
$session = Session::start($uid, $file);
|
||||
\OCP\JSON::success($session);
|
||||
exit();
|
||||
} catch (\Exception $e){
|
||||
@ -50,8 +39,8 @@ class SessionController extends Controller{
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Store the document content to its origin
|
||||
*/
|
||||
public static function save(){
|
||||
|
@ -46,5 +46,4 @@ class UserController extends Controller{
|
||||
|
||||
echo $image->show();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -57,13 +57,21 @@ $this->create('documents_session_listhtml', 'ajax/session/listHtml')
|
||||
->action('\OCA\Documents\SessionController', 'listAllHtml')
|
||||
;
|
||||
|
||||
$this->create('documents_session_join', 'ajax/session/join/{file_id}')
|
||||
$this->create('documents_session_joinasuser', 'ajax/session/joinasuser/{file_id}')
|
||||
->get()
|
||||
->action('\OCA\Documents\SessionController', 'join')
|
||||
->action('\OCA\Documents\SessionController', 'joinAsUser')
|
||||
;
|
||||
$this->create('documents_session_join', 'ajax/session/join/{file_id}')
|
||||
$this->create('documents_session_joinasuser', 'ajax/session/joinasuser/{file_id}')
|
||||
->post()
|
||||
->action('\OCA\Documents\SessionController', 'join')
|
||||
->action('\OCA\Documents\SessionController', 'joinAsUser')
|
||||
;
|
||||
$this->create('documents_session_joinasguest', 'ajax/session/joinasguest/{token}')
|
||||
->get()
|
||||
->action('\OCA\Documents\SessionController', 'joinAsGuest')
|
||||
;
|
||||
$this->create('documents_session_joinasguest', 'ajax/session/joinasguest/{token}')
|
||||
->post()
|
||||
->action('\OCA\Documents\SessionController', 'joinAsGuest')
|
||||
;
|
||||
|
||||
$this->create('documents_session_save', 'ajax/session/save')
|
||||
|
@ -5,6 +5,7 @@ var documentsMain = {
|
||||
_members: [],
|
||||
isEditormode : false,
|
||||
useUnstable : false,
|
||||
isGuest : false,
|
||||
|
||||
UI : {
|
||||
/* Overlay HTML */
|
||||
@ -89,10 +90,14 @@ var documentsMain = {
|
||||
"use strict";
|
||||
documentsMain.UI.init();
|
||||
|
||||
// Does anything indicate that we need to autostart a session?
|
||||
var fileId = parent.location.hash.replace(/\W*/g, '')
|
||||
|| $("[name='document']").val()
|
||||
;
|
||||
if (!OC.currentUser){
|
||||
documentsMain.isGuest = true;
|
||||
var fileId = $("[name='document']").val();
|
||||
} else {
|
||||
// Does anything indicate that we need to autostart a session?
|
||||
var fileId = parent.location.hash.replace(/\W*/g, '');
|
||||
}
|
||||
|
||||
|
||||
if ($("[name='document']").val()){
|
||||
// !Login page mess wih WebODF toolbars
|
||||
@ -138,7 +143,6 @@ var documentsMain = {
|
||||
initSession: function(response) {
|
||||
"use strict";
|
||||
|
||||
|
||||
if (!response || !response.es_id || !response.status || response.status==='error'){
|
||||
OC.Notification.show(t('documents', 'Failed to load this document. Please check if it can be opened with an external odt editor. This might also mean it has been unshared or deleted recently.'));
|
||||
documentsMain.prepareGrid();
|
||||
@ -175,9 +179,15 @@ var documentsMain = {
|
||||
|
||||
joinSession: function(fileId) {
|
||||
console.log('joining session '+fileId);
|
||||
var url;
|
||||
if (documentsMain.isGuest){
|
||||
url = OC.Router.generate('documents_session_joinasguest') + '/' + fileId
|
||||
} else {
|
||||
url = OC.Router.generate('documents_session_joinasuser') + '/' + fileId
|
||||
}
|
||||
$.post(
|
||||
OC.Router.generate('documents_session_join') + '/' + fileId,
|
||||
{},
|
||||
url,
|
||||
{ },
|
||||
documentsMain.initSession
|
||||
);
|
||||
},
|
||||
@ -230,7 +240,12 @@ var documentsMain = {
|
||||
// successfull shutdown - all is good.
|
||||
// TODO: proper session leaving call to server, either by webodfServerInstance or custom
|
||||
// documentsMain.webodfServerInstance.leaveSession(sessionId, memberId, function() {
|
||||
if (documentsMain.isGuest){
|
||||
$(document.body).attr('id', 'body-login');
|
||||
$('header,footer').show();
|
||||
}
|
||||
documentsMain.webodfEditorInstance.destroy(documentsMain.UI.hideEditor);
|
||||
|
||||
// });
|
||||
});
|
||||
},
|
||||
@ -240,7 +255,7 @@ var documentsMain = {
|
||||
},
|
||||
|
||||
show: function(){
|
||||
if (!OC.currentUser){
|
||||
if (documentsMain.isGuest){
|
||||
return;
|
||||
}
|
||||
|
||||
|
111
lib/file.php
111
lib/file.php
@ -25,6 +25,8 @@ namespace OCA\Documents;
|
||||
|
||||
class File {
|
||||
protected $fileId;
|
||||
protected $owner;
|
||||
protected $path;
|
||||
|
||||
public function __construct($fileId){
|
||||
if (!$fileId){
|
||||
@ -34,37 +36,67 @@ class File {
|
||||
$this->fileId = $fileId;
|
||||
}
|
||||
|
||||
public static function getByShareToken($token){
|
||||
$linkItem = \OCP\Share::getShareByToken($token);
|
||||
if (is_array($linkItem) && isset($linkItem['uid_owner'])) {
|
||||
// seems to be a valid share
|
||||
$rootLinkItem = \OCP\Share::resolveReShare($linkItem);
|
||||
$fileOwner = $rootLinkItem['uid_owner'];
|
||||
} else {
|
||||
throw new \Exception('This file was probably unshared');
|
||||
}
|
||||
|
||||
$file = new File($rootLinkItem['file_source']);
|
||||
$file->setOwner($rootLinkItem['uid_owner']);
|
||||
$file->setPath('/files' . $rootLinkItem['file_target']);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function getFileId(){
|
||||
return $this->fileId;
|
||||
}
|
||||
|
||||
public function setOwner($owner){
|
||||
$this->owner = $owner;
|
||||
}
|
||||
|
||||
public function setPath($path){
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string owner of the current file item
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getOwnerViewAndPath(){
|
||||
$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId);
|
||||
if (!$this->owner || !$this->path){
|
||||
$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId);
|
||||
|
||||
//is it shared
|
||||
$sharedInfo = \OCP\Share::getItemSharedWithBySource(
|
||||
'file',
|
||||
$this->fileId,
|
||||
\OCP\Share::FORMAT_NONE,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if (is_array($sharedInfo)){
|
||||
$owner = $sharedInfo['uid_owner'];
|
||||
$path = $sharedInfo['path'];
|
||||
} else {
|
||||
// owner is myself
|
||||
$owner = \OCP\User::getUser();
|
||||
$path = @$fileInfo[1];
|
||||
}
|
||||
|
||||
if (!$path){
|
||||
throw new \Exception($this->fileId . ' can not be resolved');
|
||||
}
|
||||
//is it shared
|
||||
$sharedInfo = $this->getSharedBySource();
|
||||
|
||||
$view = new View('/' . $owner);
|
||||
if (is_array($sharedInfo)){
|
||||
$owner = $sharedInfo['uid_owner'];
|
||||
$path = $sharedInfo['path'];
|
||||
} else {
|
||||
// owner is myself
|
||||
$owner = \OCP\User::getUser();
|
||||
$path = @$fileInfo[1];
|
||||
}
|
||||
|
||||
if (!$path){
|
||||
throw new \Exception($this->fileId . ' can not be resolved');
|
||||
}
|
||||
|
||||
$view = new View('/' . $owner);
|
||||
|
||||
$this->owner = $owner;
|
||||
} else {
|
||||
$view = new View('/' . $this->owner);
|
||||
$path = $this->path;
|
||||
}
|
||||
|
||||
if (!$view->file_exists($path)){
|
||||
throw new \Exception($path . ' doesn\'t exist');
|
||||
@ -74,25 +106,34 @@ class File {
|
||||
}
|
||||
|
||||
public function getOwner(){
|
||||
$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId);
|
||||
if (!$this->owner){
|
||||
|
||||
//is it shared
|
||||
$sharedInfo = \OCP\Share::getItemSharedWithBySource(
|
||||
$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId);
|
||||
|
||||
//is it shared
|
||||
$sharedInfo = $this->getSharedBySource();
|
||||
if (!is_array($sharedInfo)){
|
||||
$sharedInfo = $this->getSharedByLink();
|
||||
}
|
||||
|
||||
if (is_array($sharedInfo)){
|
||||
$this->owner = $sharedInfo['uid_owner'];
|
||||
} else {
|
||||
// owner is myself
|
||||
$this->owner = \OCP\User::getUser();
|
||||
}
|
||||
}
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
protected function getSharedBySource(){
|
||||
return \OCP\Share::getItemSharedWithBySource(
|
||||
'file',
|
||||
$this->fileId,
|
||||
\OCP\Share::FORMAT_NONE,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if (is_array($sharedInfo)){
|
||||
$owner = $sharedInfo['uid_owner'];
|
||||
} else {
|
||||
// owner is myself
|
||||
$owner = \OCP\User::getUser();
|
||||
}
|
||||
|
||||
return $owner;
|
||||
}
|
||||
|
||||
}
|
@ -21,14 +21,14 @@ class Member extends Db{
|
||||
const MEMBER_STATUS_ACTIVE = 1;
|
||||
const MEMBER_STATUS_INACTIVE = 2;
|
||||
|
||||
public static function add($esId, $displayname, $color){
|
||||
public static function add($esId, $uid, $color){
|
||||
$query = \OCP\DB::prepare('
|
||||
INSERT INTO ' . self::DB_TABLE . ' (`es_id`, `uid`, `color`, `last_activity`)
|
||||
VALUES (?, ?, ?, ?)
|
||||
');
|
||||
$query->execute(array(
|
||||
$esId,
|
||||
\OCP\User::getUser(),
|
||||
$uid,
|
||||
$color,
|
||||
time()
|
||||
));
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - Documents App
|
||||
*
|
||||
@ -11,15 +12,41 @@
|
||||
|
||||
namespace OCA\Documents;
|
||||
|
||||
class Session extends Db{
|
||||
class Session extends Db {
|
||||
|
||||
const DB_TABLE = '`*PREFIX*documents_session`';
|
||||
|
||||
|
||||
public static function start($uid, File $file){
|
||||
list($ownerView, $path) = $file->getOwnerViewAndPath();
|
||||
$session = Session::getSessionByFileId( $file->getFileId() );
|
||||
|
||||
//If there is no existing session we need to start a new one
|
||||
if (!$session || empty($session)){
|
||||
|
||||
$genesisPath = $ownerView->storeDocument($ownerView, $path);
|
||||
|
||||
if (!$genesisPath){
|
||||
throw new \Exception('Unable to copy document. Check permissions and make sure you have enought free space.');
|
||||
}
|
||||
|
||||
$hash = $ownerView->getHashByGenesis($genesisPath);
|
||||
$session = Session::add(
|
||||
$genesisPath, $hash, $file->getOwner(), $file->getFileId()
|
||||
);
|
||||
}
|
||||
|
||||
$session['permissions'] = $ownerView->getFilePermissions($path);
|
||||
$session['member_id'] = (string) Member::add($session['es_id'], $uid, Helper::getRandomColor());
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
public static function add($genesis, $hash, $owner, $fileId){
|
||||
$query = \OCP\DB::prepare('
|
||||
INSERT INTO ' . self::DB_TABLE . ' (`es_id`, `genesis_url`, `genesis_hash`, `owner`, `file_id`)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
');
|
||||
|
||||
|
||||
$data = array(
|
||||
'es_id' => self::getUniqueSessionId(),
|
||||
'genesis_url' => $genesis,
|
||||
@ -28,44 +55,44 @@ class Session extends Db{
|
||||
'file_id' => $fileId
|
||||
);
|
||||
$result = $query->execute(array_values($data));
|
||||
|
||||
|
||||
if ($result){
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function getAll(){
|
||||
$query = \OCP\DB::prepare('SELECT * FROM ' . self::DB_TABLE);
|
||||
$result = $query->execute();
|
||||
return $result->fetchAll();
|
||||
}
|
||||
|
||||
|
||||
public static function getSession($id){
|
||||
$query = \OCP\DB::prepare('SELECT * FROM ' . self::DB_TABLE . ' WHERE `es_id`= ?');
|
||||
$result = $query->execute(array($id));
|
||||
return $result->fetchRow();
|
||||
}
|
||||
|
||||
|
||||
public static function getInfo($esId){
|
||||
|
||||
$query = \OCP\DB::prepare('
|
||||
SELECT `s`.*, COUNT(`m`.`member_id`) AS `users`
|
||||
FROM ' . self::DB_TABLE . ' AS `s`
|
||||
LEFT JOIN `*PREFIX*documents_member` AS `m` ON `s`.`es_id`=`m`.`es_id`
|
||||
AND `m`.`status`='. Member::MEMBER_STATUS_ACTIVE .'
|
||||
AND `m`.`status`=' . Member::MEMBER_STATUS_ACTIVE . '
|
||||
AND `m`.`uid` != ?
|
||||
WHERE `s`.`es_id` = ?
|
||||
GROUP BY `m`.`es_id`
|
||||
');
|
||||
$result = $query->execute(
|
||||
array(
|
||||
\OCP\User::getUser(),
|
||||
$esId
|
||||
array(
|
||||
\OCP\User::getUser(),
|
||||
$esId
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$info = $result->fetchRow();
|
||||
if (!is_array($info)){
|
||||
$info = array();
|
||||
@ -75,24 +102,24 @@ class Session extends Db{
|
||||
|
||||
public static function getSessionByFileId($fileId){
|
||||
$sessions = self::getSessionsByFileIds(array($fileId));
|
||||
if (count($sessions) > 1) {
|
||||
Helper::errorLog('documents','more than one session found for file id ' . $fileId);
|
||||
if (count($sessions) > 1){
|
||||
Helper::errorLog('documents', 'more than one session found for file id ' . $fileId);
|
||||
}
|
||||
|
||||
if (count($sessions)) {
|
||||
|
||||
if (count($sessions)){
|
||||
return $sessions[0];
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static function getSessionsByFileIds($fileIds){
|
||||
if (!is_array($fileIds)){
|
||||
$fileIds = array($fileIds);
|
||||
}
|
||||
|
||||
|
||||
$stmt = self::buildPlaceholders($fileIds);
|
||||
$query = \OCP\DB::prepare('SELECT * FROM ' . self::DB_TABLE . ' WHERE `file_id` IN (' . $stmt .')');
|
||||
$query = \OCP\DB::prepare('SELECT * FROM ' . self::DB_TABLE . ' WHERE `file_id` IN (' . $stmt . ')');
|
||||
$result = $query->execute($fileIds);
|
||||
$sessions = $result->fetchAll();
|
||||
if (!is_array($sessions)){
|
||||
@ -100,34 +127,34 @@ class Session extends Db{
|
||||
}
|
||||
return $sessions;
|
||||
}
|
||||
|
||||
|
||||
public static function getInfoByFileid($fileIds){
|
||||
if (!is_array($fileIds)){
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
$stmt = self::buildPlaceholders($fileIds);
|
||||
if (!$stmt){
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
$query = \OCP\DB::prepare('
|
||||
SELECT `s`.*, COUNT(`m`.`member_id`) AS `users`
|
||||
FROM ' . self::DB_TABLE . ' AS `s`
|
||||
LEFT JOIN `*PREFIX*documents_member` AS `m` ON `s`.`es_id`=`m`.`es_id`
|
||||
AND `m`.`status`='. Member::MEMBER_STATUS_ACTIVE .'
|
||||
WHERE `s`.`file_id` IN (' . $stmt .')
|
||||
AND `m`.`status`=' . Member::MEMBER_STATUS_ACTIVE . '
|
||||
WHERE `s`.`file_id` IN (' . $stmt . ')
|
||||
GROUP BY `m`.`es_id`
|
||||
');
|
||||
$result = $query->execute($fileIds);
|
||||
|
||||
|
||||
$info = $result->fetchAll();
|
||||
if (!is_array($info)){
|
||||
$info = array();
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
|
||||
public static function cleanUp($esId){
|
||||
self::delete($esId);
|
||||
Member::deleteBySessionId($esId);
|
||||
@ -140,17 +167,17 @@ class Session extends Db{
|
||||
}
|
||||
|
||||
protected static function getUniqueSessionId(){
|
||||
do {
|
||||
do{
|
||||
// this prevents branching for stable5 for now:
|
||||
// OC_Util::generate_random_bytes was camelCased
|
||||
if (method_exists('\OC_Util', 'generate_random_bytes')) {
|
||||
if (method_exists('\OC_Util', 'generate_random_bytes')){
|
||||
$id = \OC_Util::generate_random_bytes(30);
|
||||
} else {
|
||||
$id = \OC_Util::generateRandomBytes(30);
|
||||
}
|
||||
} while (self::getSession($id));
|
||||
|
||||
}while (self::getSession($id));
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ if (isset($fileOwner)) {
|
||||
\OCP\Util::addStyle( 'documents', '3rdparty/webodf/dojo-app');
|
||||
\OCP\Util::addStyle( 'documents', '3rdparty/webodf/editor' );
|
||||
\OCP\Util::addScript('documents', 'documents');
|
||||
$tmpl->assign('document', $rootLinkItem['file_source']);
|
||||
$tmpl->assign('document', $token);
|
||||
} else {
|
||||
// TODO: show nice 404 page
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user