| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * ownCloud - Documents App | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @author Victor Dubiniuk | 
					
						
							|  |  |  |  * @copyright 2013 Victor Dubiniuk victor.dubiniuk@gmail.com | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is licensed under the Affero General Public License version 3 or | 
					
						
							|  |  |  |  * later. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | namespace OCA\Documents\Db; | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-26 20:16:53 +03:00
										 |  |  | use OCP\Security\ISecureRandom; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 18:34:58 +03:00
										 |  |  | use OCA\Documents\Filter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-05-13 23:17:25 +03:00
										 |  |  |  *  Session management | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * @method string getEsId() | 
					
						
							|  |  |  |  * @method int getFileId() | 
					
						
							|  |  |  |  * @method string getGenesisUrl() | 
					
						
							|  |  |  |  * @method string getOwner() | 
					
						
							|  |  |  |  * @method string getGenesisHash() | 
					
						
							|  |  |  |  *  | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | class Session extends \OCA\Documents\Db { | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * DB table | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	const DB_TABLE = '`*PREFIX*documents_session`'; | 
					
						
							|  |  |  | 	protected $tableName  = '`*PREFIX*documents_session`'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected $insertStatement  = 'INSERT INTO `*PREFIX*documents_session` (`es_id`, `genesis_url`, `genesis_hash`, `owner`, `file_id`) | 
					
						
							|  |  |  | 			VALUES (?, ?, ?, ?, ?)'; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	protected $loadStatement = 'SELECT * FROM `*PREFIX*documents_session` WHERE `es_id`= ?'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Start a editing session or return an existing one | 
					
						
							|  |  |  | 	 * @param string $uid of the user starting a session | 
					
						
							|  |  |  | 	 * @param \OCA\Documents\File $file - file object | 
					
						
							|  |  |  | 	 * @return array | 
					
						
							|  |  |  | 	 * @throws \Exception | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2014-04-10 21:23:26 +03:00
										 |  |  | 	public static function start($uid, $file){ | 
					
						
							| 
									
										
										
										
											2013-10-02 19:55:33 +03:00
										 |  |  | 		// Create a directory to store genesis
 | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | 		$genesis = new \OCA\Documents\Genesis($file); | 
					
						
							| 
									
										
										
										
											2015-09-18 00:15:18 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | 		$oldSession = new Session(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		$oldSession->loadBy('file_id', $file->getFileId()); | 
					
						
							| 
									
										
										
										
											2013-10-02 19:55:33 +03:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		//If there is no existing session we need to start a new one
 | 
					
						
							|  |  |  | 		if (!$oldSession->hasData()){ | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | 			$newSession = new Session(array( | 
					
						
							| 
									
										
										
										
											2013-11-09 17:29:12 +03:00
										 |  |  | 				$genesis->getPath(), | 
					
						
							|  |  |  | 				$genesis->getHash(), | 
					
						
							|  |  |  | 				$file->getOwner(), | 
					
						
							|  |  |  | 				$file->getFileId() | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 			)); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (!$newSession->insert()){ | 
					
						
							|  |  |  | 				throw new \Exception('Failed to add session into database'); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-04-11 23:12:23 +03:00
										 |  |  | 		$sessionData = $oldSession | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 					->loadBy('file_id', $file->getFileId()) | 
					
						
							|  |  |  | 					->getData() | 
					
						
							| 
									
										
										
										
											2013-11-09 17:29:12 +03:00
										 |  |  | 		; | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | 		$memberColor = \OCA\Documents\Helper::getMemberColor($uid); | 
					
						
							| 
									
										
										
										
											2015-09-18 00:15:18 +03:00
										 |  |  | 		$member = new \OCA\Documents\Db\Member([ | 
					
						
							| 
									
										
										
										
											2014-04-11 23:12:23 +03:00
										 |  |  | 			$sessionData['es_id'],  | 
					
						
							| 
									
										
										
										
											2013-11-25 23:14:32 +03:00
										 |  |  | 			$uid, | 
					
						
							|  |  |  | 			$memberColor, | 
					
						
							| 
									
										
										
										
											2014-04-09 17:48:48 +03:00
										 |  |  | 			time(), | 
					
						
							| 
									
										
										
										
											2014-04-11 00:59:51 +03:00
										 |  |  | 			intval($file->isPublicShare()), | 
					
						
							|  |  |  | 			$file->getToken() | 
					
						
							| 
									
										
										
										
											2015-09-18 00:15:18 +03:00
										 |  |  | 		]); | 
					
						
							| 
									
										
										
										
											2013-11-25 23:14:32 +03:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 		if (!$member->insert()){ | 
					
						
							|  |  |  | 			throw new \Exception('Failed to add member into database'); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-27 01:57:31 +03:00
										 |  |  | 		$sessionData['member_id'] = (string) $member->getLastInsertId(); | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		// Do we have OC_Avatar in out disposal?
 | 
					
						
							| 
									
										
										
										
											2015-08-28 19:32:54 +03:00
										 |  |  | 		if (\OC::$server->getConfig()->getSystemValue('enable_avatars', true) !== true){ | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 			$imageUrl = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=='; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			$imageUrl = $uid; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-04-09 17:48:48 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 01:57:31 +03:00
										 |  |  | 		$displayName = $file->isPublicShare()  | 
					
						
							|  |  |  | 			? $uid . ' ' . \OCA\Documents\Db\Member::getGuestPostfix()  | 
					
						
							|  |  |  | 			: \OC::$server->getUserSession()->getUser()->getDisplayName($uid) | 
					
						
							|  |  |  | 		; | 
					
						
							|  |  |  | 		$userId = $file->isPublicShare() ? $displayName : \OC::$server->getUserSession()->getUser()->getUID(); | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 		$op = new \OCA\Documents\Db\Op(); | 
					
						
							|  |  |  | 		$op->addMember( | 
					
						
							| 
									
										
										
										
											2014-04-11 23:12:23 +03:00
										 |  |  | 					$sessionData['es_id'], | 
					
						
							|  |  |  | 					$sessionData['member_id'], | 
					
						
							| 
									
										
										
										
											2014-04-09 17:48:48 +03:00
										 |  |  | 					$displayName, | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 					$userId, | 
					
						
							| 
									
										
										
										
											2013-11-25 23:14:32 +03:00
										 |  |  | 					$memberColor, | 
					
						
							|  |  |  | 					$imageUrl | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2015-09-18 00:15:18 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		$sessionData['title'] = basename($file->getPath()); | 
					
						
							|  |  |  | 		$sessionData['permissions'] = $file->getPermissions(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-04-11 23:12:23 +03:00
										 |  |  | 		return $sessionData; | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	public static function cleanUp($esId){ | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | 		$session = new Session(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		$session->deleteBy('es_id', $esId); | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-08-04 21:00:58 +03:00
										 |  |  | 		$member = new \OCA\Documents\Db\Member(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		$member->deleteBy('es_id', $esId); | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-08-04 20:56:24 +03:00
										 |  |  | 		$op= new \OCA\Documents\Db\Op(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		$op->deleteBy('es_id', $esId); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-11-11 23:06:27 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	public function syncOps($memberId, $currentHead, $clientHead, $clientOps){ | 
					
						
							|  |  |  | 		$hasOps = count($clientOps)>0; | 
					
						
							|  |  |  | 		$op = new \OCA\Documents\Db\Op(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		// TODO handle the case ($currentHead == "") && ($seqHead != "")
 | 
					
						
							|  |  |  | 		if ($clientHead == $currentHead) { | 
					
						
							|  |  |  | 			// matching heads
 | 
					
						
							|  |  |  | 			if ($hasOps) { | 
					
						
							|  |  |  | 				// incoming ops without conflict
 | 
					
						
							|  |  |  | 				// Add incoming ops, respond with a new head
 | 
					
						
							|  |  |  | 				$newHead = \OCA\Documents\Db\Op::addOpsArray($this->getEsId(), $memberId, $clientOps); | 
					
						
							|  |  |  | 				$result = array( | 
					
						
							|  |  |  | 						'result' => 'added', | 
					
						
							|  |  |  | 						'head_seq' => $newHead ? $newHead : $currentHead | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				// no incoming ops (just checking for new ops...)
 | 
					
						
							|  |  |  | 				$result = array( | 
					
						
							|  |  |  | 						'result' => 'new_ops', | 
					
						
							|  |  |  | 						'ops' => array(), | 
					
						
							|  |  |  | 						'head_seq' => $currentHead | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { // HEADs do not match
 | 
					
						
							|  |  |  | 			$result = array( | 
					
						
							|  |  |  | 						'result' => $hasOps ? 'conflict' : 'new_ops', | 
					
						
							|  |  |  | 						'ops' => $op->getOpsAfterJson($this->getEsId(), $clientHead), | 
					
						
							|  |  |  | 						'head_seq' => $currentHead, | 
					
						
							|  |  |  | 			);			 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		return $result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 	public function insert(){ | 
					
						
							|  |  |  | 		$esId = $this->getUniqueSessionId(); | 
					
						
							|  |  |  | 		array_unshift($this->data, $esId); | 
					
						
							| 
									
										
										
										
											2014-11-11 21:00:33 +03:00
										 |  |  | 		return parent::insert(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-31 20:24:55 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	public function updateGenesisHash($esId, $genesisHash){ | 
					
						
							|  |  |  | 		return $this->execute( | 
					
						
							|  |  |  | 			'UPDATE `*PREFIX*documents_session` SET `genesis_hash`=? WHERE `es_id`=?', | 
					
						
							|  |  |  | 			array( | 
					
						
							| 
									
										
										
										
											2013-11-09 18:24:03 +03:00
										 |  |  | 				$genesisHash, $esId | 
					
						
							| 
									
										
										
										
											2013-10-31 20:24:55 +03:00
										 |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	public function getInfo($esId){ | 
					
						
							|  |  |  | 		$result = $this->execute(' | 
					
						
							|  |  |  | 			SELECT `s`.*, COUNT(`m`.`member_id`) AS `users` | 
					
						
							|  |  |  | 			FROM ' . $this->tableName . ' AS `s` | 
					
						
							|  |  |  | 			LEFT JOIN `*PREFIX*documents_member` AS `m` ON `s`.`es_id`=`m`.`es_id` | 
					
						
							| 
									
										
										
										
											2014-08-04 21:00:58 +03:00
										 |  |  | 				AND `m`.`status`=' . Db\Member::MEMBER_STATUS_ACTIVE . ' | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 				AND `m`.`uid` != ? | 
					
						
							|  |  |  | 			WHERE `s`.`es_id` = ? | 
					
						
							|  |  |  | 			GROUP BY `m`.`es_id` | 
					
						
							|  |  |  | 			', | 
					
						
							| 
									
										
										
										
											2015-08-27 01:57:31 +03:00
										 |  |  | 			[ | 
					
						
							|  |  |  | 					\OC::$server->getUserSession()->getUser()->getUID(), | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 					$esId | 
					
						
							| 
									
										
										
										
											2015-08-27 01:57:31 +03:00
										 |  |  | 			] | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-28 19:32:54 +03:00
										 |  |  | 		$info = $result->fetch(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		if (!is_array($info)){ | 
					
						
							|  |  |  | 			$info = array(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return $info; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	protected function getUniqueSessionId(){ | 
					
						
							| 
									
										
										
										
											2014-08-04 20:51:50 +03:00
										 |  |  | 		$testSession = new Session(); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 		do{ | 
					
						
							| 
									
										
										
										
											2015-08-26 20:16:53 +03:00
										 |  |  | 			$id = \OC::$server->getSecureRandom() | 
					
						
							|  |  |  | 				->getMediumStrengthGenerator() | 
					
						
							|  |  |  | 				->generate(30, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS); | 
					
						
							| 
									
										
										
										
											2014-04-10 17:13:19 +03:00
										 |  |  | 		} while ($testSession->load($id)->hasData()); | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return $id; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |