-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3154 from CSCfi/plugins
Plugins
- Loading branch information
Showing
29 changed files
with
844 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Plugins | ||
|
||
REMS can be extended with plugins in certain extension points. | ||
|
||
The plugins are loaded dynamically from external code found in the specified file. | ||
|
||
There should be a function defined in the plugin, that is called at the right time. The name of the function | ||
depends on the type of the extension point. | ||
|
||
All the functions receive `config` where the plugin's configuration is (from the config file). Also context | ||
specific `data` will be passed. | ||
|
||
Certain types of libraries have been exposed to plugins. Please post an issue if you want more added. | ||
|
||
Examples of plugins can be found in the `resources/plugins` directory. | ||
|
||
## Types of plugins | ||
|
||
### Transform | ||
|
||
Take `data` and do any kind of transformations to it and return the new `data`. | ||
|
||
Return the original data if nothing should be done. | ||
|
||
```clj | ||
(defn transform [config data] | ||
...) | ||
``` | ||
|
||
### Process | ||
|
||
Processes the passed `data` for side-effects, such as integration to another server using HTTP requests. | ||
|
||
Returns the errors so an empty sequence (`nil` or `[]` for example) should be returned if everything was good. | ||
Any errors will prevent the possible next process from running. | ||
|
||
In the case of a failure in processing of the same `data`, the process will be retried again, so the implementation should be idempotent. A retry can also happen for a successful process, if a processing plugin configured after this plugin fails. | ||
|
||
```clj | ||
(defn process [config data] | ||
...) | ||
``` | ||
|
||
### Validate | ||
|
||
Validates the passed `data`. | ||
|
||
Returns the errors so an empty sequence (`nil` or `[]` for example) should be returned if everything was good. | ||
Any errors will prevent the possible next validation from running, and generally the action from happening (e.g. logging in). | ||
|
||
```clj | ||
(defn validate [config data] | ||
...) | ||
``` | ||
|
||
## Extension points | ||
|
||
Next are all the current extension points and the function they expect to find in the plugin. | ||
|
||
### `:extension-point/transform-user-data` | ||
|
||
After logging in, after opening the OIDC token and potentially fetching the user info, allow transforming that data further. For example, a complex field can be parsed and the result stored in new fields. | ||
|
||
Expects `transform` function. | ||
|
||
See [AARC-G069-group-split.md](../resources/plugins/AARC-G069-group-split.md) | ||
|
||
### `:extension-point/validate-user-data` | ||
|
||
After logging in, after the user data is finalized, allow validating it to prevent invalid users from logging in. | ||
|
||
Expects `validate` function. | ||
|
||
The first returned error will be shown to the user on an error page. It can have the keys: | ||
- `:key` The translation key of the error message such as `:t.login.errors/invalid-user` (possibly from extra translations provided). | ||
- `:args` Additional arguments for the message translation (`%1`,`%2`, ...) if any. These must be translation keys too. | ||
|
||
See [validate-attributes.md](../resources/plugins/validate-attributes.md) | ||
|
||
### `:extension-point/process-entitlements` | ||
|
||
After entitlements have been updated, the new entitlements can be processed, and for example updated to | ||
another system. | ||
|
||
Expects `process` function. | ||
|
||
See [LS-AAI-GA4GH-push.md](../resources/plugins/LS-AAI-GA4GH-push.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# AARC-G069 group parse | ||
|
||
A plugin to parse group attributes according to AARC-G069. | ||
|
||
The format comes from AARC-G069 as so: | ||
|
||
<NAMESPACE>:group:<GROUP>[:<SUBGROUP>*][:role=<ROLE>][#<AUTHORITY>] | ||
|
||
The OIDC attribute name that is parsed is configured in the `:attribute-name` config. With these example attibutes: | ||
|
||
urn:geant:lifescience-ri.eu:group:example-vo.lifescience-ri.eu#aai.lifescience-ri.eu | ||
urn:geant:elixir-europe.org:group:elixir:ELIXIR%20AAI:staff#perun.elixir-czech.cz | ||
|
||
The <NAMESPACE> is: | ||
|
||
urn:geant:lifescience-ri.eu | ||
urn:geant:elixir-europe.org | ||
|
||
The <AUTHORITY> comes after `#`: | ||
|
||
aai.lifescience-ri.eu | ||
perun.elixir-czech.cz | ||
|
||
The part `:group:` is just a splitter like the `#` is. | ||
|
||
The middle part are the <GROUP> (and <SUBGROUP>s) of the person: | ||
|
||
example-vo.lifescience-ri.eu (only group) | ||
elixir:ELIXIR%20AAI:staff (group "elixir", subgroup "ELIXIR AAI", subgroup "staff") | ||
|
||
The <ROLE> is not present in the example but it is currently handled as just another subgroup. So | ||
a `role=R` would literally be just an additional `role=R` group. | ||
|
||
For a group to be valid the authority must declared in config `:trusted-authorities`. | ||
|
||
```clj | ||
(require '[clojure.string :as str]) | ||
(require '[clojure.tools.logging :as log]) | ||
(require '[rems.config :refer [env]]) | ||
(require '[rems.common.util :refer [getx]]) | ||
|
||
(defn transform [config data] | ||
(when (:log-authentication-details env) | ||
(log/info "Data" data)) | ||
|
||
(let [attribute-name (getx config :attribute-name)] | ||
(if-some [attribute-value (get data (keyword attribute-name))] | ||
(let [group-index (str/index-of attribute-value ":group:") | ||
authority-index (str/index-of attribute-value "#")] | ||
|
||
(when (:log-authentication-details env) | ||
(log/info "Indices" group-index authority-index)) | ||
|
||
(if (and group-index | ||
authority-index | ||
(< -1 group-index authority-index)) | ||
(let [namespace (subs attribute-value 0 group-index) | ||
groups-and-role (subs attribute-value (+ group-index (count ":group:")) authority-index) | ||
authority (subs attribute-value (+ authority-index (count "#"))) | ||
|
||
groups (str/split groups-and-role #":")] | ||
|
||
(when (:log-authentication-details env) | ||
(log/info "Parts" namespace groups authority)) | ||
|
||
;; TODO: check trusted authority | ||
|
||
(assoc data :groups groups)) | ||
data)) | ||
data))) | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# LifeScience AAI GA4GH push | ||
|
||
A plugin to push REMS entitlements to LifeScience AAI using GA4GH visas. | ||
|
||
See [GA4GH](../../docs/ga4gh-visas.md). | ||
|
||
```clj | ||
(defn process [config data] | ||
;; TODO implement | ||
) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Validate attributes | ||
|
||
A plugin to validate that specified attributes are present and not empty strings. | ||
|
||
```clj | ||
(require '[clojure.string :as str]) | ||
(require '[clojure.tools.logging :as log]) | ||
|
||
(defn empty-attributes [user attributes] | ||
(for [{:keys [attribute-name error-key]} attributes | ||
:let [attribute-value (get user (keyword attribute-name)) | ||
error? (str/blank? attribute-value)] | ||
:when error?] | ||
error-key)) | ||
|
||
(defn validate [config data] | ||
(when-some [invalid-attributes (seq (empty-attributes data (get config :required-attributes)))] | ||
(log/info invalid-attributes) | ||
[{:key :t.login.errors/invalid-user | ||
:args invalid-attributes}])) | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Validate group membership | ||
|
||
Check that the specified group attribute contains at least | ||
one of the valid groups. | ||
|
||
```clj | ||
(require '[rems.config :refer [env]]) | ||
(require '[clojure.string :as str]) | ||
(require '[clojure.tools.logging :as log]) | ||
|
||
(defn validate [config data] | ||
(let [{:keys [attribute-name valid-groups error-key]} config | ||
groups (get data (keyword attribute-name))] | ||
|
||
(when (:log-authentication-details env) | ||
(log/info "Groups" groups)) | ||
|
||
(when (or (empty? groups) | ||
(empty? (clojure.set/intersection (set groups) valid-groups))) | ||
[{:key error-key}]))) | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.