1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.flowable;
20
21 import java.util.List;
22 import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
23 import org.apache.syncope.core.flowable.api.UserRequestHandler;
24 import org.apache.syncope.core.flowable.impl.FlowableBpmnProcessManager;
25 import org.apache.syncope.core.flowable.impl.FlowableUserRequestHandler;
26 import org.apache.syncope.core.flowable.impl.FlowableUserWorkflowAdapter;
27 import org.apache.syncope.core.flowable.impl.FlowableWorkflowUtils;
28 import org.apache.syncope.core.flowable.support.DomainProcessEngine;
29 import org.apache.syncope.core.flowable.support.DomainProcessEngineFactoryBean;
30 import org.apache.syncope.core.flowable.support.ShellServiceTaskDisablingBpmnParseHandler;
31 import org.apache.syncope.core.flowable.support.SyncopeEntitiesVariableType;
32 import org.apache.syncope.core.flowable.support.SyncopeFormHandlerHelper;
33 import org.apache.syncope.core.flowable.support.SyncopeIdmIdentityService;
34 import org.apache.syncope.core.flowable.task.AutoActivate;
35 import org.apache.syncope.core.flowable.task.Create;
36 import org.apache.syncope.core.flowable.task.Delete;
37 import org.apache.syncope.core.flowable.task.GenerateToken;
38 import org.apache.syncope.core.flowable.task.Notify;
39 import org.apache.syncope.core.flowable.task.PasswordReset;
40 import org.apache.syncope.core.flowable.task.Reactivate;
41 import org.apache.syncope.core.flowable.task.Suspend;
42 import org.apache.syncope.core.flowable.task.Update;
43 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
44 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
45 import org.apache.syncope.core.persistence.api.dao.UserDAO;
46 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
47 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
48 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
49 import org.apache.syncope.core.provisioning.api.rules.RuleEnforcer;
50 import org.apache.syncope.core.spring.security.SecurityProperties;
51 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
52 import org.flowable.common.engine.impl.AbstractEngineConfiguration;
53 import org.flowable.common.engine.impl.cfg.IdGenerator;
54 import org.flowable.common.engine.impl.persistence.StrongUuidGenerator;
55 import org.flowable.idm.spring.SpringIdmEngineConfiguration;
56 import org.flowable.idm.spring.configurator.SpringIdmEngineConfigurator;
57 import org.flowable.spring.SpringProcessEngineConfiguration;
58 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
59 import org.springframework.boot.context.properties.EnableConfigurationProperties;
60 import org.springframework.context.ApplicationEventPublisher;
61 import org.springframework.context.ConfigurableApplicationContext;
62 import org.springframework.context.annotation.Bean;
63 import org.springframework.context.annotation.Configuration;
64 import org.springframework.context.annotation.Scope;
65 import org.springframework.core.io.Resource;
66 import org.springframework.core.io.ResourceLoader;
67
68 @EnableConfigurationProperties(WorkflowFlowableProperties.class)
69 @Configuration(proxyBeanMethods = false)
70 public class FlowableWorkflowContext {
71
72 @ConditionalOnMissingBean
73 @Bean
74 public SpringIdmEngineConfiguration syncopeIdmEngineConfiguration(final ConfigurableApplicationContext ctx) {
75 SpringIdmEngineConfiguration conf = new SpringIdmEngineConfiguration();
76 conf.setIdmIdentityService(new SyncopeIdmIdentityService(conf, ctx));
77 return conf;
78 }
79
80 @ConditionalOnMissingBean
81 @Bean
82 public SpringIdmEngineConfigurator syncopeIdmEngineConfigurator(
83 final SpringIdmEngineConfiguration syncopeIdmEngineConfiguration) {
84 SpringIdmEngineConfigurator configurator = new SpringIdmEngineConfigurator();
85 configurator.setIdmEngineConfiguration(syncopeIdmEngineConfiguration);
86 return configurator;
87 }
88
89 @ConditionalOnMissingBean
90 @Bean
91 public SyncopeFormHandlerHelper syncopeFormHandlerHelper() {
92 return new SyncopeFormHandlerHelper();
93 }
94
95 @ConditionalOnMissingBean
96 @Bean
97 public FlowableBpmnProcessManager bpmnProcessManager(final DomainProcessEngine engine) {
98 return new FlowableBpmnProcessManager(engine);
99 }
100
101 @ConditionalOnMissingBean
102 @Bean
103 public FlowableUserRequestHandler userRequestHandler(
104 final SecurityProperties securityProperties,
105 final UserDataBinder userDataBinder,
106 final DomainProcessEngine engine,
107 final UserDAO userDAO,
108 final EntityFactory entityFactory) {
109
110 return new FlowableUserRequestHandler(
111 userDataBinder,
112 securityProperties.getAdminUser(),
113 engine,
114 userDAO,
115 entityFactory);
116 }
117
118 @ConditionalOnMissingBean
119 @Bean
120 public FlowableWorkflowUtils flowableUtils(final DomainProcessEngine engine) {
121 return new FlowableWorkflowUtils(engine);
122 }
123
124 @ConditionalOnMissingBean
125 @Bean
126 public SyncopeEntitiesVariableType syncopeEntitiesVariableType() {
127 return new SyncopeEntitiesVariableType();
128 }
129
130 @ConditionalOnMissingBean
131 @Bean
132 public IdGenerator idGenerator() {
133 return new StrongUuidGenerator();
134 }
135
136 @ConditionalOnMissingBean
137 @Bean
138 @Scope("prototype")
139 public SpringProcessEngineConfiguration processEngineConfiguration(
140 final WorkflowFlowableProperties props,
141 final SpringIdmEngineConfigurator syncopeIdmEngineConfigurator,
142 final IdGenerator idGenerator,
143 final SyncopeEntitiesVariableType syncopeEntitiesVariableType,
144 final SyncopeFormHandlerHelper syncopeFormHandlerHelper) {
145
146 SpringProcessEngineConfiguration conf = new SpringProcessEngineConfiguration();
147 conf.setDatabaseSchemaUpdate(AbstractEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
148 conf.setJpaHandleTransaction(true);
149 conf.setJpaCloseEntityManager(false);
150 conf.setHistoryLevel(props.getHistoryLevel());
151 conf.setIdmEngineConfigurator(syncopeIdmEngineConfigurator);
152 conf.setCustomPreVariableTypes(List.of(syncopeEntitiesVariableType));
153 conf.setFormHandlerHelper(syncopeFormHandlerHelper);
154 conf.setIdGenerator(idGenerator);
155 conf.setPreBpmnParseHandlers(List.of(new ShellServiceTaskDisablingBpmnParseHandler()));
156 return conf;
157 }
158
159 @ConditionalOnMissingBean
160 @Bean
161 public DomainProcessEngineFactoryBean domainProcessEngineFactoryBean(final ConfigurableApplicationContext ctx) {
162 return new DomainProcessEngineFactoryBean(ctx);
163 }
164
165 @Bean
166 public Resource userWorkflowDef(final WorkflowFlowableProperties props,
167 final ResourceLoader resourceLoader) {
168 return resourceLoader.getResource(props.getUserWorkflowDef());
169 }
170
171 @ConditionalOnMissingBean(name = "flowableUWFAdapter")
172 @Bean
173 public UserWorkflowAdapter uwfAdapter(
174 final UserDataBinder userDataBinder,
175 final UserDAO userDAO,
176 final RealmDAO realmDAO,
177 final GroupDAO groupDAO,
178 final EntityFactory entityFactory,
179 final SecurityProperties securityProperties,
180 final RuleEnforcer ruleEnforcer,
181 final DomainProcessEngine engine,
182 final UserRequestHandler userRequestHandler,
183 final ApplicationEventPublisher publisher) {
184
185 return new FlowableUserWorkflowAdapter(
186 userDataBinder,
187 userDAO,
188 realmDAO,
189 groupDAO,
190 entityFactory,
191 securityProperties,
192 ruleEnforcer,
193 engine,
194 userRequestHandler,
195 publisher);
196 }
197
198 @ConditionalOnMissingBean
199 @Bean
200 public AutoActivate autoActivate(final UserDataBinder userDataBinder, final UserDAO userDAO) {
201 return new AutoActivate(userDataBinder, userDAO);
202 }
203
204 @ConditionalOnMissingBean
205 @Bean
206 public Create create(final UserDataBinder userDataBinder, final EntityFactory entityFactory) {
207 return new Create(userDataBinder, entityFactory);
208 }
209
210 @ConditionalOnMissingBean
211 @Bean
212 public Delete delete() {
213 return new Delete();
214 }
215
216 @ConditionalOnMissingBean
217 @Bean
218 public GenerateToken generateToken(final ConfParamOps confParamOps) {
219 return new GenerateToken(confParamOps);
220 }
221
222 @ConditionalOnMissingBean
223 @Bean
224 public Notify notify(final NotificationManager notificationManager) {
225 return new Notify(notificationManager);
226 }
227
228 @ConditionalOnMissingBean
229 @Bean
230 public PasswordReset passwordReset(final UserDataBinder userDataBinder, final UserDAO userDAO) {
231 return new PasswordReset(userDataBinder, userDAO);
232 }
233
234 @ConditionalOnMissingBean
235 @Bean
236 public Reactivate reactivate() {
237 return new Reactivate();
238 }
239
240 @ConditionalOnMissingBean
241 @Bean
242 public Suspend suspend() {
243 return new Suspend();
244 }
245
246 @ConditionalOnMissingBean
247 @Bean
248 public Update update(final UserDataBinder userDataBinder, final UserDAO userDAO) {
249 return new Update(userDataBinder, userDAO);
250 }
251 }