001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixcore.workflow.app;
021:
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.Map;
025: import java.util.Properties;
026:
027: import de.schlund.pfixcore.generator.IHandler;
028: import de.schlund.pfixcore.generator.IWrapper;
029: import de.schlund.pfixcore.generator.IWrapperParam;
030: import de.schlund.pfixcore.generator.RequestData;
031: import de.schlund.pfixcore.generator.StatusCodeInfo;
032: import de.schlund.pfixcore.workflow.Context;
033: import de.schlund.pfixcore.workflow.StateImpl;
034: import de.schlund.pfixxml.AbstractXMLServlet;
035: import de.schlund.pfixxml.PfixServletRequest;
036: import de.schlund.pfixxml.RequestParam;
037: import de.schlund.pfixxml.ResultDocument;
038: import de.schlund.pfixxml.XMLException;
039: import de.schlund.pfixxml.config.PageRequestConfig;
040:
041: /**
042: * DefaultAuthIWrapperState.java
043: *
044: *
045: * Created: Wed Dec 07 19:23:49 2001
046: *
047: * @author <a href="mailto:jtl@schlund.de">Jens Lautenbacher</a>
048: * @version $Id: DefaultAuthIWrapperState.java 3369 2008-02-22 10:35:46Z smarsching $
049: *
050: *
051: */
052:
053: public class DefaultAuthIWrapperState extends StateImpl {
054: /**
055: * This returns alwys true. I don't know why you'd want to overwrite
056: * this with a different behaviour.
057: *
058: * @param context a <code>Context</code> value
059: * @param req a <code>HttpServletRequest</code> value
060: * @return a <code>boolean</code> value
061: * @exception Exception if an error occurs
062: * @see de.schlund.pfixcore.workflow.State#isAccessible(Context, PfixServletRequest)
063: */
064: @Override
065: public boolean isAccessible(Context context, PfixServletRequest preq)
066: throws Exception {
067: return true;
068: }
069:
070: @Override
071: public boolean needsData(Context context, PfixServletRequest preq)
072: throws Exception {
073: IWrapper userwrapper = getAuthWrapper(context, false);
074: IHandler userhandler = userwrapper.gimmeIHandler();
075:
076: if (userhandler.needsData(context)) {
077: return true;
078: } else {
079: if (preq != null) {
080: RequestData rdata = new RequestDataImpl(context, preq);
081: ArrayList<IWrapper> aux = getAuxWrapper(context);
082: auxLoadData(aux, context, rdata);
083: }
084: return false;
085: }
086: }
087:
088: private ArrayList<IWrapper> getAuxWrapper(Context context)
089: throws Exception {
090: ArrayList<IWrapper> aux = new ArrayList<IWrapper>();
091: PageRequestConfig config = context
092: .getConfigForCurrentPageRequest();
093: Map<String, Class<? extends IWrapper>> auxwrp = config
094: .getAuxWrappers();
095:
096: if (auxwrp != null) {
097: for (Iterator<String> i = auxwrp.keySet().iterator(); i
098: .hasNext();) {
099: String prefix = i.next();
100: String iface = auxwrp.get(prefix).getName();
101: if (iface.equals("")) {
102: throw new XMLException(
103: "FATAL: No interface for prefix " + prefix);
104: }
105: Class<?> auxwrapper = Class.forName(iface);
106: IWrapper wrapper = (IWrapper) auxwrapper.newInstance();
107: wrapper.init(prefix);
108: aux.add(wrapper);
109: }
110: }
111: return aux;
112: }
113:
114: private IWrapper getAuthWrapper(Context context, boolean do_init)
115: throws Exception {
116: String pagename = null;
117: try {
118: pagename = context.getCurrentPageRequest().getName();
119: } catch (IllegalStateException e) {
120: pagename = "no pagename available";
121: }
122: PageRequestConfig config = context
123: .getConfigForCurrentPageRequest();
124:
125: String authprefix = config.getAuthWrapperPrefix();
126: String authwrapper = config.getAuthWrapperClass().getName();
127:
128: if (authprefix == null || authwrapper == null) {
129: String msg;
130: if (authprefix == null) {
131: msg = "authprefix == null (" + pagename + ")";
132: } else {
133: msg = "authwrapper == null (" + pagename + ")";
134: }
135: throw new XMLException(
136: "FATAL: Need exactly one interface definition for authpage! "
137: + msg);
138: }
139:
140: if (authwrapper.equals("")) {
141: throw new XMLException("*** No interface for prefix "
142: + authprefix);
143: }
144:
145: CAT.debug("===> authorisation handler: " + authprefix + " => "
146: + authwrapper);
147: Class<?> thewrapper = Class.forName(authwrapper);
148: IWrapper user = (IWrapper) thewrapper.newInstance();
149: if (do_init) {
150: user.init(authprefix);
151: }
152: return user;
153: }
154:
155: /**
156: * In this method, we decide if the Session is authenticated or not. If the session is not
157: * authenticated, we want to return a page to the user to query for authentication information.
158: *
159: * @param context a <code>Context</code> value
160: * @param req a <code>HttpServletRequest</code> value
161: * @return a <code>SPDocument</code> value
162: * @exception Exception if an error occurs
163: * @see de.schlund.pfixcore.workflow.State#getDocument(Context, PfixServletRequest)
164: */
165: @Override
166: public ResultDocument getDocument(Context context,
167: PfixServletRequest preq) throws Exception {
168: IWrapper user = getAuthWrapper(context, true);
169: IHandler userhandler = user.gimmeIHandler();
170: Properties properties = context.getProperties();
171: ResultDocument resdoc = super
172: .createDefaultResultDocument(context);
173: RequestData rdata = new RequestDataImpl(context, preq);
174: ArrayList<IWrapper> aux = getAuxWrapper(context);
175:
176: // Two cases: we are actively submitting data, or not.
177: // If we are, we always try to authenticate against supplied user data.
178: if (isSubmitAuthTrigger(context, preq)) {
179: CAT.debug("====> Handling AUTHDATA SUBMIT");
180: user.load(rdata);
181: if (user.errorHappened()) {
182: userhandler.retrieveCurrentStatus(context, user);
183: CAT.debug("====> Error during loading of wrapper data");
184: // Try loading the aux interfaces, just to echo the stringvals.
185: // so no error handling needs to take place.
186: auxEchoData(aux, rdata, resdoc);
187: userInsertErrors(properties, user, resdoc);
188: context.prohibitContinue();
189: } else {
190: CAT.debug("====> Calling handleSubmittedData on "
191: + userhandler.getClass().getName());
192: userhandler.handleSubmittedData(context, user);
193: if (user.errorHappened()
194: || context.isProhibitContinueSet()) { // during trying to authenticate
195: // There may have occured an error (a StatusCode is set), or prohibitContinue()
196: // has been already called (because a PageMessage has been used to signal an error condition)
197: CAT.debug("====> Error during submit handling");
198: userhandler.retrieveCurrentStatus(context, user);
199: // Try loading the aux interfaces, just to echo the stringvals.
200: // so no error handling needs to take place.
201: auxEchoData(aux, rdata, resdoc);
202: userInsertErrors(properties, user, resdoc);
203: context.prohibitContinue(); // no problem if called more than once...
204: } else {
205: // Try loading the aux interfaces, and call
206: // their handlers if no error happened.
207: auxLoadData(aux, context, rdata);
208: }
209: }
210: } else { // No data is actually submitted
211: userhandler.retrieveCurrentStatus(context, user);
212: // Try loading the aux interfaces, just to echo the stringvals.
213: // so no error handling needs to take place.
214: auxEchoData(aux, rdata, resdoc);
215: userInsertErrors(properties, user, resdoc);
216: context.prohibitContinue();
217: }
218:
219: return resdoc;
220: }
221:
222: private void userInsertErrors(Properties props, IWrapper user,
223: ResultDocument resdoc) {
224: IWrapperParam[] pinfos = user.gimmeAllParams();
225: String prefix = user.gimmePrefix();
226: for (int i = 0; i < pinfos.length; i++) {
227: IWrapperParam pinfo = pinfos[i];
228: StatusCodeInfo[] scodeinfos = pinfo.getStatusCodeInfos();
229: String name = pinfo.getName();
230: String[] value = pinfo.getStringValue();
231: if (value != null) {
232: for (int j = 0; j < value.length; j++) {
233: resdoc.addValue(prefix + "." + name, value[j]);
234: }
235: }
236: if (scodeinfos != null) {
237: for (int j = 0; j < scodeinfos.length; j++) {
238: StatusCodeInfo sci = scodeinfos[j];
239: resdoc.addStatusCode(props, sci.getStatusCode(),
240: sci.getArgs(), sci.getLevel(), prefix + "."
241: + name);
242: }
243: }
244: }
245: }
246:
247: private void auxEchoData(ArrayList<IWrapper> aux,
248: RequestData rdata, ResultDocument resdoc) throws Exception {
249: for (Iterator<IWrapper> i = aux.iterator(); i.hasNext();) {
250: IWrapper tmp = i.next();
251: tmp.load(rdata);
252: IWrapperParam[] params = tmp.gimmeAllParams();
253: String prefix = tmp.gimmePrefix();
254: for (int j = 0; j < params.length; j++) {
255: IWrapperParam par = params[j];
256: String[] sarr = par.getStringValue();
257: String val = "";
258: if (sarr != null && sarr.length > 0) {
259: val = sarr[0];
260: }
261: // put the stringvals into hidden variables,
262: // so the next submit will supply them again.
263: resdoc
264: .addHiddenValue(prefix + "." + par.getName(),
265: val);
266: }
267: }
268: for (Iterator<String> i = rdata.getParameterNames(); i
269: .hasNext();) {
270: String name = i.next();
271: if (name.equals(AbstractXMLServlet.PARAM_ANCHOR)) {
272: RequestParam[] vals = rdata.getParameters(name);
273: for (int j = 0; j < vals.length; j++) {
274: resdoc.addHiddenValue(name, vals[j].getValue());
275: }
276: }
277: }
278: }
279:
280: private void auxLoadData(ArrayList<IWrapper> aux, Context context,
281: RequestData rdata) throws Exception {
282: for (Iterator<IWrapper> i = aux.iterator(); i.hasNext();) {
283: IWrapper tmp = i.next();
284: IHandler hnd = tmp.gimmeIHandler();
285: tmp.load(rdata);
286: if (!tmp.errorHappened()) {
287: hnd.handleSubmittedData(context, tmp);
288: }
289: // No error handling here!! if it didn't work --- bad luck.
290: // We still return null, as the authentication is OK
291: }
292: }
293: }
|