Quantcast
Channel: Issues for Drupal core
Viewing all 297699 articles
Browse latest View live

Replace custom password hashing library with PHP 5.5 password_hash()

$
0
0

Problem

  1. The current password hashing library is a custom fork of phpass.
  2. It has to be maintained by Drupal. Drupal should not be in the business of developing/maintaining a password hashing library.
  3. The hashing algorithm is 100% custom. 0% interoperability.
  4. The next time we upgrade our hash algorithm or iterations count, we have to deal with it all over again. PHP's password_hash() has forward-upgrading built in to its design

Proposed resolution

The following description refers to MR !3245 (branch 1845004-phpass-module). A less ambitious proposal can be found in MR !3181 (branch 1845004-replace-custom-password-).

  • Replace the custom password hashing library with PHP 5.5's password_hash().
  • Use password_hash() with default parameters (i.e. $algo = PASSWORD_DEFAULT and $options = []). As a result, Drupal follows improvements to the defaults made in subsequent PHP releases automatically.
  • Sites with special needs may specify $algo and $options by overriding the arguments of the password service.
  • Extract the existing hashing mechanism to validate passwords of user entities created with Drupal prior to version 10.1.x into a separate core module (phpass).
  • Enable the phpass core module in a post_update hook for all existing sites.
  • Add phpass as a dependency to migrate_drupal. This ensures that passwords migrated from an existing site can be verified without any further action.
  • Keep the phpass core module disabled for new sites.
  • Deprecate \Drupal\Core\Password\PhpassHashedPassword (but not the code moved to the phpass module).

Note: Whether it is acceptable to disable the phpass module is highly individual for each existing website. Some sites have thousands of active users and breaking their logins all at the same time will result in a huge support nightmare. On other sites there is only a small circle of admin accounts. Migrating their passwords to the PHP password_hash() format might be accomplished in a few weeks without any manual intervention and the phpass module can be disabled without causing any problems in a subsequent deployment.

Drupal should deprecated the phpass module in some future release and move it to contrib. That decision could be taken based on actual usage numbers - which are expected to decline over time.

Remaining tasks

None.

API changes

  1. A new password service (Drupal\Core\Password\PhpPassword) is introduced which essentially wraps password_hash(), password_verify() and password_needs_rehash).
  2. The implementation of Drupal\Core\Password\PhpassHashedPassword is moved to a new phpass module.
  3. A deprecated subclass is left at Drupal\Core\Password\PhpassHashedPassword and removed in Drupal 11.0

Data model changes

None.


Update .visually-hidden class

$
0
0

This issue was identified in the Olivero issue queue, but seems to have a wider impact than just that theme.

When logged in to a fresh Drupal 10 installation, a fine thin line appears below the footer. This has been identified as the aria-live region, as needed by the admin toolbar. The visually-hidden class does not appear to adequately hide this element.

screenshot of Olivero theme with thin white line below footer

{{ directory }} in Twig template resolves the directory of the child theme rather than that of the parent theme

$
0
0

Given a base theme called parenttheme that is a child of stable, and a sub-theme called childtheme whose base theme is parenttheme, a Twig template implemented in the parenttheme theme renders the wrong value for the {{ directory }} variable.

  1. In the parent theme, add a node.html.twig template with the following content:
    {# contents of parenttheme/templates/node.html.twig #}
    file is themes/custom/parenttheme/templates/content/node.html.twig<br>
    directory is: {{ directory }}

    Leave node.html.twig unimplemented in child theme, so that it inherits from parent.

  2. Set default theme to childtheme.
  3. Visiting node/1 will print:
    file is themes/custom/parenttheme/templates/content/node.html.twig
    directory is themes/custom/childtheme

In theory, step 3 should produce a value of themes/custom/parenttheme for the directory variable, otherwise, how can you depend on that variable to reference URLs of additional assets from the parent theme?

In actuality, {{ directory }} is acting exactly like {{ active_theme_path() }}.

As I understand it, this basically means that you cannot use {{ directory }} to reference any static assets in a base or parent theme, such as the path to an image icon, or using the {{ source() }} Twig function to insert an inline SVG. In my case, I'm trying to do just this:

{{ source(directory ~ '/images/fluffy.svg') }}

But when I create my subtheme and visit the page, I get: Twig_Error_Loader: Template "themes/custom/childtheme/images/fluffy.svg" is not defined. Obviously, the fluffy.svg file only exists in the parent theme, next to the location of the node.html.twig template that references it. There is no reason fluffy.svg should need to be copied to the subtheme.

I initially wrote this up as a question on Stack Overflow to see if anyone had any input, but no one answered. In the end I found my own workaround.

Workaround

The workaround is to implement hook_preprocess() and set a global template variable called themename_directory that points to the parent theme path.

// @file parenttheme.theme
/**
 * Prepares global variables for all templates.
 */
function parenttheme_preprocess(&$variables) {
  $handler = \Drupal::service('theme_handler');
  $variables['parenttheme_directory'] = $handler->getTheme('parenttheme')->getPath();
}
{# @file parenttheme/templates/node.html.twig #}
{{ source( parenttheme_directory ~ 'images/fluffy.svg') }}

Use focus-within in hidden.module.css

$
0
0

Problem/Motivation

This is a followup issue to #3084166: Add a focus-within polyfill to core.

Convert hidden.module.css to use focus-within instead of focus for the benefits that it brings.

Example use-case

Allow arbitrary hidden-but-focusable skip-links that are nested with <ul><li>, such as the "Add new comment" link.

Bartik

Bartik skip link example

Olivero

Olivero skip link example

Proposed resolution

Convert hidden.module.css to use focus-within.

Forbid view/edit/delete in ContactMessageAccessControlHandler

$
0
0

Problem/Motivation

Follow-up for #2843755-19: EntityResource: Provide comprehensive test coverage for Message entity
Message entities are not stored but access handler use permission access site-wide contact form to grant access to this operations

Proposed resolution

Forbid access for unused operations.

Remaining tasks

- Review merge request
- Write a change record draft
- Review change record and mark RTBC

User interface changes

no

API changes

Yes, Access denied may occur when using a module such as contact_storage, which will need to add its own access handler. However an entity's handlers and access check providers are considered internal per Drupal backwards-compatibility and internal API.

Data model changes

no

New hook "Node access records save"

$
0
0

In some cases we need to react after calculating and saving node grants.
Hooks "node_access_records" and "node_access_records_alter" are non-useful in this cases.

Entity queries querying the latest revision very slow with lots of revisions

$
0
0

After upgrading to 8.4 we noticed a performance decrease on one of our sites. The page that is taking minutes to load is a multilanguage page with several field collections and revisions enabled.

Some debugging lead me to the change in issue 2864995.

This change introduces a latestRevision() method which is used by QuickEdit (this explains why it is only when logged in). On a field collection that has about 4000 revisions, this query takes seconds to run.

If I understand correctly the change introduces a self-join to the base revision table. Because of this, for each revision in the table, a set of revisions + next revisions is added to the result. From this result only the row that has no next revision (is null) is used (in my case 7000000 rows are searched for the one that has no next revisions).

base_table.revision_idbase_table_2.revision_id
......
335916335986
335916336066
335986336066
336066NULL

Maybe we can think of a more efficient way of querying the latest revision?

Note: Please do not create patches or re-roll previous patches. Use the Merge Request functionality.

"Please" has crept back into the codebase

$
0
0

Problem/Motivation

Our interface text guidelines specify that the word "please" shouldn't be used in interface text: https://www.drupal.org/node/604342

A number have crept back in since #679890: Using "Please" in the interface.

Proposed resolution

Remove the word "please" from strings and code comments.

Remaining tasks

Update the latest patch and include the change in #18 to cspell.json

Some test fixtures seem to include the word "please" and other tests might be testing a "please" added by vendor code. So, the attached changes only non-test strings. The tests that fail will also need to be updated.

User interface changes

"Please" removed from numerous messages.

API changes

N/A

Data model changes

N/A


Use Attribute::addClass() instead of CSS class concatenation in template_preprocess_views_view_table()

Use READ COMMITTED for all MySQL transactions on busy sites

$
0
0

Problem/Motivation

By default, Drupal uses the "REPEATABLE READ" transaction isolation level - this results in lots of deadlock errors.

Serialization failure: 1213 Deadlock found when trying to get lock

The issue Use READ COMMITTED by default for MySQL transactions sets the isolation level only if it is explicitly configured in settings.php.

All high-traffic sites need to use the "READ COMMITTED" transaction isolation level without any requirements in settings.php.

Node created timestamp and updated timestamp are different for new nodes

$
0
0

When a new node is created, the created timestamp and changed timestamp are not the same. This is because of the function copyFormValuesToEntity in ContentEntityForm.php which copies values only from non-widget fields to the entity when the node is saved. Since 'changed' is a hidden field, even though it has the same timestamp as created until this function is executed , now gets a different time than the created.

I would assume that created and changed times should be the same for new nodes. Thoughts appreciated!

Thanks,
Sukanya

Incorrect sprintf parameter usage

$
0
0

Problem/Motivation

The exception messages in class Drupal\file\FileRepository use sprintf to feed in a destination parameter. However, instead of the normal %s designated placeholder the string has the full word %destination and the parameter is passed as an array. This produces the exception message: Invalid stream wrapper: 1estination in Drupal\file\FileRepository->writeData()

Proposed resolution

Change
sprintf('Invalid stream wrapper: %destination', ['%destination' => $destination])
into
sprintf('Invalid stream wrapper: %s', $destination)

Remaining tasks

There are three exceptions like this in core/modules/file/src/FileRepository.php

Deprecate watchdog_exception

$
0
0

Problem/Motivation

We're modernizing PHP by removing procedural code. watchdog_exception is an example of that. It provides a simple wrapper around \Drupal::logger()->log() with a bit of exception decoding.

Proposed resolution

  • Deprecate watchdog_exception
  • Replace uses of watchdog_exception with \Drupal::logger()

Remaining tasks

API changes

The function watchdog_exception() has been deprecated.

CommentSelection::entityQueryAlter() fails on validate when referencing entity is not a comment

$
0
0

Problem/Motivation

#2958241: Impossible to reply to comments: commented entity considered unreferencable because CommentSelection::entityQueryAlter() joins on {node_field_data} table causes a regression when you have a comment reference on a non-comment entity type. Our use case is a contact form allows to report a comment and references that comment. This is a fatal now on 9.5 and worked on 9.4, so I think this is major if not critical, only reason it's not is that it might be a bit an obscure use case.

Steps to reproduce

1. Add a comment field anywhere, for example on a node type
2. create such an entity, reference a comment, save.

Proposed resolution

Check that the context entity really is a comment. That's more a workaround though, I'm not sure what should happen in such a case, I didn't look into what exactly the purpose of this check even is.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Allow configuration entities to be ignored during import operations

$
0
0

I've come across a number of instances where I've wanted specific configuration entities to be ignored during configuration import operations. Our current workflow basically involves full config exports from local dev environments that get get imported to dev, staging, production environments. Most recently, using the YamlForm module I ran up against this again where I wanted certain YamlForm "template" forms (which are config entities) to get imported into production but also have forms that get spawned from these templates to get ignored during configuration import so they wouldn't get deleted when importing configurations that didn't contain the spawned entities. drush cim --partial was a potential workaround but introduced other issues into our workflow.

This patch lays groundwork in core for flagging individual configuration entities to be ignored during config imports allowing more flexibility in configuration workflows. Using YamlForm as an example, a YamlForm configuration entity can be created and set to be ignored by configuration like so:

$yamlForm = YamlForm::create($values);
$yamlForm->setImportIgnore(TRUE);
$yamlForm->save();

setImportIgnore() also has an option for making the ignore settings for the entity more granular by import operation (create, update, rename, or delete):

// Ignore config import for creation and updating only.
$yamlForm->setImportIgnore(TRUE, ['create', 'update']);

Having config import ignore flags set will prevent an entity's config from getting imported as well as prevent it from showing up in change lists.


Pager h4 causes accessibility flag on many pages

$
0
0

Problem/Motivation

The pager by default uses an h4, this creates the `Heading levels should only increase by one` error in many use cases.

Steps to reproduce

Create a view with a pager that has no other content on the page.
Run axe devtools

Proposed resolution

Remove the h4 and use a nav element to wrap the pager instead.

Remaining tasks

Create MR
Accessibility review

User interface changes

API changes

Data model changes

Release notes snippet

Clean up ModuleListForm a bit

$
0
0

Problem/Motivation

The ModuleListForm has dead code and uninjected dependencies and duplicated html in the output. All of this makes it not that pleasant to work with and review.

Proposed resolution

Clean it up whilst not changing the UI at all.

Remaining tasks

User interface changes

None

API changes

Forms are not API.

Data model changes

None

"comment count" query in getForumStatistics() in \Drupal\forum\ForumManager is not limited to forum terms

$
0
0

The query being executed in forum_get_forums computes the topic_count and comment_count for ALL taxonomy-terms, not just the ones in the forum vocabulary. This is a performance issue if you have many non forum nodes.

In my setup (albeit with mostly forum nodes) this makes almost a 10% differencein query-time: 310ms vs. 283ms.
(total nodes=11724, total comments=123459 / forum nodes=11715, forum comments=118518)
(28 forum terms / 364 terms)

This patch adds a AND r.tid IN ($forum_terms) to the query. Since I am not a programmer, the foreach-loop can certainly be made nicer. This was tested with mysql, I don't know about pg.

Please review.

Remove unique constraint on block content info field

$
0
0

Problem/Motivation

The first version of validation was introduced in #1998658: Creating Custom Block with same name as existing block throws SQL error, you can check commit (https://git.drupalcode.org/project/drupal/-/commit/edcc75602fe1fc3b1d15049bdaec0198ce5aa43a)
At that moment the custom_block module has a custom table with "unique keys", but now it is not a case any more

(core/modules/block/custom_block/custom_block.install)

'unique keys' => array(
      'revision_id' => array('revision_id'),
      'uuid' => array('uuid'),
      'info' => array('info'),
    ),

Currently custom block entity has constraint UniqueField for info field. I don't see any reason to have it unique.
We can have different content block types and of course they can have not unique info fields.

A little history

This was probably from before we had UUIDs
Back in Drupal 7 these were likely using in hook block info
But now we use the uuid, so this constraint isn't needed.

Steps to reproduce

Add a few block with the same info field value.

Proposed resolution

Get rid off UniqueField constraint.

Toolbar: Fix Code Style (Keep the code DRY)

$
0
0

Keep the code DRY :)

I'm optimizing Toolbar module and break down the parts into a small patch in favor of easier reviewing.

The patch using `format-patch` to generate. Please read each commits message inside the patch to understand what's going on.

Viewing all 297699 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>