Giter VIP home page Giter VIP logo

key's Introduction

Key Module for Drupal 8

Build Status

This module provides the ability for site administrators to manage sitewide keys, which can be used, for example, to integrate with external services. Keys are available for use by other modules using a Drupal service provided by Key.

Managing Keys

To manage keys, visit admin/config/system/key. When creating a file, enter a name for the key and select the key provider to be used. Additional settings for the selected key provider may be required. For instance, if the File key provider is selected, enter a path to the file that contains the key.

Key Providers

Key leverages the Drupal 8 Plugin API for key providers, so that other modules can define additional key providers through the Key Plugin Manager. A key provider defines a method for retrieving a key, along with settings specific to that key provider, which are saved when creating a Key entity. Each plugin needs to register, as an annotation, the storage method used within the plugin.

For convention, it is recommended to use one the following storage method values:

  1. File - Stored in a file and retrieved via the local filesystem or by using a stream wrapper
  2. Configuration - Stored with Drupal’s built-in configuration management (settings, entities)
  3. Database - Stored as a field in a database record
  4. Remote - Retrieved via a remote service call

Using a Key

Modules can retrieve information about keys or a specific key value by making a call to the Key Manager service. It is best practice to inject the service into your own service, form, or controller. The following examples assume the use of the \Drupal object for brevity, but the examples can be extrapolated to fit the use case of your module.

Get All Keys

Drupal::service('key_repository')->getKeys();

Get Single Key

Drupal::service('key_repository')->getKey($key_id);

Get Default Key

Drupal::service('key_repository')->getKey();

Get Key Value

Drupal::service('key_repository')->getKey($key_id)->getKeyValue();

key's People

Contributors

adam-bergstein avatar craigmoore avatar eclipsegc avatar lahoosascoots avatar mradcliffe avatar nerdstein avatar rlhawk avatar tynor avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

key's Issues

Confirmation text when unsetting default key is unclear

When unsetting the default key, the confirmation text currently reads

Are you sure you want to remove the default key from KEYLABEL?

which is unclear. It should be something like

Are you sure you want to unset KEYLABEL as the default key?

Additionally, the text of the button should probably be consistent with the "unset" terminology and read "Unset Default" instead of "Remove Default".

Update information on key listing page

The information about keys that appears in the table on the key listing page should be updated to be more useful.

  • Remove the machine name column
  • Add columns for
    • Description
    • Key provider

The two new columns should not appear at smaller screen sizes.

Additionally, the title of the page should be changed to "Keys", from "Key Configuration".

Add Base64-encoded checkbox to Key form

From the example I gave in #40:

[W]ith Rijndael-128, it's very important that the key be 128 bits of random data. If you were to generate a 16-character key by, say, truncating the results of a hash function like MD5, it would seem to fit that requirement. However, the keyspace would actually be reduced by a factor of 2^64. Using drupal_random_bytes(16)—or whatever the D8 replacement is—truly does produce 128 bits of random data, but it's not readable. Thus the need to base64-encode it, if you want it to be readable. But then Key needs to know to base64-decode it when retrieving it.

Remove File provider's Method setting field

The Method setting field for the File key provider is used to select a transformation that should happen to the contents of the file when the key is being retrieved. The result of the transformation is the key itself. The two available options are "file contents," which does no transformation, and "MD5 hash," which uses an MD5 hash of the file contents as the key. We should change the name of the field to better reflect its purpose—perhaps to "Transformation," "Process," "Modification"—something other than "Method," which is vague.

In addition, the File provider needs to have a new option for this field, "Base64 decode," which should base64 decode the contents of the file and use that as the key. The Drupal configuration (Simple key) provider also needs to have this field as a setting, with "Base64 decode" as an option, but I will create a separate issue for that.

Fix formatting of DocBlocks in KeyManager

Shouldn't the DocBlocks for the methods in KeyManager.php have an extra asterisk in the first line to conform with DocBlock standards?

Current:

/*
 * Loading all keys.
 *

Proposed:

/**
 * Loading all keys.
 *

Rename "key type" to better reflect its functionality

In the Drupal 7 version of the Encrypt module, a plugin type called "Key Provider" was defined to allow different methods of providing a key. The name was changed to "Key Storage Method" in the Drupal 7 version of the Key module. A plugin type that defines this same functionality is needed for the Drupal 8 version of Key. "Key Type" is currently being used for that functionality, but the terminology is not correct. We could continue to use "Key Storage Method" for the label or something else—perhaps just "Storage Method," or "Location."

Decide which administrative category Key belongs to

Currently the admin page for managing keys can be found under Structure, but the path suggests that it's under Configuration (/admin/config/system/key). We should choose one or the other and be consistent.

Create new Key Form API element

To make it easy for modules to integrate with Key, the version of the module for Drupal 7 adds a new form API element called key. It extends the select element, but fills #options with the list of available keys. It also provides additional instructions for using and defining keys in the #description. Here's an example of what that looks like in code:

$form['secret_key'] = array(
  '#type' => 'key',
  '#title' => t('Secret key'),
);

This functionality should be in the Drupal 8 version also. Key for D7 has additional functionality, such as filtering, that can be added later for D8.

Extend key type services

-Add in storage method annotation field
-Add in getKeysByStorageMethod to service (filter by annotation)
-Add in getKeysByType to service (filter by plugin type)

Add ability for users to enable integration on a case-by-case basis

The Drupal 7 version of Key requires a user to specifically enable integration with other modules that can use it. This gives the user more control over when Key is handling a key for another module, instead of just taking over everything it can when it's enabled. I think this is an useful feature and we should duplicate it in the Drupal 8 module. I'm open to suggestions for how to improve this functionality.

Confirmation message when setting or unsetting default key is not correct

When setting or unsetting the default key, the following message is displayed:

content key: KEYLABEL is now default.

The "content key: " part of the message should not appear in either instance.

When unsetting the key, the message should say something to the effect that the key is no longer the default.

Move Key from Security section to System section on Configuration page

From #33:

I don't think it's possible for a contributed module to add a top-level administrative section, along with its own page, without causing complications and problems.

Problem 1: If multiple modules define the security section, multiple instances of it appear on the Configuration page.

image

Problem 2: If multiple modules define the route to the security section's page, only one will be used. For example, if Key and Password Policy both define the path "/admin/config/security", only one of the module's admin pages will be listed on it. In my tests, it was Key, but I suppose it depends on the loading order of the modules.

image

I propose that the Keys admin link be moved under the System category, unless there's an easy way to resolve the problems introduced by defining the Security category.

Error handling for File Key Provider: what is the best approach?

What is the best approach? Should Key throw an exception or return null? An exception would need to be handled with try/catch by modules that use Key so that the application does not crash, but leaves the possibility for an error message. Returning null is easier (?) for a module to handle, maybe?

Give key providers access to the key entity attributes

Use Case

Lockr (and possibly other external key providers) store metadata about keys in their own systems, which must be accessed by some ID. Reusing the key entity's ID simplifies that process and prevents the user being required to enter a separate ID for the service in addition to one for the entity itself.

It is possible to generate a random ID to satisfy that requirement. However, if an external key provider, like Lockr, aims to allow users to list and modify their keys directly in the external service, having the key names and descriptions match makes that process much easier.

Changes

(Breaks backwards compatibility.)

I propose to change KeyProviderInterface::getKeyValue()'s function signature from:

public function getKeyValue();

to

public function getKeyValue(KeyInterface $key);

and modify the configuration form such that it allows access to the key entity values from the key provider. Currently it only passes the 'key_settings' subset of form values.

Could be as simple as changing:

$plugin_settings = (new FormState())->setValues($form_state->getValue('key_settings'));
$plugin = $this->manager->createInstance($form_state->getValue('key_provider'), []);
$plugin->submitConfigurationForm($form, $plugin_settings);

to

$plugin = $this->manager->createInstance($form_state->getValue('key_provider'), []);
$plugin->submitConfigurationForm($form, $form_state);

as well as the respective change for KeyForm::validateForm().

Another option would be to not change KeyProviderInterface::getKeyValue() and leave it up to the key provider to store relevant data from the key in KeyProviderBase::submitConfigurationForm(). Though this sounds like storing redundant information since I can't think of a reason one would change the key entity without wanting the provider to update.

If there is an alternative that makes sense and maintains backwards compatibility, I would love to hear it.

Change Key Settings to Key Provider Settings globally

We need to be careful about differentiating between Keys and Key Providers. Throughout the module, key provider settings are referred to as "key settings". That introduces the potential for confusion and should be changed globally, using "key provider settings" instead of "key settings". Alternatively, we could use "provider settings", but I'm inclined to be more verbose for improved clarity.

Changing default key when one is already set results in fatal error

If a key is set as the default and you try to make a different key the default, a fatal error is returned:

Fatal error: Cannot access protected property Drupal\key\Entity\Key::$service_default in /var/www/drupal/modules/contrib/key/src/KeyRepository.php on line 125

This error is returned after the confirmation form is submitted. If you unset the default, then set the new default, there is no error.

Add ability to obscure key values

Of the two built-in providers, the only one that allows setting a key is Configuration. It makes sense for a key that was set previously to be displayed when the key is edited.

For security reasons, however, other providers that allow setting the key may want to indicate that the key has been set, but not actually display it. It can be up to the provider to decide how to do that. In the example I'm thinking of, it would be handled differently depending on what type of key it is: For API keys, asterisks would be displayed, except for the last four characters. For encryption keys, only asterisks would be shown.

The Drupal 7 version of Key deals with this issue by defining an "obscure key" callback function that can be defined and employed by the provider. The provider then needs to address the situation when a user submits an obscured key, recognizing that it hasn't actually been changed, so it doesn't get overwritten with asterisks (or whatever is being used as a placeholder for the actual key).

Make route paths for key management conform to Drupal standard

The current paths for key management look like this:

  • /admin/config/system/key
  • /admin/config/system/key/add
  • /admin/config/system/key/{key}
  • /admin/config/system/key/{key}/delete

Consider a situation where a user creates a key with a machine name of 'add'. They would never be able to edit it (though they could delete it).

We should modify the paths to match the standard Drupal pattern for paths, as follows:

  • /admin/config/system/key
  • /admin/config/system/key/add
  • /admin/config/system/key/manage/{key}
  • /admin/config/system/key/manage/{key}/delete

Submitting the key edit form without a key provider returns an error

The #empty_value is set to 'none', which is interpreted to be a key name, rather than an empty value. It should be changed to an empty string (or just not defined), unless of course we want to allow 'none' to be a valid key provider. I guess that would allow you to create a dummy key that doesn't actually return anything. Do we want that?

Add Description field to Key edit form

This can be a very useful field for users who want to add more information about a key. The Drupal 7 version of Key has it and the Drupal 8 version should, too.

Provide a better message when no keys are available

When there are no keys to list on the Key Manager page, the default Drupal no-results text (“There is no Key yet.”) is displayed, which is awkward. It should be changed to something similar to what Taxonomy provides (“No vocabularies available. Add vocabulary.”).

Add a function to the Key Repository service to get key names

In order to simplify retrieving a list of available keys by modules that integrate with Key, we should provide a function to the Key Repository service to retrieve a list of key names. These could then be easily used in a select form, for instance.

Here's an example of how this change would affect Encrypt:

Before:

$keys = ['default' => 'System Default'];
/** @var $key \Drupal\key\Entity\KeyInterface */
foreach ($this->key_repository->getKeys() as $key) {
  $key_id = $key->id();
  $key_title = $key->label();
  $keys[$key_id] = (string) $key_title;
}

After:

$keys = ['default' => 'System Default'];
$keys += $this->key_repository->getKeyNamesAsOptions();

Listing key names in select fields will be very common, so it's helpful to have a function that returns a list that's ready for the select FormAPI element.

Even better would be to provide a new key FormAPI element, the way Key for Drupal 7 does, but I'll create a new issue for that.

Fix config form

Need to determine if we need this. Currently has stubbed out options (test,test2,test3, etc).

Change HTML field label for key label field

Sorry for the confusing issue title.

A standard Drupal pattern when referring to an item’s (user-friendly) label in a form is to use the term “name”. See examples below. We should change “Label” to “Key name” to be consistent with this pattern.

image
image
image

Improve key provider names

The default key providers available have the following names:

  • Simple key
  • File key

"Key" in both instances is unnecessary and "Simple key" doesn't give a clear indication of how the key is actually being provided. I propose the following two replacement names:

  • Drupal configuration
  • File

Allow providers to perform action when a key is deleted

When a key is deleted, its provider may need to perform some action, such as deleting the actual key value, wherever it is stored. This functionality should also be triggered when the provider is changed.

Key for Drupal 7 does this with a CTools callback.

Add a plugin type to allow types of keys to be defined

Currently, the Key Type plugin type seems to be defining what is called "Key Storage Method" in the Drupal 7 version of Key and called "Key Provider" in the Drupal 7 version of Encrypt. Key Type should actually indicate the type of key being defined. For example, a module could define a key type of "Authorize.net Transaction Key," which would allow for validation rules specific to that type of key and would allow filtering of the list of keys by modules that use them. We will need a new plugin type to add storage-method functionality. I'll create a separate issue for that.

Add a new permission for administering keys

Currently 'administer site configuration' is used for the permission to access Key administration pages. A new permission should be created that is specific to administering keys.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.