예제 #1
0
 private static function getURIObject($objectURI, $type)
 {
     $Types = ucwords($type) . 's';
     $types = strtolower($Types);
     $libraryType = null;
     $baseURI = self::getBaseURI();
     // If not found, try global URI
     if (strpos($objectURI, $baseURI) !== 0) {
         throw new Exception("Invalid base URI '{$objectURI}'");
     }
     $objectURI = substr($objectURI, strlen($baseURI));
     $typeRE = "/^(users|groups)\\/([0-9]+)(?:\\/|\$)/";
     if (!preg_match($typeRE, $objectURI, $matches)) {
         throw new Exception("Invalid library URI '{$objectURI}'");
     }
     $libraryType = substr($matches[1], 0, -1);
     $id = $matches[2];
     $objectURI = preg_replace($typeRE, '', $objectURI);
     if ($libraryType == 'user') {
         if (!Zotero_Users::exists($id)) {
             return false;
         }
         $libraryID = Zotero_Users::getLibraryIDFromUserID($id);
     } else {
         if ($libraryType == 'group') {
             if (!Zotero_Groups::get($id)) {
                 return false;
             }
             $libraryID = Zotero_Groups::getLibraryIDFromGroupID($id);
         } else {
             throw new Exception("Invalid library type {$libraryType}");
         }
     }
     if ($type === 'library') {
         return $libraryID;
     } else {
         // TODO: objectID-based URI?
         if (!preg_match($types . "\\/([A-Z0-9]{8})", $objectURI, $matches)) {
             throw new Exception("Invalid object URI '{$objectURI}'");
         }
         $objectKey = $matches[1];
         return call_user_func(array("Zotero_{$Types}", "getByLibraryAndKey"), $libraryID, $objectKey);
     }
 }
예제 #2
0
 protected function setKeyPermissions($keyObj, $accessElement)
 {
     foreach ($accessElement as $accessField => $accessVal) {
         // 'write' is handled below
         if ($accessField == 'write') {
             continue;
         }
         // Group library access (<access group="23456"/>)
         if ($accessField == 'group') {
             // Grant access to all groups
             if ($accessVal === 0) {
                 $keyObj->setPermission(0, 'group', true);
                 $keyObj->setPermission(0, 'write', $accessElement['write']);
             } else {
                 $group = Zotero_Groups::get($accessVal);
                 if (!$group) {
                     $this->e400("Group not found");
                 }
                 if (!$group->hasUser($keyObj->userID)) {
                     $this->e400("User {$this->id} is not a member of group {$group->id}");
                 }
                 $keyObj->setPermission($group->libraryID, 'library', true);
                 $keyObj->setPermission($group->libraryID, 'write', $accessElement['write']);
             }
         } else {
             $libraryID = Zotero_Users::getLibraryIDFromUserID($keyObj->userID);
             $keyObj->setPermission($libraryID, $accessField, $accessVal);
             $keyObj->setPermission($libraryID, 'write', $accessElement['write']);
         }
     }
 }
예제 #3
0
 public static function setUpBeforeClass()
 {
     require "include/config.inc.php";
     self::$config = $config;
     self::$config['userLibraryID'] = Zotero_Users::getLibraryIDFromUserID($config['userID']);
 }
예제 #4
0
 /**
  * For HTTP Auth and session-based auth, generate blanket user permissions
  * manually, since there's no key object
  */
 protected function grantUserPermissions($userID)
 {
     $this->permissions = new Zotero_Permissions($userID);
     $libraryID = Zotero_Users::getLibraryIDFromUserID($userID);
     // Grant user permissions on own library and all groups
     $this->permissions->setPermission($libraryID, 'library', true);
     $this->permissions->setPermission($libraryID, 'files', true);
     $this->permissions->setPermission($libraryID, 'notes', true);
     $this->permissions->setPermission($libraryID, 'write', true);
     $this->permissions->setPermission(0, 'library', true);
     $this->permissions->setPermission(0, 'write', true);
 }
예제 #5
0
 public static function getByUserID($userID)
 {
     $libraryID = Zotero_Users::getLibraryIDFromUserID($userID);
     return self::getByLibraryID($libraryID);
 }
예제 #6
0
 private static function getDeletedObjectIDs($userID, $timestamp, $includeAllUserObjects = false)
 {
     /*
     $sql = "SELECT version FROM version WHERE schema='syncdeletelog'";
     $syncLogStart = Zotero_DB::valueQuery($sql);
     if (!$syncLogStart) {
     	throw ('Sync log start time not found');
     }
     */
     /*
     // Last sync time is before start of log
     if ($lastSyncDate && new Date($syncLogStart * 1000) > $lastSyncDate) {
     	return -1;
     }
     */
     // Personal library
     $shardID = Zotero_Shards::getByUserID($userID);
     $libraryID = Zotero_Users::getLibraryIDFromUserID($userID);
     $shardLibraryIDs[$shardID] = array($libraryID);
     // Group libraries
     if ($includeAllUserObjects) {
         $groupIDs = Zotero_Groups::getUserGroups($userID);
         if ($groupIDs) {
             // Separate groups into shards for querying
             foreach ($groupIDs as $groupID) {
                 $libraryID = Zotero_Groups::getLibraryIDFromGroupID($groupID);
                 $shardID = Zotero_Shards::getByLibraryID($libraryID);
                 if (!isset($shardLibraryIDs[$shardID])) {
                     $shardLibraryIDs[$shardID] = array();
                 }
                 $shardLibraryIDs[$shardID][] = $libraryID;
             }
         }
     }
     // Send query at each shard
     $rows = array();
     foreach ($shardLibraryIDs as $shardID => $libraryIDs) {
         $sql = "SELECT libraryID, objectType, id, timestamp\n\t\t\t\t\tFROM syncDeleteLogIDs WHERE libraryID IN (" . implode(', ', array_fill(0, sizeOf($libraryIDs), '?')) . ")";
         $params = $libraryIDs;
         if ($timestamp) {
             // Send any entries from before these were being properly sent
             if ($timestamp < 1260778500) {
                 $sql .= " AND (timestamp >= FROM_UNIXTIME(?) OR timestamp BETWEEN 1257968068 AND FROM_UNIXTIME(?))";
                 $params[] = $timestamp;
                 $params[] = 1260778500;
             } else {
                 $sql .= " AND timestamp >= FROM_UNIXTIME(?)";
                 $params[] = $timestamp;
             }
         }
         $sql .= " ORDER BY timestamp";
         $shardRows = Zotero_DB::query($sql, $params, $shardID);
         if ($shardRows) {
             $rows = array_merge($rows, $shardRows);
         }
     }
     if (!$rows) {
         return false;
     }
     $deletedIDs = array('groups' => array());
     foreach ($rows as $row) {
         $type = $row['objectType'] . 's';
         $deletedIDs[$type][] = $row['id'];
     }
     return $deletedIDs;
 }
예제 #7
0
 public static function getUserUsage($userID)
 {
     $usage = array();
     $libraryID = Zotero_Users::getLibraryIDFromUserID($userID);
     $sql = "SELECT SUM(size) AS bytes FROM storageFileItems\n\t\t\t\tJOIN items USING (itemID) WHERE libraryID=?";
     $libraryBytes = Zotero_DB::valueQuery($sql, $libraryID, Zotero_Shards::getByLibraryID($libraryID));
     $usage['library'] = round($libraryBytes / 1024 / 1024, 1);
     $groupBytes = 0;
     $usage['groups'] = array();
     $ownedLibraries = Zotero_Groups::getUserOwnedGroupLibraries($userID);
     if ($ownedLibraries) {
         $shardIDs = Zotero_Groups::getUserGroupShards($userID);
         foreach ($shardIDs as $shardID) {
             $sql = "SELECT libraryID, SUM(size) AS `bytes` FROM storageFileItems\n\t\t\t\t\t\tJOIN items I USING (itemID)\n\t\t\t\t\t\tWHERE libraryID IN\n\t\t\t\t\t\t(" . implode(', ', array_fill(0, sizeOf($ownedLibraries), '?')) . ")\n\t\t\t\t\t\tGROUP BY libraryID WITH ROLLUP";
             $libraries = Zotero_DB::query($sql, $ownedLibraries, $shardID);
             if ($libraries) {
                 foreach ($libraries as $library) {
                     if ($library['libraryID']) {
                         $usage['groups'][] = array('id' => Zotero_Groups::getGroupIDFromLibraryID($library['libraryID']), 'usage' => round($library['bytes'] / 1024 / 1024, 1));
                     } else {
                         $groupBytes += $library['bytes'];
                     }
                 }
             }
         }
     }
     $usage['total'] = round(($libraryBytes + $groupBytes) / 1024 / 1024, 1);
     return $usage;
 }
예제 #8
0
 public static function getUserLibraries($userID)
 {
     return array_merge(array(Zotero_Users::getLibraryIDFromUserID($userID)), Zotero_Groups::getUserGroupLibraries($userID));
 }
예제 #9
0
 public static function isEditable($obj)
 {
     $type = static::field('object');
     // Only enforce for sync controller for now
     if (empty($GLOBALS['controller']) || !$GLOBALS['controller'] instanceof SyncController) {
         return true;
     }
     // Make sure user has access privileges to delete
     $userID = $GLOBALS['controller']->userID;
     if (!$userID) {
         return true;
     }
     $objectLibraryID = $obj->libraryID;
     $libraryType = Zotero_Libraries::getType($objectLibraryID);
     switch ($libraryType) {
         case 'user':
             if (!empty($GLOBALS['controller']->userLibraryID)) {
                 $userLibraryID = $GLOBALS['controller']->userLibraryID;
             } else {
                 $userLibraryID = Zotero_Users::getLibraryIDFromUserID($userID);
             }
             if ($objectLibraryID != $userLibraryID) {
                 return false;
             }
             return true;
         case 'group':
             $groupID = Zotero_Groups::getGroupIDFromLibraryID($objectLibraryID);
             $group = Zotero_Groups::get($groupID);
             if (!$group->hasUser($userID) || !$group->userCanEdit($userID)) {
                 return false;
             }
             if ($type == 'item' && $obj->isImportedAttachment() && !$group->userCanEditFiles($userID)) {
                 return false;
             }
             return true;
         default:
             throw new Exception("Unsupported library type '{$libraryType}'");
     }
 }
예제 #10
0
 private function logGroupLibraryRemoval()
 {
     $users = $this->getUsers();
     $usersByShard = array();
     foreach ($users as $userID) {
         $shardID = Zotero_Shards::getByUserID($userID);
         if (!isset($usersByShard[$shardID])) {
             $usersByShard[$shardID] = array();
         }
         $usersByShard[$shardID][] = $userID;
     }
     foreach ($usersByShard as $shardID => $userIDs) {
         // Add to delete log for all group members
         $sql = "REPLACE INTO syncDeleteLogIDs (libraryID, objectType, id) VALUES ";
         $params = array();
         $sets = array();
         foreach ($userIDs as $userID) {
             $libraryID = Zotero_Users::getLibraryIDFromUserID($userID);
             $sets[] = "(?,?,?)";
             $params = array_merge($params, array($libraryID, 'group', $this->id));
         }
         $sql .= implode(",", $sets);
         Zotero_DB::query($sql, $params, $shardID);
     }
 }
예제 #11
0
 /**
  * Make sure we have a valid session
  */
 private function sessionCheck()
 {
     if (empty($_REQUEST['sessionid'])) {
         $this->error(403, 'NO_SESSION_ID', "Session ID not provided");
     }
     if (!preg_match('/^[a-f0-9]{32}$/', $_REQUEST['sessionid'])) {
         $this->error($this->apiVersion >= 9 ? 403 : 500, 'INVALID_SESSION_ID', "Invalid session ID");
     }
     $sessionID = $_REQUEST['sessionid'];
     $session = Z_Core::$MC->get("syncSession_{$sessionID}");
     $userID = $session ? $session['userID'] : null;
     // TEMP: can switch to just $session
     $ipAddress = isset($session['ipAddress']) ? $session['ipAddress'] : null;
     if (!$userID) {
         $sql = "SELECT userid, (UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(timestamp)) AS age,\n\t\t\t\t\tINET_NTOA(ipAddress) AS ipAddress FROM sessions WHERE sessionID=?";
         $session = Zotero_DB::rowQuery($sql, $sessionID);
         if (!$session) {
             $this->error($this->apiVersion >= 9 ? 403 : 500, 'INVALID_SESSION_ID', "Invalid session ID");
         }
         if ($session['age'] > $this->sessionLifetime) {
             $this->error($this->apiVersion >= 9 ? 403 : 500, 'SESSION_TIMED_OUT', "Session timed out");
         }
         $userID = $session['userid'];
         $ipAddress = $session['ipAddress'];
     }
     $updated = Z_Core::$MC->set("syncSession_{$sessionID}", array('sessionID' => $sessionID, 'userID' => $userID, 'ipAddress' => $ipAddress), $this->sessionLifetime - 1200);
     // Every 20 minutes, update the timestamp in the DB
     if (!Z_Core::$MC->get("syncSession_" . $sessionID . "_dbUpdated")) {
         $sql = "UPDATE sessions SET timestamp=NOW() WHERE sessionID=?";
         Zotero_DB::query($sql, $sessionID);
         Z_Core::$MC->set("syncSession_" . $sessionID . "_dbUpdated", true, 1200);
     }
     $this->sessionID = $sessionID;
     $this->userID = $userID;
     $this->userLibraryID = Zotero_Users::getLibraryIDFromUserID($userID);
     $this->ipAddress = $ipAddress;
 }
예제 #12
0
 /**
  * This should be called after canAccess()
  */
 public function canWrite($libraryID)
 {
     if ($this->super) {
         return true;
     }
     if ($libraryID === 0) {
         return false;
     }
     if (!$libraryID) {
         throw new Exception('libraryID not provided');
     }
     if (!empty($this->permissions[$libraryID]['write'])) {
         return true;
     }
     $libraryType = Zotero_Libraries::getType($libraryID);
     switch ($libraryType) {
         case 'user':
             return false;
             // Write permissions match key's write access to user library
         // Write permissions match key's write access to user library
         case 'publications':
             $userLibraryID = Zotero_Users::getLibraryIDFromUserID($this->userID);
             return $this->canWrite($userLibraryID);
         case 'group':
             $groupID = Zotero_Groups::getGroupIDFromLibraryID($libraryID);
             // If key has write access to all groups, grant access if user
             // has write access to group
             if (!empty($this->permissions[0]['write'])) {
                 $group = Zotero_Groups::get($groupID);
                 return $group->userCanEdit($this->userID);
             }
             return false;
         default:
             throw new Exception("Unsupported library type '{$libraryType}'");
     }
 }