1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.enduser;
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 org.apache.commons.lang3.tuple.Triple;
36 import org.apache.cxf.jaxrs.client.Client;
37 import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
38 import org.apache.syncope.client.lib.AuthenticationHandler;
39 import org.apache.syncope.client.lib.SyncopeAnonymousClient;
40 import org.apache.syncope.client.lib.SyncopeClient;
41 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
42 import org.apache.syncope.common.keymaster.client.api.DomainOps;
43 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
44 import org.apache.syncope.common.keymaster.client.api.model.Domain;
45 import org.apache.syncope.common.lib.SyncopeConstants;
46 import org.apache.syncope.common.lib.info.NumbersInfo;
47 import org.apache.syncope.common.lib.info.PlatformInfo;
48 import org.apache.syncope.common.lib.info.SystemInfo;
49 import org.apache.syncope.common.lib.to.AnyTypeTO;
50 import org.apache.syncope.common.lib.to.PlainSchemaTO;
51 import org.apache.syncope.common.lib.to.UserTO;
52 import org.apache.syncope.common.lib.types.AnyTypeKind;
53 import org.apache.syncope.common.lib.types.AttrSchemaType;
54 import org.apache.syncope.common.rest.api.beans.SchemaQuery;
55 import org.apache.syncope.common.rest.api.service.AnyTypeService;
56 import org.apache.syncope.common.rest.api.service.SchemaService;
57 import org.apache.syncope.common.rest.api.service.SyncopeService;
58 import org.apache.wicket.request.resource.IResource;
59 import org.apache.wicket.util.tester.WicketTester;
60 import org.junit.jupiter.api.BeforeAll;
61 import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
62 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
63 import org.springframework.context.annotation.Bean;
64 import org.springframework.context.annotation.Configuration;
65 import org.springframework.core.io.ResourceLoader;
66
67 public abstract class AbstractTest {
68
69 @ImportAutoConfiguration
70 @Configuration(proxyBeanMethods = false)
71 public static class SyncopeEnduserWebApplicationTestConfig {
72
73 @Bean
74 public EnduserProperties enduserProperties() {
75 EnduserProperties enduserProperties = new EnduserProperties();
76
77 enduserProperties.getSecurityHeaders().put("X-XSS-Protection", "1; mode=block");
78 enduserProperties.getSecurityHeaders().
79 put("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
80 enduserProperties.getSecurityHeaders().put("X-Content-Type-Options", "nosniff");
81 enduserProperties.getSecurityHeaders().put("X-Frame-Options", "sameorigin");
82
83 enduserProperties.setAdminUser("admin");
84
85 enduserProperties.setAnonymousUser("anonymousUser");
86
87 return enduserProperties;
88 }
89
90 @Bean
91 public ServiceOps selfServiceOps() {
92 return mock(ServiceOps.class);
93 }
94
95 @Bean
96 public DomainOps domainOps() {
97 DomainOps domainOps = mock(DomainOps.class);
98 when(domainOps.list()).thenReturn(List.of(new Domain.Builder(SyncopeConstants.MASTER_DOMAIN).build()));
99 return domainOps;
100 }
101
102 @Bean
103 public GeneralSettingsProperties generalSettingsProperties() {
104 return new GeneralSettingsProperties();
105 }
106
107 @Bean
108 public List<WicketApplicationInitConfiguration> configurations() {
109 return List.of();
110 }
111
112 @Bean
113 public WicketClassCandidatesHolder wicketClassCandidatesHolder() {
114 return new WicketClassCandidatesHolder();
115 }
116
117 @Bean
118 public WicketEndpointRepository wicketEndpointRepository() {
119 return new WicketEndpointRepositoryDefault();
120 }
121
122 @Bean
123 public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
124 ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
125 lookup.load();
126 return lookup;
127 }
128 }
129
130 public static class TestSyncopeWebApplication extends SyncopeWebApplication {
131
132 public TestSyncopeWebApplication(
133 final ResourceLoader resourceLoader,
134 final EnduserProperties props,
135 final ClassPathScanImplementationLookup lookup,
136 final ServiceOps serviceOps,
137 final List<IResource> resources) {
138
139 super(resourceLoader, props, lookup, serviceOps, resources);
140 }
141
142 public interface SyncopeServiceClient extends SyncopeService, Client {
143 }
144
145 public interface AnyTypeServiceClient extends AnyTypeService, Client {
146 }
147
148 public interface SchemaServiceClient extends SchemaService, Client {
149 }
150
151 private SyncopeService getSyncopeService() {
152 SyncopeServiceClient service = mock(SyncopeServiceClient.class);
153 when(service.type(anyString())).thenReturn(service);
154 when(service.accept(anyString())).thenReturn(service);
155
156 return service;
157 }
158
159 private SchemaService getSchemaService() {
160 SchemaServiceClient service = mock(SchemaServiceClient.class);
161
162 when(service.type(anyString())).thenReturn(service);
163 when(service.accept(anyString())).thenReturn(service);
164
165 PlainSchemaTO firstname = new PlainSchemaTO();
166 firstname.setKey("firstname");
167 firstname.setType(AttrSchemaType.String);
168 firstname.setAnyTypeClass("minimal user");
169 firstname.setMandatoryCondition("false");
170 when(service.search(any(SchemaQuery.class))).thenReturn(List.of(firstname));
171 return service;
172 }
173
174 private AnyTypeService getAnyTypeService() {
175 AnyTypeServiceClient service = mock(AnyTypeServiceClient.class);
176
177 when(service.type(anyString())).thenReturn(service);
178 when(service.accept(anyString())).thenReturn(service);
179
180 AnyTypeTO anyTypeTO = new AnyTypeTO();
181 anyTypeTO.setKey("123456");
182 anyTypeTO.setKind(AnyTypeKind.USER);
183
184 when(service.read(anyString())).thenReturn(anyTypeTO);
185 return service;
186 }
187
188 private UserTO getUserTO() {
189 UserTO userTO = new UserTO();
190 userTO.setUsername("username");
191 return userTO;
192 }
193
194 @SuppressWarnings("unchecked")
195 @Override
196 public SyncopeClientFactoryBean newClientFactory() {
197 SyncopeClient client = mock(SyncopeClient.class);
198 SyncopeAnonymousClient anonymousClient = mock(SyncopeAnonymousClient.class);
199
200 when(client.getJWT()).thenReturn("<anyJWT>");
201
202 when(client.self()).thenReturn(Triple.of(new HashMap<>(), List.of(), getUserTO()));
203
204 when(anonymousClient.platform()).thenReturn(new PlatformInfo());
205 when(anonymousClient.numbers()).thenAnswer(ic -> {
206 NumbersInfo numbersInfo = new NumbersInfo();
207
208 numbersInfo.getConfCompleteness().put(
209 NumbersInfo.ConfItem.RESOURCE.name(), numbersInfo.getTotalResources() > 0);
210 numbersInfo.getConfCompleteness().put(
211 NumbersInfo.ConfItem.ACCOUNT_POLICY.name(), false);
212 numbersInfo.getConfCompleteness().put(
213 NumbersInfo.ConfItem.PASSWORD_POLICY.name(), false);
214 numbersInfo.getConfCompleteness().put(
215 NumbersInfo.ConfItem.NOTIFICATION.name(), false);
216 numbersInfo.getConfCompleteness().put(
217 NumbersInfo.ConfItem.PULL_TASK.name(), false);
218 numbersInfo.getConfCompleteness().put(
219 NumbersInfo.ConfItem.VIR_SCHEMA.name(), false);
220 numbersInfo.getConfCompleteness().put(
221 NumbersInfo.ConfItem.ANY_TYPE.name(), false);
222 numbersInfo.getConfCompleteness().put(
223 NumbersInfo.ConfItem.SECURITY_QUESTION.name(), false);
224 numbersInfo.getConfCompleteness().put(
225 NumbersInfo.ConfItem.ROLE.name(), numbersInfo.getTotalRoles() > 0);
226
227 return numbersInfo;
228 });
229 when(anonymousClient.system()).thenReturn(new SystemInfo());
230
231 SyncopeService syncopeService = getSyncopeService();
232 when(client.getService(SyncopeService.class)).thenReturn(syncopeService);
233
234 SchemaService schemaService = getSchemaService();
235 when(client.getService(SchemaService.class)).thenReturn(schemaService);
236
237 AnyTypeService anyTypeService = getAnyTypeService();
238 when(client.getService(AnyTypeService.class)).thenReturn(anyTypeService);
239
240 SyncopeClientFactoryBean clientFactory = mock(SyncopeClientFactoryBean.class);
241 when(clientFactory.setDomain(any())).thenReturn(clientFactory);
242 when(clientFactory.create(any(AuthenticationHandler.class))).thenReturn(client);
243 when(clientFactory.create(anyString(), anyString())).thenReturn(client);
244 when(clientFactory.createAnonymous(anyString(), isNull())).thenReturn(anonymousClient);
245
246 return clientFactory;
247 }
248 }
249
250 protected static EnduserProperties PROPS;
251
252 protected static WicketTester TESTER;
253
254 @BeforeAll
255 public static void setupTester() throws IOException {
256 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
257 ctx.register(SyncopeEnduserWebApplicationTestConfig.class);
258 ctx.register(TestSyncopeWebApplication.class);
259 ctx.refresh();
260
261 PROPS = ctx.getBean(EnduserProperties.class);
262 TESTER = new WicketTester(ctx.getBean(SyncopeWebApplication.class));
263 }
264 }