/* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ package at.gv.egovernment.moa.id.configuration.struts.action; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import at.gv.egiz.components.configuration.meta.api.ConfigurationStorageException; import at.gv.egiz.eaaf.core.impl.gui.AbstractGUIFormBuilderConfiguration; import at.gv.egiz.eaaf.core.impl.gui.velocity.VelocityProvider; import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; import at.gv.egiz.eaaf.core.impl.utils.Random; import at.gv.egovernment.moa.id.auth.frontend.utils.FormBuildUtils; import at.gv.egovernment.moa.id.commons.config.ConfigurationMigrationUtils; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; import at.gv.egovernment.moa.id.commons.db.dao.config.UserDatabase; import at.gv.egovernment.moa.id.commons.db.dao.config.deprecated.MOAIDConfiguration; import at.gv.egovernment.moa.id.commons.db.dao.config.deprecated.OnlineApplication; import at.gv.egovernment.moa.id.commons.db.dao.config.deprecated.STORK; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.commons.validation.ValidationHelper; import at.gv.egovernment.moa.id.config.webgui.exception.ConfigurationException; import at.gv.egovernment.moa.id.configuration.Constants; import at.gv.egovernment.moa.id.configuration.config.ConfigurationProvider; import at.gv.egovernment.moa.id.configuration.data.oa.IOnlineApplicationData; import at.gv.egovernment.moa.id.configuration.data.oa.OAGeneralConfig; import at.gv.egovernment.moa.id.configuration.data.oa.OAPVP2Config; import at.gv.egovernment.moa.id.configuration.exception.BasicActionException; import at.gv.egovernment.moa.id.configuration.exception.BasicOAActionException; import at.gv.egovernment.moa.id.configuration.helper.LanguageHelper; import at.gv.egovernment.moa.id.configuration.helper.MailHelper; import at.gv.egovernment.moa.util.MiscUtil; import iaik.utils.URLDecoder; import lombok.extern.slf4j.Slf4j; /** * @author tlenz * */ @Slf4j public class BasicOAAction extends BasicAction { private static final long serialVersionUID = 5676123696807646246L; protected LinkedHashMap formList; protected long oaid = -1; private String oaidobj; private boolean newOA; private boolean isMetaDataRefreshRequired = false; private InputStream stream = null; /** * */ public BasicOAAction() { super(); formList = new LinkedHashMap<>(); final OAGeneralConfig generalOA = new OAGeneralConfig(); formList.put(generalOA.getName(), generalOA); } protected OnlineApplication populateOnlineApplicationFromRequest() throws BasicOAActionException { if (!ValidationHelper.validateOAID(oaidobj)) { throw new BasicOAActionException( LanguageHelper.getErrorString("errors.edit.oa.oaid", request), Constants.STRUTS_ERROR); } oaid = Long.valueOf(oaidobj); UserDatabase userdb = null; OnlineApplication onlineapplication = null; if (authUser.isAdmin()) { onlineapplication = configuration.getDbRead().getOnlineApplication(oaid); } else { userdb = configuration.getUserManagement().getUserWithID(authUser.getUserID()); if (!authUser.isAdmin() && userdb.isIsMailAddressVerified() != null && !userdb .isIsMailAddressVerified()) { log.info("Online-Applikation managemant disabled. Mail address is not verified."); throw new BasicOAActionException( LanguageHelper.getErrorString("error.editoa.mailverification", request), Constants.STRUTS_SUCCESS); } // TODO: change to direct Database operation final List oas = userdb.getOnlineApplication(); for (final String oa : oas) { if (oa.equals(oaid)) { onlineapplication = configuration.getDbRead().getOnlineApplication(oaid); break; } } if (onlineapplication == null) { throw new BasicOAActionException( LanguageHelper.getErrorString("errors.edit.oa.oaid", request), Constants.STRUTS_ERROR); } } return onlineapplication; } protected void populateBasicNewOnlineApplicationInformation() { session.setAttribute(Constants.SESSION_OAID, null); setNewOA(true); formID = Random.nextRandom(); session.setAttribute(Constants.SESSION_FORMID, formID); session.setAttribute(Constants.SESSION_BKUFORMPREVIEW, null); } protected OnlineApplication postProcessSaveOnlineApplication(OnlineApplication onlineapplication, boolean persistOA) throws BasicOAActionException { if (onlineapplication == null) { onlineapplication = new OnlineApplication(); onlineapplication.setIsNew(true); onlineapplication.setIsActive(false); if (!authUser.isAdmin()) { onlineapplication.setIsAdminRequired(true); } else { isMetaDataRefreshRequired = true; } } else { onlineapplication.setIsNew(false); if (!authUser.isAdmin() && !onlineapplication.getPublicURLPrefix().equals(getGeneralOA() .getIdentifier())) { onlineapplication.setIsAdminRequired(true); onlineapplication.setIsActive(false); log.info("User with ID " + authUser.getUserID() + " change OA-PublicURLPrefix. Reaktivation is required."); } } if (onlineapplication.isIsAdminRequired() == null || authUser.isAdmin() && getGeneralOA().isActive() && onlineapplication.isIsAdminRequired()) { onlineapplication.setIsAdminRequired(false); isMetaDataRefreshRequired = true; UserDatabase userdb = null; if (onlineapplication.getHjid() != null) { userdb = configuration.getUserManagement().getUsersWithOADBID(onlineapplication.getHjid()); } if (userdb != null && !userdb.isIsAdmin()) { try { MailHelper.sendUserOnlineApplicationActivationMail(userdb.getGivenname(), userdb.getFamilyname(), userdb.getInstitut(), onlineapplication.getPublicURLPrefix(), userdb.getMail()); } catch (final ConfigurationException e) { log.warn("Sending Mail to User " + userdb.getMail() + " failed", e); } } } // save OA configuration final String error = saveOAConfigToDatabase(onlineapplication, persistOA); if (MiscUtil.isNotEmpty(error)) { log.warn("OA configuration can not be stored!"); addActionError(error); formID = Random.nextRandom(); session.setAttribute(Constants.SESSION_FORMID, formID); throw new BasicOAActionException(error, Constants.STRUTS_ERROR_VALIDATION); } // //set metadata reload flag if reload is required // // if (getPvp2OA() != null && getPvp2OA().getMetaDataURL() != null) { // // try { // if (isMetaDataRefreshRequired // || !getPvp2OA().getMetaDataURL().equals(onlineapplication.getAuthComponentOA().getOAPVP2().getMetadataURL()) // || getPvp2OA().getFileUpload() != null // || getPvp2OA().isReLoad()) { // // log.debug("Set PVP2 Metadata refresh flag."); // MOAIDConfiguration moaconfig = configuration.getDbRead().getMOAIDConfiguration(); // moaconfig.setPvp2RefreshItem(new Date()); // ConfigurationDBUtils.saveOrUpdate(moaconfig); // // } // } catch (Throwable e) { // log.info("Found no MetadataURL in OA-Databaseconfig!", e); // } // // } return onlineapplication; } protected OnlineApplication preProcessSaveOnlineApplication() throws BasicOAActionException { try { final Object formidobj = session.getAttribute(Constants.SESSION_FORMID); if (formidobj != null && formidobj instanceof String) { final String formid = (String) formidobj; if (!formid.equals(formID)) { throw new BasicOAActionException( "FormIDs does not match. Some suspect Form is received from user " + authUser.getFamilyName() + authUser.getGivenName() + authUser.getUserID(), Constants.STRUTS_ERROR); } } else { throw new BasicOAActionException( "FormIDs does not match. Some suspect Form is received from user " + authUser.getFamilyName() + authUser.getGivenName() + authUser.getUserID(), Constants.STRUTS_ERROR); } session.setAttribute(Constants.SESSION_FORMID, null); final UserDatabase userdb = configuration.getUserManagement().getUserWithID(authUser.getUserID()); if (!authUser.isAdmin() && userdb.isIsMailAddressVerified() != null && !userdb .isIsMailAddressVerified()) { log.info("Online-Applikation managemant disabled. Mail address is not verified."); throw new BasicOAActionException( LanguageHelper.getErrorString("error.editoa.mailverification", request), Constants.STRUTS_SUCCESS); } OnlineApplication onlineapplication = null; final Long oaid = getOAIDFromSession(); // valid DBID and check entry final OAGeneralConfig oaGeneralForm = (OAGeneralConfig) formList.get(new OAGeneralConfig().getName()); final String oaidentifier = oaGeneralForm.getIdentifier(); if (MiscUtil.isEmpty(oaidentifier)) { log.info("Empty OA identifier"); throw new BasicOAActionException( LanguageHelper.getErrorString("validation.general.oaidentifier.empty", request), Constants.STRUTS_ERROR_VALIDATION); } else { if (!ValidationHelper.validateURL(oaidentifier)) { log.warn("OnlineapplikationIdentifier is not a valid URL: " + oaidentifier); throw new BasicOAActionException( LanguageHelper.getErrorString("validation.general.oaidentifier.valid", new Object[] { ValidationHelper.getNotValidOAIdentifierCharacters() }, request), Constants.STRUTS_ERROR_VALIDATION); } else { if (oaid == -1) { final List oaList = configuration.getDbRead().getAllOnlineApplications(); if (oaList != null) { for (final OnlineApplication el : oaList) { if (el.getPublicURLPrefix().startsWith(oaidentifier)) { onlineapplication = el; } } } if (onlineapplication == null) { onlineapplication = configuration.getDbRead().getOnlineApplication(oaidentifier); } if (onlineapplication != null) { log.info("The OAIdentifier is not unique"); throw new BasicOAActionException( LanguageHelper.getErrorString( "validation.general.oaidentifier.notunique", new Object[] { onlineapplication.getPublicURLPrefix() }, request), Constants.STRUTS_ERROR_VALIDATION); } else { setNewOA(true); } } else { onlineapplication = configuration.getDbRead().getOnlineApplication(oaid); if (!oaidentifier.equals(onlineapplication.getPublicURLPrefix())) { OnlineApplication dbOA = null; final List oaList = configuration.getDbRead().getAllOnlineApplications(); for (final OnlineApplication el : oaList) { if (el.getPublicURLPrefix().startsWith(oaidentifier)) { dbOA = el; } } if (dbOA == null) { dbOA = configuration.getDbRead().getOnlineApplication(oaidentifier); } if (dbOA != null && !dbOA.getHjid().equals(oaid)) { log.info("The OAIdentifier is not unique"); throw new BasicOAActionException( LanguageHelper.getErrorString( "validation.general.oaidentifier.notunique", new Object[] { dbOA.getPublicURLPrefix() }, request), Constants.STRUTS_ERROR_VALIDATION); } } } } } return onlineapplication; } catch (final BasicOAActionException e) { formID = Random.nextRandom(); session.setAttribute(Constants.SESSION_FORMID, formID); throw e; } } protected Long getOAIDFromSession() throws BasicOAActionException { final Object oadbid = request.getSession().getAttribute(Constants.SESSION_OAID); Long oaid = (long) -1; if (oadbid != null) { try { oaid = (Long) oadbid; if (oaid < 0 || oaid > Long.MAX_VALUE) { throw new BasicOAActionException( LanguageHelper.getErrorString("errors.edit.oa.oaid", request), Constants.STRUTS_ERROR); } } catch (final Throwable t) { throw new BasicOAActionException( LanguageHelper.getErrorString("errors.edit.oa.oaid", request), Constants.STRUTS_ERROR); } } return oaid; } protected String preProcessDeleteOnlineApplication() throws BasicOAActionException { try { final Object formidobj = session.getAttribute(Constants.SESSION_FORMID); if (formidobj != null && formidobj instanceof String) { final String formid = (String) formidobj; if (!formid.equals(formID)) { log.warn("FormIDs does not match. Some suspect Form is received from user " + authUser .getFamilyName() + authUser.getGivenName() + authUser.getUserID()); throw new BasicOAActionException( "FormIDs does not match. Some suspect Form is received from user " + authUser.getFamilyName() + authUser.getGivenName() + authUser.getUserID(), Constants.STRUTS_ERROR); } } else { log.warn("FormIDs does not match. Some suspect Form is received from user " + authUser.getFamilyName() + authUser.getGivenName() + authUser.getUserID()); throw new BasicOAActionException( "FormIDs does not match. Some suspect Form is received from user " + authUser.getFamilyName() + authUser.getGivenName() + authUser.getUserID(), Constants.STRUTS_ERROR); } session.setAttribute(Constants.SESSION_FORMID, null); final UserDatabase userdb = configuration.getUserManagement().getUserWithID(authUser.getUserID()); if (!authUser.isAdmin() && userdb.isIsMailAddressVerified() != null && !userdb .isIsMailAddressVerified()) { log.info("Online-Applikation managemant disabled. Mail address is not verified."); throw new BasicOAActionException( LanguageHelper.getErrorString("error.editoa.mailverification", request), Constants.STRUTS_SUCCESS); } final String oaidentifier = getGeneralOA().getIdentifier(); if (MiscUtil.isEmpty(oaidentifier)) { log.info("Empty OA identifier"); formID = Random.nextRandom(); session.setAttribute(Constants.SESSION_FORMID, formID); throw new BasicOAActionException( LanguageHelper.getErrorString("validation.general.oaidentifier.empty", request), Constants.STRUTS_ERROR_VALIDATION); } else { if (ValidationHelper.isValidOAIdentifier(oaidentifier)) { log.warn("IdentificationNumber contains potentail XSS characters: " + oaidentifier); formID = Random.nextRandom(); session.setAttribute(Constants.SESSION_FORMID, formID); throw new BasicOAActionException( LanguageHelper.getErrorString("validation.general.oaidentifier.valid", new Object[] { ValidationHelper.getNotValidOAIdentifierCharacters() }, request), Constants.STRUTS_ERROR_VALIDATION); } } return oaidentifier; } catch (final BasicOAActionException e) { formID = Random.nextRandom(); session.setAttribute(Constants.SESSION_FORMID, formID); throw e; } } private String saveOAConfigToDatabase(OnlineApplication dboa, boolean persistOA) { for (final IOnlineApplicationData form : formList.values()) { form.store(dboa, authUser, request); } try { if (dboa.isIsNew()) { if (!authUser.isAdmin()) { final UserDatabase user = configuration.getUserManagement().getUserWithID(authUser.getUserID()); List useroas = user.getOnlineApplication(); if (useroas == null) { useroas = new ArrayList<>(); } useroas.add(String.valueOf(dboa.getHjid())); configuration.getUserManagement().saveOrUpdate(user); } else { if (persistOA) { save(dboa); } } } else if (persistOA) { save(dboa); } } catch (final MOADatabaseException e) { log.warn("Online-Application can not be stored.", e); return LanguageHelper.getErrorString("error.db.oa.store", request); } return null; } protected void save(OnlineApplication oa) throws MOADatabaseException { try { STORK storkConfig = null; try { final MOAIDConfiguration moaidConfig = ConfigurationProvider.getInstance().getDbRead().getMOAIDConfiguration(); storkConfig = moaidConfig.getAuthComponentGeneral().getForeignIdentities().getSTORK(); } catch (final Exception e) { } log.debug("JaxB to Key/Value configuration transformation started ..."); final Map keyValueConfig = ConfigurationMigrationUtils.convertHyberJaxBOnlineApplicationToKeyValue(oa, storkConfig); log.debug( "JaxB to Key/Value configuration transformation finished. Start Key/Value storage process ..."); String serviceIdentifier = keyValueConfig.get(MOAIDConfigurationConstants.PREFIX_SERVICES); if (MiscUtil.isEmpty(serviceIdentifier)) { log.info("Use default ServiceIdentifier."); serviceIdentifier = MOAIDConfigurationConstants.PREFIX_OA; } if (oa.getHjid() == null) { log.debug("No hjID -> find new Service ID ..."); final String hjID = configuration.getConfigModule().buildArrayIdentifier( MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES + "." + serviceIdentifier, 0, keyValueConfig); log.debug("Find new hjID: " + hjID + " for service: " + oa.getPublicURLPrefix()); oa.setHjid(Long.valueOf(hjID)); } else { // TODO: work-around for old config tool and new key/value configuration // see: NewConfigurationDBRead.java Line 81 // if (oa.getHjid() > 1000000) { // if (serviceIdentifier.equals(MOAIDConfigurationConstants.PREFIX_GATEWAY)) // oa.setHjid(oa.getHjid() - 1000000); // else if (serviceIdentifier.equals(MOAIDConfigurationConstants.PREFIX_IIDP)) // oa.setHjid(oa.getHjid() - 2000000); // else if (serviceIdentifier.equals(MOAIDConfigurationConstants.PREFIX_VIDP)) // oa.setHjid(oa.getHjid() - 3000000); // else // log.warn("Inconsistent state found! Service Identifier for OA found but Hjid is > 1000000."); // // } } final Map absolutKeyValue = KeyValueUtils.makeKeysAbsolut( keyValueConfig, MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES + "." + serviceIdentifier + "." + String.valueOf( oa.getHjid()), MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES); configuration.getConfigModule().storeChanges(absolutKeyValue, null, null); log.info("MOA-ID Service Key/Value configuration successfull stored."); } catch (ConfigurationStorageException | at.gv.egiz.components.configuration.api.ConfigurationException e) { log.warn("MOAID Configuration can not be stored in Database", e); throw new MOADatabaseException(e.getMessage(), e); } } protected boolean delete(OnlineApplication onlineapplication) { try { log.debug("JaxB to Key/Value configuration transformation started ..."); final Map keyValueConfig = ConfigurationMigrationUtils.convertHyberJaxBOnlineApplicationToKeyValue(onlineapplication, null); log.debug( "JaxB to Key/Value configuration transformation finished. Start Key/Value storage process ..."); String serviceIdentifier = keyValueConfig.get(MOAIDConfigurationConstants.PREFIX_SERVICES); if (MiscUtil.isEmpty(serviceIdentifier)) { log.info("Use default ServiceIdentifier."); serviceIdentifier = MOAIDConfigurationConstants.PREFIX_OA; } final String deleteServiceKey = MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES + "." + serviceIdentifier + "." + String.valueOf( onlineapplication.getHjid()) + ".*"; configuration.getConfigModule().storeChanges(null, null, Arrays.asList(new String[] { deleteServiceKey })); log.info("MOA-ID Service Key/Value configuration successfull stored."); return true; } catch (final ConfigurationStorageException e) { log.warn("MOAID Configuration can not be stored in Database", e); } return false; } public String bkuFramePreview() { String preview = null; try { populateBasicInformations(); } catch (final BasicActionException e) { return Constants.STRUTS_ERROR; } InputStream input = null; try { final Object mapobj = session.getAttribute(Constants.SESSION_BKUFORMPREVIEW); if (mapobj != null && mapobj instanceof Map) { final ConfigurationProvider config = ConfigurationProvider.getInstance(); final String templateURL = config.getConfigRootDir() + ConfigurationProvider.HTMLTEMPLATE_DIR + ConfigurationProvider.HTMLTEMPLATE_FILE; final File file = new File(new URI(templateURL)); input = new FileInputStream(file); final String contextpath = config.getMOAIDInstanceURL(); if (MiscUtil.isEmpty(contextpath)) { log.info("NO MOA-ID instance URL configurated."); input.close(); throw new ConfigurationException("No MOA-ID instance configurated"); } // set parameters final Map params = (Map) mapobj; params.put( AbstractGUIFormBuilderConfiguration.PARAM_AUTHCONTEXT, contextpath); request.setCharacterEncoding("UTF-8"); final String module = request.getParameter(Constants.REQUEST_FORMCUSTOM_MODULE); String value = request.getParameter(Constants.REQUEST_FORMCUSTOM_VALUE); if (value != null) { final String[] query = URLDecoder.decode(request.getQueryString()).split("&"); value = query[1].substring("value=".length()); } synchronized (params) { if (MiscUtil.isNotEmpty(module)) { if (params.containsKey(module)) { if (MiscUtil.isNotEmpty(value)) { if (FormBuildUtils.PARAM_FONTFAMILY.contains(module) || FormBuildUtils.PARAM_HEADER_TEXT .contains(module) || value.startsWith("#")) { params.put(module, value); } else { params.put(module, "#" + value); } } else { params.put(module, FormBuildUtils.getDefaultMap().get(module)); } } } } // write preview final VelocityEngine engine = VelocityProvider.getClassPathVelocityEngine(); final VelocityContext context = new VelocityContext(); final Iterator> interator = params.entrySet().iterator(); while (interator.hasNext()) { final Entry el = interator.next(); context.put(el.getKey(), el.getValue()); } final StringWriter writer = new StringWriter(); engine.evaluate(context, writer, "BKUSelection_preview", new BufferedReader(new InputStreamReader(input))); stream = new ByteArrayInputStream(writer.toString().getBytes("UTF-8")); } else { preview = LanguageHelper.getErrorString("error.bkuformpreview.notpossible", request); } } catch (final Exception e) { log.warn("BKUSelection Preview can not be generated.", e); preview = LanguageHelper.getErrorString("error.bkuformpreview.notpossible", request); } if (stream == null && MiscUtil.isNotEmpty(preview)) { try { stream = new ByteArrayInputStream(preview.getBytes("UTF-8")); } catch (final UnsupportedEncodingException e) { e.printStackTrace(); } } return Constants.STRUTS_SUCCESS; } /** * @param oaidobj the oaidobj to set */ public void setOaidobj(String oaidobj) { this.oaidobj = oaidobj; } /** * @return the newOA */ public boolean isNewOA() { return newOA; } /** * @param newOA the newOA to set */ public void setNewOA(boolean newOA) { this.newOA = newOA; } public OAGeneralConfig getGeneralOA() { return (OAGeneralConfig) formList.get(new OAGeneralConfig().getName()); } public void setGeneralOA(OAGeneralConfig generalOA) { formList.put(generalOA.getName(), generalOA); } public OAPVP2Config getPvp2OA() { return (OAPVP2Config) formList.get(new OAPVP2Config().getName()); } public void setPvp2OA(OAPVP2Config pvp2oa) { formList.put(pvp2oa.getName(), pvp2oa); } /** * @return the stream */ public InputStream getStream() { return stream; } }