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.
As is shown in the previous workflow, this module implements two stages for user registration:
-
A OAuth 2.0 authentication (login & register) method that is configurable. At the moment the default provider is
valid
(is a built-in identity validator from the AOC consortium. However, it is possible to add other (external) providers, not necessarily available in this plugin. PRs are welcome to add OAuth registration/login in this plugin itself if they come from official sources. See the CONTRIBUTING file for more information. -
Automatic creation of the first authorization with OAuth metadata. This authorization will be used to verify the user's identity in the second stage. It saves some data from the OAuth provider, such as the unique identifier, the provider name, and the expiration date of the authorization or other. The saved data is configurable in this plugin. This data should be the one necessary to authenticate the users, without their intervention to an external census API provider in the second stage.
-
A second authorization ("Census authorization") can be issued to verify the user's identity. This authorization will be used to connect to an external API to retrieve more information about the user (mainly if belongs to a particular census). This authorization is optional and configurable in this plugin. It can be disabled if not needed.
-
The default census authorization uses Via Oberta but others can be used instead (either internal or external). If you want to incorporate a new provider see the CONTRIBUTING file for more information.
-
Once the user has obtained the census authorization, you can use it to ensure that the user belongs to a particular census. This increases the security and avoids spoofing attacks (if the second authorization methods does not uses user inputs).
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
thedecidim-trusted_ids
gem will run the following (that can also be run manually if you consider):bin/rails decidim_trusted_ids:install:migrations
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.
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 the trusted_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.
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.
-
If system attributes are defined, it will available in the system configuration page:
-
If the census authorization is created, it will be available in the census authorization page. This is how the Via Oberta Handler looks like:
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.
To start contributing to this project, first:
- Install the basic dependencies (such as Ruby and PostgreSQL)
- Clone this repository
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.
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
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:
- Sublime Text - Sublime RuboCop
- Visual Studio Code - Rubocop for Visual Studio Code
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.
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.
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
This engine is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE.