public static function refuseAuthenticatedUsers($responseType = 'redirect') { self::validateResponseType($responseType); return function () use($responseType) { if (!Auth::loggedIn()) { return true; } $errorMessage = 'You must be logged out to perform that action.'; \Directus\Slim\Middleware::refuseWithErrorMessage($errorMessage, $responseType); }; }
public function preSaveDataHook(array $rowData, $rowExistsInDatabase = false) { // New record? // Attribute the currently authenticated user as the uploader if (!$rowExistsInDatabase) { $currentUser = AuthProvider::getUserInfo(); $cmsOwnerColumnName = $this->acl->getCmsOwnerColumnByTable($this->table); $rowData[$cmsOwnerColumnName] = $currentUser['id']; } else { if (array_key_exists('date_uploaded', $rowData)) { unset($rowData['date_uploaded']); } } return $rowData; }
public function save() { $this->initialize(); $currentUserId = null; if (Auth::loggedIn()) { $currentUser = Auth::getUserInfo(); $currentUserId = intval($currentUser['id']); } /** * ACL Enforcement * Note: Field Write Blacklists are enforced at the object setter level * (AARG#__set, AARG#populate, AARG#offsetSet) */ if (!$this->rowExistsInDatabase()) { /** * Enforce Privilege: Table Add */ if (!$this->acl->hasTablePrivilege($this->table, 'add')) { $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableAddException($aclErrorPrefix . 'Table add access forbidden on table ' . $this->table); } } else { $cmsOwnerId = $this->acl->getRecordCmsOwnerId($this, $this->table); /** * Enforce Privilege: "Little" Edit (I am the record CMS owner) */ if ($cmsOwnerId === intval($currentUserId)) { if (!$this->acl->hasTablePrivilege($this->table, 'edit')) { $recordPk = self::stringifyPrimaryKeyForRecordDebugRepresentation($this->primaryKeyData); $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableEditException($aclErrorPrefix . 'Table edit access forbidden on `' . $this->table . '` table record with ' . $recordPk . ' owned by the authenticated CMS user (#' . $cmsOwnerId . ').'); } } else { if (!$this->acl->hasTablePrivilege($this->table, 'bigedit')) { $recordPk = self::stringifyPrimaryKeyForRecordDebugRepresentation($this->primaryKeyData); $recordOwner = false === $cmsOwnerId ? 'no magic owner column' : 'the CMS owner #' . $cmsOwnerId; $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableBigEditException($aclErrorPrefix . 'Table bigedit access forbidden on `' . $this->table . '` table record with ' . $recordPk . ' and ' . $recordOwner . '.'); } } } try { return parent::save(); } catch (InvalidQueryException $e) { $this->logger()->fatal('Error running save on this data: ' . print_r($this->data, true)); throw $e; } }
/** * Change the password of a user given their e-mail address * * The function will change the password of a user given their e-mail * address. If there are multiple users with the same e-mail address, and * this should never be the case, all of their passwords would be changed. * * The function will generate a new salt for every password change. * * @param string $email The e-mail of the user whose password is being * changed. * @param string $password The new password. * * @return void * * @throws PasswordChangeException Thrown when password change has failed. * */ public function changePassword($email, $password) { $salt = StringUtils::random(); $hash = Provider::hashPassword($password, $salt); $user = $this->usersTableGateway->select(['email' => $email])->current(); if (!$user) { throw new \InvalidArgumentException(__t('User not found')); } try { $update = ['password' => $hash, 'salt' => $salt, 'access_token' => sha1($user->id . StringUtils::random())]; $changed = $this->usersTableGateway->update($update, ['email' => $email]); if ($changed == 0) { throw new PasswordChangeException(__t('Could not change password for ') . $email . ': ' . __t('e-mail not found.')); } } catch (\PDOException $ex) { throw new PasswordChangeException(__t('Failed to change password') . ': ' . str($ex)); } }
public function preSaveDataHook(array $rowData, $rowExistsInDatabase = false) { $log = Bootstrap::get('log'); if (isset($rowData['id'])) { $logger = Bootstrap::get('log'); $TableGateway = new AclAwareTableGateway($this->acl, $this->table, $this->sql->getAdapter()); $dbRecord = $TableGateway->find($rowData['id']); if (false === $dbRecord) { // @todo is it better to throw an exception here? $rowExistsInDatabase = false; } } // User is updating themselves. // Corresponds to a ping indicating their last activity. // Updated their "last_access" value. if (AuthProvider::loggedIn()) { $currentUser = AuthProvider::getUserInfo(); if (isset($rowData['id']) && $rowData['id'] == $currentUser['id']) { $rowData['last_access'] = new Expression("NOW()"); } } return $rowData; }
/** * Get Hook Emitter * * @return Emitter */ private static function hookEmitter() { $emitter = new Emitter(); $emitter->addAction('application.error', function ($e) { $log = Bootstrap::get('log'); $log->error($e); }); $emitter->addAction('table.insert.directus_groups', function ($data) { $acl = Bootstrap::get('acl'); $zendDb = Bootstrap::get('zendDb'); $privilegesTable = new DirectusPrivilegesTableGateway($acl, $zendDb); $privilegesTable->insertPrivilege(['group_id' => $data['id'], 'allow_view' => 1, 'allow_add' => 0, 'allow_edit' => 1, 'allow_delete' => 0, 'allow_alter' => 0, 'table_name' => 'directus_users', 'read_field_blacklist' => 'token', 'write_field_blacklist' => 'group,token']); }); $emitter->addFilter('table.insert:before', function ($tableName, $data) { if ($tableName == 'directus_files') { unset($data['data']); $data['user'] = AuthProvider::getUserInfo('id'); } return $data; }); // Add file url and thumb url $emitter->addFilter('table.select', function ($result, $selectState) { if ($selectState['table'] == 'directus_files') { $fileRows = $result->toArray(); $files = new \Directus\Files\Files(); foreach ($fileRows as &$row) { $config = Bootstrap::get('config'); $fileURL = $config['filesystem']['root_url']; $thumbnailURL = $config['filesystem']['root_thumb_url']; $thumbnailFilenameParts = explode('.', $row['name']); $thumbnailExtension = array_pop($thumbnailFilenameParts); $row['url'] = $fileURL . '/' . $row['name']; if (in_array($thumbnailExtension, ['tif', 'tiff', 'psd', 'pdf'])) { $thumbnailExtension = 'jpg'; } $thumbnailFilename = $row['id'] . '.' . $thumbnailExtension; $row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename; // filename-ext-100-100-true.jpg // @TODO: This should be another hook listener $row['thumbnail_url'] = null; $filename = implode('.', $thumbnailFilenameParts); if ($row['type'] == 'embed/vimeo') { $oldThumbnailFilename = $row['name'] . '-vimeo-220-124-true.jpg'; } else { $oldThumbnailFilename = $filename . '-' . $thumbnailExtension . '-160-160-true.jpg'; } // 314551321-vimeo-220-124-true.jpg // hotfix: there's not thumbnail for this file if ($files->exists('thumbs/' . $oldThumbnailFilename)) { $row['thumbnail_url'] = $thumbnailURL . '/' . $oldThumbnailFilename; } if ($files->exists('thumbs/' . $thumbnailFilename)) { $row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename; } $embedManager = Bootstrap::get('embedManager'); $provider = $embedManager->getByType($row['type']); $row['html'] = null; if ($provider) { $row['html'] = $provider->getCode($row); } } $filesArrayObject = new \ArrayObject($fileRows); $result->initialize($filesArrayObject->getIterator()); } return $result; }); return $emitter; }
/** * @param Delete $delete * @return mixed * @throws Exception\RuntimeException * @throws \Directus\Acl\Exception\UnauthorizedTableBigDeleteException * @throws \Directus\Acl\Exception\UnauthorizedTableDeleteException */ protected function executeDelete(Delete $delete) { $cuurrentUserId = null; if (Auth::loggedIn()) { $currentUser = Auth::getUserInfo(); $currentUserId = intval($currentUser['id']); } $deleteState = $delete->getRawState(); $deleteTable = $this->getRawTableNameFromQueryStateTable($deleteState['table']); $cmsOwnerColumn = $this->acl->getCmsOwnerColumnByTable($deleteTable); $canBigHardDelete = $this->acl->hasTablePrivilege($deleteTable, 'bigharddelete'); $canHardDelete = $this->acl->hasTablePrivilege($deleteTable, 'harddelete'); $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); // Is this table a junction table? $deleteTableSchema = TableSchema::getTable($deleteTable); $isDeleteTableAJunction = array_key_exists('is_junction_table', $deleteTableSchema) ? (bool) $deleteTableSchema['is_junction_table'] : false; if ($isDeleteTableAJunction || !TableSchema::hasTableColumn($deleteTable, STATUS_COLUMN_NAME)) { if ($this->acl->hasTablePrivilege($deleteTable, 'bigdelete')) { $canBigHardDelete = true; } else { if ($this->acl->hasTablePrivilege($deleteTable, 'delete')) { $canHardDelete = true; } } } // @todo: clean way if ($deleteTable === 'directus_bookmarks') { $canBigHardDelete = true; } /** * ACL Enforcement */ if (!$canBigHardDelete && !$canHardDelete) { throw new UnauthorizedTableBigDeleteException($aclErrorPrefix . "BigHardDelete/HardDelete access forbidden on table `{$deleteTable}`."); } if (false === $cmsOwnerColumn) { // cannot delete if there's no magic owner column and can't big delete if (!$canBigHardDelete) { // All deletes are "big" deletes if there is no magic owner column. throw new UnauthorizedTableBigDeleteException($aclErrorPrefix . "The table `{$deleteTable}` is missing the `user_create_column` within `directus_tables` (BigHardDelete Permission Forbidden)"); } } else { if (!$canBigHardDelete) { // Who are the owners of these rows? list($predicateResultQty, $predicateOwnerIds) = $this->acl->getCmsOwnerIdsByTableGatewayAndPredicate($this, $deleteState['where']); if (in_array($currentUserId, $predicateOwnerIds)) { $exceptionMessage = "Table harddelete access forbidden on {$predicateResultQty} `{$deleteTable}` table records owned by the authenticated CMS user (#{$currentUserId})."; $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableDeleteException($aclErrorPrefix . $exceptionMessage); } } } try { return parent::executeDelete($delete); } catch (\Zend\Db\Adapter\Exception\InvalidQueryException $e) { if ('production' !== DIRECTUS_ENV) { throw new \RuntimeException("This query failed: " . $this->dumpSql($delete), 0, $e); } // @todo send developer warning throw $e; } }
/** * Relational Getter * NOTE: equivalent to old DB#get_entries */ public function getEntries($params = array()) { // @todo this is for backwards compatibility, make sure this doesn't happen and ditch the following 2 if-blocks if (!array_key_exists('orderBy', $params) && array_key_exists('sort', $params)) { $params['orderBy'] = $params['sort']; } if (!array_key_exists('orderDirection', $params) && array_key_exists('sort_order', $params)) { $params['orderDirection'] = $params['sort_order']; } // end @todo $logger = $this->logger(); $platform = $this->adapter->platform; // use for quoting // Get table column schema $schemaArray = TableSchema::getSchemaArray($this->table); // Table has `status` column? $hasActiveColumn = $this->schemaHasActiveColumn($schemaArray); $params = $this->applyDefaultEntriesSelectParams($params); $sql = new Sql($this->adapter); $select = $sql->select()->from($this->table); // Only select the fields not on the currently authenticated user group's read field blacklist $columnNames = TableSchema::getAllNonAliasTableColumnNames($this->table); $select->columns($columnNames); if (array_key_exists('related_table_filter', $params)) { $select->where->equalTo($params['related_table_filter']['column'], $params['related_table_filter']['val']); } $select = $this->applyParamsToTableEntriesSelect($params, $select, $schemaArray, $hasActiveColumn); $currentUserId = null; $currentUser = AuthProvider::getUserInfo(); $currentUserId = intval($currentUser['id']); $cmsOwnerId = $this->acl->getCmsOwnerColumnByTable($this->table); //If we have user field and do not have big view privileges but have view then only show entries we created if ($cmsOwnerId && !$this->acl->hasTablePrivilege($this->table, 'bigview') && $this->acl->hasTablePrivilege($this->table, 'view')) { $select->where->equalTo($cmsOwnerId, $currentUserId); } $results = $this->selectWith($select)->toArray(); // Note: ensure this is sufficient, in lieu of incrementing within // the foreach loop below. $foundRows = count($results); // Perform data casting based on the column types in our schema array $columns = TableSchema::getAllNonAliasTableColumns($this->table); foreach ($results as &$row) { $row = $this->parseRecordValuesByMysqlType($row, $columns); } // Eager-load related ManyToOne records $results = $this->loadManyToOneRelationships($schemaArray, $results); /** * Fetching a set of data */ if (-1 == $params[$this->primaryKeyFieldName]) { $set = array(); if ($hasActiveColumn) { $countActive = $this->countActive($hasActiveColumn); $set = array_merge($set, $countActive); } else { $set['total'] = $this->countTotal(); } $set['rows'] = $results; return $set; } /** * Fetching one item */ // @todo return null and let controller throw HTTP response if (0 == count($results)) { // throw new \DirectusException('Item not found!',404); // @todo return null and let controller handle HTTP response Bootstrap::get('app')->halt(404); } list($result) = $results; // Separate alias fields from table schema array $alias_fields = $this->filterSchemaAliasFields($schemaArray); // (fmrly $alias_schema) $result = $this->loadToManyRelationships($result, $alias_fields); return $result; }
} } $message = $messagesTableGateway->fetchMessageWithRecipients($id, $currentUser['id']); JsonView::render($message); }); $app->get("/{$v}/messages/recipients/?", function () use($params, $requestPayload, $app, $acl, $ZendDb) { $tokens = explode(' ', $_GET['q']); $usersTableGateway = new DirectusUsersTableGateway($acl, $ZendDb); $users = $usersTableGateway->findUserByFirstOrLastName($tokens); $groupsTableGateway = new DirectusGroupsTableGateway($acl, $ZendDb); $groups = $groupsTableGateway->findUserByFirstOrLastName($tokens); $result = array_merge($groups, $users); JsonView::render($result); }); $app->post("/{$v}/comments/?", function () use($params, $requestPayload, $app, $acl, $ZendDb) { $currentUser = Auth::getUserInfo(); $params['table_name'] = "directus_messages"; $TableGateway = new TableGateway($acl, "directus_messages", $ZendDb); $groupRecipients = array(); $userRecipients = array(); preg_match_all('/@\\[.*? /', $requestPayload['message'], $results); $results = $results[0]; if (count($results) > 0) { foreach ($results as $result) { $result = substr($result, 2); $typeAndId = explode('_', $result); if ($typeAndId[0] == 0) { $userRecipients[] = $typeAndId[1]; } else { $groupRecipients[] = $typeAndId[1]; }
/** * Construct Acl provider * @return \Directus\Acl */ private static function acl() { $acl = new acl(); $db = self::get('ZendDb'); $DirectusTablesTableGateway = new DirectusTablesTableGateway($acl, $db); $getTables = function () use($DirectusTablesTableGateway) { return $DirectusTablesTableGateway->select()->toArray(); }; $tableRecords = $DirectusTablesTableGateway->memcache->getOrCache(MemcacheProvider::getKeyDirectusTables(), $getTables, 1800); $magicOwnerColumnsByTable = []; foreach ($tableRecords as $tableRecord) { if (!empty($tableRecord['user_create_column'])) { $magicOwnerColumnsByTable[$tableRecord['table_name']] = $tableRecord['user_create_column']; } } $acl::$cms_owner_columns_by_table = $magicOwnerColumnsByTable; if (AuthProvider::loggedIn()) { $currentUser = AuthProvider::getUserInfo(); $Users = new DirectusUsersTableGateway($acl, $db); $cacheFn = function () use($currentUser, $Users) { return $Users->find($currentUser['id']); }; $cacheKey = MemcacheProvider::getKeyDirectusUserFind($currentUser['id']); $currentUser = $Users->memcache->getOrCache($cacheKey, $cacheFn, 10800); if ($currentUser) { $privilegesTable = new DirectusPrivilegesTableGateway($acl, $db); $acl->setGroupPrivileges($privilegesTable->getGroupPrivileges($currentUser['group'])); } } return $acl; }
<?php //If config file doesnt exist, go to install file if (!file_exists('api/config.php') || filesize('api/config.php') == 0) { header('Location: installation/index.php'); } // Composer Autoloader $loader = (require 'api/vendor/autoload.php'); $loader->add("Directus", dirname(__FILE__) . "/api/core/"); require "api/config.php"; require "api/globals.php"; /** * Temporary solution for disabling this page for logged in users. */ if (\Directus\Auth\Provider::loggedIn()) { header('Location: ' . DIRECTUS_PATH); exit; } // Get current commit hash $git = __DIR__ . '/.git'; $cacheBuster = Directus\Util\Git::getCloneHash($git); ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,maximum-scale=1.0"> <title>Directus Login</title> <!-- Icons -->
/** * Relational Getter * NOTE: equivalent to old DB#get_entries */ public function getEntries($params = []) { // @todo this is for backwards compatibility, make sure this doesn't happen and ditch the following 2 if-blocks if (!array_key_exists('orderBy', $params) && array_key_exists('sort', $params)) { $params['orderBy'] = $params['sort']; } if (!array_key_exists('orderDirection', $params) && array_key_exists('sort_order', $params)) { $params['orderDirection'] = $params['sort_order']; } // end @todo $logger = $this->logger(); $platform = $this->adapter->platform; // use for quoting // Get table column schema $schemaArray = TableSchema::getSchemaArray($this->table); // table only has one column // return an empty array if (!is_array($schemaArray) || !is_numeric_array($schemaArray)) { return []; } // Table has `status` column? $hasActiveColumn = $this->schemaHasActiveColumn($schemaArray); $params = $this->applyDefaultEntriesSelectParams($params); $sql = new Sql($this->adapter); $select = $sql->select()->from($this->table); // Only select the fields not on the currently authenticated user group's read field blacklist $columnNames = TableSchema::getAllNonAliasTableColumnNames($this->table); $select->columns($columnNames); if (array_key_exists('related_table_filter', $params)) { $select->where->equalTo($params['related_table_filter']['column'], $params['related_table_filter']['val']); } $select = $this->applyParamsToTableEntriesSelect($params, $select, $schemaArray, $hasActiveColumn); $currentUserId = null; $currentUser = AuthProvider::getUserInfo(); $currentUserId = intval($currentUser['id']); $cmsOwnerId = $this->acl->getCmsOwnerColumnByTable($this->table); //If we have user field and do not have big view privileges but have view then only show entries we created if ($cmsOwnerId && !$this->acl->hasTablePrivilege($this->table, 'bigview') && $this->acl->hasTablePrivilege($this->table, 'view')) { $select->where->equalTo($cmsOwnerId, $currentUserId); } $results = $this->selectWith($select)->toArray(); // Note: ensure this is sufficient, in lieu of incrementing within // the foreach loop below. $foundRows = count($results); // ========================================================================== // Perform data casting based on the column types in our schema array // and Convert dates into ISO 8601 Format // ========================================================================== $results = $this->parseRecord($results); // Eager-load related ManyToOne records $this->toManyCallStack = []; $results = $this->loadManyToOneRelationships($schemaArray, $results); // ============================================================================= // HOTFIX: Fetching X2M data and Infinite circle loop // ============================================================================= // Separate alias fields from table schema array $aliasColumns = $this->filterSchemaAliasFields($schemaArray); // (fmrly $alias_schema) foreach ($results as $key => $result) { $this->toManyCallStack = []; $results[$key] = $this->loadToManyRelationships($result, $aliasColumns); } /** * Fetching a set of data */ if (-1 == $params[$this->primaryKeyFieldName]) { $set = []; if ($hasActiveColumn) { $countActive = $this->countActive($hasActiveColumn); $set = array_merge($set, $countActive); } else { $set['total'] = $this->countTotal(); } $set['rows'] = $results; return $set; } if (!$results) { return $results; } list($result) = $results; return $result; }
public static function getAllSchemas($userGroupId, $versionHash) { $cacheKey = MemcacheProvider::getKeyDirectusGroupSchema($userGroupId, $versionHash); $acl = Bootstrap::get('acl'); $ZendDb = Bootstrap::get('ZendDb'); $directusPreferencesTableGateway = new DirectusPreferencesTableGateway($acl, $ZendDb); $getPreferencesFn = function () use($directusPreferencesTableGateway) { $currentUser = Auth::getUserInfo(); $preferences = $directusPreferencesTableGateway->fetchAllByUser($currentUser['id']); return $preferences; }; $getSchemasFn = function () { $tableSchemas = TableSchema::getTableSchemas(); $columnSchemas = TableSchema::getColumnSchemas(); // Nest column schemas in table schemas foreach ($tableSchemas as &$table) { $tableName = $table['id']; $table['columns'] = array_values($columnSchemas[$tableName]); foreach ($columnSchemas[$tableName] as $column) { if ($column['column_key'] == 'PRI') { $table['primary_column'] = $column['column_name']; break; } } $table = array('schema' => $table); } return $tableSchemas; }; // 3 hr cache $schemas = $directusPreferencesTableGateway->memcache->getOrCache($cacheKey, $getSchemasFn, 10800); // Append preferences post cache $preferences = $getPreferencesFn(); foreach ($schemas as &$table) { $table['preferences'] = $preferences[$table['schema']['id']]; } return $schemas; }
private function updatePassword() { $data = []; $options = $this->options; foreach ($options as $key => $value) { switch ($key) { case 'uid': case 'u': $data['id'] = $value; unset($options[$key]); break; case 'upass': case 'p': $data['password'] = $value; unset($options[$key]); break; } } if (!isset($data['password']) || !isset($data['id'])) { echo PHP_EOL . __t('Missing User ID or Password') . PHP_EOL; exit; } $zendDb = Bootstrap::get('zendDb'); $userTableGateway = new TableGateway('directus_users', $zendDb); $result = $userTableGateway->update(['password' => \Directus\Auth\Provider::hashPassword($data['password']), 'access_token' => sha1($data['id'] . \Directus\Util\StringUtils::random())], ['id' => $data['id']]); $message = 'Error trying to update the password.'; if ($result) { $message = 'Password updated successfully'; } echo PHP_EOL . __t($message) . PHP_EOL; }
function get_auth_info($attribute) { // if there's not config files created if (!defined('BASE_PATH') || !defined('APPLICATION_PATH')) { return null; } if (!Directus\Auth\Provider::loggedIn()) { return null; } $userInfo = \Directus\Auth\Provider::getUserRecord(); return isset($userInfo[$attribute]) ? $userInfo[$attribute] : null; }
if (!AuthProvider::loggedIn()) { $request_uri = $_SERVER['REQUEST_URI']; if (strpos($request_uri, DIRECTUS_PATH) === 0) { $request_uri = substr($request_uri, strlen(DIRECTUS_PATH)); } $redirect = htmlspecialchars(trim($request_uri, '/'), ENT_QUOTES, 'UTF-8'); if ($redirect) { $_SESSION['_directus_login_redirect'] = $redirect; $redirect = '?redirect=' . $redirect; } header('Location: ' . DIRECTUS_PATH . 'login.php' . $redirect); die; } $acl = Bootstrap::get('acl'); $ZendDb = Bootstrap::get('ZendDb'); $authenticatedUser = AuthProvider::loggedIn() ? AuthProvider::getUserInfo() : array(); function getNonces() { $requestNonceProvider = new RequestNonceProvider(); $nonces = array_merge($requestNonceProvider->getOptions(), array('pool' => $requestNonceProvider->getAllNonces())); return $nonces; } function getStorageAdapters() { $config = Bootstrap::get('config'); $storageAdapter = $config['filesystem']; return [$storageAdapter['adapter'] => ['adapter' => $storageAdapter['adapter'], 'root_url' => $storageAdapter['root_url'], 'root_thumb_url' => $storageAdapter['root_thumb_url']]]; } function parseTables($tableSchema) { $tables = array();
$host = 'https://' . $_SERVER['SERVER_NAME']; if ('80' != $_SERVER['SERVER_PORT']) { $host .= ':' . $_SERVER['SERVER_PORT']; } $httpsUrl = $host . $_SERVER['REQUEST_URI']; header('Location: ' . $httpsUrl); exit; } } $users = getUsers(); // hotfix // @NOTE: if the user doesn't have permission to view users // it should be log out // see: https://github.com/directus/directus/issues/1268 if (!$users) { AuthProvider::logout(); $_SESSION['error_message'] = 'Your user doesn\'t have permission to log in'; header('Location: ' . DIRECTUS_PATH . 'login.php'); exit; } $currentUserInfo = getCurrentUserInfo($users); // Cache buster $git = __DIR__ . '/.git'; $cacheBuster = Directus\Util\Git::getCloneHash($git); $tableSchema = TableSchema::getAllSchemas($currentUserInfo['group']['id'], $cacheBuster); // $tabPrivileges = getTabPrivileges(($currentUserInfo['group']['id'])); $groupId = $currentUserInfo['group']['id']; $groups = getGroups(); $currentUserGroup = []; if (isset($groups['rows']) && count($groups['rows'] > 0)) { foreach ($groups['rows'] as $group) {
$DirectusUsersTableGateway = new DirectusUsersTableGateway($acl, $ZendDb); Auth::setUserCacheRefreshProvider(function ($userId) use($DirectusUsersTableGateway) { $cacheFn = function () use($userId, $DirectusUsersTableGateway) { return $DirectusUsersTableGateway->find($userId); }; $cacheKey = MemcacheProvider::getKeyDirectusUserFind($userId); $user = $DirectusUsersTableGateway->memcache->getOrCache($cacheKey, $cacheFn, 10800); return $user; }); if (Auth::loggedIn()) { $user = Auth::getUserRecord(); $acl->setUserId($user['id']); $acl->setGroupId($user['group']); } $app->hook('slim.before.dispatch', function () use($app) { if (!Auth::loggedIn()) { http_response_code(403); echo "<h1>403 Forbidden</h1>"; // $app->halt(403); // Never works very well exit; } }); $app->get("/:id/:format(/:filename)", function ($id, $format, $filename) use($app, $acl, $ZendDb) { $notFound = function () { http_response_code(404); echo "<h1>404 Not found</h1>"; exit; }; $DirectusMedia = new TableGateway('directus_files', $ZendDb); $media = $DirectusMedia->select(function ($select) use($id) { $select->where->equalTo('id', $id);
private function isCurrentUserAdmin() { $currentUser = Auth::getUserRecord(); //Dont let non-admins have alter privilege return $currentUser['group'] == 1 ? true : false; }
/** * @param Delete $delete * @return mixed * @throws Exception\RuntimeException * @throws \Directus\Acl\Exception\UnauthorizedTableBigDeleteException * @throws \Directus\Acl\Exception\UnauthorizedTableDeleteException */ protected function executeDelete(Delete $delete) { $cuurrentUserId = null; if (Auth::loggedIn()) { $currentUser = Auth::getUserInfo(); $currentUserId = intval($currentUser['id']); } $deleteState = $delete->getRawState(); $deleteTable = $this->getRawTableNameFromQueryStateTable($deleteState['table']); $cmsOwnerColumn = $this->acl->getCmsOwnerColumnByTable($deleteTable); $canBigDelete = $this->acl->hasTablePrivilege($deleteTable, 'bigdelete'); $canDelete = $this->acl->hasTablePrivilege($deleteTable, 'delete'); $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); if (!TableSchema::hasTableColumn($deleteTable, STATUS_COLUMN_NAME)) { if ($this->acl->hasTablePrivilege($deleteTable, 'bigdelete')) { $canBigDelete = true; } else { if ($this->acl->hasTablePrivilege($deleteTable, 'delete')) { $canDelete = true; } } } // @todo: clean way if ($deleteTable === 'directus_bookmarks') { $canBigDelete = true; } /** * ACL Enforcement */ if (!$canBigDelete && !$canDelete) { throw new UnauthorizedTableBigDeleteException($aclErrorPrefix . ' forbidden to hard delete on table `' . $deleteTable . '` because it has Status Column.'); } if (false === $cmsOwnerColumn) { // cannot delete if there's no magic owner column and can't big delete if (!$canBigDelete) { // All deletes are "big" deletes if there is no magic owner column. throw new UnauthorizedTableBigDeleteException($aclErrorPrefix . 'The table `' . $deleteTable . '` is missing the `user_create_column` within `directus_tables` (BigHardDelete Permission Forbidden)'); } } else { if (!$canBigDelete) { // Who are the owners of these rows? list($predicateResultQty, $predicateOwnerIds) = $this->acl->getCmsOwnerIdsByTableGatewayAndPredicate($this, $deleteState['where']); if (!in_array($currentUserId, $predicateOwnerIds)) { // $exceptionMessage = "Table harddelete access forbidden on $predicateResultQty `$deleteTable` table records owned by the authenticated CMS user (#$currentUserId)."; $groupsTableGateway = self::makeTableGatewayFromTableName($this->acl, 'directus_groups', $this->adapter); $group = $groupsTableGateway->find($this->acl->getGroupId()); $exceptionMessage = '[' . $group['name'] . '] permissions only allow you to [delete] your own items.'; // $aclErrorPrefix = $this->acl->getErrorMessagePrefix(); throw new UnauthorizedTableDeleteException($exceptionMessage); } } } try { $this->emitter->run('table.delete:before', [$deleteTable]); $this->emitter->run('table.delete.' . $deleteTable . ':before'); $result = parent::executeDelete($delete); $this->emitter->run('table.delete', [$deleteTable]); $this->emitter->run('table.delete:after', [$deleteTable]); $this->emitter->run('table.delete.' . $deleteTable); $this->emitter->run('table.delete.' . $deleteTable . ':after'); return $result; } catch (\Zend\Db\Adapter\Exception\InvalidQueryException $e) { if ('production' !== DIRECTUS_ENV) { throw new \RuntimeException('This query failed: ' . $this->dumpSql($delete), 0, $e); } // @todo send developer warning throw $e; } }