View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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 }