/** * {@inheritdoc} * * The file name for the CSS or JS cache file is generated from the hash of * the aggregated contents of the files in $data. This forces proxies and * browsers to download new CSS when the CSS changes. */ public function dump($data, $file_extension) { // Prefix filename to prevent blocking by firewalls which reject files // starting with "ad*". $filename = $file_extension . '_' . Crypt::hashBase64($data) . '.' . $file_extension; // Create the css/ or js/ path within the files folder. $path = 'public://' . $file_extension; $uri = $path . '/' . $filename; // Create the CSS or JS file. file_prepare_directory($path, FILE_CREATE_DIRECTORY); if (!file_exists($uri) && !file_unmanaged_save_data($data, $uri, FILE_EXISTS_REPLACE)) { return FALSE; } // If CSS/JS gzip compression is enabled and the zlib extension is available // then create a gzipped version of this file. This file is served // conditionally to browsers that accept gzip using .htaccess rules. // It's possible that the rewrite rules in .htaccess aren't working on this // server, but there's no harm (other than the time spent generating the // file) in generating the file anyway. Sites on servers where rewrite rules // aren't working can set css.gzip to FALSE in order to skip // generating a file that won't be used. if (extension_loaded('zlib') && \Drupal::config('system.performance')->get($file_extension . '.gzip')) { if (!file_exists($uri . '.gz') && !file_unmanaged_save_data(gzencode($data, 9, FORCE_GZIP), $uri . '.gz', FILE_EXISTS_REPLACE)) { return FALSE; } } return $uri; }
/** * Autocomplete the label of an entity. * * @param \Symfony\Component\HttpFoundation\Request $request * The request object that contains the typed tags. * @param string $target_type * The ID of the target entity type. * @param string $selection_handler * The plugin ID of the entity reference selection handler. * @param string $selection_settings_key * The hashed key of the key/value entry that holds the selection handler * settings. * * @return \Symfony\Component\HttpFoundation\JsonResponse * The matched entity labels as a JSON response. * * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException * Thrown if the selection settings key is not found in the key/value store * or if it does not match the stored data. */ public function handleAutocomplete(Request $request, $target_type, $selection_handler, $selection_settings_key) { $matches = array(); // Get the typed string from the URL, if it exists. if ($input = $request->query->get('q')) { $typed_string = Tags::explode($input); $typed_string = Unicode::strtolower(array_pop($typed_string)); // Selection settings are passed in as a hashed key of a serialized array // stored in the key/value store. $selection_settings = $this->keyValue->get($selection_settings_key, FALSE); if ($selection_settings !== FALSE) { $selection_settings_hash = Crypt::hmacBase64(serialize($selection_settings) . $target_type . $selection_handler, Settings::getHashSalt()); if ($selection_settings_hash !== $selection_settings_key) { // Disallow access when the selection settings hash does not match the // passed-in key. throw new AccessDeniedHttpException('Invalid selection settings key.'); } } else { // Disallow access when the selection settings key is not found in the // key/value store. throw new AccessDeniedHttpException(); } $matches = $this->matcher->getMatches($target_type, $selection_handler, $selection_settings, $typed_string); } return new JsonResponse($matches); }
/** * {@inheritdoc} */ public function setUp() { parent::setUp(); $this->key = Crypt::randomBytesBase64(55); $this->state = $this->getMock('Drupal\\Core\\State\\StateInterface'); $this->privateKey = new PrivateKey($this->state); }
/** * {@inheritdoc} */ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) { $config = $this->configFactory->get('shield.settings'); $allow_cli = $config->get('allow_cli'); $user = $config->get('user'); $pass = $config->get('pass'); if (empty($user) || PHP_SAPI === 'cli' && $allow_cli) { // If username is empty, then authentication is disabled, // or if request is coming from a cli and it is allowed, // then proceed with response without shield authentication. return $this->httpKernel->handle($request, $type, $catch); } else { if ($request->server->has('PHP_AUTH_USER') && $request->server->has('PHP_AUTH_PW')) { $input_user = $request->server->get('PHP_AUTH_USER'); $input_pass = $request->server->get('PHP_AUTH_PW'); } elseif ($request->server->has('HTTP_AUTHORIZATION')) { list($input_user, $input_pass) = explode(':', base64_decode(substr($request->server->get('HTTP_AUTHORIZATION'), 6)), 2); } elseif ($request->server->has('REDIRECT_HTTP_AUTHORIZATION')) { list($input_user, $input_pass) = explode(':', base64_decode(substr($request->server->get('REDIRECT_HTTP_AUTHORIZATION'), 6)), 2); } if (isset($input_user) && $input_user === $user && Crypt::hashEquals($pass, $input_pass)) { return $this->httpKernel->handle($request, $type, $catch); } } $response = new Response(); $response->headers->add(['WWW-Authenticate' => 'Basic realm="' . strtr($config->get('print'), ['[user]' => $user, '[pass]' => $pass]) . '"']); $response->setStatusCode(401); return $response; }
/** * {@inheritdoc} */ public function generate() { // Obtain a random string of 32 hex characters. $hex = bin2hex(Crypt::randomBytes(16)); // The variable names $time_low, $time_mid, $time_hi_and_version, // $clock_seq_hi_and_reserved, $clock_seq_low, and $node correlate to // the fields defined in RFC 4122 section 4.1.2. // // Use characters 0-11 to generate 32-bit $time_low and 16-bit $time_mid. $time_low = substr($hex, 0, 8); $time_mid = substr($hex, 8, 4); // Use characters 12-15 to generate 16-bit $time_hi_and_version. // The 4 most significant bits are the version number (0100 == 0x4). // We simply skip character 12 from $hex, and concatenate the strings. $time_hi_and_version = '4' . substr($hex, 13, 3); // Use characters 16-17 to generate 8-bit $clock_seq_hi_and_reserved. // The 2 most significant bits are set to one and zero respectively. $clock_seq_hi_and_reserved = base_convert(substr($hex, 16, 2), 16, 10); $clock_seq_hi_and_reserved &= 0b111111; $clock_seq_hi_and_reserved |= 0b10000000; // Use characters 18-19 to generate 8-bit $clock_seq_low. $clock_seq_low = substr($hex, 18, 2); // Use characters 20-31 to generate 48-bit $node. $node = substr($hex, 20); // Re-combine as a UUID. $clock_seq_hi_and_reserved is still an integer. $uuid = sprintf('%s-%s-%s-%02x%s-%s', $time_low, $time_mid, $time_hi_and_version, $clock_seq_hi_and_reserved, $clock_seq_low, $node); return $uuid; }
/** * Generates a test feed and simulates last-modified and etags. * * @param $use_last_modified * Set TRUE to send a last modified header. * @param $use_etag * Set TRUE to send an etag. * @param Request $request * Information about the current HTTP request. * * @return \Symfony\Component\HttpFoundation\Response * A feed that forces cache validation. */ public function testFeed($use_last_modified, $use_etag, Request $request) { $response = new Response(); $last_modified = strtotime('Sun, 19 Nov 1978 05:00:00 GMT'); $etag = Crypt::hashBase64($last_modified); $if_modified_since = strtotime($request->server->get('HTTP_IF_MODIFIED_SINCE')); $if_none_match = stripslashes($request->server->get('HTTP_IF_NONE_MATCH')); // Send appropriate response. We respond with a 304 not modified on either // etag or on last modified. if ($use_last_modified) { $response->headers->set('Last-Modified', gmdate(DateTimePlus::RFC7231, $last_modified)); } if ($use_etag) { $response->headers->set('ETag', $etag); } // Return 304 not modified if either last modified or etag match. if ($last_modified == $if_modified_since || $etag == $if_none_match) { $response->setStatusCode(304); return $response; } // The following headers force validation of cache. $response->headers->set('Expires', 'Sun, 19 Nov 1978 05:00:00 GMT'); $response->headers->set('Cache-Control', 'must-revalidate'); $response->headers->set('Content-Type', 'application/rss+xml; charset=utf-8'); // Read actual feed from file. $file_name = drupal_get_path('module', 'aggregator_test') . '/aggregator_test_rss091.xml'; $handle = fopen($file_name, 'r'); $feed = fread($handle, filesize($file_name)); fclose($handle); $response->setContent($feed); return $response; }
/** * {@inheritdoc} */ protected function setUp() { $this->syncDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64() . '/sync'; $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) array('value' => $this->syncDirectory, 'required' => TRUE); // Other directories will be created too. $this->settings['config_directories']['custom'] = (object) array('value' => $this->publicFilesDirectory . '/config_custom', 'required' => TRUE); parent::setUp(); }
/** * Tests that a new token seed is generated upon first use. * * @covers ::get */ public function testGenerateSeedOnGet() { $key = Crypt::randomBytesBase64(); $this->privateKey->expects($this->any())->method('get')->will($this->returnValue($key)); $this->sessionMetadata->expects($this->once())->method('getCsrfTokenSeed')->will($this->returnValue(NULL)); $this->sessionMetadata->expects($this->once())->method('setCsrfTokenSeed')->with($this->isType('string')); $this->assertInternalType('string', $this->generator->get()); }
/** * Generates a unique hash for identification purposes. * * @param string $source_path * Source path of the redirect. * @param array $source_query * Source query as an array. * @param string $language * Redirect language. * * @return string * Base 64 hash. */ public static function generateHash($source_path, array $source_query, $language) { $hash = array('source' => Unicode::strtolower($source_path), 'language' => $language); if (!empty($source_query)) { $hash['source_query'] = $source_query; } redirect_sort_recursive($hash, 'ksort'); return Crypt::hashBase64(serialize($hash)); }
/** * {@inheritdoc} */ function setUp() { parent::setUp(); $this->key = Crypt::randomBytesBase64(55); $this->privateKey = $this->getMockBuilder('Drupal\\Core\\PrivateKey')->disableOriginalConstructor()->setMethods(array('get'))->getMock(); $this->privateKey->expects($this->any())->method('get')->will($this->returnValue($this->key)); $settings = array('hash_salt' => $this->randomName()); new Settings($settings); $this->generator = new CsrfTokenGenerator($this->privateKey); }
/** * {@inheritdoc} */ protected function setUp() { $this->configDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64(); $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) array('value' => $this->configDirectory . '/sync', 'required' => TRUE); // Create the files directory early so we can test the error case. mkdir($this->publicFilesDirectory); // Create a file so the directory can not be created. file_put_contents($this->configDirectory, 'Test'); parent::setUp(); }
/** * Starts a background job using a new process. * * @param \Drupal\feeds\FeedInterface $feed * The feed to start the job for. * @param string $method * Method to execute on importer; one of 'import' or 'clear'. * * @throws Exception $e * * @todo Inject these dependencies. */ protected function startBackgroundJob(FeedInterface $feed, $method) { $cid = 'feeds_feed:' . $feed->id(); $token = Crypt::randomStringHashed(55); \Drupal::state()->set($cid, array('token' => $token, 'method' => $method)); $client = \Drupal::httpClient(); // Do not wait for a response. $client->addSubscriber(new AsyncPlugin()); $url = $this->url('feeds.execute', array('feeds_feed' => $feed->id()), array('absolute' => TRUE)); $request = $client->post($url)->addPostFields(array('token' => $token)); $request->send(); }
/** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); $api_key = $this->entity; $hex = isset($api_key->key) ? $api_key->key : substr(hash('sha256', Crypt::randomBytes(16)), 0, 32); $form['label'] = array('#type' => 'textfield', '#title' => $this->t('Machine Name'), '#maxlength' => 255, '#default_value' => $api_key->label(), '#description' => $this->t("Machine Name for the API Key."), '#required' => TRUE); $form['key'] = array('#type' => 'textfield', '#title' => $this->t('API Key'), '#maxlength' => 42, '#default_value' => $hex, '#description' => $this->t("The generated API Key for an user."), '#required' => TRUE); $form['user_uuid'] = array('#type' => 'select', '#multiple' => FALSE, '#options' => self::get_user(), '#description' => $this->t("Please select the User who gets authenticated with that API Key."), '#default_value' => $api_key->user_uuid); $form['id'] = array('#type' => 'machine_name', '#default_value' => $api_key->id(), '#machine_name' => array('exists' => '\\Drupal\\api_key_auth\\Entity\\ApiKey::load'), '#disabled' => !$api_key->isNew()); /* You will need additional form elements for your custom properties. */ return $form; }
/** * Tests configuration of advanced actions through administration interface. */ function testActionConfiguration() { // Create a user with permission to view the actions administration pages. $user = $this->drupalCreateUser(array('administer actions')); $this->drupalLogin($user); // Make a POST request to admin/config/system/actions. $edit = array(); $edit['action'] = Crypt::hashBase64('action_goto_action'); $this->drupalPostForm('admin/config/system/actions', $edit, t('Create')); $this->assertResponse(200); // Make a POST request to the individual action configuration page. $edit = array(); $action_label = $this->randomMachineName(); $edit['label'] = $action_label; $edit['id'] = strtolower($action_label); $edit['url'] = 'admin'; $this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('action_goto_action'), $edit, t('Save')); $this->assertResponse(200); // Make sure that the new complex action was saved properly. $this->assertText(t('The action has been successfully saved.'), "Make sure we get a confirmation that we've successfully saved the complex action."); $this->assertText($action_label, "Make sure the action label appears on the configuration page after we've saved the complex action."); // Make another POST request to the action edit page. $this->clickLink(t('Configure')); preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches); $aid = $matches[1]; $edit = array(); $new_action_label = $this->randomMachineName(); $edit['label'] = $new_action_label; $edit['url'] = 'admin'; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertResponse(200); // Make sure that the action updated properly. $this->assertText(t('The action has been successfully saved.'), "Make sure we get a confirmation that we've successfully updated the complex action."); $this->assertNoText($action_label, "Make sure the old action label does NOT appear on the configuration page after we've updated the complex action."); $this->assertText($new_action_label, "Make sure the action label appears on the configuration page after we've updated the complex action."); $this->clickLink(t('Configure')); $element = $this->xpath('//input[@type="text" and @value="admin"]'); $this->assertTrue(!empty($element), 'Make sure the URL appears when re-editing the action.'); // Make sure that deletions work properly. $this->drupalGet('admin/config/system/actions'); $this->clickLink(t('Delete')); $this->assertResponse(200); $edit = array(); $this->drupalPostForm("admin/config/system/actions/configure/{$aid}/delete", $edit, t('Delete')); $this->assertResponse(200); // Make sure that the action was actually deleted. $this->assertRaw(t('The action %action has been deleted.', array('%action' => $new_action_label)), 'Make sure that we get a delete confirmation message.'); $this->drupalGet('admin/config/system/actions'); $this->assertResponse(200); $this->assertNoText($new_action_label, "Make sure the action label does not appear on the overview page after we've deleted the action."); $action = entity_load('action', $aid); $this->assertFalse($action, 'Make sure the action is gone after being deleted.'); }
/** * {@inheritdoc} */ public function process($text, $langcode) { $settings = $this->settings; if ($settings['settings_source'] === 'global') { $config = \Drupal::config('pathologic.settings'); $settings['protocol_style'] = $config->get('protocol_style'); $settings['local_paths'] = $config->get('local_paths'); } else { $settings = $settings['local_settings']; } // @todo Move code from .module file to inside here. return new FilterProcessResult(_pathologic_filter($text, $settings, Crypt::hashBase64(serialize($settings)))); }
/** * Tests configuration of the node_assign_owner_action action. */ public function testAssignOwnerNodeActionConfiguration() { // Create a user with permission to view the actions administration pages. $user = $this->drupalCreateUser(['administer actions']); $this->drupalLogin($user); // Make a POST request to admin/config/system/actions. $edit = []; $edit['action'] = Crypt::hashBase64('node_assign_owner_action'); $this->drupalPostForm('admin/config/system/actions', $edit, t('Create')); $this->assertResponse(200); // Make a POST request to the individual action configuration page. $edit = []; $action_label = $this->randomMachineName(); $edit['label'] = $action_label; $edit['id'] = strtolower($action_label); $edit['owner_uid'] = $user->id(); $this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('node_assign_owner_action'), $edit, t('Save')); $this->assertResponse(200); // Make sure that the new action was saved properly. $this->assertText(t('The action has been successfully saved.'), 'The node_assign_owner_action action has been successfully saved.'); $this->assertText($action_label, 'The label of the node_assign_owner_action action appears on the actions administration page after saving.'); // Make another POST request to the action edit page. $this->clickLink(t('Configure')); preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches); $aid = $matches[1]; $edit = []; $new_action_label = $this->randomMachineName(); $edit['label'] = $new_action_label; $edit['owner_uid'] = $user->id(); $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertResponse(200); // Make sure that the action updated properly. $this->assertText(t('The action has been successfully saved.'), 'The node_assign_owner_action action has been successfully updated.'); $this->assertNoText($action_label, 'The old label for the node_assign_owner_action action does not appear on the actions administration page after updating.'); $this->assertText($new_action_label, 'The new label for the node_assign_owner_action action appears on the actions administration page after updating.'); // Make sure that deletions work properly. $this->drupalGet('admin/config/system/actions'); $this->clickLink(t('Delete')); $this->assertResponse(200); $edit = []; $this->drupalPostForm("admin/config/system/actions/configure/{$aid}/delete", $edit, t('Delete')); $this->assertResponse(200); // Make sure that the action was actually deleted. $this->assertRaw(t('The action %action has been deleted.', ['%action' => $new_action_label]), 'The delete confirmation message appears after deleting the node_assign_owner_action action.'); $this->drupalGet('admin/config/system/actions'); $this->assertResponse(200); $this->assertNoText($new_action_label, 'The label for the node_assign_owner_action action does not appear on the actions administration page after deleting.'); $action = Action::load($aid); $this->assertFalse($action, 'The node_assign_owner_action action is not available after being deleted.'); }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $actions = array(); foreach ($this->manager->getDefinitions() as $id => $definition) { if (is_subclass_of($definition['class'], '\\Drupal\\Core\\Plugin\\PluginFormInterface')) { $key = Crypt::hashBase64($id); $actions[$key] = $definition['label'] . '...'; } } $form['parent'] = array('#type' => 'details', '#title' => $this->t('Create an advanced action'), '#attributes' => array('class' => array('container-inline')), '#open' => TRUE); $form['parent']['action'] = array('#type' => 'select', '#title' => $this->t('Action'), '#title_display' => 'invisible', '#options' => $actions, '#empty_option' => $this->t('Choose an advanced action')); $form['parent']['actions'] = array('#type' => 'actions'); $form['parent']['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Create')); return $form; }
/** * {@inheritdoc} * * @param string $action_id * The hashed version of the action ID. */ public function buildForm(array $form, FormStateInterface $form_state, $action_id = NULL) { // In \Drupal\action\Form\ActionAdminManageForm::buildForm() the action // are hashed. Here we have to decrypt it to find the desired action ID. foreach ($this->actionManager->getDefinitions() as $id => $definition) { $key = Crypt::hashBase64($id); if ($key === $action_id) { $this->entity->setPlugin($id); // Derive the label and type from the action definition. $this->entity->set('label', $definition['label']); $this->entity->set('type', $definition['type']); break; } } return parent::buildForm($form, $form_state); }
/** * {@inheritdoc} */ public function generate() { $hex = substr(hash('sha256', Crypt::randomBytes(16)), 0, 32); // The field names refer to RFC 4122 section 4.1.2. $time_low = substr($hex, 0, 8); $time_mid = substr($hex, 8, 4); $time_hi_and_version = base_convert(substr($hex, 12, 4), 16, 10); $time_hi_and_version &= 0xfff; $time_hi_and_version |= 4 << 12; $clock_seq_hi_and_reserved = base_convert(substr($hex, 16, 4), 16, 10); $clock_seq_hi_and_reserved &= 0x3f; $clock_seq_hi_and_reserved |= 0x80; $clock_seq_low = substr($hex, 20, 2); $nodes = substr($hex, 20); $uuid = sprintf('%s-%s-%04x-%02x%02x-%s', $time_low, $time_mid, $time_hi_and_version, $clock_seq_hi_and_reserved, $clock_seq_low, $nodes); return $uuid; }
/** * #pre_render callback to generate a placeholder. * * Ensures the same token is used for all instances, hence resulting in the * same placeholder for all places rendering the status messages for this * request (e.g. in multiple blocks). This ensures we can put the rendered * messages in all placeholders in one go. * Also ensures the same context key is used for the #post_render_cache * property, this ensures that if status messages are rendered multiple times, * their individual (but identical!) #post_render_cache properties are merged, * ensuring the callback is only invoked once. * * @see ::renderMessages() * @param array $element * A renderable array. * * @return array * The updated renderable array containing the placeholder. */ public static function generatePlaceholder(array $element) { $plugin_id = 'status_messages'; $callback = get_class() . '::renderMessages'; try { $hash_salt = Settings::getHashSalt(); } catch (\RuntimeException $e) { // Status messages are also shown during the installer, at which time no // hash salt is defined yet. $hash_salt = Crypt::randomBytes(8); } $key = $plugin_id . $element['#display']; $context = ['display' => $element['#display'], 'token' => Crypt::hmacBase64($key, $hash_salt)]; $placeholder = static::renderer()->generateCachePlaceholder($callback, $context); $element['#post_render_cache'] = [$callback => [$key => $context]]; $element['#markup'] = $placeholder; return $element; }
/** * Build Acquia Solr Search Authenticator. * * @param PreExecuteRequestEvent $event */ public function preExecuteRequest($event) { $request = $event->getRequest(); $request->addParam('request_id', uniqid(), TRUE); $endpoint = $this->client->getEndpoint(); $this->uri = $endpoint->getBaseUri() . $request->getUri(); $this->nonce = Crypt::randomBytesBase64(24); $string = $request->getRawData(); if (!$string) { $parsed_url = parse_url($this->uri); $path = isset($parsed_url['path']) ? $parsed_url['path'] : '/'; $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; $string = $path . $query; // For pings only. } $cookie = $this->calculateAuthCookie($string, $this->nonce); $request->addHeader('Cookie: ' . $cookie); $request->addHeader('User-Agent: ' . 'acquia_search/' . \Drupal::config('acquia_search.settings')->get('version')); }
/** * {@inheritdoc} */ public function setSubscription(array &$data) { if (isset($data['lease']) && is_numeric($data['lease'])) { $data['expires'] = (int) REQUEST_TIME + $data['lease']; } else { // @todo Change schema to allow NULL values. $data['lease'] = 0; $data['expires'] = 0; } // Updating an existing subscription. if ($this->hasSubscription($data['id'])) { unset($data['created']); $this->connection->update($this->table)->fields($data)->condition('id', $data['id'])->execute(); return FALSE; } else { $data['secret'] = Crypt::randomStringHashed(55); $data['token'] = Crypt::randomStringHashed(55); $data['created'] = REQUEST_TIME; $this->connection->insert($this->table)->fields($data)->execute(); return TRUE; } }
public function testActionEntityClone() { foreach (\Drupal::service('plugin.manager.action')->getDefinitions() as $id => $definition) { if (is_subclass_of($definition['class'], '\Drupal\Core\Plugin\PluginFormInterface') && $definition['label'] == 'Send email') { $action_key = Crypt::hashBase64($id); break; } } $edit = [ 'label' => 'Test send email action for clone', 'id' => 'test_send_email_for_clone', 'recipient' => '*****@*****.**', 'subject' => 'test subject', 'message' => 'test message', ]; $this->drupalPostForm("admin/config/system/actions/add/$action_key", $edit, t('Save')); $actions = \Drupal::entityTypeManager() ->getStorage('action') ->loadByProperties([ 'id' => $edit['id'], ]); $action = reset($actions); $edit = [ 'label' => 'Test send email action cloned', 'id' => 'test_send_email_cloned', ]; $this->drupalPostForm('entity_clone/action/' . $action->id(), $edit, t('Clone')); $actions = \Drupal::entityTypeManager() ->getStorage('action') ->loadByProperties([ 'id' => $edit['id'], ]); $action = reset($actions); $this->assertTrue($action, 'Test action cloned found in database.'); }
/** * {@inheritdoc} */ protected function setUp() { parent::setUp(); new Settings(array('hash_salt' => 'test')); // Account 1: 'administrator' and 'authenticated' roles. $roles_1 = array('administrator', 'authenticated'); $this->account_1 = $this->getMockBuilder('Drupal\\user\\Entity\\User')->disableOriginalConstructor()->setMethods(array('getRoles'))->getMock(); $this->account_1->expects($this->any())->method('getRoles')->will($this->returnValue($roles_1)); // Account 2: 'authenticated' and 'administrator' roles (different order). $roles_2 = array('authenticated', 'administrator'); $this->account_2 = $this->getMockBuilder('Drupal\\user\\Entity\\User')->disableOriginalConstructor()->setMethods(array('getRoles'))->getMock(); $this->account_2->expects($this->any())->method('getRoles')->will($this->returnValue($roles_2)); // Updated account 1: now also 'editor' role. $roles_1_updated = array('editor', 'administrator', 'authenticated'); $this->account_1_updated = $this->getMockBuilder('Drupal\\user\\Entity\\User')->disableOriginalConstructor()->setMethods(array('getRoles'))->getMock(); $this->account_1_updated->expects($this->any())->method('getRoles')->will($this->returnValue($roles_1_updated)); // Mocked private key + cache services. $random = Crypt::randomBytesBase64(55); $this->private_key = $this->getMockBuilder('Drupal\\Core\\PrivateKey')->disableOriginalConstructor()->setMethods(array('get'))->getMock(); $this->private_key->expects($this->any())->method('get')->will($this->returnValue($random)); $this->cache = $this->getMockBuilder('Drupal\\Core\\Cache\\CacheBackendInterface')->disableOriginalConstructor()->getMock(); $this->permissionsHash = new PermissionsHash($this->private_key, $this->cache); }
/** * Reinstall changed config files. */ public function autoImportConfig() { $config = $this->getSettings(); $changed = FALSE; foreach ($config->get('auto_import') as $key => $file) { $contents = @file_get_contents($file['filename']); if (!$contents) { continue; } $hash = Crypt::hashBase64($contents); if ($hash != $file['hash']) { $changed = TRUE; $config->set("auto_import.{$key}.hash", $hash); $data = (new InstallStorage())->decode($contents); $config_name = basename($file['filename'], '.yml'); $entity_type_id = $this->configManager->getEntityTypeIdByName($config_name); if ($entity_type_id) { $entity_storage = $this->getStorage($entity_type_id); $entity_id = $this->getEntityId($entity_storage, $config_name); $entity_type = $entity_storage->getEntityType(); $id_key = $entity_type->getKey('id'); $data[$id_key] = $entity_id; $entity = $entity_storage->create($data); if ($existing_entity = $entity_storage->load($entity_id)) { $entity->set('uuid', $existing_entity->uuid())->enforceIsNew(FALSE); } $entity_storage->save($entity); } else { $this->configFactory->getEditable($config_name)->setData($data)->save(); } } } if ($changed) { $config->save(); } }
/** * Ensures that cache IDs have a maximum length of 255 characters. * * @param string $cid * The passed in cache ID. * * @return string * A cache ID that is at most 255 characters long. */ protected function normalizeCid($cid) { // Nothing to do if the ID length is 255 characters or less. if (strlen($cid) <= 255) { return $cid; } // Return a string that uses as much as possible of the original cache ID // with the hash appended. $hash = Crypt::hashBase64($cid); return substr($cid, 0, 255 - strlen($hash)) . $hash; }
/** * {@inheritdoc} */ public function getCache($form_build_id, FormStateInterface $form_state) { if ($form = $this->keyValueExpirableFactory->get('form')->get($form_build_id)) { if (isset($form['#cache_token']) && $this->csrfToken->validate($form['#cache_token']) || !isset($form['#cache_token']) && $this->currentUser->isAnonymous()) { $this->loadCachedFormState($form_build_id, $form_state); // Generate a new #build_id if the cached form was rendered on a // cacheable page. $build_info = $form_state->getBuildInfo(); if (!empty($build_info['immutable'])) { $form['#build_id_old'] = $form['#build_id']; $form['#build_id'] = 'form-' . Crypt::randomBytesBase64(); $form['form_build_id']['#value'] = $form['#build_id']; $form['form_build_id']['#id'] = $form['#build_id']; unset($build_info['immutable']); $form_state->setBuildInfo($build_info); } return $form; } } }
/** * Generates a prefix for APCu user cache keys. * * A standardized prefix is useful to allow visual inspection of an APCu user * cache. By default, this method will produce a unique prefix per site using * the hash salt. If the setting 'apcu_ensure_unique_prefix' is set to FALSE * then if the caller does not provide a $site_path only the Drupal root will * be used. This allows WebTestBase to use the same prefix ensuring that the * number of APCu items created during a full test run is kept to a minimum. * Additionally, if a multi site implementation does not use site specific * module directories setting apcu_ensure_unique_prefix would allow the sites * to share APCu cache items. * * @param $identifier * An identifier for the prefix. For example, 'class_loader' or * 'cache_backend'. * * @return string * The prefix for APCu user cache keys. */ public static function getApcuPrefix($identifier, $root, $site_path = '') { if (static::get('apcu_ensure_unique_prefix', TRUE)) { return 'drupal.' . $identifier . '.' . \Drupal::VERSION . '.' . static::get('deployment_identifier') . '.' . hash_hmac('sha256', $identifier, static::get('hash_salt') . '.' . $root . '/' . $site_path); } return 'drupal.' . $identifier . '.' . \Drupal::VERSION . '.' . static::get('deployment_identifier') . '.' . Crypt::hashBase64($root . '/' . $site_path); }
/** * Migrates the current session to a new session id. * * @param string $old_session_id * The old session id. The new session id is $this->getId() unless * $new_insecure_session_id is not empty. */ protected function migrateStoredSession($old_session_id) { $fields = array('sid' => Crypt::hashBase64($this->getId())); $this->connection->update('sessions')->fields($fields)->condition('sid', Crypt::hashBase64($old_session_id))->execute(); }
/** * Test to be run and the results confirmed. * * Here we force test results which must match the expected results from * confirmStubResults(). */ function stubTest() { // Ensure the .htkey file exists since this is only created just before a // request. This allows the stub test to make requests. The event does not // fire here and drupal_generate_test_ua() can not generate a key for a // test in a test since the prefix has changed. // @see \Drupal\Core\Test\EventSubscriber\HttpRequestSubscriber::onBeforeSendRequest() // @see drupal_generate_test_ua(); $key_file = DRUPAL_ROOT . '/sites/simpletest/' . substr($this->databasePrefix, 10) . '/.htkey'; $private_key = Crypt::randomBytesBase64(55); $site_path = $this->container->get('site.path'); file_put_contents($key_file, $private_key); // This causes the first of the fifteen passes asserted in // confirmStubResults(). $this->pass($this->passMessage); // The first three fails are caused by enabling a non-existent module in // setUp(). // This causes the fourth of the five fails asserted in // confirmStubResults(). $this->fail($this->failMessage); // This causes the second to fourth of the fifteen passes asserted in // confirmStubResults(). $user = $this->drupalCreateUser(array($this->validPermission), 'SimpleTestTest'); // This causes the fifth of the five fails asserted in confirmStubResults(). $this->drupalCreateUser(array($this->invalidPermission)); // Test logging in as a user. // This causes the fifth to ninth of the fifteen passes asserted in // confirmStubResults(). $this->drupalLogin($user); // This causes the tenth of the fifteen passes asserted in // confirmStubResults(). $this->pass(t('Test ID is @id.', array('@id' => $this->testId))); // These cause the eleventh to fourteenth of the fifteen passes asserted in // confirmStubResults(). $this->assertTrue(file_exists($site_path . '/settings.testing.php')); // Check the settings.testing.php file got included. $this->assertTrue(function_exists('simpletest_test_stub_settings_function')); // Check that the test-specific service file got loaded. $this->assertTrue($this->container->has('site.service.yml')); $this->assertIdentical(get_class($this->container->get('cache.backend.database')), 'Drupal\\Core\\Cache\\MemoryBackendFactory'); // These cause the two exceptions asserted in confirmStubResults(). // Call trigger_error() without the required argument to trigger an E_WARNING. trigger_error(); // Generates a warning inside a PHP function. array_key_exists(NULL, NULL); // This causes the fifteenth of the fifteen passes asserted in // confirmStubResults(). $this->assertNothing(); // This causes the debug message asserted in confirmStubResults(). debug('Foo', 'Debug', FALSE); }