1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.fit.core;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.junit.jupiter.api.Assertions.fail;
26
27 import java.io.IOException;
28 import java.security.AccessControlException;
29 import java.util.List;
30 import javax.ws.rs.ForbiddenException;
31 import javax.ws.rs.core.EntityTag;
32 import javax.ws.rs.core.GenericType;
33 import javax.ws.rs.core.HttpHeaders;
34 import javax.ws.rs.core.MediaType;
35 import javax.ws.rs.core.MultivaluedMap;
36 import javax.ws.rs.core.Response;
37 import org.apache.commons.lang3.RandomStringUtils;
38 import org.apache.commons.lang3.StringUtils;
39 import org.apache.cxf.jaxrs.client.WebClient;
40 import org.apache.syncope.client.lib.BasicAuthenticationHandler;
41 import org.apache.syncope.client.lib.SyncopeClient;
42 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
43 import org.apache.syncope.common.lib.SyncopeClientException;
44 import org.apache.syncope.common.lib.request.GroupCR;
45 import org.apache.syncope.common.lib.request.GroupUR;
46 import org.apache.syncope.common.lib.request.StringReplacePatchItem;
47 import org.apache.syncope.common.lib.request.UserUR;
48 import org.apache.syncope.common.lib.to.ConnInstanceTO;
49 import org.apache.syncope.common.lib.to.GroupTO;
50 import org.apache.syncope.common.lib.to.ProvisioningResult;
51 import org.apache.syncope.common.lib.to.UserTO;
52 import org.apache.syncope.common.lib.types.ClientExceptionType;
53 import org.apache.syncope.common.rest.api.Preference;
54 import org.apache.syncope.common.rest.api.RESTHeaders;
55 import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
56 import org.apache.syncope.common.rest.api.service.ConnectorService;
57 import org.apache.syncope.common.rest.api.service.GroupService;
58 import org.apache.syncope.common.rest.api.service.UserService;
59 import org.apache.syncope.fit.AbstractITCase;
60 import org.junit.jupiter.api.Test;
61
62 public class RESTITCase extends AbstractITCase {
63
64 @Test
65 public void unauthorizedOrForbidden() {
66
67 List<ConnInstanceTO> connectors = CONNECTOR_SERVICE.list(null);
68 assertNotNull(connectors);
69 assertFalse(connectors.isEmpty());
70
71
72 try {
73 CLIENT_FACTORY.create("bellini", "passwor");
74 fail("This should not happen");
75 } catch (AccessControlException e) {
76 assertNotNull(e);
77 }
78
79
80 try {
81 CLIENT_FACTORY.create(RandomStringUtils.random(20, true, true)).self();
82 fail("This should not happen");
83 } catch (AccessControlException e) {
84 assertNotNull(e);
85 }
86
87
88 SyncopeClient goodClient = CLIENT_FACTORY.create("bellini", "password");
89 try {
90 goodClient.getService(ConnectorService.class).list(null);
91 fail("This should not happen");
92 } catch (ForbiddenException e) {
93 assertNotNull(e);
94 }
95 }
96
97 @Test
98 public void noContent() throws IOException {
99 SyncopeClient noContentclient = CLIENT_FACTORY.create(ADMIN_UNAME, ADMIN_PWD);
100 GroupService noContentService = SyncopeClient.prefer(
101 noContentclient.getService(GroupService.class), Preference.RETURN_NO_CONTENT);
102
103 GroupCR groupCR = GroupITCase.getSample("noContent");
104
105 Response response = noContentService.create(groupCR);
106 assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
107 assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
108 assertEquals(StringUtils.EMPTY, response.readEntity(String.class));
109
110 GroupTO group = getObject(response.getLocation(), GroupService.class, GroupTO.class);
111 assertNotNull(group);
112
113 GroupUR groupUR = new GroupUR();
114 groupUR.setKey(group.getKey());
115 groupUR.getPlainAttrs().add(attrAddReplacePatch("badge", "xxxxxxxxxx"));
116
117 response = noContentService.update(groupUR);
118 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
119 assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
120 assertEquals(StringUtils.EMPTY, response.readEntity(String.class));
121
122 response = noContentService.delete(group.getKey());
123 assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
124 assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
125 assertEquals(StringUtils.EMPTY, response.readEntity(String.class));
126 }
127
128 @Test
129 public void ifMatch() {
130 UserTO userTO = USER_SERVICE.create(UserITCase.getUniqueSample("ifmatch@syncope.apache.org")).
131 readEntity(new GenericType<ProvisioningResult<UserTO>>() {
132 }).getEntity();
133 assertNotNull(userTO);
134 assertNotNull(userTO.getKey());
135
136 EntityTag etag = SyncopeClient.getLatestEntityTag(USER_SERVICE);
137 assertNotNull(etag);
138 assertTrue(StringUtils.isNotBlank(etag.getValue()));
139
140 UserUR userUR = new UserUR();
141 userUR.setKey(userTO.getKey());
142 userUR.setUsername(new StringReplacePatchItem.Builder().value(userTO.getUsername() + "XX").build());
143 userTO = USER_SERVICE.update(userUR).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
144 }).getEntity();
145 assertTrue(userTO.getUsername().endsWith("XX"));
146 EntityTag etag1 = SyncopeClient.getLatestEntityTag(USER_SERVICE);
147 assertFalse(etag.getValue().equals(etag1.getValue()));
148
149 UserService ifMatchService = SyncopeClient.ifMatch(ADMIN_CLIENT.getService(UserService.class), etag);
150 userUR.setUsername(new StringReplacePatchItem.Builder().value(userTO.getUsername() + "YY").build());
151 try {
152 ifMatchService.update(userUR);
153 fail("This should not happen");
154 } catch (SyncopeClientException e) {
155 assertEquals(ClientExceptionType.ConcurrentModification, e.getType());
156 }
157
158 userTO = USER_SERVICE.read(userTO.getKey());
159 assertTrue(userTO.getUsername().endsWith("XX"));
160 }
161
162 @Test
163 public void defaultContentType() {
164
165 SyncopeClientFactoryBean factory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
166 SyncopeClient client = new SyncopeClient(
167 MediaType.WILDCARD_TYPE,
168 factory.getRestClientFactoryBean(),
169 factory.getExceptionMapper(),
170 new BasicAuthenticationHandler(ADMIN_UNAME, ADMIN_PWD),
171 false,
172 null,
173 null);
174
175
176 AnyTypeClassService service = client.getService(AnyTypeClassService.class);
177 service.list();
178
179
180 MultivaluedMap<String, String> requestHeaders = WebClient.client(service).getHeaders();
181 assertEquals(MediaType.WILDCARD, requestHeaders.getFirst(HttpHeaders.ACCEPT));
182
183
184 String contentType = WebClient.client(service).getResponse().getHeaderString(HttpHeaders.CONTENT_TYPE);
185 assertTrue(contentType.startsWith(MediaType.APPLICATION_JSON));
186 }
187
188 @Test
189 public void exportInternalStorageContent() throws IOException {
190 Response response = SYNCOPE_SERVICE.exportInternalStorageContent(100);
191 assertNotNull(response);
192 assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
193 assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
194 String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
195 assertNotNull(contentDisposition);
196
197 String configExport = response.readEntity(String.class);
198 assertFalse(configExport.isEmpty());
199 assertTrue(configExport.length() > 1000);
200 }
201 }