Refactoring permissions. Allow guests to join session

pull/1/head
Victor Dubiniuk 11 years ago
parent fd60eddf2c
commit e3e8ef5b58

@ -28,4 +28,16 @@ class Controller {
return \OCP\User::getUser(); 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; namespace OCA\Documents;
\OCP\JSON::checkLoggedIn();
//TODO: check if the session is related to a public share
//\OCP\JSON::checkLoggedIn();
\OCP\JSON::checkAppEnabled('documents'); \OCP\JSON::checkAppEnabled('documents');
// session_write_close(); // session_write_close();

@ -14,34 +14,23 @@ namespace OCA\Documents;
class SessionController extends Controller{ 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(); $uid = self::preDispatch();
$fileId = intval(@$args['file_id']); $fileId = intval(@$args['file_id']);
try{
$file = new File($fileId); $file = new File($fileId);
list($ownerView, $path) = $file->getOwnerViewAndPath(); self::join($uid, $file);
$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); protected static function join($uid, $file){
$session = Session::add( try{
$genesisPath, $session = Session::start($uid, $file);
$hash,
$file->getOwner(),
$fileId
);
}
$session['permissions'] = $ownerView->getFilePermissions($path);
$session['member_id'] = (string) Member::add($session['es_id'], $uid, Helper::getRandomColor());
\OCP\JSON::success($session); \OCP\JSON::success($session);
exit(); exit();
} catch (\Exception $e){ } catch (\Exception $e){

@ -46,5 +46,4 @@ class UserController extends Controller{
echo $image->show(); echo $image->show();
} }
} }

@ -57,13 +57,21 @@ $this->create('documents_session_listhtml', 'ajax/session/listHtml')
->action('\OCA\Documents\SessionController', 'listAllHtml') ->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() ->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() ->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') $this->create('documents_session_save', 'ajax/session/save')

@ -5,6 +5,7 @@ var documentsMain = {
_members: [], _members: [],
isEditormode : false, isEditormode : false,
useUnstable : false, useUnstable : false,
isGuest : false,
UI : { UI : {
/* Overlay HTML */ /* Overlay HTML */
@ -89,10 +90,14 @@ var documentsMain = {
"use strict"; "use strict";
documentsMain.UI.init(); documentsMain.UI.init();
if (!OC.currentUser){
documentsMain.isGuest = true;
var fileId = $("[name='document']").val();
} else {
// Does anything indicate that we need to autostart a session? // Does anything indicate that we need to autostart a session?
var fileId = parent.location.hash.replace(/\W*/g, '') var fileId = parent.location.hash.replace(/\W*/g, '');
|| $("[name='document']").val() }
;
if ($("[name='document']").val()){ if ($("[name='document']").val()){
// !Login page mess wih WebODF toolbars // !Login page mess wih WebODF toolbars
@ -138,7 +143,6 @@ var documentsMain = {
initSession: function(response) { initSession: function(response) {
"use strict"; "use strict";
if (!response || !response.es_id || !response.status || response.status==='error'){ 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.')); 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(); documentsMain.prepareGrid();
@ -175,8 +179,14 @@ var documentsMain = {
joinSession: function(fileId) { joinSession: function(fileId) {
console.log('joining session '+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( $.post(
OC.Router.generate('documents_session_join') + '/' + fileId, url,
{ }, { },
documentsMain.initSession documentsMain.initSession
); );
@ -230,7 +240,12 @@ var documentsMain = {
// successfull shutdown - all is good. // successfull shutdown - all is good.
// TODO: proper session leaving call to server, either by webodfServerInstance or custom // TODO: proper session leaving call to server, either by webodfServerInstance or custom
// documentsMain.webodfServerInstance.leaveSession(sessionId, memberId, function() { // documentsMain.webodfServerInstance.leaveSession(sessionId, memberId, function() {
if (documentsMain.isGuest){
$(document.body).attr('id', 'body-login');
$('header,footer').show();
}
documentsMain.webodfEditorInstance.destroy(documentsMain.UI.hideEditor); documentsMain.webodfEditorInstance.destroy(documentsMain.UI.hideEditor);
// }); // });
}); });
}, },
@ -240,7 +255,7 @@ var documentsMain = {
}, },
show: function(){ show: function(){
if (!OC.currentUser){ if (documentsMain.isGuest){
return; return;
} }

@ -25,6 +25,8 @@ namespace OCA\Documents;
class File { class File {
protected $fileId; protected $fileId;
protected $owner;
protected $path;
public function __construct($fileId){ public function __construct($fileId){
if (!$fileId){ if (!$fileId){
@ -34,22 +36,46 @@ class File {
$this->fileId = $fileId; $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 * @return string owner of the current file item
* @throws \Exception * @throws \Exception
*/ */
public function getOwnerViewAndPath(){ public function getOwnerViewAndPath(){
if (!$this->owner || !$this->path){
$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId); $fileInfo = \OC\Files\Cache\Cache::getById($this->fileId);
//is it shared //is it shared
$sharedInfo = \OCP\Share::getItemSharedWithBySource( $sharedInfo = $this->getSharedBySource();
'file',
$this->fileId,
\OCP\Share::FORMAT_NONE,
null,
true
);
if (is_array($sharedInfo)){ if (is_array($sharedInfo)){
$owner = $sharedInfo['uid_owner']; $owner = $sharedInfo['uid_owner'];
@ -66,6 +92,12 @@ class File {
$view = new View('/' . $owner); $view = new View('/' . $owner);
$this->owner = $owner;
} else {
$view = new View('/' . $this->owner);
$path = $this->path;
}
if (!$view->file_exists($path)){ if (!$view->file_exists($path)){
throw new \Exception($path . ' doesn\'t exist'); throw new \Exception($path . ' doesn\'t exist');
} }
@ -74,25 +106,34 @@ class File {
} }
public function getOwner(){ public function getOwner(){
if (!$this->owner){
$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId); $fileInfo = \OC\Files\Cache\Cache::getById($this->fileId);
//is it shared //is it shared
$sharedInfo = \OCP\Share::getItemSharedWithBySource( $sharedInfo = $this->getSharedBySource();
'file', if (!is_array($sharedInfo)){
$this->fileId, $sharedInfo = $this->getSharedByLink();
\OCP\Share::FORMAT_NONE, }
null,
true
);
if (is_array($sharedInfo)){ if (is_array($sharedInfo)){
$owner = $sharedInfo['uid_owner']; $this->owner = $sharedInfo['uid_owner'];
} else { } else {
// owner is myself // owner is myself
$owner = \OCP\User::getUser(); $this->owner = \OCP\User::getUser();
}
}
return $this->owner;
} }
return $owner; protected function getSharedBySource(){
return \OCP\Share::getItemSharedWithBySource(
'file',
$this->fileId,
\OCP\Share::FORMAT_NONE,
null,
true
);
} }
} }

@ -21,14 +21,14 @@ class Member extends Db{
const MEMBER_STATUS_ACTIVE = 1; const MEMBER_STATUS_ACTIVE = 1;
const MEMBER_STATUS_INACTIVE = 2; const MEMBER_STATUS_INACTIVE = 2;
public static function add($esId, $displayname, $color){ public static function add($esId, $uid, $color){
$query = \OCP\DB::prepare(' $query = \OCP\DB::prepare('
INSERT INTO ' . self::DB_TABLE . ' (`es_id`, `uid`, `color`, `last_activity`) INSERT INTO ' . self::DB_TABLE . ' (`es_id`, `uid`, `color`, `last_activity`)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
'); ');
$query->execute(array( $query->execute(array(
$esId, $esId,
\OCP\User::getUser(), $uid,
$color, $color,
time() time()
)); ));

@ -1,4 +1,5 @@
<?php <?php
/** /**
* ownCloud - Documents App * ownCloud - Documents App
* *
@ -12,8 +13,34 @@
namespace OCA\Documents; namespace OCA\Documents;
class Session extends Db { class Session extends Db {
const DB_TABLE = '`*PREFIX*documents_session`'; 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){ public static function add($genesis, $hash, $owner, $fileId){
$query = \OCP\DB::prepare(' $query = \OCP\DB::prepare('
INSERT INTO ' . self::DB_TABLE . ' (`es_id`, `genesis_url`, `genesis_hash`, `owner`, `file_id`) INSERT INTO ' . self::DB_TABLE . ' (`es_id`, `genesis_url`, `genesis_hash`, `owner`, `file_id`)

@ -38,7 +38,7 @@ if (isset($fileOwner)) {
\OCP\Util::addStyle( 'documents', '3rdparty/webodf/dojo-app'); \OCP\Util::addStyle( 'documents', '3rdparty/webodf/dojo-app');
\OCP\Util::addStyle( 'documents', '3rdparty/webodf/editor' ); \OCP\Util::addStyle( 'documents', '3rdparty/webodf/editor' );
\OCP\Util::addScript('documents', 'documents'); \OCP\Util::addScript('documents', 'documents');
$tmpl->assign('document', $rootLinkItem['file_source']); $tmpl->assign('document', $token);
} else { } else {
// TODO: show nice 404 page // TODO: show nice 404 page
} }

Loading…
Cancel
Save