Refactoring permissions. Allow guests to join session

pull/1/head
Victor Dubiniuk 11 years ago
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;
}

@ -25,6 +25,8 @@ namespace OCA\Documents;
class File {
protected $fileId;
protected $owner;
protected $path;
public function __construct($fileId){
if (!$fileId){
@ -34,38 +36,68 @@ 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
);
//is it shared
$sharedInfo = $this->getSharedBySource();
if (is_array($sharedInfo)){
$owner = $sharedInfo['uid_owner'];
$path = $sharedInfo['path'];
} else {
// owner is myself
$owner = \OCP\User::getUser();
$path = @$fileInfo[1];
}
if (is_array($sharedInfo)){
$owner = $sharedInfo['uid_owner'];
$path = $sharedInfo['path'];
if (!$path){
throw new \Exception($this->fileId . ' can not be resolved');
}
$view = new View('/' . $owner);
$this->owner = $owner;
} 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('/' . $this->owner);
$path = $this->path;
}
$view = new View('/' . $owner);
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){
$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId);
//is it shared
$sharedInfo = \OCP\Share::getItemSharedWithBySource(
//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…
Cancel
Save