We are delighted to share our new EIC Delivery Methodology for efficiently managing Saviynt Implementations and delivering quick time to value. CLICK HERE.

Service Account integration queries

Govind
New Contributor
New Contributor

We need some help in service account module. Can someone please help us for below items:-
1. We need to fetch manager of service account owners (owners selected on service account form) in workflow, I tried below listed variables
A. As custom query,
select userkey from users where username in ('${ServiceAccountOwnerMap.get(USEROWNERS).get(ALL).collect{it.owner}}') :- Approval is going to admin
B. As USERNAME
${accountOwners.manager[0]} - Approval going nowhere even not to admin
2. Using normal manager approval block is sending request to the manager of the requestor, not to the manager of account owner. We wish to send the approval to the manager of the account owner.
3. Account type shall be by default “Service Account” and it shall not be editable.
4. Name of the attribute “Account Name” which can be used to fetch the value of “Account Name” in json i.e. How to fetch the value of Account Name (present on form) in json.

Thanks

Govind Kumar

Govind_0-1656582718032.pngGovind_1-1656582747750.png

5. "Account Name" should be renamed as "Proposed Account Name".
6. Have svc pre-populated in Account Name and it shall be editable i.e user can delete "svc" and enter new values.
7. Remove Security System and endpoint name from the top of the form.
8. For another service account endpoint use case, "Account Name" should be generated by logic and overwrite the name if provided by user. On next screen it should show correct name.
9. Need object of account owner for using in workflow to fetch user properties of owner. And also to use in connection json
10. Remove "Account type" dropdown from the service account form
11. Restrict the owner selection to have Users with certain employee type in the “Account owner” field of the Service account form. We want to enforce this limitation at endpoint level, not at global level.

13 REPLIES 13

rushikeshvartak
All-Star
All-Star
  1.  Service Account Owner Manager Custom Query

select manager as userkey from users where FIND_IN_SET(users.userkey,(select distinct REPLACE(raa.attribute_value," ","")  from request_access_attrs raa , ars_requests ar, request_access ra WHERE ar.REQUESTKEY = ra.REQUESTKEY and  ra.REQUEST_ACCESSKEY = raa.REQUEST_ACCESS_KEY and ar.requestkey=${ARSREQUEST.id} and raa.ATTRIBUTE_NAME="USEROWNERKEY"))!=0  union  select users.manager as userkey from usergroup_users, users where usergroup_users.USERKEY = users.USERKEY AND FIND_IN_SET(usergroup_users.user_groupkey,(select distinct REPLACE(raa.attribute_value," ","")  from request_access_attrs raa , ars_requests ar, request_access ra WHERE ar.REQUESTKEY = ra.REQUESTKEY and  ra.REQUEST_ACCESSKEY = raa.REQUEST_ACCESS_KEY and ar.requestkey=${ARSREQUEST.id} and raa.ATTRIBUTE_NAME="USERGROUPOWNERKEY"))!=0

3. Restrict Account Type

  • under endpoint - add only Service Account 
  • under restrict visibility of entitlement if requestor selected other account type
  • add mandatory dynamic attribute if user selected other than service account show blank so user won't be able to proceed

4. ${accountName}

rushikeshvartak_0-1656621452173.png

 


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

This is not working in v2020.1.2 and also in v23.1, tried in both getting below exceptions:-

Below query throws exception while trying to save.
 
Query:-
 
select userkey from users where FIND_IN_SET(users.userkey,(select distinct REPLACE(raa.attribute_value," ","")from request_access_attrs raa , ars_requests ar, request_access ra WHERE ar.REQUESTKEY = ra.REQUESTKEY and ra.REQUEST_ACCESSKEY = raa.REQUEST_ACCESS_KEY and ar.requestkey=${ARSREQUEST.id} and raa.ATTRIBUTE_NAME="USEROWNERKEY"))!=0
And also, looked at this forrum for alternate solution which seems to have worked previous versions:-
 
select userkey from users where FIND_IN_SET(users.userkey,(select distinct REPLACE(raa.attribute_value," ","")  from request_access_attrs raa , ars_requests ar, request_access ra WHERE ar.REQUESTKEY = ra.REQUESTKEY and  ra.REQUEST_ACCESSKEY = raa.REQUEST_ACCESS_KEY and ar.requestkey=${ARSREQUEST.id} and raa.ATTRIBUTE_NAME="USEROWNERKEY"))!=0
Error:-
"ecm","2023-03-23T09:15:44.328+00:00","{"log":"2023-03-23 09:15:43,599 [http-nio-8080-exec-111] 
DEBUG services.WorkflowHistoryService  - Exception in saveNewWorkflow: java.lang.RuntimeException:
org.xml.sax.SAXParseException; lineNumber: 13; columnNumber: 135; Element type \"string\" must
be followed by either attribute specifications, \"\u003e\" or

FYI:- Custom query Block assignment to User Owners of Service Accounts:- Query Used:- select userkey from users where FIND_IN_SET(users.userkey,(select distinct REPLACE(raa.attribute_value,'' '','''')from request_access_attrs raa , ars_requests ar, request_access ra WHERE ar.REQUESTKEY = ra.REQUESTKEY andra.REQUEST_ACCESSKEY = raa.REQUEST_ACCESS_KEY and ar.requestkey=${ARSREQUEST.id} and raa.ATTRIBUTE_NAME=''USEROWNERKEY''))!=0 Documentation Link:- https://docs.saviyntcloud.com/bundle/EIC-Admin-v2021x/page/Content/Chapter12-Workflows/Workflow-Comp... Issues:- First save, doesn't work with (') in query block for CustomQuery Block, it doesn't allow to save with json, unless the query is saved with ('') 2 single quotes to escape it. Or save it with a simpler query, then from next time the (') quote query or "e; either works, but the ('') 2 single quotes is not handled in 2020.1.2, is not working to resolve the query in controller. So has to be replaced, with single('), would recommend, this be tested through somebody from documentation team, if it a regression bug or something wrong with the issue it should be noted.

sahajranajee
Saviynt Employee
Saviynt Employee

Hi @Govind ,

Please find my answers inline (all relevant to v2021.x) :

5. "Account Name" should be renamed as "Proposed Account Name".
--> This can be achieved via the UI Branding Configuration module. Update the key 'NameKey.label' to 'Proposed {0} Name'

sahajranajee_1-1657039967789.png

 


6. Have svc pre-populated in Account Name and it shall be editable i.e user can delete "svc" and enter new values.
--> This is not supported OOTB from product configuration but is possible via gsp modification. Please modify the following gsp to achieve this : createrequestsecondstep.gsp, createrequestsecondstepint.gsp


7. Remove Security System and endpoint name from the top of the form.
--> This is not supported OOTB from product configuration but is possible via gsp modification. Please modify the following gsp to achieve this : createrequestsecondstepint.gsp


8. For another service account endpoint use case, "Account Name" should be generated by logic and overwrite the name if provided by user. On next screen it should show correct name.
--> This not supported OOTB from product configuration. Also, if you are going to do gsp modification for this, it would be easier to not allow the user to not input any account name. This will need changes across the following gsps : createrequestsecondstep.gsp, createrequestsecondstepint.gsp


9. Need object of account owner for using in workflow to fetch user properties of owner. And also to use in connection json
--> To do this check on the Workflow, try using a logic similar as below with Expression language as 'Groovy'. 

com.saviynt.ecm.identitywarehouse.domain.Users.get(Long.valueOf(dynamicAttributesReqAccess.get(requestaccesskey).get('USEROWNERKEY'))).employeeType == 'Employee'

sahajranajee_0-1657120746404.png

For The Connector JSONs, use ServiceAccountOwnerMap. Examples below

ServiceAccountOwnerMap.ServiceAccountType.equals('Service')
ServiceAccountOwnerMap.get('USEROWNERS').get('1').collect{it.city.toString()}[0] 


10. Remove "Account type" dropdown from the service account form
--> This is not supported OOTB from product configuration but is possible via gsp modification. Please modify the following gsp to achieve this : entitlementmap.gsp


11. Restrict the owner selection to have Users with certain employee type in the “Account owner” field of the Service account form. We want to enforce this limitation at endpoint level, not at global level.
--> This is not possible. The most you can do is restrict the employee to be able to raise Service Account requests via 'Service Account Access Query' but you will not be able control who gets chosen as the owner of the account. You can then club this with the Q. 9 and assign it to a dummy approver.

Please note the gsps listed above are not packaged as standard for modification from the UI and need to be enabled separately. To enable them, go to Settings --> Configuration Files --> externalconfig.properties .


Search for parameter : sync.ecm.viewsfiles.customise ; add it if its no available and add the needed gsps in a comma separated format as below :

 

sync.ecm.viewsfiles.customise=workflowmanagement/groupManagement.gsp,roles/create.gsp,roles/edit.gsp,roles/list.gsp,roles/windows/create.gsp,roles/windows/show.gsp,roles/unixGroup/create.gsp,roles/unixGroup/show.gsp,roles/oktaGroup/create.gsp,roles/oktaGroup/show.gsp,roles/gcp/create.gsp,roles/gcp/show.gsp,roles/azureADGroup/create.gsp,roles/azureADGroup/show.gsp,roles/adsiGroup/create.gsp,roles/adsiGroup/show.gsp,roles/adGroup/create.gsp,roles/adGroup/show.gsp,workflowmanagement/createrequestsecondstep.gsp,workflowmanagement/hierachyentitlementbyendpoint.gsp,workflowmanagement/createrequestsecondstepint.gsp,workflowmanagement/entitlementmap.gsp

 

I am also attaching a couple of sample gsps that i have used to implement point 6(without svc append, conditions are added to allow generate button for one endpoint and hide for the other) and 7 .

sahajranajee_0-1657039654040.png

 

Please use these only reference to help understand the gsp modifications made as these are not tested and production ready. Ensure that you do thorough testing of your modifications done to the gsps once you implement your changes.

The above changes would need an application restarted also supported from the UI.

 


Regards,
Sahaj Ranajee
Sr. Product Specialist

piyushm
Regular Contributor II
Regular Contributor II

@rushikeshvartakIn the first query, Is it possible to get only the user key for owners who have rank 1? The request should only be assigned to rank 1 . For example, if there are 3 owners being added in the new service account request with ranks 1,2,3, then the request should be assigned to only Rank1 user being added in the request.

Yes u can add


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

piyushm
Regular Contributor II
Regular Contributor II

@rushikeshvartak

I have posted the query I am using and the issue on other thread, if you can take a look.

https://forums.saviynt.com/t5/identity-governance/workflow-to-assign-approval-request-only-to-rank1/...

taken care


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

piyushm
Regular Contributor II
Regular Contributor II

@rushikeshvartak@sahajranajee

Is there way to get the ownerkey for only rank1 user from the request attributes using the groovy expression?

com.saviynt.ecm.identitywarehouse.domain.Users.get(Long.valueOf(dynamicAttributesReqAccess.get(requestaccesskey).get('USEROWNERKEY')))

com.saviynt.ecm.identitywarehouse.domain.Users.get(Long.valueOf(dynamicAttributesReqAccess.get(requestaccesskey).get('USERRANKJSON')))

Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

piyushm
Regular Contributor II
Regular Contributor II

This is not working. The request itself is not getting created.

piyushm_1-1669062352608.png

what is error in logs


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

piyushm
Regular Contributor II
Regular Contributor II

"ecm","2022-11-22T01:34:56.982+00:00","{"log":"2022-11-22 01:34:56,467 [http-nio-8080-exec-8] ERROR services.WorkflowService - Exception in workflow service\n","stream":"stdout","time":"2022-11-22T01:34:56.467831393Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"org.jbpm.api.JbpmException: script evaluation error: javax.script.ScriptException: java.lang.NullPointerException: Cannot invoke method get() on null object\n","stream":"stdout","time":"2022-11-22T01:34:56.467858238Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.script.ScriptManager.evaluate(ScriptManager.java:127)\n","stream":"stdout","time":"2022-11-22T01:34:56.467863584Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.script.ScriptManager.evaluate(ScriptManager.java:115)\n","stream":"stdout","time":"2022-11-22T01:34:56.467866499Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.script.ScriptManager.evaluateExpression(ScriptManager.java:87)\n","stream":"stdout","time":"2022-11-22T01:34:56.46786898Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.el.ScriptExpression.evaluateInScope(ScriptExpression.java:48)\n","stream":"stdout","time":"2022-11-22T01:34:56.467871788Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.el.Expression.evaluate(Expression.java:108)\n","stream":"stdout","time":"2022-11-22T01:34:56.467874291Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.model.ExpressionCondition.evaluate(ExpressionCondition.java:41)\n","stream":"stdout","time":"2022-11-22T01:34:56.467876556Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.jpdl.internal.activity.DecisionConditionActivity.findTransitionUsingConditions(DecisionConditionActivity.java:62)\n","stream":"stdout","time":"2022-11-22T01:34:56.467879255Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.jpdl.internal.activity.DecisionConditionActivity.execute(DecisionConditionActivity.java:47)\n","stream":"stdout","time":"2022-11-22T01:34:56.467887247Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.jpdl.internal.activity.DecisionConditionActivity.execute(DecisionConditionActivity.java:43)\n","stream":"stdout","time":"2022-11-22T01:34:56.467889991Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.model.op.ExecuteActivity.perform(ExecuteActivity.java:60)\n","stream":"stdout","time":"2022-11-22T01:34:56.467892361Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:672)\n","stream":"stdout","time":"2022-11-22T01:34:56.467894781Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperation(ExecutionImpl.java:632)\n","stream":"stdout","time":"2022-11-22T01:34:56.467897141Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.model.ExecutionImpl.start(ExecutionImpl.java:217)\n","stream":"stdout","time":"2022-11-22T01:34:56.467899748Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.cmd.StartProcessInstanceInLatestCmd.execute(StartProcessInstanceInLatestCmd.java:63)\n","stream":"stdout","time":"2022-11-22T01:34:56.467902069Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.cmd.StartProcessInstanceInLatestCmd.execute(StartProcessInstanceInLatestCmd.java:36)\n","stream":"stdout","time":"2022-11-22T01:34:56.467904585Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)\n","stream":"stdout","time":"2022-11-22T01:34:56.467906909Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.tx.SpringCommandCallback.doInTransaction(SpringCommandCallback.java:45)\n","stream":"stdout","time":"2022-11-22T01:34:56.467909224Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.tx.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:49)\n","stream":"stdout","time":"2022-11-22T01:34:56.467911604Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)\n","stream":"stdout","time":"2022-11-22T01:34:56.467914748Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)\n","stream":"stdout","time":"2022-11-22T01:34:56.467917192Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)\n","stream":"stdout","time":"2022-11-22T01:34:56.467919618Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at org.jbpm.pvm.internal.svc.ExecutionServiceImpl.startProcessInstanceByKey(ExecutionServiceImpl.java:71)\n","stream":"stdout","time":"2022-11-22T01:34:56.467922053Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at com.saviynt.ecm.services.WorkflowService.workflowaccessreqStart(WorkflowService.groovy:1054)\n","stream":"stdout","time":"2022-11-22T01:34:56.467924432Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at com.saviynt.ecm.services.WorkflowService$_createRequestFinalStep_closure277.doCall(WorkflowService.groovy:24627)\n","stream":"stdout","time":"2022-11-22T01:34:56.467926696Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at com.saviynt.ecm.services.WorkflowService.createRequestFinalStep(WorkflowService.groovy:21465)\n","stream":"stdout","time":"2022-11-22T01:34:56.46792934Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at com.saviynt.ecm.workflow.WorkflowmanagementController$_closure165.doCall(WorkflowmanagementController.groovy:11629)\n","stream":"stdout","time":"2022-11-22T01:34:56.467931663Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)\n","stream":"stdout","time":"2022-11-22T01:34:56.467934029Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at com.saviynt.webservice.SaviyntRestAuthenticationFilter.doFilter(SaviyntRestAuthenticationFilter.groovy:144)\n","stream":"stdout","time":"2022-11-22T01:34:56.467936441Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:62)\n","stream":"stdout","time":"2022-11-22T01:34:56.467938808Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.java:59)\n","stream":"stdout","time":"2022-11-22T01:34:56.467941176Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at com.mrhaki.grails.plugin.xframeoptions.web.XFrameOptionsFilter.doFilterInternal(XFrameOptionsFilter.java:69)\n","stream":"stdout","time":"2022-11-22T01:34:56.467945278Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at com.brandseye.cors.CorsFilter.doFilter(CorsFilter.java:82)\n","stream":"stdout","time":"2022-11-22T01:34:56.467947784Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"\u0009at java.lang.Thread.run(Thread.java:750)\n","stream":"stdout","time":"2022-11-22T01:34:56.467950088Z"}"
"ecm","2022-11-22T01:34:56.982+00:00","{"log":"Caused by: javax.script.ScriptException: javax.script.ScriptException: java.lang.NullPointerException: Cannot invoke method get() on null object\n","stream":"stdout","time":"2022-11-22T01:34:56.467952421Z"}"
"ecm","2022-11-22T01:34: