commit f0b380456c769936e5a777ac4f67bfd0fe32f3c8 Author: Mauro Mugnaini Date: Thu Jan 14 18:15:40 2021 +0100 First commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0b314ec --- /dev/null +++ b/LICENSE @@ -0,0 +1,310 @@ +Originale +Permalink +Blame +Cronologia + +European Union Public Licence v. 1.2 + +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the 'EUPL') applies to the Work (as defined +below) which is provided under the terms of this Licence. Any use of the Work, +other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). + +The Work is provided under the terms of this Licence when the Licensor (as +defined below) has placed the following notice immediately following the copyright +notice for the Work: + + + + Licensed under the EUPL + + + +or has expressed by any other means his willingness to license under the EUPL. + + 1. Definitions + + In this Licence, the following terms have the following meaning: + + — 'The Licence': this Licence. + +— 'The Original Work': the work or software distributed or communicated by +the Licensor under this Licence, available as Source Code and also as Executable +Code as the case may be. + +— 'Derivative Works': the works or software that could be created by the Licensee, +based upon the Original Work or modifications thereof. This Licence does not +define the extent of modification or dependence on the Original Work required +in order to classify a work as a Derivative Work; this extent is determined +by copyright law applicable in the country mentioned in Article 15. + + — 'The Work': the Original Work or its Derivative Works. + +— 'The Source Code': the human-readable form of the Work which is the most +convenient for people to study and modify. + +— 'The Executable Code': any code which has generally been compiled and which +is meant to be interpreted by a computer as a program. + +— 'The Licensor': the natural or legal person that distributes or communicates +the Work under the Licence. + +— 'Contributor(s)': any natural or legal person who modifies the Work under +the Licence, or otherwise contributes to the creation of a Derivative Work. + +— 'The Licensee' or 'You': any natural or legal person who makes any usage +of the Work under the terms of the Licence. + +— 'Distribution' or 'Communication': any act of selling, giving, lending, +renting, distributing, communicating, transmitting, or otherwise making available, +online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + + 2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable +licence to do the following, for the duration of copyright vested in the Original +Work: + + — use the Work in any circumstance and for all usage, + + — reproduce the Work, + + — modify the Work, and make Derivative Works based upon the Work, + +— communicate to the public, including the right to make available or display +the Work or copies thereof to the public and perform publicly, as the case +may be, the Work, + + — distribute the Work or copies thereof, + + — lend and rent the Work or copies thereof, + + — sublicense rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether +now known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make effective +the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights +to any patents held by the Licensor, to the extent necessary to make use of +the rights granted on the Work under this Licence. + + 3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as Executable +Code. If the Work is provided as Executable Code, the Licensor provides in +addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice +following the copyright notice attached to the Work, a repository where the +Source Code is easily and freely accessible for as long as the Licensor continues +to distribute or communicate the Work. + + 4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits +from any exception or limitation to the exclusive rights of the rights owners +in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + + 5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the disclaimer +of warranties. The Licensee must include a copy of such notices and a copy +of the Licence with every copy of the Work he/she distributes or communicates. +The Licensee must cause any Derivative Work to carry prominent notices stating +that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the +Original Works or Derivative Works, this Distribution or Communication will +be done under the terms of this Licence or of a later version of this Licence +unless the Original Work is expressly distributed only under this version +of the Licence — for example by communicating 'EUPL v. 1.2 only'. The Licensee +(becoming Licensor) cannot offer or impose any additional terms or conditions +on the Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative +Works or copies thereof based upon both the Work and another work licensed +under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, 'Compatible +Licence' refers to the licences listed in the appendix attached to this Licence. +Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible +Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the +Work, the Licensee will provide a machine-readable copy of the Source Code +or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade +names, trademarks, service marks, or names of the Licensor, except as required +for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + + 6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she brings +to the Work are owned by him/her or licensed to him/her and that he/she has +the power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent Contributors +grant You a licence to their contributions to the Work, under the terms of +this Licence. + + 7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +Contributors. It is not a finished work and may therefore contain defects +or 'bugs' inherent to this type of development. + +For the above reason, the Work is provided under the Licence on an 'as is' +basis and without warranties of any kind concerning the Work, including without +limitation merchantability, fitness for a particular purpose, absence of defects +or errors, accuracy, non-infringement of intellectual property rights other +than copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a condition +for the grant of any rights to the Work. + + 8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the +use of the Work, including without limitation, damages for loss of goodwill, +work stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such damage. +However, the Licensor will be liable under statutory product liability laws +as far such laws apply to the Work. + + 9. Additional agreements + +While distributing the Work, You may choose to conclude an additional agreement, +defining obligations or services consistent with this Licence. However, if +accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, +and only if You agree to indemnify, defend, and hold each Contributor harmless +for any liability incurred by, or claims asserted against such Contributor +by the fact You have accepted any warranty or additional liability. + + 10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon 'I agree' +placed under the bottom of a window displaying the text of this Licence or +by affirming consent in any other similar way, in accordance with the rules +of applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and conditions +by exercising any rights granted to You by Article 2 of this Licence, such +as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + + 11. Information to the public + +In case of any Distribution or Communication of the Work by means of electronic +communication by You (for example, by offering to download the Work from a +remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable +law regarding the Licensor, the Licence and the way it may be accessible, +concluded, stored and reproduced by the Licensee. + + 12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically +upon any breach by the Licensee of the terms of the Licence. + +Such a termination will not terminate the licences of any person who has received +the Work from the Licensee under the Licence, provided such persons remain +in full compliance with the Licence. + + 13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as +a whole. Such provision will be construed or reformed so as necessary to make +it valid and enforceable. + +The European Commission may publish other linguistic versions or new versions +of this Licence or updated versions of the Appendix, so far this is required +and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version +of their choice. + + 14. Jurisdiction + + Without prejudice to specific agreement between parties, + +— any litigation resulting from the interpretation of this License, arising +between the European Union institutions, bodies, offices or agencies, as a +Licensor, and any Licensee, will be subject to the jurisdiction of the Court +of Justice of the European Union, as laid down in article 272 of the Treaty +on the Functioning of the European Union, + +— any litigation arising between other parties and resulting from the interpretation +of this License, will be subject to the exclusive jurisdiction of the competent +court where the Licensor resides or conducts its primary business. + + 15. Applicable Law + + Without prejudice to specific agreement between parties, + +— this Licence shall be governed by the law of the European Union Member State +where the Licensor has his seat, resides or has his registered office, + +— this licence shall be governed by Belgian law if the Licensor has no seat, +residence or registered office inside a European Union Member State. + +Appendix + +'Compatible Licences' according to Article 5 EUPL are: + + — GNU General Public License (GPL) v. 2, v. 3 + + — GNU Affero General Public License (AGPL) v. 3 + + — Open Software License (OSL) v. 2.1, v. 3.0 + + — Eclipse Public License (EPL) v. 1.0 + + — CeCILL v. 2.0, v. 2.1 + + — Mozilla Public Licence (MPL) v. 2 + + — GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 + +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for +works other than software + + — European Union Public Licence (EUPL) v. 1.1, v. 1.2 + +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity +(LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the +above licences without producing a new version of the EUPL, as long as they +provide the rights granted in Article 2 of this Licence and protect the covered +Source Code from exclusive appropriation. + +All other changes or additions to this Appendix require the production of +a new EUPL version. diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..f8d6df8 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,9 @@ +--- +env : "dev" +keycloak_server : "accounts.{{ env }}.d4science.org" +keycloak_baseurl: "https://{{keycloak_server}}" +d4science_realm_name: "d4scienceee" +d4science_realm_url: "{{ keycloak_baseurl }}/auth/admin/realms/{{ d4science_realm_name }}" +d4science_realm_theme: "d4science" +ldap_server: "ldap.pre.d4science.org" +orchestrator_baseUrl: "https://orchestrator.d4science.org/api/workflow/" diff --git a/defaults/plain_main.yml b/defaults/plain_main.yml new file mode 100644 index 0000000..b220f39 --- /dev/null +++ b/defaults/plain_main.yml @@ -0,0 +1,12 @@ +--- +keycloak_username: "" +keycloak_password: "" +eosc_clientId: "" +eosc_clientSecret: "" +linkedin_clientId: "" +linkedin_clientSecret: "" +google_clientId: "" +google_clientSecret: "" +recaptcha_key: "" +recaptcha_secret: "" +ldap_credential: "" diff --git a/defaults/vault_main.yml b/defaults/vault_main.yml new file mode 100644 index 0000000..eb2eae0 --- /dev/null +++ b/defaults/vault_main.yml @@ -0,0 +1,36 @@ +$ANSIBLE_VAULT;1.1;AES256 +65633233343737346434623733613537313636366164336637656434633362643536316430306666 +3739373234636662646637663163336136386566386631370a623038336435643031643865656637 +62386663643066346330376630353333636663363433623831656534613833383835613466636565 +6363366661663039630a376133303438373864613035663136323834656530633636636637353032 +62633435326661626131356535313832613134633631393264383039396161633561343738643965 +37643665643639636165653137353038396536633138313563316165663334393038383239653461 +30333834656664633564656363396633303636616436353766326566643437373535343530616662 +65333963393738623966623138356562356539363637316133656565346638346265366633373362 +62653239323665633032353765313862396135623231393932623630303965303563633835613437 +39316365343235303765623132323861323139613064326565643031303063646461613633643431 +31306363363437393334633761316265393264613465323466376365346266373335343139646532 +37336635366363383230353238333339326635663635373234373233346361653964323266663365 +31623434656661353735636263333761313062363439346633393830383733636362373761666430 +66343732333066383264663632343838663631336266363066616562386333346661633234363035 +63333762353235326638323662396661643037376664333764393739643534363861316431643963 +61323061386466623562383862316261313430376361666132623863373265646266366439646239 +33393630336431346330383834353734373539303731653237613664643463366262356462336262 +33326337653335653033373537366431623666613639343338313566306134386366613937333830 +30336532386333633436383738373439663466653862316264356438653061373362336666393736 +35373130316638353234373434616232326565393866366133303039656463356161326531353065 +63636637313233623661356633343038623464656430643339353934333737363936363738663462 +62333431303139666562653836616633636535336264396530306637326362663631643061616232 +33326534333338366132313230396266333438303133653862616435633138346237386631363936 +64646432616364636336373737346436653566326439663364653030613538373631653931333236 +63343735306665636532353932323239366366613732303564303737393734303639666631303837 +62616665376634353337396334353431386334653031633366393762366635366462396265396331 +38663137343462613438616636376163613462376631343566363263383435656363363162343864 +36343936386362363263333034666534383032663431393562303934343232303063386134663633 +66636366373835326132626138646165376431646566393834346164613065646234626333333337 +34353231616136623263306563383063316530353234333334666664313366623137393665326434 +35313432373034366335313237376539376133383665623537313835373566313036383863653539 +35313435663364646533376461386435363131663766353165616562336536623734623961613031 +34383930653961346233333135363363363930383337643964396432353663643535316163373935 +66656663303632653935333936343666613663346437663037336235646361363733386538373738 +646164323961613266623033646532653830 diff --git a/files/infrastructure-client_role.json b/files/infrastructure-client_role.json new file mode 100644 index 0000000..cf560ca --- /dev/null +++ b/files/infrastructure-client_role.json @@ -0,0 +1,3 @@ +{ + "clientRole" : false, "name" : "Infrastructure-Client", "description" : "Infrastructure-Client role" +} diff --git a/files/infrastructure-manager_role.json b/files/infrastructure-manager_role.json new file mode 100644 index 0000000..59593bd --- /dev/null +++ b/files/infrastructure-manager_role.json @@ -0,0 +1,3 @@ +{ + "clientRole" : false, "name" : "Infrastructure-Manager", "description" : "Infrastructure-Manager role" +} diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..034d46d --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,30 @@ +--- +galaxy_info: + author: Mauro Mugnaini + description: Devop + company: Nubisware S.r.l. + + issue_tracker_url: https://redmine-s2i2s.isti.cnr.it/projects/provisioning + + license: EUPL 1.2+ + + min_ansible_version: 2.8 + + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + platforms: + - name: Ubuntu + versions: + - bionic + - name: EL + versions: + - 7 + - 8 + + galaxy_tags: + - keycloak + - d4science + - realm + +dependencies: diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..48ca27e --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,246 @@ +--- + - name: "Getting Token for service access on Keycloak" + uri: + url: "{{ keycloak_baseurl }}/auth/realms/master/protocol/openid-connect/token" + method: POST + body_format: form-urlencoded + body: + username: "{{ keycloak_username }}" + password: "{{ keycloak_password }}" + grant_type: "password" + client_id: "admin-cli" + register: keycloak_token + run_once: True + + - name: "Find out, if realm {{ d4science_realm_name }} exists on Keycloak" + uri: + url: "{{ d4science_realm_url }}" + method: GET + status_code: + - 200 + - 404 + headers: + Accept: "application/json" + Authorization: "Bearer {{ keycloak_token.json.access_token }}" + register: d4science_realm_check + run_once: True + + - name: "Create and configure d4science realm named: {{ d4science_realm_name }}" + vars: + authorization: "Bearer {{ keycloak_token.json.access_token }}" + block: + + - name: "Create new {{ d4science_realm_name }} realm on Keycloak" + uri: + url: "{{ keycloak_baseurl }}/auth/admin/realms" + method: POST + body: "{{ lookup('template', 'd4science_realm.json.j2') }}" + body_format: "json" + status_code: + - 201 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + register: d4science_realm_create + + - name: "Getting {{ d4science_realm_name }} registration flow executions" + uri: + url: "{{ d4science_realm_url }}/authentication/flows/registration/executions" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "{{ authorization }}" + register: registration_executions + + - name: "Enabling ReCaptcha registration flow executions" + uri: + url: "{{d4science_realm_url}}/authentication/flows/registration/executions" + method: PUT + body: "{'id':'{{ registration_executions.json | json_query(query_id) }}','requirement':'REQUIRED','providerId': 'registration-recaptcha-action' }" + body_format: "json" + status_code: + - 204 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + vars: + query_id: "[?providerId == 'registration-recaptcha-action'] | [0].id" + + - name: "Configuring ReCaptcha" + uri: + url: "{{d4science_realm_url}}/authentication/executions/{{ registration_executions.json | json_query(query_id) }}/config" + method: POST + body: "{'alias':'reCaptcha','config':{'secret':'{{ recaptcha_secret }}','site.key':'{{ recaptcha_key }}','useRecaptchaNet':'false'}}" + body_format: "json" + status_code: + - 201 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + vars: + query_id: "[?providerId == 'registration-recaptcha-action'] | [0].id" + + + - name: "Adding Infrastructure-Manager realm role" + uri: + url: "{{d4science_realm_url}}/roles" + method: POST + body: "{{ lookup('file', 'infrastructure-manager_role.json') }}" + body_format: "json" + status_code: + - 201 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + + - name: "Adding Infrastructure-Client realm role" + uri: + url: "{{d4science_realm_url}}/roles" + method: POST + body: "{{ lookup('file', 'infrastructure-client_role.json') }}" + body_format: "json" + status_code: + - 201 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + + - name: "Adding orchestrator client to realm" + uri: + url: "{{ d4science_realm_url }}/clients" + method: POST + body: "{{ lookup('template', 'orchestrator_client.json.j2') }}" + body_format: "json" + status_code: + - 201 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + register: orchestrator_client_create + + - name: "Adding lr62_portal client to realm" + uri: + url: "{{ d4science_realm_url }}/clients" + method: POST + body: "{{ lookup('template', 'lr62_portal_client.json.j2') }}" + body_format: "json" + status_code: + - 201 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + register: lr62_client_create + + - name: "Getting orchestrator service-account-user" + uri: + url: "{{ d4science_realm_url }}/clients/{{ orchestrator_client_create.location.split('/').pop() }}/service-account-user" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "{{ authorization }}" + register: orchestrator_sau + + - name: "Getting lr62_portal service-account-user" + uri: + url: "{{ d4science_realm_url }}/clients/{{ lr62_client_create.location.split('/').pop() }}/service-account-user" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "{{ authorization }}" + register: lr62_sau + + - name: "Getting {{ d4science_realm_name }} realm roles" + uri: + url: "{{ d4science_realm_url }}/roles" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "{{ authorization }}" + register: d4s_realm_roles + + - name: "Assigning infrastructure-manager role to orchestrator SAU" + uri: + url: "{{ d4science_realm_url }}/users/{{ orchestrator_sau.json.id }}/role-mappings/realm" + method: POST + body: "{{ d4s_realm_roles.json | json_query(\"[?name == 'Infrastructure-Manager']\") }}" + body_format: "json" + status_code: + - 204 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + register: lr62_client_create + + - name: "Assigning infrastructure-client role to lr62_portal SAU" + uri: + url: "{{ d4science_realm_url }}/users/{{ lr62_sau.json.id }}/role-mappings/realm" + method: POST + body: "{{ d4s_realm_roles.json | json_query(query) }}" + body_format: "json" + status_code: + - 204 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + register: lr62_client_create + vars: + query: "[?name == 'Infrastructure-Client']" + + + - name: "Getting realm-management client by clientId" + uri: + url: "{{ d4science_realm_url }}/clients?clientId=realm-management" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "{{ authorization }}" + register: realm_management_client + + - name: "Getting realm-management client roles" + uri: + url: "{{ d4science_realm_url }}/clients/{{ realm_management_client.json[0].id }}/roles" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "{{ authorization }}" + register: realm_management_roles + + - name: "Assigning realm-management roles to orchestrator SAU" + uri: + url: "{{ d4science_realm_url }}/users/{{ orchestrator_sau.json.id }}/role-mappings/clients/{{ realm_management_client.json[0].id }}" + method: POST + body: "{{ realm_management_roles.json | json_query(query) }}" + body_format: "json" + status_code: + - 204 + headers: + Content-type: "application/json" + Accept: "application/json" + Authorization: "{{ authorization }}" + vars: + query: "[?contains([`manage-users`, `view-users`, `manage-clients`, `query-clients`, `query-users`], name)]" + + run_once: True + when: "d4science_realm_check.status == 404" + diff --git a/templates/d4science_realm.json.j2 b/templates/d4science_realm.json.j2 new file mode 100644 index 0000000..587c069 --- /dev/null +++ b/templates/d4science_realm.json.j2 @@ -0,0 +1,623 @@ +{ + "id": "{{ d4science_realm_name }}", + "realm": "{{ d4science_realm_name }}", + "displayName": "D4Science Accounts {{ env }}", + "displayNameHtml": "

D4Science {{ env }}

Welcome

", + "notBefore": 0, + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "ssoSessionIdleTimeoutRememberMe": 0, + "ssoSessionMaxLifespanRememberMe": 0, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespanEnabled": false, + "offlineSessionMaxLifespan": 5184000, + "clientSessionIdleTimeout": 0, + "clientSessionMaxLifespan": 0, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "enabled": true, + "sslRequired": "external", + "registrationAllowed": true, + "registrationEmailAsUsername": false, + "rememberMe": true, + "verifyEmail": true, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": true, + "editUsernameAllowed": false, + "bruteForceProtected": true, + "permanentLockout": false, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "defaultRoles": [ + "offline_access", + "uma_authorization" + ], + "requiredCredentials": [ + "password" + ], + "passwordPolicy": "length(8)", + "browserSecurityHeaders": { + "contentSecurityPolicyReportOnly": "", + "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", + "xFrameOptions": "ALLOW-FROM https://www.google.com", + "contentSecurityPolicy": "frame-src 'self' https://www.google.com;", + "xXSSProtection": "1; mode=block", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" + }, + "smtpServer": { + "host": "localhost", + "from": "noreply@d4science.org", + "starttls": "", + "auth": "", + "ssl": "" + }, + "loginTheme": "{{ d4science_realm_theme }}", + "accountTheme": "{{ d4science_realm_theme }}", + "adminTheme": "{{ d4science_realm_theme }}", + "eventsListeners": [ + "orchestrator-event-publisher", + "jboss-logging", + "email" + ], + "identityProviders": [ + { + "alias": "eosc-oidc", + "displayName": "Academic / other account", + "providerId": "oidc", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": true, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "userInfoUrl": "https://aai.eosc-portal.eu/oidc/userinfo", + "validateSignature": "true", + "clientId": "{{ eosc_clientId }}", + "tokenUrl": "https://aai.eosc-portal.eu/oidc/token", + "jwksUrl": "https://aai.eosc-portal.eu/oidc/jwk", + "issuer": "https://aai.eosc-portal.eu/oidc/", + "useJwksUrl": "false", + "publicKeySignatureVerifier": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjCaIg7INT8AGjPYS7Kmg\nO0K0+axSzCVIlnqHZ8M1hKBfXd4QxZajrqLnwza2yzCGcHNC2aNIYzKm/D2oCx2R\nGzemcgKkcxOznNg2+0H4xlx86FbpVv4VZRXzPqIoc/CU5uyGdR5d58CtOMKhCecS\ny8q3vQ9fnhtLPqYFslLpL+u+3vvcur1rJn/a5GB9th55Lwmq9OyzlAeupbVP1q0A\nI92R1UGUswEPotBFk+a6IVfzToNK7zPdw02IAO/wVDUN1x0Baewm1t8KfviV8m41\nJmjmnUg4p/vLzfA/VKAFqtzwxZCKMkxtu7JwODiIRehMCz4AKBTvvi2k97aMHY+Y\nXQIDAQAB\n-----END PUBLIC KEY-----", + "authorizationUrl": "https://aai.eosc-portal.eu/oidc/authorize", + "clientAuthMethod": "client_secret_post", + "syncMode": "IMPORT", + "clientSecret": "{{ eosc_clientSecret }}", + "defaultScope": "openid profile email", + "guiOrder" : "1" + } + }, + { + "alias": "linkedin", + "providerId": "linkedin", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": true, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "syncMode": "IMPORT", + "clientSecret": "{{ linkedin_clientSecret }}", + "clientId": "{{ linkedin_clientId }}", + "useJwksUrl": "true", + "guiOrder" : "2" + } + }, + { + "alias": "google", + "providerId": "google", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": true, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "syncMode": "IMPORT", + "clientSecret": "{{ google_clientSecret }}", + "clientId": "{{ google_clientId }}", + "useJwksUrl": "true", + "guiOrder" : "3" + } + } + ], + "identityProviderMappers": [ + { + "name": "username from email importer", + "identityProviderAlias": "google", + "identityProviderMapper": "username-from-idp-email-mapper", + "config": { + "syncMode": "INHERIT" + } + }, + { + "name": "username from email importer", + "identityProviderAlias": "eosc-oidc", + "identityProviderMapper": "username-from-idp-email-mapper", + "config": { + "syncMode": "INHERIT", + "auto-resolve": "true" + } + }, + { + "name": "picture importer", + "identityProviderAlias": "linkedin", + "identityProviderMapper": "linkedin-user-attribute-mapper", + "config": { + "syncMode": "INHERIT", + "jsonField": "picture", + "attribute": "picture", + "userAttribute": "picture" + } + }, + { + "name": "avatar", + "identityProviderAlias": "linkedin", + "identityProviderMapper": "avatar-importer", + "config": { + "use-libravatar": "true", + "syncMode": "INHERIT" + } + }, + { + "name": "picture importer", + "identityProviderAlias": "eosc-oidc", + "identityProviderMapper": "oidc-user-attribute-idp-mapper", + "config": { + "syncMode": "INHERIT", + "claim": "picture", + "user.attribute": "picture" + } + }, + { + "name": "picture", + "identityProviderAlias": "google", + "identityProviderMapper": "google-user-attribute-mapper", + "config": { + "syncMode": "INHERIT", + "jsonField": "picture", + "userAttribute": "picture" + } + }, + { + "name": "avatar", + "identityProviderAlias": "google", + "identityProviderMapper": "avatar-importer", + "config": { + "use-libravatar": "true", + "syncMode": "INHERIT" + } + }, + { + "name": "profilePicture importer", + "identityProviderAlias": "linkedin", + "identityProviderMapper": "linkedin-user-attribute-mapper", + "config": { + "syncMode": "INHERIT", + "jsonField": "profilePicture.displayImage", + "userAttribute": "linkedin-profilePicture" + } + }, + { + "name": "avatar", + "identityProviderAlias": "eosc-oidc", + "identityProviderMapper": "avatar-importer", + "config": { + "use-libravatar": "true", + "syncMode": "INHERIT" + } + }, + { + "name": "username from email importer", + "identityProviderAlias": "linkedin", + "identityProviderMapper": "username-from-idp-email-mapper", + "config": { + "syncMode": "INHERIT", + "auto-resolve": "true" + } + } + ], + "components": { + "org.keycloak.storage.UserStorageProvider": [ + { + "name": "{{ ldap_server }}", + "providerId": "ldap", + "subComponents": { + "org.keycloak.storage.ldap.mappers.LDAPStorageMapper": [ + { + "name": "first name", + "providerId": "user-attribute-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "givenName" + ], + "is.mandatory.in.ldap": [ + "true" + ], + "is.binary.attribute": [ + "false" + ], + "read.only": [ + "false" + ], + "always.read.value.from.ldap": [ + "true" + ], + "user.model.attribute": [ + "firstName" + ] + } + }, + { + "name": "email", + "providerId": "user-attribute-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "mail" + ], + "is.mandatory.in.ldap": [ + "false" + ], + "read.only": [ + "false" + ], + "always.read.value.from.ldap": [ + "false" + ], + "user.model.attribute": [ + "email" + ] + } + }, + { + "name": "username", + "providerId": "user-attribute-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "uid" + ], + "is.mandatory.in.ldap": [ + "true" + ], + "is.binary.attribute": [ + "false" + ], + "always.read.value.from.ldap": [ + "false" + ], + "read.only": [ + "true" + ], + "user.model.attribute": [ + "username" + ] + } + }, + { + "name": "d4science-groups", + "providerId": "group-ldap-mapper", + "subComponents": {}, + "config": { + "membership.attribute.type": [ + "DN" + ], + "group.name.ldap.attribute": [ + "cn" + ], + "membership.user.ldap.attribute": [ + "uid" + ], + "preserve.group.inheritance": [ + "true" + ], + "groups.dn": [ + "ou=Groups,o=D4Science,ou=Organizations,dc=d4science,dc=org" + ], + "mapped.group.attributes": [ + "gidNumber" + ], + "mode": [ + "LDAP_ONLY" + ], + "user.roles.retrieve.strategy": [ + "LOAD_GROUPS_BY_MEMBER_ATTRIBUTE" + ], + "ignore.missing.groups": [ + "false" + ], + "membership.ldap.attribute": [ + "member" + ], + "group.object.classes": [ + "groupofnames,posixGroup,top" + ], + "memberof.ldap.attribute": [ + "memberOf" + ], + "drop.non.existing.groups.during.sync": [ + "true" + ] + } + }, + { + "name": "fullname", + "providerId": "full-name-ldap-mapper", + "subComponents": {}, + "config": { + "read.only": [ + "false" + ], + "write.only": [ + "true" + ], + "ldap.full.name.attribute": [ + "cn" + ] + } + }, + { + "name": "last name", + "providerId": "user-attribute-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "sn" + ], + "is.mandatory.in.ldap": [ + "true" + ], + "always.read.value.from.ldap": [ + "true" + ], + "read.only": [ + "false" + ], + "user.model.attribute": [ + "lastName" + ] + } + }, + { + "name": "creation date", + "providerId": "user-attribute-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "createTimestamp" + ], + "is.mandatory.in.ldap": [ + "false" + ], + "read.only": [ + "true" + ], + "always.read.value.from.ldap": [ + "true" + ], + "user.model.attribute": [ + "createTimestamp" + ] + } + }, + { + "name": "modify date", + "providerId": "user-attribute-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "modifyTimestamp" + ], + "is.mandatory.in.ldap": [ + "false" + ], + "read.only": [ + "true" + ], + "always.read.value.from.ldap": [ + "true" + ], + "user.model.attribute": [ + "modifyTimestamp" + ] + } + }, + { + "name": "homeDirectory", + "providerId": "ua-templated-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "homeDirectory" + ], + "is.mandatory.in.ldap": [ + "true" + ], + "read.only": [ + "false" + ], + "always.read.value.from.ldap": [ + "true" + ], + "template.string": [ + "/home/${VALUE}" + ], + "user.model.attribute": [ + "username" + ] + } + }, + { + "name": "sshPublicKey mapper", + "providerId": "certificate-ldap-mapper", + "subComponents": {}, + "config": { + "ldap.attribute": [ + "sshPublicKey" + ], + "is.mandatory.in.ldap": [ + "false" + ], + "is.binary.attribute": [ + "true" + ], + "read.only": [ + "true" + ], + "always.read.value.from.ldap": [ + "true" + ], + "user.model.attribute": [ + "sshPublicKey" + ] + } + } + ] + }, + "config": { + "fullSyncPeriod": [ + "-1" + ], + "pagination": [ + "true" + ], + "connectionPooling": [ + "true" + ], + "usersDn": [ + "ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org" + ], + "cachePolicy": [ + "DEFAULT" + ], + "useKerberosForPasswordAuthentication": [ + "false" + ], + "importEnabled": [ + "true" + ], + "enabled": [ + "true" + ], + "usernameLDAPAttribute": [ + "uid" + ], + "bindCredential": [ + "{{ ldap_credential }}" + ], + "changedSyncPeriod": [ + "-1" + ], + "bindDn": [ + "cn=Directory Manager" + ], + "lastSync": [ + "1595253546" + ], + "vendor": [ + "other" + ], + "uuidLDAPAttribute": [ + "nsUniqueId" + ], + "allowKerberosAuthentication": [ + "false" + ], + "connectionUrl": [ + "ldaps://{{ ldap_server }}" + ], + "syncRegistrations": [ + "true" + ], + "authType": [ + "simple" + ], + "debug": [ + "false" + ], + "searchScope": [ + "1" + ], + "useTruststoreSpi": [ + "never" + ], + "priority": [ + "1" + ], + "trustEmail": [ + "true" + ], + "userObjectClasses": [ + "inetOrgPerson, organizationalPerson, posixAccount, organizationalPerson, person, inetUser, shadowAccount, ldapPublicKey, top" + ], + "rdnLDAPAttribute": [ + "uid" + ], + "editMode": [ + "WRITABLE" + ], + "validatePasswordPolicy": [ + "true" + ], + "batchSizeForSync": [ + "1000" + ] + } + } + ] + }, + "internationalizationEnabled": true, + "supportedLocales": [ + "de", + "no", + "ru", + "sv", + "pt-BR", + "lt", + "en", + "it", + "fr", + "zh-CN", + "es", + "ja", + "sk", + "pl", + "ca", + "nl", + "tr" + ], + "defaultLocale": "en", + "requiredActions": [ + { + "alias": "terms_and_conditions", + "name": "Terms and Conditions", + "providerId": "terms_and_conditions", + "enabled": true, + "defaultAction": true, + "priority": 20, + "config": {} + } + ] +} diff --git a/templates/gw_public_client.json.j2 b/templates/gw_public_client.json.j2 new file mode 100644 index 0000000..16a8ecb --- /dev/null +++ b/templates/gw_public_client.json.j2 @@ -0,0 +1,30 @@ +{ + "baseUrl" : "https://{{ gw_server_name }}/", + "bearerOnly" : false, + "clientId" : "{{ gw-server-name }}", + "name" : "{{ gw-server-name }}", + "description" : "Pre D4Science Gateway", + "directAccessGrantsEnabled" : true, + "enabled" : true, + "protocol" : "openid-connect", + "publicClient" : true, + "redirectUris" : ["https://{{ gw_server_name }}/c/portal/login"], + "attributes": { + "login_theme": "{{ gw_server_name }}" + }, + "protocolMappers": [ + { + "name": "send-groups-in-token", + "protocol": "openid-connect", + "protocolMapper": "oidc-group-membership-mapper", + "consentRequired": false, + "config": { + "full.path": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "userinfo.token.claim": "true" + } + } + ] +} diff --git a/templates/lr62_portal_client.json.j2 b/templates/lr62_portal_client.json.j2 new file mode 100644 index 0000000..fc86bb8 --- /dev/null +++ b/templates/lr62_portal_client.json.j2 @@ -0,0 +1,29 @@ +{ + "baseUrl" : "https://{{env}}.d4science.org/", + "bearerOnly" : false, + "clientId" : "lr62_portal", + "name" : "lr62_portal", + "description" : "The D4Science {{env}} Portal", + "directAccessGrantsEnabled" : true, + "authorizationServicesEnabled" : true, + "serviceAccountsEnabled" : true, + "enabled" : true, + "protocol" : "openid-connect", + "publicClient" : false, + "redirectUris" : ["https://{{env}}.d4science.org/"], + "protocolMappers": [ + { + "name": "send-groups-in-token", + "protocol": "openid-connect", + "protocolMapper": "oidc-group-membership-mapper", + "consentRequired": false, + "config": { + "full.path": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "userinfo.token.claim": "true" + } + } + ] +} diff --git a/templates/orchestrator_client.json.j2 b/templates/orchestrator_client.json.j2 new file mode 100644 index 0000000..b21031f --- /dev/null +++ b/templates/orchestrator_client.json.j2 @@ -0,0 +1,29 @@ +{ + "baseUrl" : "{{orchestrator_baseUrl}}", + "bearerOnly" : false, + "clientId" : "orchestrator", + "name" : "orchestrator", + "description" : "The D4Science {{env}} Orchestrator", + "directAccessGrantsEnabled" : true, + "authorizationServicesEnabled" : true, + "serviceAccountsEnabled" : true, + "enabled" : true, + "protocol" : "openid-connect", + "publicClient" : false, + "redirectUris" : ["{{orchestrator_baseUrl}}"], + "protocolMappers": [ + { + "name": "send-groups-in-token", + "protocol": "openid-connect", + "protocolMapper": "oidc-group-membership-mapper", + "consentRequired": false, + "config": { + "full.path": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "userinfo.token.claim": "true" + } + } + ] +}