ConsorciAOC-PRJ / decidim-module-trusted-ids

Trusted IDs Authentications for Decidim
GNU Affero General Public License v3.0
0 stars 1 forks source link

Decidim :: Trusted IDs

[CI] Lint [CI] Test Maintainability Codecov Gem Version

Translations:

Translations

This module is an evolution of the original IdCat Mòbil that was funded by the Department d'Exteriors of Generalitat de Catalunya and developed by CodiTramuntana.

On of the goals of this module is to decouple the authentication method from the IdCat Mòbil and pursue a more agnostic with a registry of providers. It also implements additional user options for extended verification methods using Via Oberta (or other providers) with improved user's control over personal data management.

The main goal, though, is to provide an, opinionated, easy to use, and secure authentication method for Decidim with strong authentication systems. That is, OAuth authentication systems that provide a unique identifier for each user. Preferably from official entities. Each user logged using this system will be verified automatically using the integrated verification method that this plugin provides, and will save the unique identifier as metadata.

Later on, this metadata will be used to connect to an additional, configurable, API to retrieve more information about the user. This information will be used to verify the user's identity with more granularity (for instance, restrict user actions to certain user properties, such as which census belongs to).

Finally, GDPR regulations are very present in this workflow, so user consent is a must. This plugins adds some additional steps to the registration process to give the user more control over the data that is being used, and to give the user the ability to revoke consent at any time.

Workflow:

Workflow

As is shown in the previous workflow, this module implements two stages for user registration:

First stage:
Second stage:

Installation

Add this line to your application's Gemfile:

gem "decidim-trusted_ids"

Or, if you want to stay up to date with the latest changes use this line instead:

gem 'decidim-trusted_ids', git: "https://github.com/ConsorciAOC-PRJ/decidim-module-trusted-ids"

And then execute:

bundle
bin/rails decidim:upgrade
bin/rails db:migrate

EXPERTS ONLY

Under the hood, when running bundle exec rails decidim:upgrade the decidim-trusted_ids gem will run the following (that can also be run manually if you consider):

bin/rails decidim_trusted_ids:install:migrations

Using OAuth in Decidim

This module adds a new authentication method to Decidim that allows users to log in and register using an OAuth2 provider. This provider must be configured in the ENV variables or through an initializer.

One important thing to note is that, in order to use an OAuth authentication system, you need on the provider to register and authorize the return url of your Decidim instance. This is usually done by adding the URL of your Decidim instance to the list of authorized URLs in the OAuth provider's settings.

By default this plugin uses the valid provider, which is a built-in identity validator from the AOC consortium.

This means that you need to enable the following return url in the OAuth provider:

https://your-decidim-instance.com/users/auth/valid/callback

If you are using a different provider, you should replace valid with the name of your provider.

Usage

This plugin comes prepared to be used solely with ENV variables, but you can also configure it through an initializer.

By default, you can use these variables to configure the module:

Environment variable Description Default value
OMNIAUTH_PROVIDER The OAuth2 provider to use. Currently only valid is built-in in this plugin. Note that this word will be used as a prefix (in uppercase) for all the omniauth values defined after this. If you use a different provider, say foo, nexts ENV vars will start with FOO_ instead of VALID_ valid
CUSTOM_LOGIN_SCREEN Whether to use a custom login screen or the default Decidim login screen. true (only if omniauth is enabled)
OMNIAUTH_ENABLED_BY_DEFAULT Whether the OAuth2 login is enabled by default. If false must be enabled in system. true (if VALID_CLIENT_ID is present)
OMNIAUTH_GLOBAL_ATTRIBUTES Attributes sent to the Omniauth provider that are not writeable in the /system admin. Separated by spaces. site icon_path scope
VALID_CLIENT_ID The OAuth2 client ID. Note that the prefix VALID is because OMNIAUTH_PROVIDER is set to "valid". Other values will require to name this variable accordingly (for instance FOO_CLIENT_ID). IF this variable is empty, no OAuth login will be used. nil
VALID_CLIENT_SECRET The OAuth2 client secret. nil
VALID_SITE The OAuth2 site. nil
VALID_ICON The icon used for the login button. media/images/valid-icon.png
VALID_SCOPE The OAuth2 scope that returns the necessary fields for registration (some OAuth method might override this making it unnecessary). autenticacio_usuari
VERIFICATION_EXPIRATION_TIME In seconds, how long the authorizations will be valid. Use zero or empty to prevent expiration. 7776000 (90 days)
SEND_VERIFICATION_NOTIFICATIONS Whether to send notifications to users when they are verified or the verification process fails. true
CENSUS_AUTHORIZATION_HANDLER The authorization handler to use for the census authorization. Currently only via_oberta_handler is built-in in this plugin. via_oberta_handler
CENSUS_AUTHORIZATION_FORM The authorization form to use for the census authorization. This is an standard authorization form and it should be responsible for the actions of connecting to a census API and handle any user interaction that might require. Currently only ViaObertaHandler is built-in in this plugin. Decidim::ViaOberta::Verifications::ViaObertaHandler
CENSUS_AUTHORIZATION_ENV The environment variable that will be used to store the census authorization. In the case of Via Oberta, calls to the proper URL api. production
CENSUS_AUTHORIZATION_API_URL The URL of the census API. By default it is empty, if defined, overrides the pre-defined URL obtained from the previous ENV var (if the census authorization is created this way). nil
CENSUS_AUTHORIZATION_SYSTEM_ATTRIBUTES This var defines which attributes need to be configured at the /system multi-tenant super admin page. These might be secret properties that can be used by the census authorization but might vary from tenant to tenant. Each value must be a word, separated by spaces. See the screenshots section. nif ine municipal_code province_code organization_name

In`addition, metadata obtained from the OAuth provider that need to be stored in thetrusted_ids_handler` authorization can be configured through next variables.

Note that these ENVs variables work the same way as the previous VALID_* vars. If the provider is foo, it should start with FOO_METADATA_*.

Any ENV var starting as VALID_METADATA_SUFFIX will make the plugin to save a metadata attribute called suffix as part of the authorization metadata encrypted hash.

As the the returned JSON from a successful OAuth login/registration might follow a different structure, you can configure the names of the fields that will be used to extract the metadata. This is done by using each word inside the value of the ENV var (separated by spaces) as a level in the JSON structure. For instance, if you have a return OAuth JSON data like this:

{
  "uid": "12345678Z",
  "provider": "valid",
  "credentials": {
    "expires_at": "2020-12-31T23:59:59Z"
  },
  "info": {
    "identifier_type": "NIF",
    "method": "idcat_mobil"
  },
  "assurance_level": "high"
}

You can configure the ENV vars like this:

Environment variable Value
VALID_METADATA_EXPIRES_AT credentials expires_at
VALID_METADATA_IDENTIFIER_TYPE info identifier_type
VALID_METADATA_METHOD info method
VALID_METADATA_ASSURANCE_LEVEL info assurance_level

And this will store in the trusted_ids_handler authorization metadata the following values:

{
  "uid": "12345678Z",
  "provider": "valid",
  "extra" {
    "expires_at": "2020-12-31T23:59:59Z",
    "identifier_type": "NIF",
    "method": "idcat_mobil",
    "assurance_level": "high"
  }
}

Note that the uid and provider fields are always stored, and the extra field is used to store any other metadata.

Via initializer

If you are using a different source for your settings, you can also configure this module through an initializer.

For instance, create a file config/initializers/decidim_trusted_ids.rb with the following content:

Decidim::TrustedIds.configure do |config|
  # The name of the omniauth provider, must be registered in Decidim.
  config.omniauth_provider = "valid"
  config.omniauth = {
    enabled: true,
    client_id: "my-client-id",
    client_secret: "my-client-secret",
    site: "https://identitats-pre.aoc.cat",
    scope: "autenticacio_usuari",
    icon: "media/images/valid-icon.png"
  },
  ...
end

For the complete list of available options, see the trusted_ids file.

Screenshots

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/ConsorciAOC-PRJ/decidim-module-trusted-ids.

If you want to create your own authorization or OmniAuth methods, make sure to read the CONTRIBUTING.md file first.

Developing

To start contributing to this project, first:

Decidim's main repository also provides a Docker configuration file if you prefer to use Docker instead of installing the dependencies locally on your machine.

You can create the development app by running the following commands after cloning this project:

bundle
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake development_app

Note that the database user has to have rights to create and drop a database in order to create the dummy test app database.

Then to test how the module works in Decidim, start the development server:

DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bin/rails s

Note that bin/rails is a convenient wrapper around the command cd development_app; bundle exec rails.

In case you are using rbenv and have the rbenv-vars plugin installed for it, you can add the environment variables to the root directory of the project in a file named .rbenv-vars. If these are defined for the environment, you can omit defining these in the commands shown above.

Webpacker notes

As latests versions of Decidim, this repository uses Webpacker for Rails. This means that compilation of assets is required every time a Javascript or CSS file is modified. Usually, this happens automatically, but in some cases (specially when actively changes that type of files) you want to speed up the process.

To do that, start in a separate terminal than the one with bin/rails s, and BEFORE it, the following command:

bin/webpack-dev-server

Code Styling

Please follow the code styling defined by the different linters that ensure we are all talking with the same language collaborating on the same project. This project is set to follow the same rules that Decidim itself follows.

Rubocop linter is used for the Ruby language.

You can run the code styling checks by running the following commands from the console:

bundle exec rubocop

To ease up following the style guide, you should install the plugin to your favorite editor, such as:

Testing

To run the tests run the following in the gem development path:

bundle
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rake test_app
DATABASE_USERNAME=<username> DATABASE_PASSWORD=<password> bundle exec rspec

Note that the database user has to have rights to create and drop a database in order to create the dummy test app database.

In case you are using rbenv and have the rbenv-vars plugin installed for it, you can add these environment variables to the root directory of the project in a file named .rbenv-vars. In this case, you can omit defining these in the commands shown above.

Test code coverage

Running tests automatically generates a code coverage report. To generate the complete report run all the tests using this command:

bundle exec rspec

This will generate a folder named coverage in the project root which contains the code coverage report.

Localization

If you would like to see this module in your own language, you can help with its translation at Crowdin:

https://crowdin.com/project/decidim-trusted-ids

License

This engine is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE.