From b0a47c226de112ee51c6d82d6e3f93b1cc8d32f3 Mon Sep 17 00:00:00 2001 From: Krishnan Subramanian Date: Thu, 8 Dec 2022 13:12:02 -0800 Subject: [PATCH 1/6] Formsflow 4.0.7 upgrade --- .gitignore | 5 ++++- apps/forms-flow-ai/forms-flow-bpm/pom-docker.xml | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index dbe9c82b..623f1a72 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -.vscode/ \ No newline at end of file +.vscode/ + +**/.idea/ +*.iml \ No newline at end of file diff --git a/apps/forms-flow-ai/forms-flow-bpm/pom-docker.xml b/apps/forms-flow-ai/forms-flow-bpm/pom-docker.xml index 9cd3e294..7392e00b 100644 --- a/apps/forms-flow-ai/forms-flow-bpm/pom-docker.xml +++ b/apps/forms-flow-ai/forms-flow-bpm/pom-docker.xml @@ -25,10 +25,10 @@ 7.15.0 1.2.2 1.2.0 - 2.4.8 - 2.4.8 - 2.12.2 - 2.2.1 + 2.6.4 + 2.6.4 + 2.13.3 + 2.2.3 From eb7561e0d75648123abe5cb96bd999a3f3a04945 Mon Sep 17 00:00:00 2001 From: dinesh Date: Tue, 18 Apr 2023 23:36:33 -0700 Subject: [PATCH 2/6] Debugging the analytics error --- .../bpm/extension/hooks/listeners/AnalyticsListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/listeners/AnalyticsListener.java b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/listeners/AnalyticsListener.java index 5f71b29a..891cbe67 100644 --- a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/listeners/AnalyticsListener.java +++ b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/listeners/AnalyticsListener.java @@ -108,7 +108,7 @@ private Map injectAdditionalProcessingFields(DelegateExecution ex if (StringUtils.isNotEmpty(idir)) { prcMap.put(entry.getKey(),entry.getValue()); if(!execution.getVariables().containsKey(StringUtils.substringBefore(entry.getKey(), "_idir").concat("_name"))) { - String idirName = getName(execution, idir); + String idirName = getName(execution, variables.get("provider_idir_userid").toString()); execution.setVariable(StringUtils.substringBefore(entry.getKey(), "_idir").concat("_name"), idirName); prcMap.put(StringUtils.substringBefore(entry.getKey(), "_idir").concat("_name"),idirName); } From a9eed588e1b31f2f70c93b0ba87a04eef1ed6251 Mon Sep 17 00:00:00 2001 From: dinesh Date: Wed, 26 Apr 2023 12:18:26 -0700 Subject: [PATCH 3/6] web build docker file change --- apps/forms-flow-ai/forms-flow-web/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/forms-flow-ai/forms-flow-web/Dockerfile b/apps/forms-flow-ai/forms-flow-web/Dockerfile index 73a969c6..e0f734e5 100644 --- a/apps/forms-flow-ai/forms-flow-web/Dockerfile +++ b/apps/forms-flow-ai/forms-flow-web/Dockerfile @@ -31,6 +31,6 @@ RUN npm run build FROM artifacts.developer.gov.bc.ca/docker-remote/nginx:1.17 as production-stage RUN mkdir /app COPY --from=build-stage /app/build /usr/share/nginx/html -COPY nginx.conf /etc/nginx/nginx.conf +COPY --from=build-stage /app/nginx.conf /etc/nginx/nginx.conf EXPOSE 8080:8080 CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file From c55b07552c523e35f7f08c7d267ad60c6d5fb86c Mon Sep 17 00:00:00 2001 From: dinesh Date: Wed, 3 May 2023 15:23:56 -0700 Subject: [PATCH 4/6] keycloak user query change --- .../KeycloakIdentityProviderSession.java | 78 +++++++++++ .../keycloak/plugin/KeycloakUserService.java | 123 ++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakIdentityProviderSession.java create mode 100644 apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakUserService.java diff --git a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakIdentityProviderSession.java b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakIdentityProviderSession.java new file mode 100644 index 00000000..3f4ff681 --- /dev/null +++ b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakIdentityProviderSession.java @@ -0,0 +1,78 @@ +package org.camunda.bpm.extension.keycloak.plugin; + +import java.util.Collections; +import java.util.List; + +import org.camunda.bpm.engine.identity.Group; +import org.camunda.bpm.engine.identity.User; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.extension.keycloak.*; +import org.camunda.bpm.extension.keycloak.cache.QueryCache; +import org.camunda.bpm.extension.keycloak.rest.KeycloakRestTemplate; +import org.camunda.bpm.extension.keycloak.util.KeycloakPluginLogger; +import org.springframework.util.StringUtils; + +/** + * @author aot + * + */ +public class KeycloakIdentityProviderSession + extends org.camunda.bpm.extension.keycloak.KeycloakIdentityProviderSession { + + public KeycloakIdentityProviderSession(KeycloakConfiguration keycloakConfiguration, KeycloakRestTemplate restTemplate, KeycloakContextProvider keycloakContextProvider, + QueryCache> userQueryCache, QueryCache> groupQueryCache, + QueryCache checkPasswordCache, + String webClientId, boolean enableClientAuth) { + super(keycloakConfiguration, restTemplate, keycloakContextProvider, userQueryCache, groupQueryCache, checkPasswordCache); + this.groupService = new KeycloakGroupService(keycloakConfiguration, restTemplate, keycloakContextProvider, webClientId, enableClientAuth); + this.userService = new KeycloakUserService(keycloakConfiguration, restTemplate, keycloakContextProvider, webClientId, enableClientAuth); + } + + /** + * Get the group ID of the configured admin group. Enable configuration using group path as well. + * This prevents common configuration pitfalls and makes it consistent to other configuration options + * like the flag 'useGroupPathAsCamundaGroupId'. + * + * @param configuredAdminGroupName the originally configured admin group name + * @return the corresponding keycloak group ID to use: either internal keycloak ID or path, depending on config + * + * @see org.camunda.bpm.extension.keycloak.KeycloakGroupService#getKeycloakAdminGroupId(java.lang.String) + */ + public String getKeycloakAdminGroupId(String configuredAdminGroupName) { + return groupService.getKeycloakAdminGroupId(configuredAdminGroupName); + } + + /** + * + * @param userQuery + * @return + */ + protected List findUserByQueryCriteria(KeycloakUserQuery userQuery) { + StringBuilder resultLogger = new StringBuilder(); + if (KeycloakPluginLogger.INSTANCE.isDebugEnabled()) { + resultLogger.append("Keycloak group query results: ["); + } + + List allMatchingUsers = userQueryCache.getOrCompute(CacheableKeycloakUserQuery.of(userQuery), + this::doFindUserByQueryCriteria); + List processedUsers = userService.postProcessResults(userQuery, allMatchingUsers, resultLogger); + if (KeycloakPluginLogger.INSTANCE.isDebugEnabled()) { + resultLogger.append("]"); + KeycloakPluginLogger.INSTANCE.groupQueryResult(resultLogger.toString()); + } + + return processedUsers; + } + + /** + * + * @param userQuery + * @return + */ + private List doFindUserByQueryCriteria(CacheableKeycloakUserQuery userQuery) { + return StringUtils.hasLength(userQuery.getGroupId()) ? + this.userService.requestUsersByGroupId(userQuery) : + this.userService.requestUsersWithoutGroupId(userQuery); + } + +} \ No newline at end of file diff --git a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakUserService.java b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakUserService.java new file mode 100644 index 00000000..1122703c --- /dev/null +++ b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/keycloak/plugin/KeycloakUserService.java @@ -0,0 +1,123 @@ +package org.camunda.bpm.extension.keycloak.plugin; + +import org.camunda.bpm.engine.identity.User; +import org.camunda.bpm.engine.impl.persistence.entity.UserEntity; +import org.camunda.bpm.extension.keycloak.KeycloakConfiguration; +import org.camunda.bpm.extension.keycloak.rest.KeycloakRestTemplate; +import org.camunda.bpm.extension.keycloak.KeycloakContextProvider; +import org.camunda.bpm.extension.keycloak.KeycloakGroupNotFoundException; +import org.camunda.bpm.extension.keycloak.CacheableKeycloakUserQuery; +import org.camunda.bpm.engine.impl.identity.IdentityProviderException; +import org.camunda.bpm.extension.keycloak.json.JsonException; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestClientException; +import org.springframework.util.StringUtils; + +import java.util.logging.Logger; + +import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import static org.camunda.bpm.extension.keycloak.json.JsonUtil.*; + +/** + * Keycloak User Service. + * Custom class for Implementation of user queries against Keycloak's REST API. + */ +public class KeycloakUserService extends org.camunda.bpm.extension.keycloak.KeycloakUserService { + + /** This class' logger. */ + private final Logger LOGGER = Logger.getLogger(KeycloakUserService.class.getName()); + + private String webClientId; + private boolean enableClientAuth; + + public KeycloakUserService(KeycloakConfiguration keycloakConfiguration, KeycloakRestTemplate restTemplate, + KeycloakContextProvider keycloakContextProvider,String webClientId,boolean enableClientAuth) { + super(keycloakConfiguration, restTemplate, keycloakContextProvider); + this.webClientId = webClientId; + this.enableClientAuth = enableClientAuth; + } + + @Override + public List requestUsersByGroupId(CacheableKeycloakUserQuery query) { + String groupId = query.getGroupId(); + List userList = new ArrayList<>(); + + try { + // get Keycloak specific groupID + String keyCloakID; + try { + keyCloakID = getKeycloakGroupID(groupId); + } catch (KeycloakGroupNotFoundException e) { + // group not found: empty search result + return Collections.emptyList(); + } + + // get members of this group + ResponseEntity response = restTemplate.exchange( + keycloakConfiguration.getKeycloakAdminUrl() + "/groups/" + keyCloakID + "/members?max=" + getMaxQueryResultSize(), + HttpMethod.GET, String.class); + if (!response.getStatusCode().equals(HttpStatus.OK)) { + throw new IdentityProviderException( + "Unable to read group members from " + keycloakConfiguration.getKeycloakAdminUrl() + + ": HTTP status code " + response.getStatusCodeValue()); + } + + JsonArray searchResult = parseAsJsonArray(response.getBody()); + for (int i = 0; i < searchResult.size(); i++) { + JsonObject keycloakUser = getJsonObjectAtIndex(searchResult, i); + if (keycloakConfiguration.isUseEmailAsCamundaUserId() && + !StringUtils.hasLength(getJsonString(keycloakUser, "email"))) { + continue; + } + if (keycloakConfiguration.isUseUsernameAsCamundaUserId() && + !StringUtils.hasLength(getJsonString(keycloakUser, "username"))) { + continue; + } + userList.add(transformUser(keycloakUser)); + } + + } catch (HttpClientErrorException hcee) { + // if groupID is unknown server answers with HTTP 404 not found + if (hcee.getStatusCode().equals(HttpStatus.NOT_FOUND)) { + return Collections.emptyList(); + } + throw hcee; + } catch (RestClientException | JsonException rce) { + throw new IdentityProviderException("Unable to query members of group " + groupId, rce); + } + + return userList; + } + + private UserEntity transformUser(JsonObject result) throws JsonException { + UserEntity user = new UserEntity(); + String userId = getJsonString(result, "username"); + JsonObject attributes = getJsonObject(result, "attributes"); + if(attributes != null) { + JsonArray userIds = attributes.getAsJsonArray("userid"); + if(userIds != null) { + userId = userIds.get(0).getAsString(); + } + } + + String email = getJsonString(result, "email"); + String firstName = getJsonString(result, "firstName"); + String lastName = getJsonString(result, "lastName"); + user.setId(userId); + user.setEmail(email); + user.setFirstName(firstName); + user.setLastName(lastName); + return user; + } +} \ No newline at end of file From 19a68d4517c1448e671bbb241277eead678d2b83 Mon Sep 17 00:00:00 2001 From: dinesh Date: Tue, 9 May 2023 10:13:43 -0700 Subject: [PATCH 5/6] getUser method change --- .../java/org/camunda/bpm/extension/hooks/services/IUser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/services/IUser.java b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/services/IUser.java index 6bc0994c..539cdb95 100644 --- a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/services/IUser.java +++ b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/services/IUser.java @@ -20,16 +20,17 @@ public interface IUser { default String getName(DelegateExecution execution, String userId) { - User user = execution.getProcessEngine().getIdentityService().createUserQuery().userId(userId).singleResult(); + User user = getUser(execution, userId); return user.getFirstName()+" "+user.getLastName(); } default String getEmail(DelegateExecution execution, String userId) { - User user = execution.getProcessEngine().getIdentityService().createUserQuery().userId(userId).singleResult(); + User user = getUser(execution, userId); return user.getEmail(); } default User getUser(DelegateExecution execution, String userId) { + userId = execution.getVariable("provider_idir_userid").toString(); return execution.getProcessEngine().getIdentityService().createUserQuery().userId(userId).singleResult(); } From 96fdcdabb67c902bd3e4426cd8e63f7f8a58b7b5 Mon Sep 17 00:00:00 2001 From: dinesh Date: Thu, 1 Jun 2023 14:40:40 -0700 Subject: [PATCH 6/6] adding engagement_source, service_location_type variables to orbeon submission --- .../hooks/controllers/FormBuilderPipelineController.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/controllers/FormBuilderPipelineController.java b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/controllers/FormBuilderPipelineController.java index 75cb6f3f..af7f7ece 100644 --- a/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/controllers/FormBuilderPipelineController.java +++ b/apps/forms-flow-ai/forms-flow-bpm/src/main/java/org/camunda/bpm/extension/hooks/controllers/FormBuilderPipelineController.java @@ -198,12 +198,19 @@ private Map prepareRequestVariableMap(String formXML) throws IOEx variables.put("files_entity_key", new VariableData("cciifiles")); variables.put("submit_date_time", new VariableData(new DateTime().toString())); variables.put("entered_by", new VariableData("orbeon")); + VariableData serviceMethodData = (VariableData)variables.get("service_method"); + variables.put("engagement_source", new VariableData(serviceMethodData.getValue().toString())); + VariableData serviceChannelData = (VariableData)variables.get("service_channel"); + if(serviceChannelData.getValue().toString().equals("Service BC Location")){ + variables.put("service_location_type", new VariableData("service_centre")); + }else if(serviceChannelData.getValue().equals("Mobile Outreach Location")){ + variables.put("service_location_type", new VariableData("mobile_outreach")); + } variables.put("service_channel", new VariableData("Service BC Location")); // Check if Orbeon is submitted with a value for "mobile-location" if(variables.containsKey("mobile_location")) { // Set location parameter to "Mobile Outreach" variables.put("location", new VariableData("Mobile Outreach")); - LOGGER.info("Mobile Location Found: "+variables); } } return variables;