INF-162 - Enable the LDAP configuration from REST API

- Create LDAP configuration
- Create LDAP mappers
- Enable Audit logging
- Verify the LDAP Authentication in Molecule environment
- Verify the user operation, create from Keycloak and search from LDAP

Change-Id: Ie6ea7f40cfe403ee3747a30b0bfb3acc9c72057f
diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml
index 5796c8d..3e075cf 100644
--- a/molecule/default/molecule.yml
+++ b/molecule/default/molecule.yml
@@ -19,6 +19,14 @@
   inventory:
     host_vars:
       debian-11-priv:
+        keycloak_server: "http://localhost:8080"
+        keycloak_admin_api: "{{ keycloak_server }}/auth/admin/realms/master"
+        keycloak_ldap_testing_user: "test2"
+        keycloak_ldap_server: "ldap://127.0.0.1:389"
+        keycloak_ldap_userdn: "ou=people,dc=testing,dc=org"
+        keycloak_ldap_admin_dn: "cn=Directory Manager"
+        keycloak_ldap_admin_password: "changeme"
+        keyclaok_ldap_user_object: "inetOrgPerson,organizationalPerson"
         keycloak_admin_username: "admin"
         keycloak_admin_password: "changeme"
         keycloak_client_settings:
diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml
new file mode 100644
index 0000000..7c28828
--- /dev/null
+++ b/molecule/default/prepare.yml
@@ -0,0 +1,15 @@
+---
+# keycloak molecule/default/prepare.yml
+#
+# SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+- name: Prepare for Keycloak by installing dependency roles
+  hosts: all
+
+  vars:
+    ds389_suffix: "dc=testing,dc=org"
+    ds389_root_password: >-
+        {SSHA512}hZUoI/9C3PeGS4nphClWw6Rg2CTX4P0S74GS3YxsmfQdeBobBEkKyUycxQ1HNB9TJHVokY9dpChFOfDPbKzmf3BbiOC1YAFI
+  roles:
+    - ds389
diff --git a/molecule/default/templates/ldap.testconnection.j2 b/molecule/default/templates/ldap.testconnection.j2
new file mode 100644
index 0000000..7b2950f
--- /dev/null
+++ b/molecule/default/templates/ldap.testconnection.j2
@@ -0,0 +1,15 @@
+{#
+SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org>
+SPDX-License-Identifier: Apache-2.0
+#}
+{
+   "action":"testAuthentication",
+   "connectionUrl":"{{ keycloak_ldap_server }}",
+   "authType":"simple",
+   "bindDn":"{{ keycloak_ldap_admin_dn }}",
+   "bindCredential":"{{ keycloak_ldap_admin_password }}",
+   "useTruststoreSpi":"ldapsOnly",
+   "connectionTimeout":"",
+   "startTls":"",
+   "componentId":"{{ ldap_id }}"
+}
diff --git a/molecule/default/templates/ldap.testuser.j2 b/molecule/default/templates/ldap.testuser.j2
new file mode 100644
index 0000000..faa527e
--- /dev/null
+++ b/molecule/default/templates/ldap.testuser.j2
@@ -0,0 +1,16 @@
+{#
+SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org>
+SPDX-License-Identifier: Apache-2.0
+#}
+{
+   "enabled":true,
+   "attributes":{
+   },
+   "groups":[
+   ],
+   "emailVerified":"",
+   "username":"{{ keycloak_ldap_testing_user }}",
+   "email":"test@test.com",
+   "firstName":"first",
+   "lastName":"last"
+}
diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml
index 74ba85a..15e0431 100644
--- a/molecule/default/verify.yml
+++ b/molecule/default/verify.yml
@@ -9,7 +9,7 @@
   tasks:
   - name: "Create Token for service Keycloak"
     uri:
-      url: http://localhost:8080/auth/realms/master/protocol/openid-connect/token
+      url: "{{ keycloak_server }}/auth/realms/master/protocol/openid-connect/token"
       method: POST
       body_format: form-urlencoded
       body:
@@ -21,7 +21,7 @@
 
   - name: "Get Client List"
     uri:
-      url: http://localhost:8080/auth/admin/realms/master/clients
+      url: "{{ keycloak_admin_api }}/clients"
       method: GET
       headers:
         Accept: "application/json"
@@ -38,3 +38,92 @@
     assert:
       that:
         - find is defined
+
+  - name: "Get existing LDAP configuration"
+    uri:
+      url: "{{ keycloak_admin_api }}/components?type=org.keycloak.storage.UserStorageProvider"
+      method: GET
+      headers:
+        Accept: "application/json"
+        Authorization: "Bearer {{ keycloak_token.json.access_token }}"
+    register: keycloak_components_list
+
+  - name: Check if the Keycloak already has the LDAP configuration
+    set_fact:
+      ldap_id: "{{ item.id }}"
+    with_items: "{{ keycloak_components_list.json }}"
+    when: item.name == "ldap"
+
+  - name: Generate a local json file for LDAP configuration
+    become: false
+    delegate_to: localhost
+    template:
+      src: "{{ item }}.j2"
+      dest: "/tmp/{{ item }}"
+      mode: "0600"
+    with_items:
+      - ldap.testconnection
+      - ldap.testuser
+
+  - name: Test LDAP Authentication
+    uri:
+      url: "{{ keycloak_admin_api }}/testLDAPConnection"
+      method: POST
+      src: /tmp/ldap.testconnection
+      status_code: [204]
+      headers:
+        Content-Type: application/json
+        Authorization: "Bearer {{ keycloak_token.json.access_token }}"
+
+  - name: Create user via Keycloak
+    uri:
+      url: "{{ keycloak_admin_api }}/users"
+      method: POST
+      src: /tmp/ldap.testuser
+      status_code: [201]
+      headers:
+        Content-Type: application/json
+        Authorization: "Bearer {{ keycloak_token.json.access_token }}"
+    register: keycloak_create_user_response
+
+  - name: Get User ID from previous response
+    set_fact:
+      user_id: "{{ keycloak_create_user_response.location | basename }}"
+
+  - name: Verify created user via LDAP
+    community.general.ldap_entry:
+      dn: "uid={{ keycloak_ldap_testing_user }},{{ keycloak_ldap_userdn }}"
+      objectClass: "{{ keyclaok_ldap_user_object }}"
+      server_uri: "{{ keycloak_ldap_server }}"
+      bind_dn: "{{ keycloak_ldap_admin_dn }}"
+      bind_pw: "{{ keycloak_ldap_admin_password }}"
+    register: result
+
+  - name: Delete user via Keycloak
+    uri:
+      url: "{{ keycloak_admin_api }}/users/{{ user_id }}"
+      method: DELETE
+      status_code: [204]
+      headers:
+        Content-Type: application/json
+        Authorization: "Bearer {{ keycloak_token.json.access_token }}"
+
+  - name: Verify removed user via LDAP
+    community.general.ldap_entry:
+      dn: "uid={{ keycloak_ldap_testing_user }},{{ keycloak_ldap_userdn }}"
+      objectClass: "{{ keyclaok_ldap_user_object }}"
+      server_uri: "{{ keycloak_ldap_server }}"
+      bind_dn: "{{ keycloak_ldap_admin_dn }}"
+      bind_pw: "{{ keycloak_ldap_admin_password }}"
+    register: result
+    failed_when:
+      - '"missing attribute" not in result.details'
+
+  - name: Remove local LDAP json file
+    delegate_to: localhost
+    file:
+      path: "/tmp/{{ item }}"
+      state: absent
+    with_items:
+      - ldap.testconnection
+      - ldap.testuser