2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * ===================================================================
8 * Unless otherwise specified, all software contained herein is licensed
9 * under the Apache License, Version 2.0 (the "License");
10 * you may not use this software except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * Unless otherwise specified, all documentation contained herein is licensed
22 * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
23 * you may not use this documentation except in compliance with the License.
24 * You may obtain a copy of the License at
26 * https://creativecommons.org/licenses/by/4.0/
28 * Unless required by applicable law or agreed to in writing, documentation
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
34 * ============LICENSE_END============================================
38 package org.onap.portalsdk.core.onboarding.crossapi;
40 import java.io.BufferedReader;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.InputStreamReader;
44 import java.io.PrintWriter;
45 import java.io.StringWriter;
46 import java.util.List;
49 import javax.servlet.ServletException;
50 import javax.servlet.annotation.WebServlet;
51 import javax.servlet.http.HttpServlet;
52 import javax.servlet.http.HttpServletRequest;
53 import javax.servlet.http.HttpServletResponse;
55 import org.apache.commons.logging.Log;
56 import org.apache.commons.logging.LogFactory;
57 import org.onap.portalsdk.core.onboarding.exception.PortalAPIException;
58 import org.onap.portalsdk.core.onboarding.listener.PortalTimeoutHandler;
59 import org.onap.portalsdk.core.onboarding.rest.RestWebServiceClient;
60 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
61 import org.onap.portalsdk.core.onboarding.util.PortalApiProperties;
62 import org.onap.portalsdk.core.restful.domain.EcompRole;
63 import org.onap.portalsdk.core.restful.domain.EcompUser;
64 import org.owasp.esapi.ESAPI;
66 import com.fasterxml.jackson.core.JsonProcessingException;
67 import com.fasterxml.jackson.core.type.TypeReference;
68 import com.fasterxml.jackson.databind.DeserializationFeature;
69 import com.fasterxml.jackson.databind.ObjectMapper;
72 * This servlet performs the functions described below. It listens on a path
73 * like "/api" (see {@link PortalApiConstants#API_PREFIX}). The servlet checks
74 * for authorized access and rejects unauthorized requests.
76 * <LI>Proxies user (i.e., browser) requests for web analytics. The GET method
77 * fetches javascript from the Portal and returns it. The POST method forwards
78 * data sent by the browser on to Portal. These requests are checked for a valid
79 * User UID in a header; these requests do NOT use the application
80 * username-password header.</LI>
81 * <LI>Responds to ECOMP Portal API requests to query and update user, role and
82 * user-role information. The servlet proxies all requests on to a local Java
83 * class that implements {@link IPortalRestAPIService}. These requests must have
84 * the application username-password header.</LI>
86 * This servlet will not start if the required portal.properties file is not
87 * found on the classpath.
90 @WebServlet(urlPatterns = { PortalApiConstants.API_PREFIX + "/*" })
91 public class PortalRestAPIProxy extends HttpServlet implements IPortalRestAPIService {
93 private static final long serialVersionUID = 1L;
95 private static final String APPLICATION_JSON = "application/json";
97 private static final Log logger = LogFactory.getLog(PortalRestAPIProxy.class);
100 * Mapper for JSON to object etc.
102 private final ObjectMapper mapper = new ObjectMapper();
105 * Client-supplied class that implements our interface.
107 private static IPortalRestAPIService portalRestApiServiceImpl;
108 private static final String isAccessCentralized = PortalApiProperties
109 .getProperty(PortalApiConstants.ROLE_ACCESS_CENTRALIZED);
110 private static final String errorMessage = "Access Management is not allowed for Centralized applications." ;
111 private static final String isCentralized = "remote";
114 public PortalRestAPIProxy() {
115 // Ensure that any additional fields sent by the Portal
116 // will be ignored when creating objects.
117 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
121 public void init() throws ServletException {
122 String className = PortalApiProperties.getProperty(PortalApiConstants.PORTAL_API_IMPL_CLASS);
123 if (className == null)
124 throw new ServletException(
125 "init: Failed to find class name property " + PortalApiConstants.PORTAL_API_IMPL_CLASS);
127 logger.debug("init: creating instance of class " + className);
128 Class<?> implClass = Class.forName(className);
129 if (!isCentralized.equals(isAccessCentralized))
130 portalRestApiServiceImpl = (IPortalRestAPIService) (implClass.getConstructor().newInstance());
132 portalRestApiServiceImpl = new PortalRestAPICentralServiceImpl();
134 } catch (Exception ex) {
135 throw new ServletException("init: Failed to find or instantiate class " + className, ex);
140 protected void doPost(HttpServletRequest request, HttpServletResponse response)
141 throws IOException, ServletException {
142 if (portalRestApiServiceImpl == null) {
143 // Should never happen due to checks in init()
144 logger.error("doPost: no service class instance");
145 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
146 response.getWriter().write(buildJsonResponse(false, "Misconfigured - no instance of service class"));
149 String requestUri = request.getRequestURI();
150 String responseJson = "";
151 String storeAnalyticsContextPath = "/storeAnalytics";
152 if (requestUri.endsWith(PortalApiConstants.API_PREFIX + storeAnalyticsContextPath)) {
155 userId = getUserId(request);
156 } catch (PortalAPIException e) {
157 logger.error("Issue with invoking getUserId implemenation !!! ", e);
158 throw new ServletException(e);
160 if (userId == null || userId.length() == 0) {
161 logger.debug("doPost: userId is null or empty");
162 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
163 responseJson = buildJsonResponse(false, "Not authorized for " + storeAnalyticsContextPath);
165 // User ID obtained from request
167 String appUserName = "";
168 String appPassword = "";
171 for (Map.Entry<String, String> entry : getCredentials().entrySet()) {
173 if (entry.getKey().equalsIgnoreCase("username")) {
174 appUserName = entry.getValue();
175 } else if (entry.getKey().equalsIgnoreCase("password")) {
176 appPassword = entry.getValue();
178 appName = entry.getValue();
182 String credential = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY);
183 // for now lets also pass uebkey as user name and password
184 String requestBody = readRequestBody(request);
185 @SuppressWarnings("unchecked")
186 Map<String, String> bodyMap = mapper.readValue(requestBody, Map.class);
188 bodyMap.put("userid", userId);
189 requestBody = mapper.writeValueAsString(bodyMap);
190 logger.debug("doPost: StoreAnalytics requestbody: "+ requestBody);
191 responseJson = RestWebServiceClient.getInstance().postPortalContent(storeAnalyticsContextPath,
192 userId, appName, null, appUserName, appPassword, "application/json", requestBody, true);
193 logger.debug("doPost: postPortalContent returns " + responseJson);
194 response.setStatus(HttpServletResponse.SC_OK);
195 } catch (Exception ex) {
196 logger.error("doPost: " + storeAnalyticsContextPath + " caught exception", ex);
197 responseJson = buildJsonResponse(ex);
198 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
201 writeAndFlush(response, APPLICATION_JSON, responseJson);
205 boolean secure = false;
207 secure = isAppAuthenticated(request);
208 } catch (PortalAPIException ex) {
209 logger.error("doPost: isAppAuthenticated threw exception", ex);
210 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
211 response.getWriter().write(buildJsonResponse(false, "Failed to authenticate request"));
215 logger.debug("doPost: isAppAuthenticated answered false");
216 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
217 writeAndFlush(response, APPLICATION_JSON, buildJsonResponse(false, "Not authorized"));
222 String requestBody = readRequestBody(request);
223 if (logger.isDebugEnabled())
224 logger.debug("doPost: URI = " + requestUri + ", payload = " + requestBody);
229 * 1. /user <-- save user
231 * 2. /user/{loginId} <-- edit user
233 * 3. /user/{loginId}/roles <-- save roles for user
236 // On success return the empty string.
238 if (requestUri.endsWith("/updateSessionTimeOuts")) {
239 if (updateSessionTimeOuts(requestBody)) {
240 logger.debug("doPost: updated session timeouts");
241 response.setStatus(HttpServletResponse.SC_OK);
243 String msg = "Failed to update session time outs";
244 logger.error("doPost: " + msg);
245 responseJson = buildJsonResponse(false, msg);
246 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
248 } else if (requestUri.endsWith("/timeoutSession")) {
249 String portalJSessionId = request.getParameter("portalJSessionId");
250 if (portalJSessionId == null) {
251 portalJSessionId = "";
253 if (timeoutSession(portalJSessionId)) {
254 logger.debug("doPost: timed out session");
255 response.setStatus(HttpServletResponse.SC_OK);
257 String msg = "Failed to timeout session";
258 logger.error("doPost: " + msg);
259 responseJson = buildJsonResponse(false, msg);
260 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
263 // Example: /user <-- create user
264 if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/user")) {
266 EcompUser user = mapper.readValue(requestBody, EcompUser.class);
268 if (logger.isDebugEnabled())
269 logger.debug("doPost: pushUser: success");
270 responseJson = buildJsonResponse(true, "user saved successfully");
271 response.setStatus(HttpServletResponse.SC_OK);
272 } catch (Exception ex) {
273 responseJson = buildJsonResponse(ex);
274 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
275 logger.error("doPost: pushUser: caught exception", ex);
278 // Example: /user/abc <-- edit user abc
279 if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !(requestUri.endsWith("/roles"))) {
280 String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1);
282 EcompUser user = mapper.readValue(requestBody, EcompUser.class);
283 editUser(loginId, user);
284 if (logger.isDebugEnabled())
285 logger.debug("doPost: editUser: success");
286 responseJson = buildJsonResponse(true, "user saved successfully");
287 response.setStatus(HttpServletResponse.SC_OK);
288 } catch (Exception ex) {
289 responseJson = buildJsonResponse(ex);
290 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
291 logger.error("doPost: editUser: caught exception", ex);
294 // Example: /user/{loginId}/roles <-- save roles for user
295 if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) {
296 String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1,
297 requestUri.lastIndexOf('/'));
299 if (isCentralized.equals(isAccessCentralized)) {
300 responseJson = buildJsonResponse(true, errorMessage);
301 response.setStatus(HttpServletResponse.SC_OK);
303 TypeReference<List<EcompRole>> typeRef = new TypeReference<List<EcompRole>>() {
305 List<EcompRole> roles = mapper.readValue(requestBody, typeRef);
306 pushUserRole(loginId, roles);
307 if (logger.isDebugEnabled())
308 logger.debug("doPost: pushUserRole: success");
309 responseJson = buildJsonResponse(true, "saveRoles is successful");
310 response.setStatus(HttpServletResponse.SC_OK);
312 } catch (Exception ex) {
313 responseJson = buildJsonResponse(ex);
314 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
315 logger.error("doPost: pushUserRole: caught exception", ex);
318 String msg = "doPost: no match for request " + requestUri;
319 logger.warn( ESAPI.encoder().encodeForHTML(msg));
320 responseJson = buildJsonResponse(false, msg);
321 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
323 } catch (Exception ex) {
324 logger.error("doPost: Failed to process request " + ESAPI.encoder().encodeForHTML(requestUri), ex);
325 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
326 responseJson = buildJsonResponse(ex);
329 writeAndFlush(response, APPLICATION_JSON, responseJson);
334 protected void doGet(HttpServletRequest request, HttpServletResponse response)
335 throws IOException, ServletException {
337 if (portalRestApiServiceImpl == null) {
338 // Should never happen due to checks in init()
339 logger.error("doGet: no service class instance");
340 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
341 writeAndFlush(response, APPLICATION_JSON,
342 buildJsonResponse(false, "Misconfigured - no instance of service class"));
346 String requestUri = request.getRequestURI();
347 String contentType = APPLICATION_JSON;
348 String webAnalyticsContextPath = "/analytics";
349 if (requestUri.endsWith(PortalApiConstants.API_PREFIX + webAnalyticsContextPath)) {
350 String responseString;
353 userId = getUserId(request);
354 } catch (PortalAPIException e) {
355 logger.error("Issue with invoking getUserId implemenation !!! ", e);
356 throw new ServletException(e);
358 if (userId == null || userId.length() == 0) {
359 logger.debug("doGet: userId is null or empty");
360 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
361 responseString = buildJsonResponse(false, "Not authorized for " + webAnalyticsContextPath);
363 // User ID obtained from request
365 String appUserName = "";
366 String appPassword = "";
369 for (Map.Entry<String, String> entry : getCredentials().entrySet()) {
371 if (entry.getKey().equalsIgnoreCase("username")) {
372 appUserName = entry.getValue();
373 } else if (entry.getKey().equalsIgnoreCase("password")) {
374 appPassword = entry.getValue();
376 appName = entry.getValue();
379 String credential = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY);
380 // for now lets also pass uebkey as user name and password
381 contentType = "text/javascript";
383 responseString = RestWebServiceClient.getInstance().getPortalContent(webAnalyticsContextPath,
384 userId, appName, null, appUserName, appPassword, true);
386 if (logger.isDebugEnabled())
387 logger.debug("doGet: " + webAnalyticsContextPath + ": " + responseString);
388 response.setStatus(HttpServletResponse.SC_OK);
389 } catch (Exception ex) {
390 responseString = buildJsonResponse(ex);
391 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
392 logger.error("doGet: " + webAnalyticsContextPath + " caught exception", ex);
395 writeAndFlush(response, contentType, responseString);
399 boolean secure = false;
401 secure = isAppAuthenticated(request);
402 } catch (PortalAPIException ex) {
403 logger.error("doGet: isAppAuthenticated threw exception", ex);
404 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
405 writeAndFlush(response, APPLICATION_JSON, buildJsonResponse(false, "Failed to authenticate request"));
410 if (logger.isDebugEnabled())
411 logger.debug("doGet: isAppAuthenticated answered false");
412 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
413 writeAndFlush(response, APPLICATION_JSON, buildJsonResponse(false, "Not authorized"));
417 String responseJson = null;
419 // Ignore any request body in a GET.
420 logger.debug("doGet: URI = " + requestUri);
423 * 1. /roles <-- get roles
425 * 2. /user/{loginId} <-- get user
427 * 3. /users <-- get all users
429 * 4. /user/{loginId}/roles <-- get roles for user
432 if (requestUri.endsWith("/sessionTimeOuts")) {
434 responseJson = getSessionTimeOuts();
435 logger.debug("doGet: got session timeouts");
436 response.setStatus(HttpServletResponse.SC_OK);
437 } catch(Exception ex) {
438 String msg = "Failed to get session time outs";
439 logger.error("doGet: " + msg);
440 responseJson = buildJsonResponse(false, msg);
441 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
444 // Example: /users <-- get all users
445 if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/users")) {
447 List<EcompUser> users = getUsers();
448 responseJson = mapper.writeValueAsString(users);
449 if (logger.isDebugEnabled())
450 logger.debug("doGet: getUsers: " + responseJson);
451 } catch (Exception ex) {
452 responseJson = buildShortJsonResponse(ex);
453 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
454 logger.error("doGet: getUsers: caught exception", ex);
457 // Example: /roles <-- get all roles
459 if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/roles")) {
461 List<EcompRole> roles = getAvailableRoles(getUserId(request));
462 responseJson = mapper.writeValueAsString(roles);
463 if (logger.isDebugEnabled())
464 logger.debug("doGet: getAvailableRoles: " + responseJson);
465 } catch (Exception ex) {
466 responseJson = buildJsonResponse(ex);
467 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
468 logger.error("doGet: getAvailableRoles: caught exception", ex);
471 // Example: /user/abc <-- get user abc
472 if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !requestUri.endsWith("/roles")) {
473 String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1);
475 EcompUser user = getUser(loginId);
476 responseJson = mapper.writeValueAsString(user);
477 if (logger.isDebugEnabled())
478 logger.debug("doGet: getUser: " + responseJson);
479 } catch (Exception ex) {
480 responseJson = buildJsonResponse(ex);
481 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
482 logger.error("doGet: getUser: caught exception", ex);
485 // Example: /user/abc/roles <-- get roles for user abc
486 else if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) {
487 String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1,
488 requestUri.lastIndexOf('/'));
490 List<EcompRole> roles = getUserRoles(loginId);
491 responseJson = mapper.writeValueAsString(roles);
492 if (logger.isDebugEnabled())
493 logger.debug("doGet: getUserRoles: " + responseJson);
494 } catch (Exception ex) {
495 responseJson = buildJsonResponse(ex);
496 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
497 logger.error("doGet: getUserRoles: caught exception", ex);
501 logger.warn("doGet: no match found for request");
502 responseJson = buildJsonResponse(false, "No match for request");
503 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
505 } catch (Exception ex) {
506 logger.error("doGet: Failed to process request", ex);
507 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
508 responseJson = buildJsonResponse(ex);
510 writeAndFlush(response, APPLICATION_JSON, responseJson);
513 public String getSessionTimeOuts() {
514 return PortalTimeoutHandler.gatherSessionExtensions();
517 public boolean timeoutSession(String portalJSessionId) {
518 return PortalTimeoutHandler.invalidateSession(portalJSessionId);
521 public boolean updateSessionTimeOuts(String sessionMap) {
522 return PortalTimeoutHandler.updateSessionExtensions(sessionMap);
526 public void pushUser(EcompUser user) throws PortalAPIException {
527 portalRestApiServiceImpl.pushUser(user);
531 public void editUser(String loginId, EcompUser user) throws PortalAPIException {
532 portalRestApiServiceImpl.editUser(loginId, user);
536 public EcompUser getUser(String loginId) throws PortalAPIException {
537 return portalRestApiServiceImpl.getUser(loginId);
541 public List<EcompUser> getUsers() throws PortalAPIException {
542 return portalRestApiServiceImpl.getUsers();
546 public List<EcompRole> getAvailableRoles(String requestedLoginId) throws PortalAPIException {
547 return portalRestApiServiceImpl.getAvailableRoles(requestedLoginId);
551 public void pushUserRole(String loginId, List<EcompRole> roles) throws PortalAPIException {
552 portalRestApiServiceImpl.pushUserRole(loginId, roles);
556 public List<EcompRole> getUserRoles(String loginId) throws PortalAPIException {
557 return portalRestApiServiceImpl.getUserRoles(loginId);
561 public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException {
562 return portalRestApiServiceImpl.isAppAuthenticated(request);
566 * Sets the content type and writes the response.
570 * @param responseBody
571 * @throws IOException
573 private void writeAndFlush(HttpServletResponse response, String contentType, String responseBody)
575 response.setContentType(contentType);
576 PrintWriter out = response.getWriter();
577 out.print(responseBody);
582 * Reads the request body and closes the input stream.
585 * @return String read from the request, the empty string if nothing is read.
586 * @throws IOException
588 private static String readRequestBody(HttpServletRequest request) throws IOException {
591 StringBuilder stringBuilder = new StringBuilder();
592 BufferedReader bufferedReader = null;
594 InputStream inputStream = request.getInputStream();
595 if (inputStream != null) {
596 bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
597 char[] charBuffer = new char[1024];
599 while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
600 stringBuilder.append(charBuffer, 0, bytesRead);
603 stringBuilder.append("");
606 if (bufferedReader != null) {
608 bufferedReader.close();
609 } catch (IOException ex) {
610 logger.error("readRequestBody", ex);
614 body = stringBuilder.toString();
619 * Builds JSON object with status + message response body.
622 * True to indicate success, false to signal failure.
624 * Message to include in the response object; ignored if null.
628 * { "status" : "ok" (or "error"), "message": "some explanation" }
631 private String buildJsonResponse(boolean success, String msg) {
632 PortalAPIResponse response = new PortalAPIResponse(success, msg);
635 json = mapper.writeValueAsString(response);
636 } catch (JsonProcessingException ex) {
637 // Truly should never, ever happen
638 logger.error("buildJsonResponse", ex);
639 json = "{ \"status\": \"error\",\"message\":\"" + ex.toString() + "\" }";
645 * Builds JSON object with status of error and message containing stack trace
646 * for the specified throwable.
649 * Throwable with stack trace to use as message
654 * { "status" : "error", "message": "some-big-stacktrace" }
657 private String buildJsonResponse(Throwable t) {
658 StringWriter sw = new StringWriter();
659 PrintWriter pw = new PrintWriter(sw);
660 t.printStackTrace(pw);
661 return buildJsonResponse(false, sw.toString());
664 private String buildShortJsonResponse(Throwable t)
666 String errorMessage = t.getMessage();
667 return buildJsonResponse(false, errorMessage);
671 public String getUserId(HttpServletRequest request) throws PortalAPIException {
672 return portalRestApiServiceImpl.getUserId(request);
675 public static IPortalRestAPIService getPortalRestApiServiceImpl() {
676 return portalRestApiServiceImpl;
679 public static void setPortalRestApiServiceImpl(IPortalRestAPIService portalRestApiServiceImpl) {
680 PortalRestAPIProxy.portalRestApiServiceImpl = portalRestApiServiceImpl;
684 public Map<String, String> getCredentials() throws PortalAPIException {
685 return portalRestApiServiceImpl.getCredentials();