1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.fit.enduser;
20
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22
23 import com.giffing.wicket.spring.boot.context.extensions.WicketApplicationInitConfiguration;
24 import com.giffing.wicket.spring.boot.context.extensions.boot.actuator.WicketEndpointRepository;
25 import com.giffing.wicket.spring.boot.starter.app.classscanner.candidates.WicketClassCandidatesHolder;
26 import com.giffing.wicket.spring.boot.starter.configuration.extensions.core.settings.general.GeneralSettingsProperties;
27 import com.giffing.wicket.spring.boot.starter.configuration.extensions.external.spring.boot.actuator.WicketEndpointRepositoryDefault;
28 import java.io.InputStream;
29 import java.time.OffsetDateTime;
30 import java.time.format.DateTimeFormatter;
31 import java.util.List;
32 import java.util.Locale;
33 import java.util.Properties;
34 import org.apache.syncope.client.enduser.EnduserProperties;
35 import org.apache.syncope.client.enduser.FlowableEnduserContext;
36 import org.apache.syncope.client.enduser.IdRepoEnduserContext;
37 import org.apache.syncope.client.enduser.OIDCC4UIEnduserContext;
38 import org.apache.syncope.client.enduser.SAML2SP4UIEnduserContext;
39 import org.apache.syncope.client.enduser.SyncopeWebApplication;
40 import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup;
41 import org.apache.syncope.client.enduser.pages.Login;
42 import org.apache.syncope.client.lib.SyncopeClient;
43 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
44 import org.apache.syncope.common.keymaster.client.self.SelfKeymasterClientContext;
45 import org.apache.syncope.common.keymaster.client.zookeeper.ZookeeperKeymasterClientContext;
46 import org.apache.syncope.common.lib.Attr;
47 import org.apache.syncope.common.lib.SyncopeConstants;
48 import org.apache.syncope.common.lib.request.UserCR;
49 import org.apache.syncope.common.rest.api.beans.AnyQuery;
50 import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
51 import org.apache.syncope.common.rest.api.service.SyncopeService;
52 import org.apache.syncope.common.rest.api.service.UserService;
53 import org.apache.syncope.fit.AbstractUIITCase;
54 import org.apache.wicket.util.tester.FormTester;
55 import org.apache.wicket.util.tester.WicketTester;
56 import org.junit.jupiter.api.AfterAll;
57 import org.junit.jupiter.api.BeforeAll;
58 import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
59 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
60 import org.springframework.context.annotation.Bean;
61 import org.springframework.context.annotation.Configuration;
62 import org.springframework.test.context.support.TestPropertySourceUtils;
63
64 public abstract class AbstractEnduserITCase extends AbstractUIITCase {
65
66 @ImportAutoConfiguration(classes = {
67 SelfKeymasterClientContext.class,
68 ZookeeperKeymasterClientContext.class,
69 IdRepoEnduserContext.class,
70 FlowableEnduserContext.class,
71 SAML2SP4UIEnduserContext.class,
72 OIDCC4UIEnduserContext.class })
73 @Configuration(proxyBeanMethods = false)
74 public static class SyncopeEnduserWebApplicationTestConfig {
75
76 @Bean
77 public EnduserProperties enduserProperties() {
78 EnduserProperties enduserProperties = new EnduserProperties();
79
80 enduserProperties.setAdminUser(ADMIN_UNAME);
81
82 enduserProperties.setAnonymousUser(ANONYMOUS_UNAME);
83 enduserProperties.setAnonymousKey(ANONYMOUS_KEY);
84
85 enduserProperties.setCsrf(false);
86
87 return enduserProperties;
88 }
89
90 @Bean
91 public GeneralSettingsProperties generalSettingsProperties() {
92 return new GeneralSettingsProperties();
93 }
94
95 @Bean
96 public List<WicketApplicationInitConfiguration> configurations() {
97 return List.of();
98 }
99
100 @Bean
101 public WicketClassCandidatesHolder wicketClassCandidatesHolder() {
102 return new WicketClassCandidatesHolder();
103 }
104
105 @Bean
106 public WicketEndpointRepository wicketEndpointRepository() {
107 return new WicketEndpointRepositoryDefault();
108 }
109
110 @Bean
111 public ClassPathScanImplementationLookup classPathScanImplementationLookup() {
112 ClassPathScanImplementationLookup lookup = new ClassPathScanImplementationLookup();
113 lookup.load();
114 return lookup;
115 }
116 }
117
118 protected static SyncopeClientFactoryBean CLIENT_FACTORY;
119
120 protected static SyncopeClient ADMIN_CLIENT;
121
122 protected static UserService USER_SERVICE;
123
124 protected static SecurityQuestionService SECURITY_QUESTION_SERVICE;
125
126 @BeforeAll
127 public static void setUp() {
128 Locale.setDefault(Locale.ENGLISH);
129
130 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
131
132 ctx.register(SyncopeEnduserWebApplicationTestConfig.class);
133 ctx.register(SyncopeWebApplication.class);
134
135 String springActiveProfiles = null;
136 try (InputStream propStream = AbstractEnduserITCase.class.getResourceAsStream("/test.properties")) {
137 Properties props = new Properties();
138 props.load(propStream);
139
140 springActiveProfiles = props.getProperty("springActiveProfiles");
141 } catch (Exception e) {
142 LOG.error("Could not load /test.properties", e);
143 }
144 assertNotNull(springActiveProfiles);
145
146 if (springActiveProfiles.contains("zookeeper")) {
147 TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
148 ctx, "keymaster.address=127.0.0.1:2181");
149 } else {
150 TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
151 ctx, "keymaster.address=http://localhost:9080/syncope/rest/keymaster");
152 }
153 TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
154 ctx, "keymaster.username=" + ANONYMOUS_UNAME);
155 TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
156 ctx, "keymaster.password=" + ANONYMOUS_KEY);
157
158 ctx.refresh();
159
160 TESTER = new WicketTester(ctx.getBean(SyncopeWebApplication.class));
161
162 SYNCOPE_SERVICE = new SyncopeClientFactoryBean().
163 setAddress(ADDRESS).create(ADMIN_UNAME, ADMIN_PWD).
164 getService(SyncopeService.class);
165 }
166
167 @BeforeAll
168 public static void restSetup() {
169 CLIENT_FACTORY = new SyncopeClientFactoryBean().setAddress(ADDRESS);
170 LOG.info("Performing IT with content type {}", CLIENT_FACTORY.getContentType().getMediaType());
171
172 ADMIN_CLIENT = CLIENT_FACTORY.create(ADMIN_UNAME, ADMIN_PWD);
173
174 USER_SERVICE = ADMIN_CLIENT.getService(UserService.class);
175
176
177 USER_SERVICE.create(new UserCR.Builder(SyncopeConstants.ROOT_REALM, "mustchangepassword").
178 password("password123").
179 mustChangePassword(true).
180 plainAttr(attr("fullname", "mustchangepassword@apache.org")).
181 plainAttr(attr("firstname", "mustchangepassword@apache.org")).
182 plainAttr(attr("surname", "surname")).
183 plainAttr(attr("ctype", "a type")).
184 plainAttr(attr("userId", "mustchangepassword@apache.org")).
185 plainAttr(attr("email", "mustchangepassword@apache.org")).
186 plainAttr(attr("loginDate", DateTimeFormatter.ISO_LOCAL_DATE.format(OffsetDateTime.now()))).
187 build());
188
189
190 USER_SERVICE.create(new UserCR.Builder(SyncopeConstants.ROOT_REALM, "selfpwdreset").
191 password("password123").
192 plainAttr(attr("fullname", "selfpwdreset@apache.org")).
193 plainAttr(attr("firstname", "selfpwdreset@apache.org")).
194 plainAttr(attr("surname", "surname")).
195 plainAttr(attr("ctype", "a type")).
196 plainAttr(attr("userId", "selfpwdreset@apache.org")).
197 plainAttr(attr("email", "selfpwdreset@apache.org")).
198 plainAttr(attr("loginDate", DateTimeFormatter.ISO_LOCAL_DATE.format(OffsetDateTime.now()))).
199 build());
200
201
202 USER_SERVICE.create(new UserCR.Builder(SyncopeConstants.ROOT_REALM, "selfupdate").
203 password("password123").
204 plainAttr(attr("fullname", "selfupdate@apache.org")).
205 plainAttr(attr("firstname", "selfupdate@apache.org")).
206 plainAttr(attr("surname", "surname")).
207 plainAttr(attr("ctype", "a type")).
208 plainAttr(attr("userId", "selfupdate@apache.org")).
209 build());
210
211 SECURITY_QUESTION_SERVICE = ADMIN_CLIENT.getService(SecurityQuestionService.class);
212 }
213
214 @AfterAll
215 public static void cleanUp() {
216 USER_SERVICE.search(new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
217 fiql(SyncopeClient.getUserSearchConditionBuilder().
218 is("username").equalTo("selfupdate").
219 or("username").equalTo("selfpwdreset").
220 or("username").equalTo("mustchangepassword").query()).
221 build()).getResult().forEach(user -> USER_SERVICE.delete(user.getKey()));
222 }
223
224 protected static void doLogin(final String user, final String passwd) {
225 TESTER.startPage(Login.class);
226 TESTER.assertRenderedPage(Login.class);
227
228 FormTester formTester = TESTER.newFormTester("login");
229 formTester.setValue("username", user);
230 formTester.setValue("password", passwd);
231 formTester.submit("submit");
232 }
233
234 protected static Attr attr(final String schema, final String value) {
235 return new Attr.Builder(schema).value(value).build();
236 }
237 }