From 627badaf69987c01811c477219fd943757a635f5 Mon Sep 17 00:00:00 2001 From: "Christopher Lott (Christopher) (cl778h)" Date: Mon, 12 Jun 2017 09:49:00 -0400 Subject: [PORTAL-16 PORTAL-18] Widget ms; staging Remove staging repositories from poms. Add widget microservice code base. Add portal unit tests. Repair defects. Normalize line endings. Change-Id: Ia5e48da2a3141b352439ecd548cddf918f4df585 Signed-off-by: Christopher Lott (cl778h) --- .../portalapp/conf/ExternalAppConfig.java | 1 + .../portalapp/controller/ONAPLoginController.java | 162 +- .../portalapp/portal/service/EPAppServiceImpl.java | 10 + .../portalapp/portal/service/UserRolesService.java | 58 - .../portal/service/UserRolesServiceImpl.java | 605 +----- .../portalapp/util/SessionCookieUtil.java | 129 ++ .../src/main/webapp/WEB-INF/conf/system.properties | 6 +- .../src/main/webapp/WEB-INF/defs/definitions.xml | 2 +- .../webapp/WEB-INF/fusion/defs/definitions.xml | 120 -- .../external/b2b/css/b2b-angular/font_icons.css | 1 + .../ds2/css/digital-ng-library/ecomp-ionicons.css | 156 ++ .../ds2/css/digital-ng-library/ionicons.css | 1480 +++++++++++++ .../app/fusion/external/ds2/css/fonts/ionicons.eot | Bin 0 -> 120724 bytes .../app/fusion/external/ds2/css/fonts/ionicons.svg | 2230 ++++++++++++++++++++ .../app/fusion/external/ds2/css/fonts/ionicons.ttf | Bin 0 -> 188508 bytes .../fusion/external/ds2/css/fonts/ionicons.woff | Bin 0 -> 67904 bytes ecomp-portal-BE-os/src/main/webapp/index.jsp | 82 +- .../portal/controller/SharedContextRestClient.java | 560 ++--- .../SharedContextRestControllerTest.java | 250 +-- .../controller/SharedContextTestProperties.java | 162 +- .../controller/shared-context-test.properties | 56 +- .../portal/listener/HealthMonitorTest.java | 72 +- .../portal/utils/EcompPortalUtilsTest.java | 66 +- 23 files changed, 4719 insertions(+), 1489 deletions(-) delete mode 100644 ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesService.java create mode 100644 ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/util/SessionCookieUtil.java delete mode 100644 ecomp-portal-BE-os/src/main/webapp/WEB-INF/fusion/defs/definitions.xml create mode 100644 ecomp-portal-BE-os/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/font_icons.css create mode 100644 ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css create mode 100644 ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ionicons.css create mode 100644 ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.eot create mode 100644 ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.svg create mode 100644 ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.ttf create mode 100644 ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.woff (limited to 'ecomp-portal-BE-os/src') diff --git a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/conf/ExternalAppConfig.java b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/conf/ExternalAppConfig.java index 971c671a..a16cf56b 100644 --- a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/conf/ExternalAppConfig.java +++ b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/conf/ExternalAppConfig.java @@ -97,6 +97,7 @@ public class ExternalAppConfig extends AppConfig implements Configurable { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/app/fusion/**").addResourceLocations("/app/fusion/"); registry.addResourceHandler("/static/**").addResourceLocations("/static/"); registry.addResourceHandler("/images/**").addResourceLocations("/images/"); registry.addResourceHandler("/**").addResourceLocations("/public/"); diff --git a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/controller/ONAPLoginController.java b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/controller/ONAPLoginController.java index 1f45d982..67f79b8b 100644 --- a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/controller/ONAPLoginController.java +++ b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/controller/ONAPLoginController.java @@ -1,81 +1,81 @@ -/*- - * ================================================================================ - * ECOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ================================================================================ - */ -package org.openecomp.portalapp.controller; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openecomp.portalsdk.core.auth.LoginStrategy; -import org.openecomp.portalsdk.core.controller.UnRestrictedBaseController; -import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler; -import org.openecomp.portalsdk.core.service.LoginService; -import org.openecomp.portalsdk.core.service.ProfileService; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class ONAPLoginController extends UnRestrictedBaseController { - @Autowired - ProfileService service; - @Autowired - private LoginService loginService; - @Autowired - private LoginStrategy loginStrategy; - String viewName; - - @RequestMapping(value = { "/doLogin" }, method = RequestMethod.GET) - public ModelAndView doLogin(HttpServletRequest request, HttpServletResponse response) throws Exception { - return loginStrategy.doLogin(request, response); - } - - public String getJessionId(HttpServletRequest request) { - return request.getSession().getId(); - } - - protected void initateSessionMgtHandler(HttpServletRequest request) { - String jSessionId = getJessionId(request); - PortalTimeoutHandler.sessionCreated(jSessionId, jSessionId, AppUtils.getSession(request)); - } - - public String getViewName() { - return viewName; - } - - public void setViewName(String viewName) { - this.viewName = viewName; - } - - public LoginService getLoginService() { - return loginService; - } - - public void setLoginService(LoginService loginService) { - this.loginService = loginService; - } - -} +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +package org.openecomp.portalapp.controller; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.openecomp.portalsdk.core.auth.LoginStrategy; +import org.openecomp.portalsdk.core.controller.UnRestrictedBaseController; +import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler; +import org.openecomp.portalsdk.core.service.LoginService; +import org.openecomp.portalsdk.core.service.ProfileService; +import org.openecomp.portalsdk.core.web.support.AppUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; + +@Controller +@RequestMapping("/") +public class ONAPLoginController extends UnRestrictedBaseController { + @Autowired + ProfileService service; + @Autowired + private LoginService loginService; + @Autowired + private LoginStrategy loginStrategy; + String viewName; + + @RequestMapping(value = { "/doLogin" }, method = RequestMethod.GET) + public ModelAndView doLogin(HttpServletRequest request, HttpServletResponse response) throws Exception { + return loginStrategy.doLogin(request, response); + } + + public String getJessionId(HttpServletRequest request) { + return request.getSession().getId(); + } + + protected void initateSessionMgtHandler(HttpServletRequest request) { + String jSessionId = getJessionId(request); + PortalTimeoutHandler.sessionCreated(jSessionId, jSessionId, AppUtils.getSession(request)); + } + + public String getViewName() { + return viewName; + } + + public void setViewName(String viewName) { + this.viewName = viewName; + } + + public LoginService getLoginService() { + return loginService; + } + + public void setLoginService(LoginService loginService) { + this.loginService = loginService; + } + +} diff --git a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/EPAppServiceImpl.java b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/EPAppServiceImpl.java index 074821f6..1f829380 100644 --- a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/EPAppServiceImpl.java +++ b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/EPAppServiceImpl.java @@ -20,7 +20,9 @@ package org.openecomp.portalapp.portal.service; +import java.security.GeneralSecurityException; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.TreeSet; @@ -33,6 +35,9 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.att.nsa.cambria.client.CambriaClientFactory; +import com.att.nsa.cambria.client.CambriaTopicManager; + @Service("epAppService") @Transactional @org.springframework.context.annotation.Configuration @@ -68,4 +73,9 @@ public class EPAppServiceImpl extends EPAppCommonServiceImpl implements EPAppSer return userApps; } + + public CambriaTopicManager getTopicManager(LinkedList urlList, String key, String secret) throws GeneralSecurityException, Exception{ + return CambriaClientFactory.createTopicManager( null, urlList, key, secret); + } + } \ No newline at end of file diff --git a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesService.java b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesService.java deleted file mode 100644 index b285051c..00000000 --- a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesService.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * ================================================================================ - * ECOMP Portal - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ================================================================================ - */ -package org.openecomp.portalapp.portal.service; - -import java.util.List; - -import org.apache.cxf.transport.http.HTTPException; -import org.openecomp.portalapp.portal.domain.EPRole; -import org.openecomp.portalapp.portal.domain.EPUser; -import org.openecomp.portalapp.portal.domain.EPUserApp; -import org.openecomp.portalapp.portal.transport.AppWithRolesForUser; -import org.openecomp.portalapp.portal.transport.RoleInAppForUser; -import org.openecomp.portalapp.portal.transport.UserApplicationRoles; - -public interface UserRolesService { - - public List getAppRolesForUser(Long appId, String userId); - - public boolean setAppWithUserRoleStateForUser(EPUser user, AppWithRolesForUser newAppRolesForUser); - - public List getUsersFromAppEndpoint(Long appId) throws HTTPException; - - public List importRolesFromRemoteApplication(Long appId) throws HTTPException; - - - /** - * Gets entries from the local fn_user_role table for the specified user and - * app. - * - * @param appId - * ID of row in fn_app - * @param userid - * ID of row in fn_user - * @return List of EPRole; empty if none found. - */ - public List getCachedAppRolesForUser(Long appId, Long userId); - - public String updateRemoteUserProfile(String orgUserId, Long appId); - - -} diff --git a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesServiceImpl.java b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesServiceImpl.java index a0aac922..1f98e752 100644 --- a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesServiceImpl.java +++ b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/portal/service/UserRolesServiceImpl.java @@ -20,49 +20,23 @@ package org.openecomp.portalapp.portal.service; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import javax.annotation.PostConstruct; - -import org.apache.commons.lang.StringUtils; import org.apache.cxf.transport.http.HTTPException; -import org.hibernate.Query; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; import org.openecomp.portalapp.portal.domain.EPApp; import org.openecomp.portalapp.portal.domain.EPRole; import org.openecomp.portalapp.portal.domain.EPUser; import org.openecomp.portalapp.portal.domain.EPUserApp; import org.openecomp.portalapp.portal.logging.aop.EPMetricsLog; -import org.openecomp.portalapp.portal.logging.format.EPAppMessagesEnum; -import org.openecomp.portalapp.portal.logging.logic.EPLogUtil; -import org.openecomp.portalapp.portal.transport.AppWithRolesForUser; -import org.openecomp.portalapp.portal.transport.FunctionalMenuItem; -import org.openecomp.portalapp.portal.transport.FunctionalMenuRole; import org.openecomp.portalapp.portal.transport.RemoteUserWithRoles; -import org.openecomp.portalapp.portal.transport.RoleInAppForUser; -import org.openecomp.portalapp.portal.transport.RolesInAppForUser; import org.openecomp.portalapp.portal.transport.UserApplicationRoles; -import org.openecomp.portalapp.portal.utils.EPSystemProperties; -import org.openecomp.portalapp.portal.utils.EcompPortalUtils; import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.restful.domain.EcompRole; import org.openecomp.portalsdk.core.service.DataAccessService; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.openecomp.portalsdk.core.util.SystemProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -71,398 +45,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; @org.springframework.context.annotation.Configuration @EnableAspectJAutoProxy @EPMetricsLog -public class UserRolesServiceImpl implements UserRolesService { - private static Long ACCOUNT_ADMIN_ROLE_ID = 999L; +public class UserRolesServiceImpl extends UserRolesCommonServiceImpl implements UserRolesService { private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(UserRolesServiceImpl.class); - @Autowired - private SessionFactory sessionFactory; @Autowired private DataAccessService dataAccessService; @Autowired - SearchService searchService; - @Autowired - EPAppService appsService; - @Autowired - EPLdapService ldapService; - @Autowired - ApplicationsRestClientService applicationsRestClientService; - @Autowired - EPRoleService epRoleService; - @Autowired - UserProfileService userProfileService; - - @PostConstruct - private void init() { - try { - ACCOUNT_ADMIN_ROLE_ID = Long - .valueOf(SystemProperties.getProperty(EPSystemProperties.ACCOUNT_ADMIN_ROLE_ID)); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e)); - } - } - - private static HashMap hashMapFromEcompRoles(EcompRole[] ecompRoles) { - HashMap result = new HashMap(); - if (ecompRoles != null) { - for (int i = 0; i < ecompRoles.length; i++) { - if (ecompRoles[i].getId() != null) { - result.put(ecompRoles[i].getId(), ecompRoles[i]); - } - } - } - return result; - } - - private void createLocalUserIfNecessary(String orgUserId) { - if (StringUtils.isEmpty(orgUserId)) { - logger.error(EELFLoggerDelegate.errorLogger, "createLocalUserIfNecessary : empty orgUserId!"); - return; - } - Session localSession = null; - Transaction transaction = null; - try { - localSession = sessionFactory.openSession(); - transaction = localSession.beginTransaction(); - @SuppressWarnings("unchecked") - List userList = localSession - .createQuery("from " + EPUser.class.getName() + " where org_user_id='" + orgUserId + "'").list(); - if (userList.size() == 0) { - EPUser client = searchService.searchUserByUserId(orgUserId); - if (client == null) { - String msg = "cannot create user " + orgUserId + ", because he cannot be found in phonebook"; - logger.error(EELFLoggerDelegate.errorLogger, msg); - } else { - client.setLoginId(orgUserId); - client.setActive(true); - localSession.save(client); - } - } - transaction.commit(); - } catch (Exception e) { - EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError); - EcompPortalUtils.rollbackTransaction(transaction, "searchOrCreateUser rollback, exception = " + e); - } finally { - EcompPortalUtils.closeLocalSession(localSession, "searchOrCreateUser"); - } - } - - private static void syncUserRoles(SessionFactory sessionFactory, String orgUserId, Long appId, - EcompRole[] userAppRoles) throws Exception { - HashMap newUserAppRolesMap = hashMapFromEcompRoles(userAppRoles); - boolean result = false; - Session localSession = null; - Transaction transaction = null; - - try { - localSession = sessionFactory.openSession(); - transaction = localSession.beginTransaction(); - @SuppressWarnings("unchecked") - List userList = localSession - .createQuery("from " + EPUser.class.getName() + " where org_user_id='" + orgUserId + "'").list(); - if (userList.size() > 0) { - EPUser client = userList.get(0); - @SuppressWarnings("unchecked") - List userRoles = localSession.createQuery("from " + EPUserApp.class.getName() - + " where app.id=" + appId + " and userId=" + client.getId()).list(); - for (EPUserApp userRole : userRoles) { - if (!userRole.getRoleId().equals(ACCOUNT_ADMIN_ROLE_ID)) { - - Long userAppRoleId = userRole.getAppRoleId(); - if (!newUserAppRolesMap.containsKey(userAppRoleId)) { - localSession.delete(userRole); - } else { - newUserAppRolesMap.remove(userAppRoleId); - } - } - } - Collection newRolesToAdd = newUserAppRolesMap.values(); - if (newRolesToAdd.size() > 0) { - EPApp app = (EPApp) localSession.get(EPApp.class, appId); - @SuppressWarnings("unchecked") - List roles = localSession - .createQuery("from " + EPRole.class.getName() + " where appId=" + appId).list(); - HashMap rolesMap = new HashMap(); - for (EPRole role : roles) { - rolesMap.put(role.getAppRoleId(), role); - } - for (EcompRole userRole : newRolesToAdd) { - EPUserApp userApp = new EPUserApp(); - userApp.setUserId(client.getId()); - userApp.setApp(app); - userApp.setRole(rolesMap.get(userRole.getId())); - localSession.save(userApp); - } - } - } - transaction.commit(); - result = true; - } catch (Exception e) { - EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError); - EcompPortalUtils.rollbackTransaction(transaction, - "Exception occurred in syncUserRoles, Details: " + EcompPortalUtils.getStackTrace(e)); - } finally { - localSession.close(); - if (!result) { - throw new Exception( - "Exception occurred in syncUserRoles while closing database session for app: '" + appId + "'."); - } - } - } - - // Called when getting the list of roles for the user - private List constructRolesInAppForUserGet(EcompRole[] appRoles, EcompRole[] userAppRoles) { - List rolesInAppForUser = new ArrayList(); - - Set userAppRolesMap = new HashSet(); - if (userAppRoles != null) { - for (EcompRole ecompRole : userAppRoles) { - userAppRolesMap.add(ecompRole.getId()); - } - } else { - String message = String - .format("UserRolesServiceImpl.constructRolesInAppForUserGet has received userAppRoles list empty."); - logger.info(EELFLoggerDelegate.errorLogger, message); - } - - if (appRoles != null) { - for (EcompRole ecompRole : appRoles) { - RoleInAppForUser roleForUser = new RoleInAppForUser(ecompRole.getId(), ecompRole.getName()); - roleForUser.isApplied = userAppRolesMap.contains(ecompRole.getId()); - rolesInAppForUser.add(roleForUser); - } - } else { - String message = String - .format("UserRolesServiceImpl.constructRolesInAppForUser has received appRoles list empty."); - logger.info(EELFLoggerDelegate.errorLogger, message); - } - return rolesInAppForUser; - } - - public List getAppRolesForUser(Long appId, String orgUserId) { - List rolesInAppForUser = null; - try { - EcompRole[] appRoles = applicationsRestClientService.get(EcompRole[].class, appId, "/roles"); - - // Test this error case, for generating an internal Ecomp Portal - // error - // EcompRole[] appRoles = null; - // If there is an exception in the rest client api, then null will - // be returned. - if (appRoles != null) { - syncAppRoles(sessionFactory, appId, appRoles); - EcompRole[] userAppRoles; - try { - userAppRoles = applicationsRestClientService.get(EcompRole[].class, appId, - String.format("/user/%s/roles", orgUserId)); - if (userAppRoles == null) { - if (EcompPortalUtils.getExternalAppResponseCode() == 400) { - EcompPortalUtils.setExternalAppResponseCode(200); - logger.error(EELFLoggerDelegate.errorLogger, - "400 returned from /user/{userid}/roles, assuming user doesn't exist, app is framework SDK based, and things are ok. Overriding to 200 until framework SDK returns a useful response."); - logger.debug(EELFLoggerDelegate.debugLogger, - "400 returned from /user/{userid}/roles, assuming user doesn't exist, app is framework SDK based, and things are ok. Overriding to 200 until framework SDK returns a useful response."); - } - } - // If the remote application isn't down we MUST to sync user - // roles here in case we have this user here! - syncUserRoles(sessionFactory, orgUserId, appId, userAppRoles); - } catch (Exception e) { - // TODO: we may need to check if user exists, maybe remote - // app is down. - logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e)); - logger.error(EELFLoggerDelegate.errorLogger, - "LR: user " + orgUserId + " does not exist in remote application: " + appId + "."); - userAppRoles = new EcompRole[0]; - } - rolesInAppForUser = constructRolesInAppForUserGet(appRoles, userAppRoles); - // Test this error case, for generating an external app error - // EcompPortalUtils.setResponseCode(404); - } - } catch (Exception e) { - String message = String.format( - "Received an exception while performing getAppRolesForUser for the User %s, and for the AppId %s, Details: %s", - orgUserId, Long.toString(appId), EcompPortalUtils.getStackTrace(e)); - logger.error(EELFLoggerDelegate.errorLogger, message); - } - return rolesInAppForUser; - - } - - // copies of methods in GetAppsWithUserRoleState - private void syncAppRoles(SessionFactory sessionFactory, Long appId, EcompRole[] appRoles) throws Exception { - logger.debug(EELFLoggerDelegate.debugLogger, "entering syncAppRoles for appId: " + appId); - HashMap newRolesMap = hashMapFromEcompRoles(appRoles); - boolean result = false; - Session localSession = null; - Transaction transaction = null; - - try { - localSession = sessionFactory.openSession(); - transaction = localSession.beginTransaction(); - // Attention! All roles from remote application supposed to be - // active! - @SuppressWarnings("unchecked") - List currentAppRoles = localSession - .createQuery("from " + EPRole.class.getName() + " where appId=" + appId).list(); - List obsoleteRoles = new ArrayList(); - for (int i = 0; i < currentAppRoles.size(); i++) { - EPRole oldAppRole = currentAppRoles.get(i); - if (oldAppRole.getAppRoleId() != null) { - EcompRole role = null; - role = newRolesMap.get(oldAppRole.getAppRoleId()); - if (role != null) { - if (!(role.getName() == null || oldAppRole.getName().equals(role.getName()))) { - oldAppRole.setName(role.getName()); - localSession.update(oldAppRole); - } - newRolesMap.remove(oldAppRole.getAppRoleId()); - } else { - obsoleteRoles.add(oldAppRole); - } - } else { - obsoleteRoles.add(oldAppRole); - } - } - Collection newRolesToAdd = newRolesMap.values(); - for (EcompRole role : newRolesToAdd) { - logger.debug(EELFLoggerDelegate.debugLogger, "about to add missing role: " + role.toString()); - EPRole newRole = new EPRole(); - // Attention! All roles from remote application supposed to be - // active! - newRole.setActive(true); - newRole.setName(role.getName()); - newRole.setAppId(appId); - newRole.setAppRoleId(role.getId()); - localSession.save(newRole); - } - if (obsoleteRoles.size() > 0) { - logger.debug(EELFLoggerDelegate.debugLogger, "we have obsolete roles to delete"); - for (EPRole role : obsoleteRoles) { - logger.debug(EELFLoggerDelegate.debugLogger, "obsolete role: " + role.toString()); - Long roleId = role.getId(); - // delete obsolete roles here - // Must delete all records with foreign key constraints on - // fn_role: - // fn_user_role, fn_role_composite, fn_role_function, - // fn_user_pseudo_role, fn_menu_functional_roles. - // And for fn_menu_functional, if no other roles for that - // menu item, remove the url. - - // Delete from fn_user_role - @SuppressWarnings("unchecked") - List userRoles = localSession.createQuery( - "from " + EPUserApp.class.getName() + " where app.id=" + appId + " and role_id=" + roleId) - .list(); - - logger.debug(EELFLoggerDelegate.debugLogger, "number of userRoles to delete: " + userRoles.size()); - for (EPUserApp userRole : userRoles) { - logger.debug(EELFLoggerDelegate.debugLogger, - "about to delete userRole: " + userRole.toString()); - localSession.delete(userRole); - logger.debug(EELFLoggerDelegate.debugLogger, - "finished deleting userRole: " + userRole.toString()); - } - - // Delete from fn_menu_functional_roles - @SuppressWarnings("unchecked") - List funcMenuRoles = localSession - .createQuery("from " + FunctionalMenuRole.class.getName() + " where roleId=" + roleId) - .list(); - int numMenuRoles = funcMenuRoles.size(); - logger.debug(EELFLoggerDelegate.debugLogger, - "number of funcMenuRoles for roleId: " + roleId + ": " + numMenuRoles); - for (FunctionalMenuRole funcMenuRole : funcMenuRoles) { - Long menuId = funcMenuRole.menuId; - // If this is the only role for this menu item, then the - // app and roles will be gone, - // so must null out the url too, to be consistent - @SuppressWarnings("unchecked") - List funcMenuRoles2 = localSession - .createQuery("from " + FunctionalMenuRole.class.getName() + " where menuId=" + menuId) - .list(); - int numMenuRoles2 = funcMenuRoles2.size(); - logger.debug(EELFLoggerDelegate.debugLogger, - "number of funcMenuRoles for menuId: " + menuId + ": " + numMenuRoles2); - localSession.delete(funcMenuRole); - if (numMenuRoles2 == 1) { - // If this is the only role for this menu item, then - // the app and roles will be gone, - // so must null out the url too, to be consistent - logger.debug(EELFLoggerDelegate.debugLogger, - "There is exactly 1 menu item for this role, so emptying the url"); - @SuppressWarnings("unchecked") - List funcMenuItems = localSession - .createQuery( - "from " + FunctionalMenuItem.class.getName() + " where menuId=" + menuId) - .list(); - if (funcMenuItems.size() > 0) { - logger.debug(EELFLoggerDelegate.debugLogger, "got the menu item"); - FunctionalMenuItem funcMenuItem = funcMenuItems.get(0); - funcMenuItem.url = ""; - localSession.update(funcMenuItem); - } - } - } - - // Delete from fn_role_function - String sql = "DELETE FROM fn_role_function WHERE role_id=" + roleId; - logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql); - Query query = localSession.createSQLQuery(sql); - query.executeUpdate(); - - // Delete from fn_role_composite - sql = "DELETE FROM fn_role_composite WHERE parent_role_id=" + roleId + " OR child_role_id=" - + roleId; - logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql); - query = localSession.createSQLQuery(sql); - query.executeUpdate(); - - // Delete from fn_user_pseudo_role - sql = "DELETE FROM fn_user_pseudo_role WHERE pseudo_role_id=" + roleId; - logger.debug(EELFLoggerDelegate.debugLogger, "Executing query: " + sql); - query = localSession.createSQLQuery(sql); - query.executeUpdate(); - - logger.debug(EELFLoggerDelegate.debugLogger, "about to delete the role: " + role.toString()); - localSession.delete(role); - logger.debug(EELFLoggerDelegate.debugLogger, "deleted the role"); - } - } - logger.debug(EELFLoggerDelegate.debugLogger, "about to commit the transaction"); - transaction.commit(); - logger.debug(EELFLoggerDelegate.debugLogger, "committed the transaction"); - result = true; - } catch (Exception e) { - EPLogUtil.logEcompError(EPAppMessagesEnum.BeDaoSystemError); - EcompPortalUtils.rollbackTransaction(transaction, - "Exception occurred in syncAppRoles, Details: " + EcompPortalUtils.getStackTrace(e)); - } finally { - localSession.close(); - if (!result) { - throw new Exception( - "Exception occurred in syncAppRoles while closing database session for app: '" + appId + "'."); - } - } - } - - // Called when updating the list of roles for the user - private RolesInAppForUser constructRolesInAppForUserUpdate(String orgUserId, Long appId, - Set userRolesInRemoteApp) { - RolesInAppForUser result; - result = new RolesInAppForUser(); - result.appId = appId; - result.orgUserId = orgUserId; - for (EcompRole role : userRolesInRemoteApp) { - RoleInAppForUser roleInAppForUser = new RoleInAppForUser(); - roleInAppForUser.roleId = role.getId(); - roleInAppForUser.roleName = role.getName(); - roleInAppForUser.isApplied = new Boolean(true); - result.roles.add(roleInAppForUser); - } - return result; - } + private ApplicationsRestClientService applicationsRestClientService; private EPUser getUserFromRemoteApp(String orgUserId, EPApp app, ApplicationsRestClientService applicationsRestClientService) throws HTTPException { @@ -471,41 +61,6 @@ public class UserRolesServiceImpl implements UserRolesService { return user; } - private boolean remoteUserShouldBeCreated(List roleInAppForUserList) { - for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) { - if (roleInAppForUser.isApplied.booleanValue()) { - return true; - } - } - return false; - } - - private Set postUsersRolesToRemoteApp(List roleInAppForUserList, ObjectMapper mapper, - ApplicationsRestClientService applicationsRestClientService, Long appId, String orgUserId) - throws JsonProcessingException, HTTPException { - Set updatedUserRoles = constructUsersEcompRoles(roleInAppForUserList); - String userRolesAsString = mapper.writeValueAsString(updatedUserRoles); - applicationsRestClientService.post(EcompRole.class, appId, userRolesAsString, - String.format("/user/%s/roles", orgUserId)); - // TODO: We should add code that verifies that the post operation did - // succeed. Because the SDK may still return 200 OK with an html page - // even when it fails! - return updatedUserRoles; - } - - private Set constructUsersEcompRoles(List roleInAppForUserList) { - Set existingUserRoles = new TreeSet(); - for (RoleInAppForUser roleInAppForUser : roleInAppForUserList) { - if (roleInAppForUser.isApplied) { - EcompRole ecompRole = new EcompRole(); - ecompRole.setId(roleInAppForUser.roleId); - ecompRole.setName(roleInAppForUser.roleName); - existingUserRoles.add(ecompRole); - } - } - return existingUserRoles; - } - private static void createNewUserOnRemoteApp(String orgUserId, EPApp app, ApplicationsRestClientService applicationsRestClientService, SearchService searchService, ObjectMapper mapper) throws Exception { @@ -527,126 +82,6 @@ public class UserRolesServiceImpl implements UserRolesService { applicationsRestClientService.post(EPUser.class, app.getId(), userAsString, String.format("/user", orgUserId)); } - public String updateRemoteUserProfile(String orgUserId, Long appId) { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - EPUser client = searchService.searchUserByUserId(orgUserId); - EPUser newUser = new EPUser(); - newUser.setActive(client.getActive()); - newUser.setFirstName(client.getFirstName()); - newUser.setLastName(client.getLastName()); - newUser.setLoginId(client.getLoginId()); - newUser.setLoginPwd(client.getLoginPwd()); - newUser.setMiddleInitial(client.getMiddleInitial()); - newUser.setEmail(client.getEmail()); - newUser.setOrgUserId(client.getLoginId()); - try { - String userAsString = mapper.writeValueAsString(newUser); - List appList = appsService.getUserRemoteApps(client.getId().toString()); - // applicationsRestClientService.post(EPUser.class, appId, - // userAsString, String.format("/user", orgUserId)); - for (EPApp eachApp : appList) { - try { - applicationsRestClientService.post(EPUser.class, eachApp.getId(), userAsString, - String.format("/user/%s", orgUserId)); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Failed to update user: " + client.getOrgUserId() - + " in remote app. appId = " + eachApp.getId()); - } - } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return "failure"; - } - - return "success"; - - } - - private static final Object syncRests = new Object(); - - @Override - public boolean setAppWithUserRoleStateForUser(EPUser user, AppWithRolesForUser newAppRolesForUser) { - boolean result = false; - String orgUserId = ""; - if (newAppRolesForUser != null && newAppRolesForUser.orgUserId != null) { - orgUserId = newAppRolesForUser.orgUserId.trim(); - } - Long appId = newAppRolesForUser.appId; - List roleInAppForUserList = newAppRolesForUser.appRoles; - if (orgUserId.length() > 0) { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - try { - EPApp app = appsService.getApp(appId); - EPUser remoteAppUser = getUserFromRemoteApp(orgUserId, app, applicationsRestClientService); - if (remoteAppUser == null) { - if (remoteUserShouldBeCreated(roleInAppForUserList)) { - createNewUserOnRemoteApp(orgUserId, app, applicationsRestClientService, searchService, mapper); - // If we succeed, we know that the new user was - // persisted on remote app. - remoteAppUser = getUserFromRemoteApp(orgUserId, app, applicationsRestClientService); - if (remoteAppUser == null) { - logger.error(EELFLoggerDelegate.errorLogger, - "Failed to persist new user: " + orgUserId + " in remote app. appId = " + appId); - // return null; - } - } - } - if (remoteAppUser != null) { - Set userRolesInRemoteApp = postUsersRolesToRemoteApp(roleInAppForUserList, mapper, - applicationsRestClientService, appId, orgUserId); - RolesInAppForUser rolesInAppForUser = constructRolesInAppForUserUpdate(orgUserId, appId, - userRolesInRemoteApp); - result = applyChangesInUserRolesForAppToEcompDB(rolesInAppForUser); - } - } catch (Exception e) { - String message = String.format( - "Failed to create user or update user roles for the User %s, and for the AppId %s, Details: %s", - orgUserId, Long.toString(appId), EcompPortalUtils.getStackTrace(e)); - logger.error(EELFLoggerDelegate.errorLogger, message); - result = false; - } - - } - return result; - } - - // This is for a single app - private boolean applyChangesInUserRolesForAppToEcompDB(RolesInAppForUser rolesInAppForUser) { - boolean result = false; - String orgUserId = rolesInAppForUser.orgUserId; - Long appId = rolesInAppForUser.appId; - synchronized (syncRests) { - if (rolesInAppForUser != null) { - createLocalUserIfNecessary(orgUserId); - } - - if (rolesInAppForUser != null) { - EcompRole[] userAppRoles = new EcompRole[rolesInAppForUser.roles.size()]; - for (int i = 0; i < rolesInAppForUser.roles.size(); i++) { - RoleInAppForUser roleInAppForUser = rolesInAppForUser.roles.get(i); - EcompRole role = new EcompRole(); - role.setId(roleInAppForUser.roleId); - role.setName(roleInAppForUser.roleName); - userAppRoles[i] = role; - } - try { - syncUserRoles(sessionFactory, orgUserId, appId, userAppRoles); - result = true; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, - "applyChangesInUserRolesForAppToEcompDB syncUserRoles, orgUserId = " + orgUserId); - logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e)); - } - } - } - return result; - } - @Override public List getUsersFromAppEndpoint(Long appId) throws HTTPException { RemoteUserWithRoles[] remoteUsers = applicationsRestClientService.get(RemoteUserWithRoles[].class, appId, @@ -654,7 +89,7 @@ public class UserRolesServiceImpl implements UserRolesService { ArrayList userApplicationRoles = new ArrayList(); for (RemoteUserWithRoles remoteUser : remoteUsers) { UserApplicationRoles userWithRemoteAppRoles = convertToUserApplicationRoles(appId, remoteUser); - if(userWithRemoteAppRoles.getRoles()!=null && userWithRemoteAppRoles.getRoles().size()>0) { + if (userWithRemoteAppRoles.getRoles() != null && userWithRemoteAppRoles.getRoles().size() > 0) { userApplicationRoles.add(userWithRemoteAppRoles); } else { logger.debug(EELFLoggerDelegate.debugLogger, "User " + userWithRemoteAppRoles.getOrgUserId() @@ -666,16 +101,6 @@ public class UserRolesServiceImpl implements UserRolesService { return userApplicationRoles; } - private UserApplicationRoles convertToUserApplicationRoles(Long appId, RemoteUserWithRoles remoteUser) { - UserApplicationRoles userWithRemoteAppRoles = new UserApplicationRoles(); - userWithRemoteAppRoles.setAppId(appId); - userWithRemoteAppRoles.setOrgUserId(remoteUser.getLoginId()); - userWithRemoteAppRoles.setFirstName(remoteUser.getFirstName()); - userWithRemoteAppRoles.setLastName(remoteUser.getLastName()); - userWithRemoteAppRoles.setRoles(remoteUser.getRoles()); - return userWithRemoteAppRoles; - } - public static void persistExternalRoleInEcompDb(EPRole externalAppRole, Long appId, EPRoleService roleService) { externalAppRole.setAppId(appId); externalAppRole.setAppRoleId(externalAppRole.getId()); @@ -689,30 +114,6 @@ public class UserRolesServiceImpl implements UserRolesService { externalAppRole.getAppRoleId(), externalAppRole.getName())); } - @Override - public List importRolesFromRemoteApplication(Long appId) throws HTTPException { - EPRole[] appRolesFull = applicationsRestClientService.get(EPRole[].class, appId, "/rolesFull"); - List rolesList = Arrays.asList(appRolesFull); - for (EPRole externalAppRole : rolesList) { - - // Try to find an existing extern role for the app in the local - // ecomp DB. If so, then use its id to update the existing external - // application role record. - Long externAppId = externalAppRole.getId(); - EPRole existingAppRole = epRoleService.getRole(appId, externAppId); - if (existingAppRole != null) { - logger.debug(EELFLoggerDelegate.debugLogger, - String.format("ecomp role already exists for app=%s; appRoleId=%s. No need to import this one.", - appId, externAppId)); - continue; - } - // persistExternalRoleInEcompDb(externalAppRole, appId, - // roleService); - } - - return rolesList; - } - @Override public List getCachedAppRolesForUser(Long appId, Long userId) { // Find the records for this user-app combo, if any diff --git a/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/util/SessionCookieUtil.java b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/util/SessionCookieUtil.java new file mode 100644 index 00000000..1ef44a44 --- /dev/null +++ b/ecomp-portal-BE-os/src/main/java/org/openecomp/portalapp/util/SessionCookieUtil.java @@ -0,0 +1,129 @@ +/*- + * ================================================================================ + * ECOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +package org.openecomp.portalapp.util; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalapp.portal.utils.EPCommonSystemProperties; +import org.openecomp.portalapp.portal.utils.EcompPortalUtils; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler; +import org.openecomp.portalsdk.core.onboarding.util.CipherUtil; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.AppUtils; + +public class SessionCookieUtil { + + //private static final String JSESSIONID = "JSESSIONID"; + private static final String EP_SERVICE = "EPService"; + private static final String USER_ID = "UserId"; + private static Integer cookieMaxAge = -1; + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SessionCookieUtil.class); + + public static void preSetUp(HttpServletRequest request, + HttpServletResponse response) { + initateSessionMgtHandler(request); + //set up EPService cookie + setUpEPServiceCookie(request, response); + } + + public static void setUpEPServiceCookie(HttpServletRequest request, + HttpServletResponse response) { + String jSessionId = getJessionId(request); + Cookie cookie1 = new Cookie(EP_SERVICE, jSessionId); + cookie1.setMaxAge(cookieMaxAge); + cookie1.setDomain(EPCommonSystemProperties.getProperty(EPCommonSystemProperties.COOKIE_DOMAIN)); + cookie1.setPath("/"); + response.addCookie(cookie1); + } + + public static void setUpUserIdCookie(HttpServletRequest request, + HttpServletResponse response,String userId) throws Exception { + logger.info("************** session cookie util set up UserId cookie begins"); + userId = CipherUtil.encrypt(userId, + SystemProperties.getProperty(SystemProperties.Decryption_Key)); + Cookie cookie1 = new Cookie(USER_ID, userId); + cookie1.setMaxAge(cookieMaxAge); + cookie1.setDomain(EPCommonSystemProperties.getProperty(EPCommonSystemProperties.COOKIE_DOMAIN)); + cookie1.setPath("/"); + response.addCookie(cookie1); + logger.info("************** session cookie util set up EP cookie completed"); + } + + public static String getUserIdFromCookie(HttpServletRequest request, + HttpServletResponse response) throws Exception { + String userId = ""; + Cookie[] cookies = request.getCookies(); + Cookie userIdcookie = null; + if (cookies != null) + for (Cookie cookie : cookies) + if (cookie.getName().equals(USER_ID)) + userIdcookie = cookie; + if(userIdcookie!=null){ + userId = CipherUtil.decrypt(userIdcookie.getValue(), + SystemProperties.getProperty(SystemProperties.Decryption_Key)); + } + + logger.info("************** session cookie util set up EP cookie completed"); + return userId; + } + + public static String getJessionId(HttpServletRequest request){ + + return request.getSession().getId(); + /* + Cookie ep = WebUtils.getCookie(request, JSESSIONID); + if(ep==null){ + return request.getSession().getId(); + } + return ep.getValue(); + */ + } + + protected static void initateSessionMgtHandler(HttpServletRequest request) { + String jSessionId = getJessionId(request); + storeMaxInactiveTime(request); + PortalTimeoutHandler.sessionCreated(jSessionId, jSessionId, AppUtils.getSession(request)); + } + + protected static void storeMaxInactiveTime(HttpServletRequest request) { + HttpSession session = AppUtils.getSession(request); + if(session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null) + session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME,session.getMaxInactiveInterval()); + } + + public static void resetSessionMaxIdleTimeOut(HttpServletRequest request) { + try { + HttpSession session = AppUtils.getSession(request); + final Object maxIdleAttribute = session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME); + if(session != null && maxIdleAttribute != null) { + session.setMaxInactiveInterval(Integer.parseInt(maxIdleAttribute.toString())); + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Could not reset the session timeout. Details: " + EcompPortalUtils.getStackTrace(e)); + } + + } + +} diff --git a/ecomp-portal-BE-os/src/main/webapp/WEB-INF/conf/system.properties b/ecomp-portal-BE-os/src/main/webapp/WEB-INF/conf/system.properties index 8c682649..0fc2c69d 100644 --- a/ecomp-portal-BE-os/src/main/webapp/WEB-INF/conf/system.properties +++ b/ecomp-portal-BE-os/src/main/webapp/WEB-INF/conf/system.properties @@ -33,7 +33,8 @@ hb.show_sql = false hb.db_reconnect = true hb.idle_connection_test_period = 3600 -app_display_name = app_display_name +# Ecomp portal title +app_display_name = Portal files_path = /demeter/WebApps/dev/ECOMP_APP/files context_root = ECOMPPORTAL # menu settings @@ -109,10 +110,9 @@ microservices.widget.local.port = 8082 #delete auditlog from number of days ago auditlog_del_day_from = 365 - #authenticate user server authenticate_user_server=http://todo_enter_auth_server_hostname:8383/openid-connect-server-webapp/allUsers #window width threshold to collapse left/right menu when page onload window_width_threshold_left_menu = 1400 -window_width_threshold_right_menu = 1350 \ No newline at end of file +window_width_threshold_right_menu = 1350 diff --git a/ecomp-portal-BE-os/src/main/webapp/WEB-INF/defs/definitions.xml b/ecomp-portal-BE-os/src/main/webapp/WEB-INF/defs/definitions.xml index 603e1144..0fa84a9c 100644 --- a/ecomp-portal-BE-os/src/main/webapp/WEB-INF/defs/definitions.xml +++ b/ecomp-portal-BE-os/src/main/webapp/WEB-INF/defs/definitions.xml @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/font_icons.css b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/font_icons.css new file mode 100644 index 00000000..0aa5b857 --- /dev/null +++ b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/font_icons.css @@ -0,0 +1 @@ +/* font_icons.css is in open source - this empty file prevents 404 error in browser */ diff --git a/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css new file mode 100644 index 00000000..0bbd8a3f --- /dev/null +++ b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css @@ -0,0 +1,156 @@ +@charset "UTF-8"; + +@font-face { + font-family: "Ionicons"; + src: url("../fonts/ionicons.eot?v=2.0.0"); + src: url("../fonts/ionicons.eot?v=2.0.0#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=2.0.0") format("truetype"), url("../fonts/ionicons.woff?v=2.0.0") format("woff"), url("../fonts/ionicons.svg?v=2.0.0#Ionicons") format("svg"); + font-weight: normal; + font-style: normal; +} + +.ionicons, .icon-arrows-download:before, +.icon-securityalerts-alertL:before, +.icon-controls-add-maximize:before, +.icon-controls-add-maximize-circle:before, .icon-misc-time:before, +.icoSecurityalerts:before, .icon-apps-marketplace:before , +.icon-content-grid:before, .icon-documents-archive:before, +.icon-arrows-vertical-arrow-down:before, .icoArrows-download:before, +.icoArrows-incoming-call:before, .icon-arrows-outgoing-call:before, +.icon-arrows-upload:before, .icon-arrows-straight-arrow:before, +.icoArrows-vertical-arrow:before, .icon-people-userbookmark:before, +.icon-controls-check:before, .icon-chevron-down:before, +.icon-controls-down:before, .icon-controls-left:before, +.icon-controls-right:before, .icon-chevron-up:before, +.icoDocuments-report:before, .icon-edit:before, .icon-misc-pen:before, +.icon-controls-up:before, .icon-overview:before, +.icon-settings:before, .icon-building-home:before, +.icon-documents-book:before, .icoDocuments-book-outline:before, +.icoDocuments-bookmarks:before, +.icoDocuments-bookmarks-outline:before, .icon-add-widget:before , +.icon-documents-copy:before, .icon-content-flag:before, +.icon-primary-accordion-minus:before, .icon-misc-piechart:before, +.icon-misc-piechart-outline:before, +.icon-primary-accordion-plus:before, .icon-star:before, +.icon-building-door:before, .icon-content-gridguide:before, +.icon-user:before, .icon-people-oneperson:before, +.icon-people-oneperson-add:before, +.icon-people-oneperson-stalker:before, .icon-controls-pointer:before, +.icon-arrows-replay-restart:before, .icon-content-star:before, +.icon-misc-trash:before, .icon-arrows-upload:before, +.icon-controls-upPRIMARY, .ion-navicon +{ + display: inline-block; + font-family: "Ionicons"; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + text-rendering: auto; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: + grayscale; +} + +.icoSecurityalerts-alert:before { content: "\f100"; } + +.icon-arrows-download:before { content: "\f41f"; } + +.icon-controls-add-maximize:before { content: "\f2c7"; } + +.icon-controls-add-maximize-circle:before { content: "\f359"; } + +.icon-misc-time:before { content: "\f35a"; } + +.icoSecurityalerts:before { content: "\f35b"; } + +.icon-content-grid:before { content: "\f35c"; } + +.icon-documents-archive:before { content: "\f2c9"; } + +.icon-arrows-vertical-arrow-down:before { content: "\f35d"; } + +.icon-arrows-download:before { content: "\f35e"; } + +.icon-arrows-incoming-call:before { content: "\f360"; } + +.icoArrows-outgoing-call:before { content: "\f362"; } + +.icoArrows-upload:before { content: "\f364"; } + +.icoArrows-straight-arrow:before { content: "\f30f"; } + +.icon-arrows-vertical-arrow:before { content: "\f366"; } + +.icon-people-userbookmark:before { content: "\f39f"; } + +.icon-controls-check:before { content: "\f121"; } + +.icon-chevron-down:before { content: "\f123"; } + +.icon-controls-left:before { content: "\f124"; } + +.icon-controls-right:before { content: "\f125"; } + +.icon-chevron-up:before { content: "\f126"; } + +.icoDocuments-report:before { content: "\f274"; } + +.icon-overview:before { content: "\f133"; } + +.icon-controls-down:before { content: "\f3d0"; } + +.icon-controls-up:before { content: "\f3d8"; } + +.icon-documents-book:before { content: "\f3e8"; } + +.icoDocuments-book-outline:before { content: "\f3e7"; } + +.icoDocuments-bookmarks:before { content: "\f3ea"; } + +.icoDocuments-bookmarks-outline:before { content: "\f3e9"; } + +.icon-documents-copy:before { content: "\f41c"; } + +.icon-content-flag:before { content: "\f42d"; } + +.icon-primary-accordion-minus:before { content: "\f463"; } + +.icon-misc-piechart:before { content: "\f484"; } + +.icon-misc-piechart-outline:before { content: "\f483"; } + +.icon-primary-accordion-plus:before { content: "\f48a"; } + +.icon-building-door:before { content: "\f29f"; } + +.icon-content-gridguide:before { content: "\f20d"; } + +.icon-people-oneperson:before { content: "\f213"; } + +.icon-people-oneperson-add:before { content: "\f211"; } + +.icon-people-oneperson-stalker:before { content: "\f212"; } + +.icon-arrows-replay-restart:before { content: "\f21c"; } + +.icon-misc-trash:before { content: "\f252"; } + +.icon-arrows-upload:before { content: "\f255"; } + +.icon-user:before { content: "\f213"; } + +.icon-star:before { content: "\f4b3"; } + +.icon-edit:before { content: "\f2bf"; } + +.icon-settings:before { content: "\f13d"; } + +.icon-apps-marketplace:before { content: "\f35c"; } + +.icon-add-widget:before { content: "\f3f0"; } + +.icon-controls-upPRIMARY:before { content: "\f3d8"; } + +.ion-navicon:before { content: "\f20e"; } diff --git a/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ionicons.css b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ionicons.css new file mode 100644 index 00000000..885aa6bd --- /dev/null +++ b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ionicons.css @@ -0,0 +1,1480 @@ +@charset "UTF-8"; +/*! + Ionicons, v2.0.0 + Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ + https://twitter.com/benjsperry https://twitter.com/ionicframework + MIT License: https://github.com/driftyco/ionicons + + Android-style icons originally built by Google’s + Material Design Icons: https://github.com/google/material-design-icons + used under CC BY http://creativecommons.org/licenses/by/4.0/ + Modified icons to fit ionicon’s grid from original. +*/ +@font-face { font-family: "Ionicons"; src: url("../fonts/ionicons.eot?v=2.0.0"); src: url("../fonts/ionicons.eot?v=2.0.0#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=2.0.0") format("truetype"), url("../fonts/ionicons.woff?v=2.0.0") format("woff"), url("../fonts/ionicons.svg?v=2.0.0#Ionicons") format("svg"); font-weight: normal; font-style: normal; } +.ion, .ionicons, .ion-alert:before, .ion-alert-circled:before, .ion-android-add:before, .ion-android-add-circle:before, .ion-android-alarm-clock:before, .ion-android-alert:before, .ion-android-apps:before, .ion-android-archive:before, .ion-android-arrow-back:before, .ion-android-arrow-down:before, .ion-android-arrow-dropdown:before, .ion-android-arrow-dropdown-circle:before, .ion-android-arrow-dropleft:before, .ion-android-arrow-dropleft-circle:before, .ion-android-arrow-dropright:before, .ion-android-arrow-dropright-circle:before, .ion-android-arrow-dropup:before, .ion-android-arrow-dropup-circle:before, .ion-android-arrow-forward:before, .ion-android-arrow-up:before, .ion-android-attach:before, .ion-android-bar:before, .ion-android-bicycle:before, .ion-android-boat:before, .ion-android-bookmark:before, .ion-android-bulb:before, .ion-android-bus:before, .ion-android-calendar:before, .ion-android-call:before, .ion-android-camera:before, .ion-android-cancel:before, .ion-android-car:before, .ion-android-cart:before, .ion-android-chat:before, .ion-android-checkbox:before, .ion-android-checkbox-blank:before, .ion-android-checkbox-outline:before, .ion-android-checkbox-outline-blank:before, .ion-android-checkmark-circle:before, .ion-android-clipboard:before, .ion-android-close:before, .ion-android-cloud:before, .ion-android-cloud-circle:before, .ion-android-cloud-done:before, .ion-android-cloud-outline:before, .ion-android-color-palette:before, .ion-android-compass:before, .ion-android-contact:before, .ion-android-contacts:before, .ion-android-contract:before, .ion-android-create:before, .ion-android-delete:before, .ion-android-desktop:before, .ion-android-document:before, .ion-android-done:before, .ion-android-done-all:before, .ion-android-download:before, .ion-android-drafts:before, .ion-android-exit:before, .ion-android-expand:before, .ion-android-favorite:before, .ion-android-favorite-outline:before, .ion-android-film:before, .ion-android-folder:before, .ion-android-folder-open:before, .ion-android-funnel:before, .ion-android-globe:before, .ion-android-hand:before, .ion-android-hangout:before, .ion-android-happy:before, .ion-android-home:before, .ion-android-image:before, .ion-android-laptop:before, .ion-android-list:before, .ion-android-locate:before, .ion-android-lock:before, .ion-android-mail:before, .ion-android-map:before, .ion-android-menu:before, .ion-android-microphone:before, .ion-android-microphone-off:before, .ion-android-more-horizontal:before, .ion-android-more-vertical:before, .ion-android-navigate:before, .ion-android-notifications:before, .ion-android-notifications-none:before, .ion-android-notifications-off:before, .ion-android-open:before, .ion-android-options:before, .ion-android-people:before, .ion-android-person:before, .ion-android-person-add:before, .ion-android-phone-landscape:before, .ion-android-phone-portrait:before, .ion-android-pin:before, .ion-android-plane:before, .ion-android-playstore:before, .ion-android-print:before, .ion-android-radio-button-off:before, .ion-android-radio-button-on:before, .ion-android-refresh:before, .ion-android-remove:before, .ion-android-remove-circle:before, .ion-android-restaurant:before, .ion-android-sad:before, .ion-android-search:before, .ion-android-send:before, .ion-android-settings:before, .ion-android-share:before, .ion-android-share-alt:before, .ion-android-star:before, .ion-android-star-half:before, .ion-android-star-outline:before, .ion-android-stopwatch:before, .ion-android-subway:before, .ion-android-sunny:before, .ion-android-sync:before, .ion-android-textsms:before, .ion-android-time:before, .ion-android-train:before, .ion-android-unlock:before, .ion-android-upload:before, .ion-android-volume-down:before, .ion-android-volume-mute:before, .ion-android-volume-off:before, .ion-android-volume-up:before, .ion-android-walk:before, .ion-android-warning:before, .ion-android-watch:before, .ion-android-wifi:before, .ion-aperture:before, .ion-archive:before, .ion-arrow-down-a:before, .ion-arrow-down-b:before, .ion-arrow-down-c:before, .ion-arrow-expand:before, .ion-arrow-graph-down-left:before, .ion-arrow-graph-down-right:before, .ion-arrow-graph-up-left:before, .ion-arrow-graph-up-right:before, .ion-arrow-left-a:before, .ion-arrow-left-b:before, .ion-arrow-left-c:before, .ion-arrow-move:before, .ion-arrow-resize:before, .ion-arrow-return-left:before, .ion-arrow-return-right:before, .ion-arrow-right-a:before, .ion-arrow-right-b:before, .ion-arrow-right-c:before, .ion-arrow-shrink:before, .ion-arrow-swap:before, .ion-arrow-up-a:before, .ion-arrow-up-b:before, .ion-arrow-up-c:before, .ion-asterisk:before, .ion-at:before, .ion-backspace:before, .ion-backspace-outline:before, .ion-bag:before, .ion-battery-charging:before, .ion-battery-empty:before, .ion-battery-full:before, .ion-battery-half:before, .ion-battery-low:before, .ion-beaker:before, .ion-beer:before, .ion-bluetooth:before, .ion-bonfire:before, .ion-bookmark:before, .ion-bowtie:before, .ion-briefcase:before, .ion-bug:before, .ion-calculator:before, .ion-calendar:before, .ion-camera:before, .ion-card:before, .ion-cash:before, .ion-chatbox:before, .ion-chatbox-working:before, .ion-chatboxes:before, .ion-chatbubble:before, .ion-chatbubble-working:before, .ion-chatbubbles:before, .ion-checkmark:before, .ion-checkmark-circled:before, .ion-checkmark-round:before, .ion-chevron-down:before, .ion-chevron-left:before, .ion-chevron-right:before, .ion-chevron-up:before, .ion-clipboard:before, .ion-clock:before, .ion-close:before, .ion-close-circled:before, .ion-close-round:before, .ion-closed-captioning:before, .ion-cloud:before, .ion-code:before, .ion-code-download:before, .ion-code-working:before, .ion-coffee:before, .ion-compass:before, .ion-compose:before, .ion-connection-bars:before, .ion-contrast:before, .ion-crop:before, .ion-cube:before, .ion-disc:before, .ion-document:before, .ion-document-text:before, .ion-drag:before, .ion-earth:before, .ion-easel:before, .ion-edit:before, .ion-egg:before, .ion-eject:before, .ion-email:before, .ion-email-unread:before, .ion-erlenmeyer-flask:before, .ion-erlenmeyer-flask-bubbles:before, .ion-eye:before, .ion-eye-disabled:before, .ion-female:before, .ion-filing:before, .ion-film-marker:before, .ion-fireball:before, .ion-flag:before, .ion-flame:before, .ion-flash:before, .ion-flash-off:before, .ion-folder:before, .ion-fork:before, .ion-fork-repo:before, .ion-forward:before, .ion-funnel:before, .ion-gear-a:before, .ion-gear-b:before, .ion-grid:before, .ion-hammer:before, .ion-happy:before, .ion-happy-outline:before, .ion-headphone:before, .ion-heart:before, .ion-heart-broken:before, .ion-help:before, .ion-help-buoy:before, .ion-help-circled:before, .ion-home:before, .ion-icecream:before, .ion-image:before, .ion-images:before, .ion-information:before, .ion-information-circled:before, .ion-ionic:before, .ion-ios-alarm:before, .ion-ios-alarm-outline:before, .ion-ios-albums:before, .ion-ios-albums-outline:before, .ion-ios-americanfootball:before, .ion-ios-americanfootball-outline:before, .ion-ios-analytics:before, .ion-ios-analytics-outline:before, .ion-ios-arrow-back:before, .ion-ios-arrow-down:before, .ion-ios-arrow-forward:before, .ion-ios-arrow-left:before, .ion-ios-arrow-right:before, .ion-ios-arrow-thin-down:before, .ion-ios-arrow-thin-left:before, .ion-ios-arrow-thin-right:before, .ion-ios-arrow-thin-up:before, .ion-ios-arrow-up:before, .ion-ios-at:before, .ion-ios-at-outline:before, .ion-ios-barcode:before, .ion-ios-barcode-outline:before, .ion-ios-baseball:before, .ion-ios-baseball-outline:before, .ion-ios-basketball:before, .ion-ios-basketball-outline:before, .ion-ios-bell:before, .ion-ios-bell-outline:before, .ion-ios-body:before, .ion-ios-body-outline:before, .ion-ios-bolt:before, .ion-ios-bolt-outline:before, .ion-ios-book:before, .ion-ios-book-outline:before, .ion-ios-bookmarks:before, .ion-ios-bookmarks-outline:before, .ion-ios-box:before, .ion-ios-box-outline:before, .ion-ios-briefcase:before, .ion-ios-briefcase-outline:before, .ion-ios-browsers:before, .ion-ios-browsers-outline:before, .ion-ios-calculator:before, .ion-ios-calculator-outline:before, .ion-ios-calendar:before, .ion-ios-calendar-outline:before, .ion-ios-camera:before, .ion-ios-camera-outline:before, .ion-ios-cart:before, .ion-ios-cart-outline:before, .ion-ios-chatboxes:before, .ion-ios-chatboxes-outline:before, .ion-ios-chatbubble:before, .ion-ios-chatbubble-outline:before, .ion-ios-checkmark:before, .ion-ios-checkmark-empty:before, .ion-ios-checkmark-outline:before, .ion-ios-circle-filled:before, .ion-ios-circle-outline:before, .ion-ios-clock:before, .ion-ios-clock-outline:before, .ion-ios-close:before, .ion-ios-close-empty:before, .ion-ios-close-outline:before, .ion-ios-cloud:before, .ion-ios-cloud-download:before, .ion-ios-cloud-download-outline:before, .ion-ios-cloud-outline:before, .ion-ios-cloud-upload:before, .ion-ios-cloud-upload-outline:before, .ion-ios-cloudy:before, .ion-ios-cloudy-night:before, .ion-ios-cloudy-night-outline:before, .ion-ios-cloudy-outline:before, .ion-ios-cog:before, .ion-ios-cog-outline:before, .ion-ios-color-filter:before, .ion-ios-color-filter-outline:before, .ion-ios-color-wand:before, .ion-ios-color-wand-outline:before, .ion-ios-compose:before, .ion-ios-compose-outline:before, .ion-ios-contact:before, .ion-ios-contact-outline:before, .ion-ios-copy:before, .ion-ios-copy-outline:before, .ion-ios-crop:before, .ion-ios-crop-strong:before, .ion-ios-download:before, .ion-ios-download-outline:before, .ion-ios-drag:before, .ion-ios-email:before, .ion-ios-email-outline:before, .ion-ios-eye:before, .ion-ios-eye-outline:before, .ion-ios-fastforward:before, .ion-ios-fastforward-outline:before, .ion-ios-filing:before, .ion-ios-filing-outline:before, .ion-ios-film:before, .ion-ios-film-outline:before, .ion-ios-flag:before, .ion-ios-flag-outline:before, .ion-ios-flame:before, .ion-ios-flame-outline:before, .ion-ios-flask:before, .ion-ios-flask-outline:before, .ion-ios-flower:before, .ion-ios-flower-outline:before, .ion-ios-folder:before, .ion-ios-folder-outline:before, .ion-ios-football:before, .ion-ios-football-outline:before, .ion-ios-game-controller-a:before, .ion-ios-game-controller-a-outline:before, .ion-ios-game-controller-b:before, .ion-ios-game-controller-b-outline:before, .ion-ios-gear:before, .ion-ios-gear-outline:before, .ion-ios-glasses:before, .ion-ios-glasses-outline:before, .ion-ios-grid-view:before, .ion-ios-grid-view-outline:before, .ion-ios-heart:before, .ion-ios-heart-outline:before, .ion-ios-help:before, .ion-ios-help-empty:before, .ion-ios-help-outline:before, .ion-ios-home:before, .ion-ios-home-outline:before, .ion-ios-infinite:before, .ion-ios-infinite-outline:before, .ion-ios-information:before, .ion-ios-information-empty:before, .ion-ios-information-outline:before, .ion-ios-ionic-outline:before, .ion-ios-keypad:before, .ion-ios-keypad-outline:before, .ion-ios-lightbulb:before, .ion-ios-lightbulb-outline:before, .ion-ios-list:before, .ion-ios-list-outline:before, .ion-ios-location:before, .ion-ios-location-outline:before, .ion-ios-locked:before, .ion-ios-locked-outline:before, .ion-ios-loop:before, .ion-ios-loop-strong:before, .ion-ios-medical:before, .ion-ios-medical-outline:before, .ion-ios-medkit:before, .ion-ios-medkit-outline:before, .ion-ios-mic:before, .ion-ios-mic-off:before, .ion-ios-mic-outline:before, .ion-ios-minus:before, .ion-ios-minus-empty:before, .ion-ios-minus-outline:before, .ion-ios-monitor:before, .ion-ios-monitor-outline:before, .ion-ios-moon:before, .ion-ios-moon-outline:before, .ion-ios-more:before, .ion-ios-more-outline:before, .ion-ios-musical-note:before, .ion-ios-musical-notes:before, .ion-ios-navigate:before, .ion-ios-navigate-outline:before, .ion-ios-nutrition:before, .ion-ios-nutrition-outline:before, .ion-ios-paper:before, .ion-ios-paper-outline:before, .ion-ios-paperplane:before, .ion-ios-paperplane-outline:before, .ion-ios-partlysunny:before, .ion-ios-partlysunny-outline:before, .ion-ios-pause:before, .ion-ios-pause-outline:before, .ion-ios-paw:before, .ion-ios-paw-outline:before, .ion-ios-people:before, .ion-ios-people-outline:before, .ion-ios-person:before, .ion-ios-person-outline:before, .ion-ios-personadd:before, .ion-ios-personadd-outline:before, .ion-ios-photos:before, .ion-ios-photos-outline:before, .ion-ios-pie:before, .ion-ios-pie-outline:before, .ion-ios-pint:before, .ion-ios-pint-outline:before, .ion-ios-play:before, .ion-ios-play-outline:before, .ion-ios-plus:before, .ion-ios-plus-empty:before, .ion-ios-plus-outline:before, .ion-ios-pricetag:before, .ion-ios-pricetag-outline:before, .ion-ios-pricetags:before, .ion-ios-pricetags-outline:before, .ion-ios-printer:before, .ion-ios-printer-outline:before, .ion-ios-pulse:before, .ion-ios-pulse-strong:before, .ion-ios-rainy:before, .ion-ios-rainy-outline:before, .ion-ios-recording:before, .ion-ios-recording-outline:before, .ion-ios-redo:before, .ion-ios-redo-outline:before, .ion-ios-refresh:before, .ion-ios-refresh-empty:before, .ion-ios-refresh-outline:before, .ion-ios-reload:before, .ion-ios-reverse-camera:before, .ion-ios-reverse-camera-outline:before, .ion-ios-rewind:before, .ion-ios-rewind-outline:before, .ion-ios-rose:before, .ion-ios-rose-outline:before, .ion-ios-search:before, .ion-ios-search-strong:before, .ion-ios-settings:before, .ion-ios-settings-strong:before, .ion-ios-shuffle:before, .ion-ios-shuffle-strong:before, .ion-ios-skipbackward:before, .ion-ios-skipbackward-outline:before, .ion-ios-skipforward:before, .ion-ios-skipforward-outline:before, .ion-ios-snowy:before, .ion-ios-speedometer:before, .ion-ios-speedometer-outline:before, .ion-ios-star:before, .ion-ios-star-half:before, .ion-ios-star-outline:before, .ion-ios-stopwatch:before, .ion-ios-stopwatch-outline:before, .ion-ios-sunny:before, .ion-ios-sunny-outline:before, .ion-ios-telephone:before, .ion-ios-telephone-outline:before, .ion-ios-tennisball:before, .ion-ios-tennisball-outline:before, .ion-ios-thunderstorm:before, .ion-ios-thunderstorm-outline:before, .ion-ios-time:before, .ion-ios-time-outline:before, .ion-ios-timer:before, .ion-ios-timer-outline:before, .ion-ios-toggle:before, .ion-ios-toggle-outline:before, .ion-ios-trash:before, .ion-ios-trash-outline:before, .ion-ios-undo:before, .ion-ios-undo-outline:before, .ion-ios-unlocked:before, .ion-ios-unlocked-outline:before, .ion-ios-upload:before, .ion-ios-upload-outline:before, .ion-ios-videocam:before, .ion-ios-videocam-outline:before, .ion-ios-volume-high:before, .ion-ios-volume-low:before, .ion-ios-wineglass:before, .ion-ios-wineglass-outline:before, .ion-ios-world:before, .ion-ios-world-outline:before, .ion-ipad:before, .ion-iphone:before, .ion-ipod:before, .ion-jet:before, .ion-key:before, .ion-knife:before, .ion-laptop:before, .ion-leaf:before, .ion-levels:before, .ion-lightbulb:before, .ion-link:before, .ion-load-a:before, .ion-load-b:before, .ion-load-c:before, .ion-load-d:before, .ion-location:before, .ion-lock-combination:before, .ion-locked:before, .ion-log-in:before, .ion-log-out:before, .ion-loop:before, .ion-magnet:before, .ion-male:before, .ion-man:before, .ion-map:before, .ion-medkit:before, .ion-merge:before, .ion-mic-a:before, .ion-mic-b:before, .ion-mic-c:before, .ion-minus:before, .ion-minus-circled:before, .ion-minus-round:before, .ion-model-s:before, .ion-monitor:before, .ion-more:before, .ion-mouse:before, .ion-music-note:before, .ion-navicon:before, .ion-navicon-round:before, .ion-navigate:before, .ion-network:before, .ion-no-smoking:before, .ion-nuclear:before, .ion-outlet:before, .ion-paintbrush:before, .ion-paintbucket:before, .ion-paper-airplane:before, .ion-paperclip:before, .ion-pause:before, .ion-person:before, .ion-person-add:before, .ion-person-stalker:before, .ion-pie-graph:before, .ion-pin:before, .ion-pinpoint:before, .ion-pizza:before, .ion-plane:before, .ion-planet:before, .ion-play:before, .ion-playstation:before, .ion-plus:before, .ion-plus-circled:before, .ion-plus-round:before, .ion-podium:before, .ion-pound:before, .ion-power:before, .ion-pricetag:before, .ion-pricetags:before, .ion-printer:before, .ion-pull-request:before, .ion-qr-scanner:before, .ion-quote:before, .ion-radio-waves:before, .ion-record:before, .ion-refresh:before, .ion-reply:before, .ion-reply-all:before, .ion-ribbon-a:before, .ion-ribbon-b:before, .ion-sad:before, .ion-sad-outline:before, .ion-scissors:before, .ion-search:before, .ion-settings:before, .ion-share:before, .ion-shuffle:before, .ion-skip-backward:before, .ion-skip-forward:before, .ion-social-android:before, .ion-social-android-outline:before, .ion-social-angular:before, .ion-social-angular-outline:before, .ion-social-apple:before, .ion-social-apple-outline:before, .ion-social-bitcoin:before, .ion-social-bitcoin-outline:before, .ion-social-buffer:before, .ion-social-buffer-outline:before, .ion-social-chrome:before, .ion-social-chrome-outline:before, .ion-social-codepen:before, .ion-social-codepen-outline:before, .ion-social-css3:before, .ion-social-css3-outline:before, .ion-social-designernews:before, .ion-social-designernews-outline:before, .ion-social-dribbble:before, .ion-social-dribbble-outline:before, .ion-social-dropbox:before, .ion-social-dropbox-outline:before, .ion-social-euro:before, .ion-social-euro-outline:before, .ion-social-facebook:before, .ion-social-facebook-outline:before, .ion-social-foursquare:before, .ion-social-foursquare-outline:before, .ion-social-freebsd-devil:before, .ion-social-github:before, .ion-social-github-outline:before, .ion-social-google:before, .ion-social-google-outline:before, .ion-social-googleplus:before, .ion-social-googleplus-outline:before, .ion-social-hackernews:before, .ion-social-hackernews-outline:before, .ion-social-html5:before, .ion-social-html5-outline:before, .ion-social-instagram:before, .ion-social-instagram-outline:before, .ion-social-javascript:before, .ion-social-javascript-outline:before, .ion-social-linkedin:before, .ion-social-linkedin-outline:before, .ion-social-markdown:before, .ion-social-nodejs:before, .ion-social-octocat:before, .ion-social-pinterest:before, .ion-social-pinterest-outline:before, .ion-social-python:before, .ion-social-reddit:before, .ion-social-reddit-outline:before, .ion-social-rss:before, .ion-social-rss-outline:before, .ion-social-sass:before, .ion-social-skype:before, .ion-social-skype-outline:before, .ion-social-snapchat:before, .ion-social-snapchat-outline:before, .ion-social-tumblr:before, .ion-social-tumblr-outline:before, .ion-social-tux:before, .ion-social-twitch:before, .ion-social-twitch-outline:before, .ion-social-twitter:before, .ion-social-twitter-outline:before, .ion-social-usd:before, .ion-social-usd-outline:before, .ion-social-vimeo:before, .ion-social-vimeo-outline:before, .ion-social-whatsapp:before, .ion-social-whatsapp-outline:before, .ion-social-windows:before, .ion-social-windows-outline:before, .ion-social-wordpress:before, .ion-social-wordpress-outline:before, .ion-social-yahoo:before, .ion-social-yahoo-outline:before, .ion-social-yen:before, .ion-social-yen-outline:before, .ion-social-youtube:before, .ion-social-youtube-outline:before, .ion-soup-can:before, .ion-soup-can-outline:before, .ion-speakerphone:before, .ion-speedometer:before, .ion-spoon:before, .ion-star:before, .ion-stats-bars:before, .ion-steam:before, .ion-stop:before, .ion-thermometer:before, .ion-thumbsdown:before, .ion-thumbsup:before, .ion-toggle:before, .ion-toggle-filled:before, .ion-transgender:before, .ion-trash-a:before, .ion-trash-b:before, .ion-trophy:before, .ion-tshirt:before, .ion-tshirt-outline:before, .ion-umbrella:before, .ion-university:before, .ion-unlocked:before, .ion-upload:before, .ion-usb:before, .ion-videocamera:before, .ion-volume-high:before, .ion-volume-low:before, .ion-volume-medium:before, .ion-volume-mute:before, .ion-wand:before, .ion-waterdrop:before, .ion-wifi:before, .ion-wineglass:before, .ion-woman:before, .ion-wrench:before, .ion-xbox:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + +.ion-alert:before { content: "\f101"; } + +.ion-alert-circled:before { content: "\f100"; } + +.ion-android-add:before { content: "\f2c7"; } + +.ion-android-add-circle:before { content: "\f359"; } + +.ion-android-alarm-clock:before { content: "\f35a"; } + +.ion-android-alert:before { content: "\f35b"; } + +.ion-android-apps:before { content: "\f35c"; } + +.ion-android-archive:before { content: "\f2c9"; } + +.ion-android-arrow-back:before { content: "\f2ca"; } + +.ion-android-arrow-down:before { content: "\f35d"; } + +.ion-android-arrow-dropdown:before { content: "\f35f"; } + +.ion-android-arrow-dropdown-circle:before { content: "\f35e"; } + +.ion-android-arrow-dropleft:before { content: "\f361"; } + +.ion-android-arrow-dropleft-circle:before { content: "\f360"; } + +.ion-android-arrow-dropright:before { content: "\f363"; } + +.ion-android-arrow-dropright-circle:before { content: "\f362"; } + +.ion-android-arrow-dropup:before { content: "\f365"; } + +.ion-android-arrow-dropup-circle:before { content: "\f364"; } + +.ion-android-arrow-forward:before { content: "\f30f"; } + +.ion-android-arrow-up:before { content: "\f366"; } + +.ion-android-attach:before { content: "\f367"; } + +.ion-android-bar:before { content: "\f368"; } + +.ion-android-bicycle:before { content: "\f369"; } + +.ion-android-boat:before { content: "\f36a"; } + +.ion-android-bookmark:before { content: "\f36b"; } + +.ion-android-bulb:before { content: "\f36c"; } + +.ion-android-bus:before { content: "\f36d"; } + +.ion-android-calendar:before { content: "\f2d1"; } + +.ion-android-call:before { content: "\f2d2"; } + +.ion-android-camera:before { content: "\f2d3"; } + +.ion-android-cancel:before { content: "\f36e"; } + +.ion-android-car:before { content: "\f36f"; } + +.ion-android-cart:before { content: "\f370"; } + +.ion-android-chat:before { content: "\f2d4"; } + +.ion-android-checkbox:before { content: "\f374"; } + +.ion-android-checkbox-blank:before { content: "\f371"; } + +.ion-android-checkbox-outline:before { content: "\f373"; } + +.ion-android-checkbox-outline-blank:before { content: "\f372"; } + +.ion-android-checkmark-circle:before { content: "\f375"; } + +.ion-android-clipboard:before { content: "\f376"; } + +.ion-android-close:before { content: "\f2d7"; } + +.ion-android-cloud:before { content: "\f37a"; } + +.ion-android-cloud-circle:before { content: "\f377"; } + +.ion-android-cloud-done:before { content: "\f378"; } + +.ion-android-cloud-outline:before { content: "\f379"; } + +.ion-android-color-palette:before { content: "\f37b"; } + +.ion-android-compass:before { content: "\f37c"; } + +.ion-android-contact:before { content: "\f2d8"; } + +.ion-android-contacts:before { content: "\f2d9"; } + +.ion-android-contract:before { content: "\f37d"; } + +.ion-android-create:before { content: "\f37e"; } + +.ion-android-delete:before { content: "\f37f"; } + +.ion-android-desktop:before { content: "\f380"; } + +.ion-android-document:before { content: "\f381"; } + +.ion-android-done:before { content: "\f383"; } + +.ion-android-done-all:before { content: "\f382"; } + +.ion-android-download:before { content: "\f2dd"; } + +.ion-android-drafts:before { content: "\f384"; } + +.ion-android-exit:before { content: "\f385"; } + +.ion-android-expand:before { content: "\f386"; } + +.ion-android-favorite:before { content: "\f388"; } + +.ion-android-favorite-outline:before { content: "\f387"; } + +.ion-android-film:before { content: "\f389"; } + +.ion-android-folder:before { content: "\f2e0"; } + +.ion-android-folder-open:before { content: "\f38a"; } + +.ion-android-funnel:before { content: "\f38b"; } + +.ion-android-globe:before { content: "\f38c"; } + +.ion-android-hand:before { content: "\f2e3"; } + +.ion-android-hangout:before { content: "\f38d"; } + +.ion-android-happy:before { content: "\f38e"; } + +.ion-android-home:before { content: "\f38f"; } + +.ion-android-image:before { content: "\f2e4"; } + +.ion-android-laptop:before { content: "\f390"; } + +.ion-android-list:before { content: "\f391"; } + +.ion-android-locate:before { content: "\f2e9"; } + +.ion-android-lock:before { content: "\f392"; } + +.ion-android-mail:before { content: "\f2eb"; } + +.ion-android-map:before { content: "\f393"; } + +.ion-android-menu:before { content: "\f394"; } + +.ion-android-microphone:before { content: "\f2ec"; } + +.ion-android-microphone-off:before { content: "\f395"; } + +.ion-android-more-horizontal:before { content: "\f396"; } + +.ion-android-more-vertical:before { content: "\f397"; } + +.ion-android-navigate:before { content: "\f398"; } + +.ion-android-notifications:before { content: "\f39b"; } + +.ion-android-notifications-none:before { content: "\f399"; } + +.ion-android-notifications-off:before { content: "\f39a"; } + +.ion-android-open:before { content: "\f39c"; } + +.ion-android-options:before { content: "\f39d"; } + +.ion-android-people:before { content: "\f39e"; } + +.ion-android-person:before { content: "\f3a0"; } + +.ion-android-person-add:before { content: "\f39f"; } + +.ion-android-phone-landscape:before { content: "\f3a1"; } + +.ion-android-phone-portrait:before { content: "\f3a2"; } + +.ion-android-pin:before { content: "\f3a3"; } + +.ion-android-plane:before { content: "\f3a4"; } + +.ion-android-playstore:before { content: "\f2f0"; } + +.ion-android-print:before { content: "\f3a5"; } + +.ion-android-radio-button-off:before { content: "\f3a6"; } + +.ion-android-radio-button-on:before { content: "\f3a7"; } + +.ion-android-refresh:before { content: "\f3a8"; } + +.ion-android-remove:before { content: "\f2f4"; } + +.ion-android-remove-circle:before { content: "\f3a9"; } + +.ion-android-restaurant:before { content: "\f3aa"; } + +.ion-android-sad:before { content: "\f3ab"; } + +.ion-android-search:before { content: "\f2f5"; } + +.ion-android-send:before { content: "\f2f6"; } + +.ion-android-settings:before { content: "\f2f7"; } + +.ion-android-share:before { content: "\f2f8"; } + +.ion-android-share-alt:before { content: "\f3ac"; } + +.ion-android-star:before { content: "\f2fc"; } + +.ion-android-star-half:before { content: "\f3ad"; } + +.ion-android-star-outline:before { content: "\f3ae"; } + +.ion-android-stopwatch:before { content: "\f2fd"; } + +.ion-android-subway:before { content: "\f3af"; } + +.ion-android-sunny:before { content: "\f3b0"; } + +.ion-android-sync:before { content: "\f3b1"; } + +.ion-android-textsms:before { content: "\f3b2"; } + +.ion-android-time:before { content: "\f3b3"; } + +.ion-android-train:before { content: "\f3b4"; } + +.ion-android-unlock:before { content: "\f3b5"; } + +.ion-android-upload:before { content: "\f3b6"; } + +.ion-android-volume-down:before { content: "\f3b7"; } + +.ion-android-volume-mute:before { content: "\f3b8"; } + +.ion-android-volume-off:before { content: "\f3b9"; } + +.ion-android-volume-up:before { content: "\f3ba"; } + +.ion-android-walk:before { content: "\f3bb"; } + +.ion-android-warning:before { content: "\f3bc"; } + +.ion-android-watch:before { content: "\f3bd"; } + +.ion-android-wifi:before { content: "\f305"; } + +.ion-aperture:before { content: "\f313"; } + +.ion-archive:before { content: "\f102"; } + +.ion-arrow-down-a:before { content: "\f103"; } + +.ion-arrow-down-b:before { content: "\f104"; } + +.ion-arrow-down-c:before { content: "\f105"; } + +.ion-arrow-expand:before { content: "\f25e"; } + +.ion-arrow-graph-down-left:before { content: "\f25f"; } + +.ion-arrow-graph-down-right:before { content: "\f260"; } + +.ion-arrow-graph-up-left:before { content: "\f261"; } + +.ion-arrow-graph-up-right:before { content: "\f262"; } + +.ion-arrow-left-a:before { content: "\f106"; } + +.ion-arrow-left-b:before { content: "\f107"; } + +.ion-arrow-left-c:before { content: "\f108"; } + +.ion-arrow-move:before { content: "\f263"; } + +.ion-arrow-resize:before { content: "\f264"; } + +.ion-arrow-return-left:before { content: "\f265"; } + +.ion-arrow-return-right:before { content: "\f266"; } + +.ion-arrow-right-a:before { content: "\f109"; } + +.ion-arrow-right-b:before { content: "\f10a"; } + +.ion-arrow-right-c:before { content: "\f10b"; } + +.ion-arrow-shrink:before { content: "\f267"; } + +.ion-arrow-swap:before { content: "\f268"; } + +.ion-arrow-up-a:before { content: "\f10c"; } + +.ion-arrow-up-b:before { content: "\f10d"; } + +.ion-arrow-up-c:before { content: "\f10e"; } + +.ion-asterisk:before { content: "\f314"; } + +.ion-at:before { content: "\f10f"; } + +.ion-backspace:before { content: "\f3bf"; } + +.ion-backspace-outline:before { content: "\f3be"; } + +.ion-bag:before { content: "\f110"; } + +.ion-battery-charging:before { content: "\f111"; } + +.ion-battery-empty:before { content: "\f112"; } + +.ion-battery-full:before { content: "\f113"; } + +.ion-battery-half:before { content: "\f114"; } + +.ion-battery-low:before { content: "\f115"; } + +.ion-beaker:before { content: "\f269"; } + +.ion-beer:before { content: "\f26a"; } + +.ion-bluetooth:before { content: "\f116"; } + +.ion-bonfire:before { content: "\f315"; } + +.ion-bookmark:before { content: "\f26b"; } + +.ion-bowtie:before { content: "\f3c0"; } + +.ion-briefcase:before { content: "\f26c"; } + +.ion-bug:before { content: "\f2be"; } + +.ion-calculator:before { content: "\f26d"; } + +.ion-calendar:before { content: "\f117"; } + +.ion-camera:before { content: "\f118"; } + +.ion-card:before { content: "\f119"; } + +.ion-cash:before { content: "\f316"; } + +.ion-chatbox:before { content: "\f11b"; } + +.ion-chatbox-working:before { content: "\f11a"; } + +.ion-chatboxes:before { content: "\f11c"; } + +.ion-chatbubble:before { content: "\f11e"; } + +.ion-chatbubble-working:before { content: "\f11d"; } + +.ion-chatbubbles:before { content: "\f11f"; } + +.ion-checkmark:before { content: "\f122"; } + +.ion-checkmark-circled:before { content: "\f120"; } + +.ion-checkmark-round:before { content: "\f121"; } + +.ion-chevron-down:before { content: "\f123"; } + +.ion-chevron-left:before { content: "\f124"; } + +.ion-chevron-right:before { content: "\f125"; } + +.ion-chevron-up:before { content: "\f126"; } + +.ion-clipboard:before { content: "\f127"; } + +.ion-clock:before { content: "\f26e"; } + +.ion-close:before { content: "\f12a"; } + +.ion-close-circled:before { content: "\f128"; } + +.ion-close-round:before { content: "\f129"; } + +.ion-closed-captioning:before { content: "\f317"; } + +.ion-cloud:before { content: "\f12b"; } + +.ion-code:before { content: "\f271"; } + +.ion-code-download:before { content: "\f26f"; } + +.ion-code-working:before { content: "\f270"; } + +.ion-coffee:before { content: "\f272"; } + +.ion-compass:before { content: "\f273"; } + +.ion-compose:before { content: "\f12c"; } + +.ion-connection-bars:before { content: "\f274"; } + +.ion-contrast:before { content: "\f275"; } + +.ion-crop:before { content: "\f3c1"; } + +.ion-cube:before { content: "\f318"; } + +.ion-disc:before { content: "\f12d"; } + +.ion-document:before { content: "\f12f"; } + +.ion-document-text:before { content: "\f12e"; } + +.ion-drag:before { content: "\f130"; } + +.ion-earth:before { content: "\f276"; } + +.ion-easel:before { content: "\f3c2"; } + +.ion-edit:before { content: "\f2bf"; } + +.ion-egg:before { content: "\f277"; } + +.ion-eject:before { content: "\f131"; } + +.ion-email:before { content: "\f132"; } + +.ion-email-unread:before { content: "\f3c3"; } + +.ion-erlenmeyer-flask:before { content: "\f3c5"; } + +.ion-erlenmeyer-flask-bubbles:before { content: "\f3c4"; } + +.ion-eye:before { content: "\f133"; } + +.ion-eye-disabled:before { content: "\f306"; } + +.ion-female:before { content: "\f278"; } + +.ion-filing:before { content: "\f134"; } + +.ion-film-marker:before { content: "\f135"; } + +.ion-fireball:before { content: "\f319"; } + +.ion-flag:before { content: "\f279"; } + +.ion-flame:before { content: "\f31a"; } + +.ion-flash:before { content: "\f137"; } + +.ion-flash-off:before { content: "\f136"; } + +.ion-folder:before { content: "\f139"; } + +.ion-fork:before { content: "\f27a"; } + +.ion-fork-repo:before { content: "\f2c0"; } + +.ion-forward:before { content: "\f13a"; } + +.ion-funnel:before { content: "\f31b"; } + +.ion-gear-a:before { content: "\f13d"; } + +.ion-gear-b:before { content: "\f13e"; } + +.ion-grid:before { content: "\f13f"; } + +.ion-hammer:before { content: "\f27b"; } + +.ion-happy:before { content: "\f31c"; } + +.ion-happy-outline:before { content: "\f3c6"; } + +.ion-headphone:before { content: "\f140"; } + +.ion-heart:before { content: "\f141"; } + +.ion-heart-broken:before { content: "\f31d"; } + +.ion-help:before { content: "\f143"; } + +.ion-help-buoy:before { content: "\f27c"; } + +.ion-help-circled:before { content: "\f142"; } + +.ion-home:before { content: "\f144"; } + +.ion-icecream:before { content: "\f27d"; } + +.ion-image:before { content: "\f147"; } + +.ion-images:before { content: "\f148"; } + +.ion-information:before { content: "\f14a"; } + +.ion-information-circled:before { content: "\f149"; } + +.ion-ionic:before { content: "\f14b"; } + +.ion-ios-alarm:before { content: "\f3c8"; } + +.ion-ios-alarm-outline:before { content: "\f3c7"; } + +.ion-ios-albums:before { content: "\f3ca"; } + +.ion-ios-albums-outline:before { content: "\f3c9"; } + +.ion-ios-americanfootball:before { content: "\f3cc"; } + +.ion-ios-americanfootball-outline:before { content: "\f3cb"; } + +.ion-ios-analytics:before { content: "\f3ce"; } + +.ion-ios-analytics-outline:before { content: "\f3cd"; } + +.ion-ios-arrow-back:before { content: "\f3cf"; } + +.ion-ios-arrow-down:before { content: "\f3d0"; } + +.ion-ios-arrow-forward:before { content: "\f3d1"; } + +.ion-ios-arrow-left:before { content: "\f3d2"; } + +.ion-ios-arrow-right:before { content: "\f3d3"; } + +.ion-ios-arrow-thin-down:before { content: "\f3d4"; } + +.ion-ios-arrow-thin-left:before { content: "\f3d5"; } + +.ion-ios-arrow-thin-right:before { content: "\f3d6"; } + +.ion-ios-arrow-thin-up:before { content: "\f3d7"; } + +.ion-ios-arrow-up:before { content: "\f3d8"; } + +.ion-ios-at:before { content: "\f3da"; } + +.ion-ios-at-outline:before { content: "\f3d9"; } + +.ion-ios-barcode:before { content: "\f3dc"; } + +.ion-ios-barcode-outline:before { content: "\f3db"; } + +.ion-ios-baseball:before { content: "\f3de"; } + +.ion-ios-baseball-outline:before { content: "\f3dd"; } + +.ion-ios-basketball:before { content: "\f3e0"; } + +.ion-ios-basketball-outline:before { content: "\f3df"; } + +.ion-ios-bell:before { content: "\f3e2"; } + +.ion-ios-bell-outline:before { content: "\f3e1"; } + +.ion-ios-body:before { content: "\f3e4"; } + +.ion-ios-body-outline:before { content: "\f3e3"; } + +.ion-ios-bolt:before { content: "\f3e6"; } + +.ion-ios-bolt-outline:before { content: "\f3e5"; } + +.ion-ios-book:before { content: "\f3e8"; } + +.ion-ios-book-outline:before { content: "\f3e7"; } + +.ion-ios-bookmarks:before { content: "\f3ea"; } + +.ion-ios-bookmarks-outline:before { content: "\f3e9"; } + +.ion-ios-box:before { content: "\f3ec"; } + +.ion-ios-box-outline:before { content: "\f3eb"; } + +.ion-ios-briefcase:before { content: "\f3ee"; } + +.ion-ios-briefcase-outline:before { content: "\f3ed"; } + +.ion-ios-browsers:before { content: "\f3f0"; } + +.ion-ios-browsers-outline:before { content: "\f3ef"; } + +.ion-ios-calculator:before { content: "\f3f2"; } + +.ion-ios-calculator-outline:before { content: "\f3f1"; } + +.ion-ios-calendar:before { content: "\f3f4"; } + +.ion-ios-calendar-outline:before { content: "\f3f3"; } + +.ion-ios-camera:before { content: "\f3f6"; } + +.ion-ios-camera-outline:before { content: "\f3f5"; } + +.ion-ios-cart:before { content: "\f3f8"; } + +.ion-ios-cart-outline:before { content: "\f3f7"; } + +.ion-ios-chatboxes:before { content: "\f3fa"; } + +.ion-ios-chatboxes-outline:before { content: "\f3f9"; } + +.ion-ios-chatbubble:before { content: "\f3fc"; } + +.ion-ios-chatbubble-outline:before { content: "\f3fb"; } + +.ion-ios-checkmark:before { content: "\f3ff"; } + +.ion-ios-checkmark-empty:before { content: "\f3fd"; } + +.ion-ios-checkmark-outline:before { content: "\f3fe"; } + +.ion-ios-circle-filled:before { content: "\f400"; } + +.ion-ios-circle-outline:before { content: "\f401"; } + +.ion-ios-clock:before { content: "\f403"; } + +.ion-ios-clock-outline:before { content: "\f402"; } + +.ion-ios-close:before { content: "\f406"; } + +.ion-ios-close-empty:before { content: "\f404"; } + +.ion-ios-close-outline:before { content: "\f405"; } + +.ion-ios-cloud:before { content: "\f40c"; } + +.ion-ios-cloud-download:before { content: "\f408"; } + +.ion-ios-cloud-download-outline:before { content: "\f407"; } + +.ion-ios-cloud-outline:before { content: "\f409"; } + +.ion-ios-cloud-upload:before { content: "\f40b"; } + +.ion-ios-cloud-upload-outline:before { content: "\f40a"; } + +.ion-ios-cloudy:before { content: "\f410"; } + +.ion-ios-cloudy-night:before { content: "\f40e"; } + +.ion-ios-cloudy-night-outline:before { content: "\f40d"; } + +.ion-ios-cloudy-outline:before { content: "\f40f"; } + +.ion-ios-cog:before { content: "\f412"; } + +.ion-ios-cog-outline:before { content: "\f411"; } + +.ion-ios-color-filter:before { content: "\f414"; } + +.ion-ios-color-filter-outline:before { content: "\f413"; } + +.ion-ios-color-wand:before { content: "\f416"; } + +.ion-ios-color-wand-outline:before { content: "\f415"; } + +.ion-ios-compose:before { content: "\f418"; } + +.ion-ios-compose-outline:before { content: "\f417"; } + +.ion-ios-contact:before { content: "\f41a"; } + +.ion-ios-contact-outline:before { content: "\f419"; } + +.ion-ios-copy:before { content: "\f41c"; } + +.ion-ios-copy-outline:before { content: "\f41b"; } + +.ion-ios-crop:before { content: "\f41e"; } + +.ion-ios-crop-strong:before { content: "\f41d"; } + +.ion-ios-download:before { content: "\f420"; } + +.ion-ios-download-outline:before { content: "\f41f"; } + +.ion-ios-drag:before { content: "\f421"; } + +.ion-ios-email:before { content: "\f423"; } + +.ion-ios-email-outline:before { content: "\f422"; } + +.ion-ios-eye:before { content: "\f425"; } + +.ion-ios-eye-outline:before { content: "\f424"; } + +.ion-ios-fastforward:before { content: "\f427"; } + +.ion-ios-fastforward-outline:before { content: "\f426"; } + +.ion-ios-filing:before { content: "\f429"; } + +.ion-ios-filing-outline:before { content: "\f428"; } + +.ion-ios-film:before { content: "\f42b"; } + +.ion-ios-film-outline:before { content: "\f42a"; } + +.ion-ios-flag:before { content: "\f42d"; } + +.ion-ios-flag-outline:before { content: "\f42c"; } + +.ion-ios-flame:before { content: "\f42f"; } + +.ion-ios-flame-outline:before { content: "\f42e"; } + +.ion-ios-flask:before { content: "\f431"; } + +.ion-ios-flask-outline:before { content: "\f430"; } + +.ion-ios-flower:before { content: "\f433"; } + +.ion-ios-flower-outline:before { content: "\f432"; } + +.ion-ios-folder:before { content: "\f435"; } + +.ion-ios-folder-outline:before { content: "\f434"; } + +.ion-ios-football:before { content: "\f437"; } + +.ion-ios-football-outline:before { content: "\f436"; } + +.ion-ios-game-controller-a:before { content: "\f439"; } + +.ion-ios-game-controller-a-outline:before { content: "\f438"; } + +.ion-ios-game-controller-b:before { content: "\f43b"; } + +.ion-ios-game-controller-b-outline:before { content: "\f43a"; } + +.ion-ios-gear:before { content: "\f43d"; } + +.ion-ios-gear-outline:before { content: "\f43c"; } + +.ion-ios-glasses:before { content: "\f43f"; } + +.ion-ios-glasses-outline:before { content: "\f43e"; } + +.ion-ios-grid-view:before { content: "\f441"; } + +.ion-ios-grid-view-outline:before { content: "\f440"; } + +.ion-ios-heart:before { content: "\f443"; } + +.ion-ios-heart-outline:before { content: "\f442"; } + +.ion-ios-help:before { content: "\f446"; } + +.ion-ios-help-empty:before { content: "\f444"; } + +.ion-ios-help-outline:before { content: "\f445"; } + +.ion-ios-home:before { content: "\f448"; } + +.ion-ios-home-outline:before { content: "\f447"; } + +.ion-ios-infinite:before { content: "\f44a"; } + +.ion-ios-infinite-outline:before { content: "\f449"; } + +.ion-ios-information:before { content: "\f44d"; } + +.ion-ios-information-empty:before { content: "\f44b"; } + +.ion-ios-information-outline:before { content: "\f44c"; } + +.ion-ios-ionic-outline:before { content: "\f44e"; } + +.ion-ios-keypad:before { content: "\f450"; } + +.ion-ios-keypad-outline:before { content: "\f44f"; } + +.ion-ios-lightbulb:before { content: "\f452"; } + +.ion-ios-lightbulb-outline:before { content: "\f451"; } + +.ion-ios-list:before { content: "\f454"; } + +.ion-ios-list-outline:before { content: "\f453"; } + +.ion-ios-location:before { content: "\f456"; } + +.ion-ios-location-outline:before { content: "\f455"; } + +.ion-ios-locked:before { content: "\f458"; } + +.ion-ios-locked-outline:before { content: "\f457"; } + +.ion-ios-loop:before { content: "\f45a"; } + +.ion-ios-loop-strong:before { content: "\f459"; } + +.ion-ios-medical:before { content: "\f45c"; } + +.ion-ios-medical-outline:before { content: "\f45b"; } + +.ion-ios-medkit:before { content: "\f45e"; } + +.ion-ios-medkit-outline:before { content: "\f45d"; } + +.ion-ios-mic:before { content: "\f461"; } + +.ion-ios-mic-off:before { content: "\f45f"; } + +.ion-ios-mic-outline:before { content: "\f460"; } + +.ion-ios-minus:before { content: "\f464"; } + +.ion-ios-minus-empty:before { content: "\f462"; } + +.ion-ios-minus-outline:before { content: "\f463"; } + +.ion-ios-monitor:before { content: "\f466"; } + +.ion-ios-monitor-outline:before { content: "\f465"; } + +.ion-ios-moon:before { content: "\f468"; } + +.ion-ios-moon-outline:before { content: "\f467"; } + +.ion-ios-more:before { content: "\f46a"; } + +.ion-ios-more-outline:before { content: "\f469"; } + +.ion-ios-musical-note:before { content: "\f46b"; } + +.ion-ios-musical-notes:before { content: "\f46c"; } + +.ion-ios-navigate:before { content: "\f46e"; } + +.ion-ios-navigate-outline:before { content: "\f46d"; } + +.ion-ios-nutrition:before { content: "\f470"; } + +.ion-ios-nutrition-outline:before { content: "\f46f"; } + +.ion-ios-paper:before { content: "\f472"; } + +.ion-ios-paper-outline:before { content: "\f471"; } + +.ion-ios-paperplane:before { content: "\f474"; } + +.ion-ios-paperplane-outline:before { content: "\f473"; } + +.ion-ios-partlysunny:before { content: "\f476"; } + +.ion-ios-partlysunny-outline:before { content: "\f475"; } + +.ion-ios-pause:before { content: "\f478"; } + +.ion-ios-pause-outline:before { content: "\f477"; } + +.ion-ios-paw:before { content: "\f47a"; } + +.ion-ios-paw-outline:before { content: "\f479"; } + +.ion-ios-people:before { content: "\f47c"; } + +.ion-ios-people-outline:before { content: "\f47b"; } + +.ion-ios-person:before { content: "\f47e"; } + +.ion-ios-person-outline:before { content: "\f47d"; } + +.ion-ios-personadd:before { content: "\f480"; } + +.ion-ios-personadd-outline:before { content: "\f47f"; } + +.ion-ios-photos:before { content: "\f482"; } + +.ion-ios-photos-outline:before { content: "\f481"; } + +.ion-ios-pie:before { content: "\f484"; } + +.ion-ios-pie-outline:before { content: "\f483"; } + +.ion-ios-pint:before { content: "\f486"; } + +.ion-ios-pint-outline:before { content: "\f485"; } + +.ion-ios-play:before { content: "\f488"; } + +.ion-ios-play-outline:before { content: "\f487"; } + +.ion-ios-plus:before { content: "\f48b"; } + +.ion-ios-plus-empty:before { content: "\f489"; } + +.ion-ios-plus-outline:before { content: "\f48a"; } + +.ion-ios-pricetag:before { content: "\f48d"; } + +.ion-ios-pricetag-outline:before { content: "\f48c"; } + +.ion-ios-pricetags:before { content: "\f48f"; } + +.ion-ios-pricetags-outline:before { content: "\f48e"; } + +.ion-ios-printer:before { content: "\f491"; } + +.ion-ios-printer-outline:before { content: "\f490"; } + +.ion-ios-pulse:before { content: "\f493"; } + +.ion-ios-pulse-strong:before { content: "\f492"; } + +.ion-ios-rainy:before { content: "\f495"; } + +.ion-ios-rainy-outline:before { content: "\f494"; } + +.ion-ios-recording:before { content: "\f497"; } + +.ion-ios-recording-outline:before { content: "\f496"; } + +.ion-ios-redo:before { content: "\f499"; } + +.ion-ios-redo-outline:before { content: "\f498"; } + +.ion-ios-refresh:before { content: "\f49c"; } + +.ion-ios-refresh-empty:before { content: "\f49a"; } + +.ion-ios-refresh-outline:before { content: "\f49b"; } + +.ion-ios-reload:before { content: "\f49d"; } + +.ion-ios-reverse-camera:before { content: "\f49f"; } + +.ion-ios-reverse-camera-outline:before { content: "\f49e"; } + +.ion-ios-rewind:before { content: "\f4a1"; } + +.ion-ios-rewind-outline:before { content: "\f4a0"; } + +.ion-ios-rose:before { content: "\f4a3"; } + +.ion-ios-rose-outline:before { content: "\f4a2"; } + +.ion-ios-search:before { content: "\f4a5"; } + +.ion-ios-search-strong:before { content: "\f4a4"; } + +.ion-ios-settings:before { content: "\f4a7"; } + +.ion-ios-settings-strong:before { content: "\f4a6"; } + +.ion-ios-shuffle:before { content: "\f4a9"; } + +.ion-ios-shuffle-strong:before { content: "\f4a8"; } + +.ion-ios-skipbackward:before { content: "\f4ab"; } + +.ion-ios-skipbackward-outline:before { content: "\f4aa"; } + +.ion-ios-skipforward:before { content: "\f4ad"; } + +.ion-ios-skipforward-outline:before { content: "\f4ac"; } + +.ion-ios-snowy:before { content: "\f4ae"; } + +.ion-ios-speedometer:before { content: "\f4b0"; } + +.ion-ios-speedometer-outline:before { content: "\f4af"; } + +.ion-ios-star:before { content: "\f4b3"; } + +.ion-ios-star-half:before { content: "\f4b1"; } + +.ion-ios-star-outline:before { content: "\f4b2"; } + +.ion-ios-stopwatch:before { content: "\f4b5"; } + +.ion-ios-stopwatch-outline:before { content: "\f4b4"; } + +.ion-ios-sunny:before { content: "\f4b7"; } + +.ion-ios-sunny-outline:before { content: "\f4b6"; } + +.ion-ios-telephone:before { content: "\f4b9"; } + +.ion-ios-telephone-outline:before { content: "\f4b8"; } + +.ion-ios-tennisball:before { content: "\f4bb"; } + +.ion-ios-tennisball-outline:before { content: "\f4ba"; } + +.ion-ios-thunderstorm:before { content: "\f4bd"; } + +.ion-ios-thunderstorm-outline:before { content: "\f4bc"; } + +.ion-ios-time:before { content: "\f4bf"; } + +.ion-ios-time-outline:before { content: "\f4be"; } + +.ion-ios-timer:before { content: "\f4c1"; } + +.ion-ios-timer-outline:before { content: "\f4c0"; } + +.ion-ios-toggle:before { content: "\f4c3"; } + +.ion-ios-toggle-outline:before { content: "\f4c2"; } + +.ion-ios-trash:before { content: "\f4c5"; } + +.ion-ios-trash-outline:before { content: "\f4c4"; } + +.ion-ios-undo:before { content: "\f4c7"; } + +.ion-ios-undo-outline:before { content: "\f4c6"; } + +.ion-ios-unlocked:before { content: "\f4c9"; } + +.ion-ios-unlocked-outline:before { content: "\f4c8"; } + +.ion-ios-upload:before { content: "\f4cb"; } + +.ion-ios-upload-outline:before { content: "\f4ca"; } + +.ion-ios-videocam:before { content: "\f4cd"; } + +.ion-ios-videocam-outline:before { content: "\f4cc"; } + +.ion-ios-volume-high:before { content: "\f4ce"; } + +.ion-ios-volume-low:before { content: "\f4cf"; } + +.ion-ios-wineglass:before { content: "\f4d1"; } + +.ion-ios-wineglass-outline:before { content: "\f4d0"; } + +.ion-ios-world:before { content: "\f4d3"; } + +.ion-ios-world-outline:before { content: "\f4d2"; } + +.ion-ipad:before { content: "\f1f9"; } + +.ion-iphone:before { content: "\f1fa"; } + +.ion-ipod:before { content: "\f1fb"; } + +.ion-jet:before { content: "\f295"; } + +.ion-key:before { content: "\f296"; } + +.ion-knife:before { content: "\f297"; } + +.ion-laptop:before { content: "\f1fc"; } + +.ion-leaf:before { content: "\f1fd"; } + +.ion-levels:before { content: "\f298"; } + +.ion-lightbulb:before { content: "\f299"; } + +.ion-link:before { content: "\f1fe"; } + +.ion-load-a:before { content: "\f29a"; } + +.ion-load-b:before { content: "\f29b"; } + +.ion-load-c:before { content: "\f29c"; } + +.ion-load-d:before { content: "\f29d"; } + +.ion-location:before { content: "\f1ff"; } + +.ion-lock-combination:before { content: "\f4d4"; } + +.ion-locked:before { content: "\f200"; } + +.ion-log-in:before { content: "\f29e"; } + +.ion-log-out:before { content: "\f29f"; } + +.ion-loop:before { content: "\f201"; } + +.ion-magnet:before { content: "\f2a0"; } + +.ion-male:before { content: "\f2a1"; } + +.ion-man:before { content: "\f202"; } + +.ion-map:before { content: "\f203"; } + +.ion-medkit:before { content: "\f2a2"; } + +.ion-merge:before { content: "\f33f"; } + +.ion-mic-a:before { content: "\f204"; } + +.ion-mic-b:before { content: "\f205"; } + +.ion-mic-c:before { content: "\f206"; } + +.ion-minus:before { content: "\f209"; } + +.ion-minus-circled:before { content: "\f207"; } + +.ion-minus-round:before { content: "\f208"; } + +.ion-model-s:before { content: "\f2c1"; } + +.ion-monitor:before { content: "\f20a"; } + +.ion-more:before { content: "\f20b"; } + +.ion-mouse:before { content: "\f340"; } + +.ion-music-note:before { content: "\f20c"; } + +.ion-navicon:before { content: "\f20e"; } + +.ion-navicon-round:before { content: "\f20d"; } + +.ion-navigate:before { content: "\f2a3"; } + +.ion-network:before { content: "\f341"; } + +.ion-no-smoking:before { content: "\f2c2"; } + +.ion-nuclear:before { content: "\f2a4"; } + +.ion-outlet:before { content: "\f342"; } + +.ion-paintbrush:before { content: "\f4d5"; } + +.ion-paintbucket:before { content: "\f4d6"; } + +.ion-paper-airplane:before { content: "\f2c3"; } + +.ion-paperclip:before { content: "\f20f"; } + +.ion-pause:before { content: "\f210"; } + +.ion-person:before { content: "\f213"; } + +.ion-person-add:before { content: "\f211"; } + +.ion-person-stalker:before { content: "\f212"; } + +.ion-pie-graph:before { content: "\f2a5"; } + +.ion-pin:before { content: "\f2a6"; } + +.ion-pinpoint:before { content: "\f2a7"; } + +.ion-pizza:before { content: "\f2a8"; } + +.ion-plane:before { content: "\f214"; } + +.ion-planet:before { content: "\f343"; } + +.ion-play:before { content: "\f215"; } + +.ion-playstation:before { content: "\f30a"; } + +.ion-plus:before { content: "\f218"; } + +.ion-plus-circled:before { content: "\f216"; } + +.ion-plus-round:before { content: "\f217"; } + +.ion-podium:before { content: "\f344"; } + +.ion-pound:before { content: "\f219"; } + +.ion-power:before { content: "\f2a9"; } + +.ion-pricetag:before { content: "\f2aa"; } + +.ion-pricetags:before { content: "\f2ab"; } + +.ion-printer:before { content: "\f21a"; } + +.ion-pull-request:before { content: "\f345"; } + +.ion-qr-scanner:before { content: "\f346"; } + +.ion-quote:before { content: "\f347"; } + +.ion-radio-waves:before { content: "\f2ac"; } + +.ion-record:before { content: "\f21b"; } + +.ion-refresh:before { content: "\f21c"; } + +.ion-reply:before { content: "\f21e"; } + +.ion-reply-all:before { content: "\f21d"; } + +.ion-ribbon-a:before { content: "\f348"; } + +.ion-ribbon-b:before { content: "\f349"; } + +.ion-sad:before { content: "\f34a"; } + +.ion-sad-outline:before { content: "\f4d7"; } + +.ion-scissors:before { content: "\f34b"; } + +.ion-search:before { content: "\f21f"; } + +.ion-settings:before { content: "\f2ad"; } + +.ion-share:before { content: "\f220"; } + +.ion-shuffle:before { content: "\f221"; } + +.ion-skip-backward:before { content: "\f222"; } + +.ion-skip-forward:before { content: "\f223"; } + +.ion-social-android:before { content: "\f225"; } + +.ion-social-android-outline:before { content: "\f224"; } + +.ion-social-angular:before { content: "\f4d9"; } + +.ion-social-angular-outline:before { content: "\f4d8"; } + +.ion-social-apple:before { content: "\f227"; } + +.ion-social-apple-outline:before { content: "\f226"; } + +.ion-social-bitcoin:before { content: "\f2af"; } + +.ion-social-bitcoin-outline:before { content: "\f2ae"; } + +.ion-social-buffer:before { content: "\f229"; } + +.ion-social-buffer-outline:before { content: "\f228"; } + +.ion-social-chrome:before { content: "\f4db"; } + +.ion-social-chrome-outline:before { content: "\f4da"; } + +.ion-social-codepen:before { content: "\f4dd"; } + +.ion-social-codepen-outline:before { content: "\f4dc"; } + +.ion-social-css3:before { content: "\f4df"; } + +.ion-social-css3-outline:before { content: "\f4de"; } + +.ion-social-designernews:before { content: "\f22b"; } + +.ion-social-designernews-outline:before { content: "\f22a"; } + +.ion-social-dribbble:before { content: "\f22d"; } + +.ion-social-dribbble-outline:before { content: "\f22c"; } + +.ion-social-dropbox:before { content: "\f22f"; } + +.ion-social-dropbox-outline:before { content: "\f22e"; } + +.ion-social-euro:before { content: "\f4e1"; } + +.ion-social-euro-outline:before { content: "\f4e0"; } + +.ion-social-facebook:before { content: "\f231"; } + +.ion-social-facebook-outline:before { content: "\f230"; } + +.ion-social-foursquare:before { content: "\f34d"; } + +.ion-social-foursquare-outline:before { content: "\f34c"; } + +.ion-social-freebsd-devil:before { content: "\f2c4"; } + +.ion-social-github:before { content: "\f233"; } + +.ion-social-github-outline:before { content: "\f232"; } + +.ion-social-google:before { content: "\f34f"; } + +.ion-social-google-outline:before { content: "\f34e"; } + +.ion-social-googleplus:before { content: "\f235"; } + +.ion-social-googleplus-outline:before { content: "\f234"; } + +.ion-social-hackernews:before { content: "\f237"; } + +.ion-social-hackernews-outline:before { content: "\f236"; } + +.ion-social-html5:before { content: "\f4e3"; } + +.ion-social-html5-outline:before { content: "\f4e2"; } + +.ion-social-instagram:before { content: "\f351"; } + +.ion-social-instagram-outline:before { content: "\f350"; } + +.ion-social-javascript:before { content: "\f4e5"; } + +.ion-social-javascript-outline:before { content: "\f4e4"; } + +.ion-social-linkedin:before { content: "\f239"; } + +.ion-social-linkedin-outline:before { content: "\f238"; } + +.ion-social-markdown:before { content: "\f4e6"; } + +.ion-social-nodejs:before { content: "\f4e7"; } + +.ion-social-octocat:before { content: "\f4e8"; } + +.ion-social-pinterest:before { content: "\f2b1"; } + +.ion-social-pinterest-outline:before { content: "\f2b0"; } + +.ion-social-python:before { content: "\f4e9"; } + +.ion-social-reddit:before { content: "\f23b"; } + +.ion-social-reddit-outline:before { content: "\f23a"; } + +.ion-social-rss:before { content: "\f23d"; } + +.ion-social-rss-outline:before { content: "\f23c"; } + +.ion-social-sass:before { content: "\f4ea"; } + +.ion-social-skype:before { content: "\f23f"; } + +.ion-social-skype-outline:before { content: "\f23e"; } + +.ion-social-snapchat:before { content: "\f4ec"; } + +.ion-social-snapchat-outline:before { content: "\f4eb"; } + +.ion-social-tumblr:before { content: "\f241"; } + +.ion-social-tumblr-outline:before { content: "\f240"; } + +.ion-social-tux:before { content: "\f2c5"; } + +.ion-social-twitch:before { content: "\f4ee"; } + +.ion-social-twitch-outline:before { content: "\f4ed"; } + +.ion-social-twitter:before { content: "\f243"; } + +.ion-social-twitter-outline:before { content: "\f242"; } + +.ion-social-usd:before { content: "\f353"; } + +.ion-social-usd-outline:before { content: "\f352"; } + +.ion-social-vimeo:before { content: "\f245"; } + +.ion-social-vimeo-outline:before { content: "\f244"; } + +.ion-social-whatsapp:before { content: "\f4f0"; } + +.ion-social-whatsapp-outline:before { content: "\f4ef"; } + +.ion-social-windows:before { content: "\f247"; } + +.ion-social-windows-outline:before { content: "\f246"; } + +.ion-social-wordpress:before { content: "\f249"; } + +.ion-social-wordpress-outline:before { content: "\f248"; } + +.ion-social-yahoo:before { content: "\f24b"; } + +.ion-social-yahoo-outline:before { content: "\f24a"; } + +.ion-social-yen:before { content: "\f4f2"; } + +.ion-social-yen-outline:before { content: "\f4f1"; } + +.ion-social-youtube:before { content: "\f24d"; } + +.ion-social-youtube-outline:before { content: "\f24c"; } + +.ion-soup-can:before { content: "\f4f4"; } + +.ion-soup-can-outline:before { content: "\f4f3"; } + +.ion-speakerphone:before { content: "\f2b2"; } + +.ion-speedometer:before { content: "\f2b3"; } + +.ion-spoon:before { content: "\f2b4"; } + +.ion-star:before { content: "\f24e"; } + +.ion-stats-bars:before { content: "\f2b5"; } + +.ion-steam:before { content: "\f30b"; } + +.ion-stop:before { content: "\f24f"; } + +.ion-thermometer:before { content: "\f2b6"; } + +.ion-thumbsdown:before { content: "\f250"; } + +.ion-thumbsup:before { content: "\f251"; } + +.ion-toggle:before { content: "\f355"; } + +.ion-toggle-filled:before { content: "\f354"; } + +.ion-transgender:before { content: "\f4f5"; } + +.ion-trash-a:before { content: "\f252"; } + +.ion-trash-b:before { content: "\f253"; } + +.ion-trophy:before { content: "\f356"; } + +.ion-tshirt:before { content: "\f4f7"; } + +.ion-tshirt-outline:before { content: "\f4f6"; } + +.ion-umbrella:before { content: "\f2b7"; } + +.ion-university:before { content: "\f357"; } + +.ion-unlocked:before { content: "\f254"; } + +.ion-upload:before { content: "\f255"; } + +.ion-usb:before { content: "\f2b8"; } + +.ion-videocamera:before { content: "\f256"; } + +.ion-volume-high:before { content: "\f257"; } + +.ion-volume-low:before { content: "\f258"; } + +.ion-volume-medium:before { content: "\f259"; } + +.ion-volume-mute:before { content: "\f25a"; } + +.ion-wand:before { content: "\f358"; } + +.ion-waterdrop:before { content: "\f25b"; } + +.ion-wifi:before { content: "\f25c"; } + +.ion-wineglass:before { content: "\f2b9"; } + +.ion-woman:before { content: "\f25d"; } + +.ion-wrench:before { content: "\f2ba"; } + +.ion-xbox:before { content: "\f30c"; } diff --git a/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.eot b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.eot new file mode 100644 index 00000000..92a3f20a Binary files /dev/null and b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.eot differ diff --git a/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.svg b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.svg new file mode 100644 index 00000000..49fc8f36 --- /dev/null +++ b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.svg @@ -0,0 +1,2230 @@ + + + + + +Created by FontForge 20120731 at Thu Dec 4 09:51:48 2014 + By Adam Bradley +Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.ttf b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.ttf new file mode 100644 index 00000000..c4e46324 Binary files /dev/null and b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.ttf differ diff --git a/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.woff b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.woff new file mode 100644 index 00000000..5f3a14e0 Binary files /dev/null and b/ecomp-portal-BE-os/src/main/webapp/app/fusion/external/ds2/css/fonts/ionicons.woff differ diff --git a/ecomp-portal-BE-os/src/main/webapp/index.jsp b/ecomp-portal-BE-os/src/main/webapp/index.jsp index 2811bb4b..2ccd977a 100644 --- a/ecomp-portal-BE-os/src/main/webapp/index.jsp +++ b/ecomp-portal-BE-os/src/main/webapp/index.jsp @@ -1,41 +1,41 @@ -<%-- - ================================================================================ - ECOMP Portal - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ================================================================================ - --%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> - -<%-- Redirected because we can't set the welcome page to a virtual URL. --%> -<%-- - --%> - - - ecompportal-BE index.jsp - - -

ECOMP Portal Core

- This is the ecompportal-BE application, page index.jsp. - - <% - - response.sendRedirect("welcome.htm"); - - %> - - - - +<%-- + ================================================================================ + ECOMP Portal + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ================================================================================ + --%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<%-- Redirected because we can't set the welcome page to a virtual URL. --%> +<%-- + --%> + + + ecompportal-BE index.jsp + + +

ECOMP Portal Core

+ This is the ecompportal-BE application, page index.jsp. + + <% + + response.sendRedirect("welcome.htm"); + + %> + + + + diff --git a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestClient.java b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestClient.java index 49686c80..c3ca2430 100644 --- a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestClient.java +++ b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestClient.java @@ -1,280 +1,280 @@ -/*- - * ================================================================================ - * ECOMP Portal - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ================================================================================ - */ -package org.openecomp.portalapp.portal.controller; - -import java.net.URI; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.SSLContext; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.Consts; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.ssl.SSLContexts; -import org.apache.http.ssl.TrustStrategy; -import org.apache.http.util.EntityUtils; -/** - * Provides reusable features for test cases to get or post from an REST - * endpoint, allowing use of HTTPS connections to servers that use self-signed - * certificates. - */ -public class SharedContextRestClient { - - private static final Log logger = LogFactory.getLog(SharedContextRestClient.class); - - /** - * Convenience method that builds and sends a GET request using properties - * to build the URI and populate header with credentials. - * - * @param task - * last component(s) of REST endpoint name; e.g., "get". - * @param contextId - * @param contextKey - * @return JSON string fetched - * @throws Exception - * if the HTTP response code is anything other than OK. - */ - public static String getJson(final SharedContextTestProperties properties, final String task, - final String contextId, final String contextKey) throws Exception { - String requestPath = '/' + properties.getProperty(SharedContextTestProperties.APPNAME) // - + '/' + properties.getProperty(SharedContextTestProperties.RESTPATH) // - + '/' + task; - return getJson(properties.getProperty(SharedContextTestProperties.HOSTNAME), // - properties.getProperty(SharedContextTestProperties.PORT, -1), // - properties.getProperty(SharedContextTestProperties.SECURE, true), // - properties.getProperty(SharedContextTestProperties.UEBKEY), // - properties.getProperty(SharedContextTestProperties.USERNAME), // - properties.getProperty(SharedContextTestProperties.PASSWORD), requestPath, // - contextId, // - contextKey); - } - - /** - * Constructs and sends a GET request using the specified values. - * - * @param hostname - * @param port - * ignored if negative - * @param secure - * If true, uses https; else http. - * @param headerUebkey - * @param headerUsername - * @param headerPassword - * @param requestPath - * full path of the REST endpoint - * @param contextId - * @param contextKey - * Ignored if null - * @return JSON result - */ - public static String getJson(final String hostname, final int port, boolean secure, final String headerUebkey, - final String headerUsername, final String headerPassword, final String requestPath, final String contextId, - final String contextKey) throws Exception { - - URIBuilder uriBuilder = new URIBuilder(); - if (secure) - uriBuilder.setScheme("https"); - else - uriBuilder.setScheme("http"); - uriBuilder.setHost(hostname); - if (port > 0) - uriBuilder.setPort(port); - uriBuilder.setPath(requestPath); - uriBuilder.addParameter("context_id", contextId); - if (contextKey != null) - uriBuilder.addParameter("ckey", contextKey); - final URI uri = uriBuilder.build(); - - CloseableHttpClient httpClient; - if (secure) { - // Tell HttpClient to accept any server certificate for HTTPS. - // http://stackoverflow.com/questions/24720013/apache-http-client-ssl-certificate-error - SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() { - @Override - public boolean isTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - return true; - } - }).build(); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, - NoopHostnameVerifier.INSTANCE); - httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build(); - } else { - httpClient = HttpClients.createDefault(); - } - - HttpGet httpGet = new HttpGet(uri); - httpGet.setHeader("uebkey", headerUebkey); - httpGet.setHeader("username", headerUsername); - httpGet.setHeader("password", headerPassword); - - String json = null; - CloseableHttpResponse response = null; - try { - logger.debug("GET from " + uri); - response = httpClient.execute(httpGet); - logger.info("Status is " + response.getStatusLine()); - if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) - throw new Exception("Status is " + response.getStatusLine().toString()); - HttpEntity entity = response.getEntity(); - if (entity == null) { - logger.warn("Entity is null!"); - } else { - // entity content length is never set. - // this naively tries to read everything. - json = EntityUtils.toString(entity); - EntityUtils.consume(entity); - } - } finally { - if (response != null) - response.close(); - } - return json; - } - - /** - * Convenience method that builds and sends a POST request using properties - * to build the URI and populate header with credentials. - * - * @param path - * last component(s) of REST endpoint name; e.g., "users" or - * "user/{userid}/roles". - * @return JSON string fetched - * @throws Exception - * if the HTTP response code is anything other than OK. - */ - public static String postJson(final SharedContextTestProperties properties, final String path, final String json) - throws Exception { - String requestPath = '/' + properties.getProperty(SharedContextTestProperties.APPNAME) // - + '/' + properties.getProperty(SharedContextTestProperties.RESTPATH) // - + '/' + path; - return postJson(properties.getProperty(SharedContextTestProperties.HOSTNAME), // - properties.getProperty(SharedContextTestProperties.PORT, -1), // - properties.getProperty(SharedContextTestProperties.SECURE, true), // - properties.getProperty(SharedContextTestProperties.UEBKEY), // - properties.getProperty(SharedContextTestProperties.USERNAME), // - properties.getProperty(SharedContextTestProperties.PASSWORD), // - requestPath, // - json); - } - - /** - * Constructs and sends a POST request using the specified values. - * - * @param hostname - * @param port - * @param secure - * If true, uses https; else http. - * @param requestPath - * full path of the REST endpoint - * @param headerUebkey - * @param headerUsername - * @param headerPassword - * @param json - * Content to post - * @return JSON result - * @throws Exception - */ - public static String postJson(final String hostname, final int port, boolean secure, final String headerUebkey, - final String headerUsername, final String headerPassword, final String requestPath, final String json) - throws Exception { - - URIBuilder builder = new URIBuilder(); - if (secure) - builder.setScheme("https"); - else - builder.setScheme("http"); - builder.setHost(hostname); - if (port > 0) - builder.setPort(port); - builder.setPath(requestPath); - final URI uri = builder.build(); - - CloseableHttpClient httpClient; - if (secure) { - // Tell HttpClient to accept any server certificate for HTTPS. - // http://stackoverflow.com/questions/24720013/apache-http-client-ssl-certificate-error - SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() { - @Override - public boolean isTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - return true; - } - }).build(); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, - NoopHostnameVerifier.INSTANCE); - httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build(); - } else { - httpClient = HttpClients.createDefault(); - } - HttpPost httpPost = new HttpPost(uri); - httpPost.setHeader("uebkey", headerUebkey); - httpPost.setHeader("username", headerUsername); - httpPost.setHeader("password", headerPassword); - - StringEntity postEntity = new StringEntity(json, ContentType.create("application/json", Consts.UTF_8)); - httpPost.setEntity(postEntity); - - String responseJson = null; - CloseableHttpResponse response = null; - try { - logger.debug("POST to " + uri); - response = httpClient.execute(httpPost); - logger.info("Status is " + response.getStatusLine()); - if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) - throw new Exception("Status is " + response.getStatusLine().toString()); - - HttpEntity entity = response.getEntity(); - if (entity == null) { - logger.warn("Entity is null!"); - } else { - long len = entity.getContentLength(); - if (len < 0) - logger.warn("Content length is -1"); - if (len < 2048) { - responseJson = EntityUtils.toString(entity); - logger.debug(responseJson); - } else { - logger.warn("Not implemented - stream content"); - } - EntityUtils.consume(entity); - } - } finally { - if (response != null) - response.close(); - } - return responseJson; - } - -} +/*- + * ================================================================================ + * ECOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +package org.openecomp.portalapp.portal.controller; + +import java.net.URI; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Consts; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; +/** + * Provides reusable features for test cases to get or post from an REST + * endpoint, allowing use of HTTPS connections to servers that use self-signed + * certificates. + */ +public class SharedContextRestClient { + + private static final Log logger = LogFactory.getLog(SharedContextRestClient.class); + + /** + * Convenience method that builds and sends a GET request using properties + * to build the URI and populate header with credentials. + * + * @param task + * last component(s) of REST endpoint name; e.g., "get". + * @param contextId + * @param contextKey + * @return JSON string fetched + * @throws Exception + * if the HTTP response code is anything other than OK. + */ + public static String getJson(final SharedContextTestProperties properties, final String task, + final String contextId, final String contextKey) throws Exception { + String requestPath = '/' + properties.getProperty(SharedContextTestProperties.APPNAME) // + + '/' + properties.getProperty(SharedContextTestProperties.RESTPATH) // + + '/' + task; + return getJson(properties.getProperty(SharedContextTestProperties.HOSTNAME), // + properties.getProperty(SharedContextTestProperties.PORT, -1), // + properties.getProperty(SharedContextTestProperties.SECURE, true), // + properties.getProperty(SharedContextTestProperties.UEBKEY), // + properties.getProperty(SharedContextTestProperties.USERNAME), // + properties.getProperty(SharedContextTestProperties.PASSWORD), requestPath, // + contextId, // + contextKey); + } + + /** + * Constructs and sends a GET request using the specified values. + * + * @param hostname + * @param port + * ignored if negative + * @param secure + * If true, uses https; else http. + * @param headerUebkey + * @param headerUsername + * @param headerPassword + * @param requestPath + * full path of the REST endpoint + * @param contextId + * @param contextKey + * Ignored if null + * @return JSON result + */ + public static String getJson(final String hostname, final int port, boolean secure, final String headerUebkey, + final String headerUsername, final String headerPassword, final String requestPath, final String contextId, + final String contextKey) throws Exception { + + URIBuilder uriBuilder = new URIBuilder(); + if (secure) + uriBuilder.setScheme("https"); + else + uriBuilder.setScheme("http"); + uriBuilder.setHost(hostname); + if (port > 0) + uriBuilder.setPort(port); + uriBuilder.setPath(requestPath); + uriBuilder.addParameter("context_id", contextId); + if (contextKey != null) + uriBuilder.addParameter("ckey", contextKey); + final URI uri = uriBuilder.build(); + + CloseableHttpClient httpClient; + if (secure) { + // Tell HttpClient to accept any server certificate for HTTPS. + // http://stackoverflow.com/questions/24720013/apache-http-client-ssl-certificate-error + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() { + @Override + public boolean isTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException { + return true; + } + }).build(); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, + NoopHostnameVerifier.INSTANCE); + httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build(); + } else { + httpClient = HttpClients.createDefault(); + } + + HttpGet httpGet = new HttpGet(uri); + httpGet.setHeader("uebkey", headerUebkey); + httpGet.setHeader("username", headerUsername); + httpGet.setHeader("password", headerPassword); + + String json = null; + CloseableHttpResponse response = null; + try { + logger.debug("GET from " + uri); + response = httpClient.execute(httpGet); + logger.info("Status is " + response.getStatusLine()); + if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) + throw new Exception("Status is " + response.getStatusLine().toString()); + HttpEntity entity = response.getEntity(); + if (entity == null) { + logger.warn("Entity is null!"); + } else { + // entity content length is never set. + // this naively tries to read everything. + json = EntityUtils.toString(entity); + EntityUtils.consume(entity); + } + } finally { + if (response != null) + response.close(); + } + return json; + } + + /** + * Convenience method that builds and sends a POST request using properties + * to build the URI and populate header with credentials. + * + * @param path + * last component(s) of REST endpoint name; e.g., "users" or + * "user/{userid}/roles". + * @return JSON string fetched + * @throws Exception + * if the HTTP response code is anything other than OK. + */ + public static String postJson(final SharedContextTestProperties properties, final String path, final String json) + throws Exception { + String requestPath = '/' + properties.getProperty(SharedContextTestProperties.APPNAME) // + + '/' + properties.getProperty(SharedContextTestProperties.RESTPATH) // + + '/' + path; + return postJson(properties.getProperty(SharedContextTestProperties.HOSTNAME), // + properties.getProperty(SharedContextTestProperties.PORT, -1), // + properties.getProperty(SharedContextTestProperties.SECURE, true), // + properties.getProperty(SharedContextTestProperties.UEBKEY), // + properties.getProperty(SharedContextTestProperties.USERNAME), // + properties.getProperty(SharedContextTestProperties.PASSWORD), // + requestPath, // + json); + } + + /** + * Constructs and sends a POST request using the specified values. + * + * @param hostname + * @param port + * @param secure + * If true, uses https; else http. + * @param requestPath + * full path of the REST endpoint + * @param headerUebkey + * @param headerUsername + * @param headerPassword + * @param json + * Content to post + * @return JSON result + * @throws Exception + */ + public static String postJson(final String hostname, final int port, boolean secure, final String headerUebkey, + final String headerUsername, final String headerPassword, final String requestPath, final String json) + throws Exception { + + URIBuilder builder = new URIBuilder(); + if (secure) + builder.setScheme("https"); + else + builder.setScheme("http"); + builder.setHost(hostname); + if (port > 0) + builder.setPort(port); + builder.setPath(requestPath); + final URI uri = builder.build(); + + CloseableHttpClient httpClient; + if (secure) { + // Tell HttpClient to accept any server certificate for HTTPS. + // http://stackoverflow.com/questions/24720013/apache-http-client-ssl-certificate-error + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() { + @Override + public boolean isTrusted(final X509Certificate[] chain, final String authType) + throws CertificateException { + return true; + } + }).build(); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, + NoopHostnameVerifier.INSTANCE); + httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build(); + } else { + httpClient = HttpClients.createDefault(); + } + HttpPost httpPost = new HttpPost(uri); + httpPost.setHeader("uebkey", headerUebkey); + httpPost.setHeader("username", headerUsername); + httpPost.setHeader("password", headerPassword); + + StringEntity postEntity = new StringEntity(json, ContentType.create("application/json", Consts.UTF_8)); + httpPost.setEntity(postEntity); + + String responseJson = null; + CloseableHttpResponse response = null; + try { + logger.debug("POST to " + uri); + response = httpClient.execute(httpPost); + logger.info("Status is " + response.getStatusLine()); + if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) + throw new Exception("Status is " + response.getStatusLine().toString()); + + HttpEntity entity = response.getEntity(); + if (entity == null) { + logger.warn("Entity is null!"); + } else { + long len = entity.getContentLength(); + if (len < 0) + logger.warn("Content length is -1"); + if (len < 2048) { + responseJson = EntityUtils.toString(entity); + logger.debug(responseJson); + } else { + logger.warn("Not implemented - stream content"); + } + EntityUtils.consume(entity); + } + } finally { + if (response != null) + response.close(); + } + return responseJson; + } + +} diff --git a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestControllerTest.java b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestControllerTest.java index a7a86e8c..5bb7a456 100644 --- a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestControllerTest.java +++ b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextRestControllerTest.java @@ -1,125 +1,125 @@ -/*- - * ================================================================================ - * ECOMP Portal - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ================================================================================ - */ -package org.openecomp.portalapp.portal.controller; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Assert; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * Tests the endpoints exposed by the Shared Context REST controller in Portal - * Core. - * - * @author clott - */ -public class SharedContextRestControllerTest { - - private final Log logger = LogFactory.getLog(getClass()); - - private final SharedContextTestProperties properties; - - private final String ckey = "ckey"; - private final String cvalue = "cvalue"; - - // Supposed to be a Portal session ID - private final String cxid = UUID.randomUUID().toString(); - - private final String key = "key123"; - private final String value1 = "first value"; - private final String value2 = "second value"; - - public SharedContextRestControllerTest() throws IOException { - properties = new SharedContextTestProperties(); - } - - @SuppressWarnings("unchecked") - //@Test - public void test() throws Exception { - String response = null, val = null; - ObjectMapper mapper = new ObjectMapper(); - Map responseMap, jsonMap; - - logger.info("Get on empty context"); - response = SharedContextRestClient.getJson(properties, "get", cxid, key); - // Should not exist - just generated the UUID - Map responseMap1 = mapper.readValue(response, Map.class); - response = (String) responseMap1.get("response"); - Assert.assertNull(response); - - logger.info("Set a new context"); - response = setContext(cxid, key, value1); - Assert.assertNotNull(response); - responseMap = mapper.readValue(response, Map.class); - String responseValue = (String) responseMap.get("response"); - Assert.assertNotNull(responseValue); - Assert.assertEquals("added", responseValue); - - logger.info("Get existing context"); - response = SharedContextRestClient.getJson(properties, "get", cxid, key); - responseMap = mapper.readValue(response, Map.class); - jsonMap = (Map) responseMap.get("response"); - Assert.assertNotNull(jsonMap); - val = (String) jsonMap.get(cvalue); - Assert.assertEquals(val, value1); - - logger.info("Overwrite exiting context"); - response = setContext(cxid, key, value2); - Assert.assertNotNull(response); - responseMap = mapper.readValue(response, Map.class); - response = (String) responseMap.get("response"); - Assert.assertNotNull(responseValue); - // Assert.assertEquals("replaced", responseValue); - - logger.info("Get existing context to verify overwrite"); - response = SharedContextRestClient.getJson(properties, "get", cxid, key); - responseMap = mapper.readValue(response, Map.class); - jsonMap = (Map) responseMap.get("response"); - Assert.assertNotNull(jsonMap); - val = (String) jsonMap.get(cvalue); - Assert.assertEquals(val, value2); - - logger.info("Delete one context"); - response = SharedContextRestClient.getJson(properties, "remove", cxid, key); - responseMap = mapper.readValue(response, Map.class); - response = (String) responseMap.get("response"); - Assert.assertEquals(response, "removed"); - - logger.info("Clear the context"); - response = SharedContextRestClient.getJson(properties, "clear", cxid, null); - Assert.assertEquals("", response); - } - - private String setContext(String context, String id, String value) throws Exception { - ObjectMapper mapper = new ObjectMapper(); - HashMap stringMap = new HashMap(); - stringMap.put("context_id", cxid); - stringMap.put(ckey, key); - stringMap.put(cvalue, value2); - String json = mapper.writeValueAsString(stringMap); - String response = SharedContextRestClient.postJson(properties, "set", json); - return response; - } -} +/*- + * ================================================================================ + * ECOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +package org.openecomp.portalapp.portal.controller; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Tests the endpoints exposed by the Shared Context REST controller in Portal + * Core. + * + * @author clott + */ +public class SharedContextRestControllerTest { + + private final Log logger = LogFactory.getLog(getClass()); + + private final SharedContextTestProperties properties; + + private final String ckey = "ckey"; + private final String cvalue = "cvalue"; + + // Supposed to be a Portal session ID + private final String cxid = UUID.randomUUID().toString(); + + private final String key = "key123"; + private final String value1 = "first value"; + private final String value2 = "second value"; + + public SharedContextRestControllerTest() throws IOException { + properties = new SharedContextTestProperties(); + } + + @SuppressWarnings("unchecked") + //@Test + public void test() throws Exception { + String response = null, val = null; + ObjectMapper mapper = new ObjectMapper(); + Map responseMap, jsonMap; + + logger.info("Get on empty context"); + response = SharedContextRestClient.getJson(properties, "get", cxid, key); + // Should not exist - just generated the UUID + Map responseMap1 = mapper.readValue(response, Map.class); + response = (String) responseMap1.get("response"); + Assert.assertNull(response); + + logger.info("Set a new context"); + response = setContext(cxid, key, value1); + Assert.assertNotNull(response); + responseMap = mapper.readValue(response, Map.class); + String responseValue = (String) responseMap.get("response"); + Assert.assertNotNull(responseValue); + Assert.assertEquals("added", responseValue); + + logger.info("Get existing context"); + response = SharedContextRestClient.getJson(properties, "get", cxid, key); + responseMap = mapper.readValue(response, Map.class); + jsonMap = (Map) responseMap.get("response"); + Assert.assertNotNull(jsonMap); + val = (String) jsonMap.get(cvalue); + Assert.assertEquals(val, value1); + + logger.info("Overwrite exiting context"); + response = setContext(cxid, key, value2); + Assert.assertNotNull(response); + responseMap = mapper.readValue(response, Map.class); + response = (String) responseMap.get("response"); + Assert.assertNotNull(responseValue); + // Assert.assertEquals("replaced", responseValue); + + logger.info("Get existing context to verify overwrite"); + response = SharedContextRestClient.getJson(properties, "get", cxid, key); + responseMap = mapper.readValue(response, Map.class); + jsonMap = (Map) responseMap.get("response"); + Assert.assertNotNull(jsonMap); + val = (String) jsonMap.get(cvalue); + Assert.assertEquals(val, value2); + + logger.info("Delete one context"); + response = SharedContextRestClient.getJson(properties, "remove", cxid, key); + responseMap = mapper.readValue(response, Map.class); + response = (String) responseMap.get("response"); + Assert.assertEquals(response, "removed"); + + logger.info("Clear the context"); + response = SharedContextRestClient.getJson(properties, "clear", cxid, null); + Assert.assertEquals("", response); + } + + private String setContext(String context, String id, String value) throws Exception { + ObjectMapper mapper = new ObjectMapper(); + HashMap stringMap = new HashMap(); + stringMap.put("context_id", cxid); + stringMap.put(ckey, key); + stringMap.put(cvalue, value2); + String json = mapper.writeValueAsString(stringMap); + String response = SharedContextRestClient.postJson(properties, "set", json); + return response; + } +} diff --git a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextTestProperties.java b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextTestProperties.java index baed554b..9344150f 100644 --- a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextTestProperties.java +++ b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/SharedContextTestProperties.java @@ -1,81 +1,81 @@ -/*- - * ================================================================================ - * ECOMP Portal - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ================================================================================ - */ -package org.openecomp.portalapp.portal.controller; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -/** - * Trivial extension of Properties that populates itself from a known source. - */ -public class SharedContextTestProperties extends Properties { - - private static final long serialVersionUID = -4064100267979036550L; - - // property names - public static final String HOSTNAME = "hostname"; - public static final String PORT = "port"; - public static final String SECURE = "secure"; - public static final String APPNAME = "appname"; - public static final String RESTPATH = "restpath"; - public static final String UEBKEY = "uebkey"; - public static final String USERNAME = "username"; - public static final String PASSWORD = "password"; - - /** - * Expected on the classpath - */ - private static final String propertiesFileName = "shared-context-test.properties"; - - /** - * Constructor populates itself from properties file found in same package. - * - * @throws Exception - */ - public SharedContextTestProperties() throws IOException { - InputStream inStream = getClass().getResourceAsStream(propertiesFileName); - if (inStream == null) - throw new IOException("Failed to find file on classpath: " + propertiesFileName); - super.load(inStream); - inStream.close(); - } - - public int getProperty(final String name, final int defVal) throws NumberFormatException { - String prop = getProperty(name); - if (prop == null) - return defVal; - return Integer.parseInt(prop); - } - - public boolean getProperty(final String name, final boolean defVal) { - String prop = getProperty(name); - if (prop == null) - return false; - return Boolean.parseBoolean(prop); - } - - // Test this class - public static void main(String[] args) throws Exception { - SharedContextTestProperties p = new SharedContextTestProperties(); - System.out.println("Property " + SharedContextTestProperties.HOSTNAME + " = " - + p.getProperty(SharedContextTestProperties.HOSTNAME)); - } -} +/*- + * ================================================================================ + * ECOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +package org.openecomp.portalapp.portal.controller; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * Trivial extension of Properties that populates itself from a known source. + */ +public class SharedContextTestProperties extends Properties { + + private static final long serialVersionUID = -4064100267979036550L; + + // property names + public static final String HOSTNAME = "hostname"; + public static final String PORT = "port"; + public static final String SECURE = "secure"; + public static final String APPNAME = "appname"; + public static final String RESTPATH = "restpath"; + public static final String UEBKEY = "uebkey"; + public static final String USERNAME = "username"; + public static final String PASSWORD = "password"; + + /** + * Expected on the classpath + */ + private static final String propertiesFileName = "shared-context-test.properties"; + + /** + * Constructor populates itself from properties file found in same package. + * + * @throws Exception + */ + public SharedContextTestProperties() throws IOException { + InputStream inStream = getClass().getResourceAsStream(propertiesFileName); + if (inStream == null) + throw new IOException("Failed to find file on classpath: " + propertiesFileName); + super.load(inStream); + inStream.close(); + } + + public int getProperty(final String name, final int defVal) throws NumberFormatException { + String prop = getProperty(name); + if (prop == null) + return defVal; + return Integer.parseInt(prop); + } + + public boolean getProperty(final String name, final boolean defVal) { + String prop = getProperty(name); + if (prop == null) + return false; + return Boolean.parseBoolean(prop); + } + + // Test this class + public static void main(String[] args) throws Exception { + SharedContextTestProperties p = new SharedContextTestProperties(); + System.out.println("Property " + SharedContextTestProperties.HOSTNAME + " = " + + p.getProperty(SharedContextTestProperties.HOSTNAME)); + } +} diff --git a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/shared-context-test.properties b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/shared-context-test.properties index 3e44a781..934779d9 100644 --- a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/shared-context-test.properties +++ b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/controller/shared-context-test.properties @@ -1,28 +1,28 @@ -### -# ================================================================================ -# ECOMP Portal -# ================================================================================ -# Copyright (C) 2017 AT&T Intellectual Property -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ================================================================================ -### - -hostname= localhost -# port = 80 -secure = true -appname = ecompportal -restpath = context -uebkey = xgnLrmNmkfCRnIwa -username = Default -password = AppPassword!1 +### +# ================================================================================ +# ECOMP Portal +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ================================================================================ +### + +hostname= localhost +# port = 80 +secure = true +appname = ecompportal +restpath = context +uebkey = xgnLrmNmkfCRnIwa +username = Default +password = AppPassword!1 diff --git a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/listener/HealthMonitorTest.java b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/listener/HealthMonitorTest.java index 6d01f2c9..f87f5bd1 100644 --- a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/listener/HealthMonitorTest.java +++ b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/listener/HealthMonitorTest.java @@ -1,36 +1,36 @@ -/*- - * ================================================================================ - * ECOMP Portal - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ================================================================================ - */ -package org.openecomp.portalapp.portal.listener; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class HealthMonitorTest { - - @Test - public void initialFlagsTest() { - assertEquals(false, HealthMonitor.isBackEndUp()); - assertEquals(false, HealthMonitor.isFrontEndUp()); - assertEquals(false, HealthMonitor.isDatabaseUp()); - assertEquals(false, HealthMonitor.isUebUp()); - } - -} +/*- + * ================================================================================ + * ECOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +package org.openecomp.portalapp.portal.listener; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class HealthMonitorTest { + + @Test + public void initialFlagsTest() { + assertEquals(false, HealthMonitor.isBackEndUp()); + assertEquals(false, HealthMonitor.isFrontEndUp()); + assertEquals(false, HealthMonitor.isDatabaseUp()); + assertEquals(false, HealthMonitor.isUebUp()); + } + +} diff --git a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/utils/EcompPortalUtilsTest.java b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/utils/EcompPortalUtilsTest.java index 4df4f761..b1dd853f 100644 --- a/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/utils/EcompPortalUtilsTest.java +++ b/ecomp-portal-BE-os/src/test/java/org/openecomp/portalapp/portal/utils/EcompPortalUtilsTest.java @@ -1,33 +1,33 @@ -/*- - * ================================================================================ - * ECOMP Portal - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ================================================================================ - */ -package org.openecomp.portalapp.portal.utils; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class EcompPortalUtilsTest { - - - @Test - public void legitimateUserIdFailureTest() { - assertEquals(false, EcompPortalUtils.legitimateUserId("1#@23456")); - } -} +/*- + * ================================================================================ + * ECOMP Portal + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ================================================================================ + */ +package org.openecomp.portalapp.portal.utils; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class EcompPortalUtilsTest { + + + @Test + public void legitimateUserIdFailureTest() { + assertEquals(false, EcompPortalUtils.legitimateUserId("1#@23456")); + } +} -- cgit 1.2.3-korg