1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.console;
20
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyString;
23 import static org.mockito.ArgumentMatchers.isNull;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26
27 import com.giffing.wicket.spring.boot.context.extensions.WicketApplicationInitConfiguration;
28 import com.giffing.wicket.spring.boot.context.extensions.boot.actuator.WicketEndpointRepository;
29 import com.giffing.wicket.spring.boot.starter.app.classscanner.candidates.WicketClassCandidatesHolder;
30 import com.giffing.wicket.spring.boot.starter.configuration.extensions.core.settings.general.GeneralSettingsProperties;
31 import com.giffing.wicket.spring.boot.starter.configuration.extensions.external.spring.boot.actuator.WicketEndpointRepositoryDefault;
32 import java.io.IOException;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Set;
36 import org.apache.commons.lang3.tuple.Pair;
37 import org.apache.commons.lang3.tuple.Triple;
38 import org.apache.cxf.jaxrs.client.Client;
39 import org.apache.syncope.client.console.commons.AccessPolicyConfProvider;
40 import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionLinksProvider;
41 import org.apache.syncope.client.console.commons.AnyDirectoryPanelAdditionalActionsProvider;
42 import org.apache.syncope.client.console.commons.AnyWizardBuilderAdditionalSteps;
43 import org.apache.syncope.client.console.commons.ExternalResourceProvider;
44 import org.apache.syncope.client.console.commons.ImplementationInfoProvider;
45 import org.apache.syncope.client.console.commons.PolicyTabProvider;
46 import org.apache.syncope.client.console.commons.StatusProvider;
47 import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider;
48 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
49 import org.apache.syncope.client.console.wizards.any.UserFormFinalizer;
50 import org.apache.syncope.client.lib.AuthenticationHandler;
51 import org.apache.syncope.client.lib.SyncopeAnonymousClient;
52 import org.apache.syncope.client.lib.SyncopeClient;
53 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
54 import org.apache.syncope.common.keymaster.client.api.DomainOps;
55 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
56 import org.apache.syncope.common.keymaster.client.api.model.Domain;
57 import org.apache.syncope.common.lib.SyncopeConstants;
58 import org.apache.syncope.common.lib.info.NumbersInfo;
59 import org.apache.syncope.common.lib.info.PlatformInfo;
60 import org.apache.syncope.common.lib.info.SystemInfo;
61 import org.apache.syncope.common.lib.to.AnyTypeTO;
62 import org.apache.syncope.common.lib.to.PlainSchemaTO;
63 import org.apache.syncope.common.lib.to.UserTO;
64 import org.apache.syncope.common.lib.types.AnyTypeKind;
65 import org.apache.syncope.common.lib.types.AttrSchemaType;
66 import org.apache.syncope.common.rest.api.beans.SchemaQuery;
67 import org.apache.syncope.common.rest.api.service.AnyTypeService;
68 import org.apache.syncope.common.rest.api.service.FIQLQueryService;
69 import org.apache.syncope.common.rest.api.service.SchemaService;
70 import org.apache.syncope.common.rest.api.service.SyncopeService;
71 import org.apache.wicket.request.resource.IResource;
72 import org.apache.wicket.util.tester.WicketTester;
73 import org.junit.jupiter.api.BeforeAll;
74 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
75 import org.springframework.context.annotation.Bean;
76 import org.springframework.context.annotation.Configuration;
77 import org.springframework.context.annotation.Import;
78
79 public abstract class AbstractTest {
80
81 @Import(IdRepoConsoleContext.class)
82 @Configuration(proxyBeanMethods = false)
83 public static class SyncopeConsoleWebApplicationTestConfig {
84
85 @Bean
86 public ConsoleProperties consoleProperties() {
87 ConsoleProperties consoleProperties = new ConsoleProperties();
88
89 consoleProperties.getSecurityHeaders().put("X-XSS-Protection", "1; mode=block");
90 consoleProperties.getSecurityHeaders().
91 put("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
92 consoleProperties.getSecurityHeaders().put("X-Content-Type-Options", "nosniff");
93 consoleProperties.getSecurityHeaders().put("X-Frame-Options", "sameorigin");
94
95 consoleProperties.setAnonymousUser("anonymousUser");
96
97 return consoleProperties;
98 }
99
100 @Bean
101 public ServiceOps selfServiceOps() {
102 return mock(ServiceOps.class);
103 }
104
105 @Bean
106 public DomainOps domainOps() {
107 DomainOps domainOps = mock(DomainOps.class);
108 when(domainOps.list()).thenReturn(List.of(new Domain.Builder(SyncopeConstants.MASTER_DOMAIN).build()));
109 return domainOps;
110 }
111
112 @Bean
113 public GeneralSettingsProperties generalSettingsProperties() {
114 return new GeneralSettingsProperties();
115 }
116
117 @Bean
118 public List<WicketApplicationInitConfiguration> configurations() {
119 return List.of();
120 }
121
122 @Bean
123 public WicketClassCandidatesHolder wicketClassCandidatesHolder() {
124 return new WicketClassCandidatesHolder();
125 }
126
127 @Bean
128 public WicketEndpointRepository wicketEndpointRepository() {
129 return new WicketEndpointRepositoryDefault();
130 }
131
132 @Bean
133 public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
134 ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup(
135 Set.of(), consoleProperties());
136 lookup.load();
137 return lookup;
138 }
139 }
140
141 public static class TestSyncopeWebApplication extends SyncopeWebApplication {
142
143 public TestSyncopeWebApplication(
144 final ConsoleProperties props,
145 final ClassPathScanImplementationLookup lookup,
146 final ServiceOps serviceOps,
147 final ExternalResourceProvider resourceProvider,
148 final AnyDirectoryPanelAdditionalActionsProvider anyDirectoryPanelAdditionalActionsProvider,
149 final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider,
150 final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps,
151 final StatusProvider statusProvider,
152 final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider,
153 final ImplementationInfoProvider implementationInfoProvider,
154 final AccessPolicyConfProvider accessPolicyConfProvider,
155 final List<PolicyTabProvider> policyTabProviders,
156 final List<UserFormFinalizer> userFormFinalizers,
157 final List<IResource> resources) {
158
159 super(props, lookup, serviceOps, resourceProvider, anyDirectoryPanelAdditionalActionsProvider,
160 anyDirectoryPanelAdditionalActionLinksProvider, anyWizardBuilderAdditionalSteps, statusProvider,
161 virSchemaDetailsPanelProvider, implementationInfoProvider, accessPolicyConfProvider,
162 policyTabProviders, userFormFinalizers, resources);
163 }
164
165 public interface SyncopeServiceClient extends SyncopeService, Client {
166 }
167
168 public interface AnyTypeServiceClient extends AnyTypeService, Client {
169 }
170
171 public interface SchemaServiceClient extends SchemaService, Client {
172 }
173
174 public interface FIQLQueryServiceClient extends FIQLQueryService, Client {
175 }
176
177 private SyncopeService getSyncopeService() {
178 SyncopeServiceClient service = mock(SyncopeServiceClient.class);
179 when(service.type(anyString())).thenReturn(service);
180 when(service.accept(anyString())).thenReturn(service);
181
182 return service;
183 }
184
185 private SchemaService getSchemaService() {
186 SchemaServiceClient service = mock(SchemaServiceClient.class);
187
188 when(service.type(anyString())).thenReturn(service);
189 when(service.accept(anyString())).thenReturn(service);
190
191 PlainSchemaTO firstname = new PlainSchemaTO();
192 firstname.setKey("firstname");
193 firstname.setType(AttrSchemaType.String);
194 firstname.setAnyTypeClass("minimal user");
195 firstname.setMandatoryCondition("false");
196 when(service.search(any(SchemaQuery.class))).thenReturn(List.of(firstname));
197 return service;
198 }
199
200 private AnyTypeService getAnyTypeService() {
201 AnyTypeServiceClient service = mock(AnyTypeServiceClient.class);
202
203 when(service.type(anyString())).thenReturn(service);
204 when(service.accept(anyString())).thenReturn(service);
205
206 AnyTypeTO anyTypeTO = new AnyTypeTO();
207 anyTypeTO.setKey("123456");
208 anyTypeTO.setKind(AnyTypeKind.USER);
209
210 when(service.read(anyString())).thenReturn(anyTypeTO);
211 return service;
212 }
213
214 private FIQLQueryService getFIQLQueryService() {
215 FIQLQueryServiceClient service = mock(FIQLQueryServiceClient.class);
216
217 when(service.type(anyString())).thenReturn(service);
218 when(service.accept(anyString())).thenReturn(service);
219
220 return service;
221 }
222
223 private UserTO getUserTO() {
224 UserTO userTO = new UserTO();
225 userTO.setUsername("username");
226 return userTO;
227 }
228
229 @SuppressWarnings("unchecked")
230 @Override
231 public SyncopeClientFactoryBean newClientFactory() {
232 SyncopeClient client = mock(SyncopeClient.class);
233 SyncopeAnonymousClient anonymousClient = mock(SyncopeAnonymousClient.class);
234
235 when(client.self()).thenReturn(Triple.of(new HashMap<>(), List.of(), getUserTO()));
236
237 when(anonymousClient.gitAndBuildInfo()).thenReturn(Pair.of("", ""));
238 when(anonymousClient.platform()).thenReturn(new PlatformInfo());
239 when(anonymousClient.numbers()).thenAnswer(ic -> {
240 NumbersInfo numbersInfo = new NumbersInfo();
241
242 numbersInfo.getConfCompleteness().put(
243 NumbersInfo.ConfItem.RESOURCE.name(), numbersInfo.getTotalResources() > 0);
244 numbersInfo.getConfCompleteness().put(
245 NumbersInfo.ConfItem.ACCOUNT_POLICY.name(), false);
246 numbersInfo.getConfCompleteness().put(
247 NumbersInfo.ConfItem.PASSWORD_POLICY.name(), false);
248 numbersInfo.getConfCompleteness().put(
249 NumbersInfo.ConfItem.NOTIFICATION.name(), false);
250 numbersInfo.getConfCompleteness().put(
251 NumbersInfo.ConfItem.PULL_TASK.name(), false);
252 numbersInfo.getConfCompleteness().put(
253 NumbersInfo.ConfItem.VIR_SCHEMA.name(), false);
254 numbersInfo.getConfCompleteness().put(
255 NumbersInfo.ConfItem.ANY_TYPE.name(), false);
256 numbersInfo.getConfCompleteness().put(
257 NumbersInfo.ConfItem.SECURITY_QUESTION.name(), false);
258 numbersInfo.getConfCompleteness().put(
259 NumbersInfo.ConfItem.ROLE.name(), numbersInfo.getTotalRoles() > 0);
260
261 return numbersInfo;
262 });
263 when(anonymousClient.system()).thenReturn(new SystemInfo());
264
265 SyncopeService syncopeService = getSyncopeService();
266 when(client.getService(SyncopeService.class)).thenReturn(syncopeService);
267
268 SchemaService schemaService = getSchemaService();
269 when(client.getService(SchemaService.class)).thenReturn(schemaService);
270
271 AnyTypeService anyTypeService = getAnyTypeService();
272 when(client.getService(AnyTypeService.class)).thenReturn(anyTypeService);
273
274 FIQLQueryService fiqlQueryService = getFIQLQueryService();
275 when(client.getService(FIQLQueryService.class)).thenReturn(fiqlQueryService);
276
277 SyncopeClientFactoryBean clientFactory = mock(SyncopeClientFactoryBean.class);
278 when(clientFactory.setDomain(any())).thenReturn(clientFactory);
279 when(clientFactory.create(any(AuthenticationHandler.class))).thenReturn(client);
280 when(clientFactory.create(anyString(), anyString())).thenReturn(client);
281 when(clientFactory.createAnonymous(anyString(), isNull())).thenReturn(anonymousClient);
282
283 return clientFactory;
284 }
285 }
286
287 protected static ConsoleProperties PROPS;
288
289 protected static WicketTester TESTER;
290
291 @BeforeAll
292 public static void setupTester() throws IOException {
293 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
294 ctx.register(SyncopeConsoleWebApplicationTestConfig.class);
295 ctx.register(TestSyncopeWebApplication.class);
296 ctx.refresh();
297
298 PROPS = ctx.getBean(ConsoleProperties.class);
299 TESTER = new WicketTester(ctx.getBean(SyncopeWebApplication.class));
300 }
301 }