001: /*
002: * $Id: TokenHelper.java 471756 2006-11-06 15:01:43Z husted $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.util;
022:
023: import java.math.BigInteger;
024: import java.util.Map;
025: import java.util.Random;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029:
030: import com.opensymphony.xwork2.ActionContext;
031: import com.opensymphony.xwork2.util.LocalizedTextUtil;
032:
033: /**
034: * TokenHelper
035: *
036: */
037: public class TokenHelper {
038:
039: /**
040: * The default name to map the token value
041: */
042: public static final String DEFAULT_TOKEN_NAME = "struts.token";
043:
044: /**
045: * The name of the field which will hold the token name
046: */
047: public static final String TOKEN_NAME_FIELD = "struts.token.name";
048: private static final Log LOG = LogFactory.getLog(TokenHelper.class);
049: private static final Random RANDOM = new Random();
050:
051: /**
052: * Sets a transaction token into the session using the default token name.
053: *
054: * @return the token string
055: */
056: public static String setToken() {
057: return setToken(DEFAULT_TOKEN_NAME);
058: }
059:
060: /**
061: * Sets a transaction token into the session using the provided token name.
062: *
063: * @param tokenName the name to store into the session with the token as the value
064: * @return the token string
065: */
066: public static String setToken(String tokenName) {
067: Map session = ActionContext.getContext().getSession();
068: String token = generateGUID();
069: try {
070: session.put(tokenName, token);
071: } catch (IllegalStateException e) {
072: // WW-1182 explain to user what the problem is
073: String msg = "Error creating HttpSession due response is commited to client. You can use the CreateSessionInterceptor or create the HttpSession from your action before the result is rendered to the client: "
074: + e.getMessage();
075: LOG.error(msg, e);
076: throw new IllegalArgumentException(msg);
077: }
078:
079: return token;
080: }
081:
082: /**
083: * Gets a transaction token into the session using the default token name.
084: *
085: * @return token
086: */
087: public static String getToken() {
088: return getToken(DEFAULT_TOKEN_NAME);
089: }
090:
091: /**
092: * Gets the Token value from the params in the ServletActionContext using the given name
093: *
094: * @param tokenName the name of the parameter which holds the token value
095: * @return the token String or null, if the token could not be found
096: */
097: public static String getToken(String tokenName) {
098: Map params = ActionContext.getContext().getParameters();
099: String[] tokens = (String[]) params.get(tokenName);
100: String token;
101:
102: if ((tokens == null) || (tokens.length < 1)) {
103: LOG.warn("Could not find token mapped to token name "
104: + tokenName);
105:
106: return null;
107: }
108:
109: token = tokens[0];
110:
111: return token;
112: }
113:
114: /**
115: * Gets the token name from the Parameters in the ServletActionContext
116: *
117: * @return the token name found in the params, or null if it could not be found
118: */
119: public static String getTokenName() {
120: Map params = ActionContext.getContext().getParameters();
121:
122: if (!params.containsKey(TOKEN_NAME_FIELD)) {
123: LOG.warn("Could not find token name in params.");
124:
125: return null;
126: }
127:
128: String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD);
129: String tokenName;
130:
131: if ((tokenNames == null) || (tokenNames.length < 1)) {
132: LOG.warn("Got a null or empty token name.");
133:
134: return null;
135: }
136:
137: tokenName = tokenNames[0];
138:
139: return tokenName;
140: }
141:
142: /**
143: * Checks for a valid transaction token in the current request params. If a valid token is found, it is
144: * removed so the it is not valid again.
145: *
146: * @return false if there was no token set into the params (check by looking for {@link #TOKEN_NAME_FIELD}), true if a valid token is found
147: */
148: public static boolean validToken() {
149: String tokenName = getTokenName();
150:
151: if (tokenName == null) {
152: if (LOG.isDebugEnabled())
153: LOG.debug("no token name found -> Invalid token ");
154: return false;
155: }
156:
157: String token = getToken(tokenName);
158:
159: if (token == null) {
160: if (LOG.isDebugEnabled())
161: LOG.debug("no token found for token name " + tokenName
162: + " -> Invalid token ");
163: return false;
164: }
165:
166: Map session = ActionContext.getContext().getSession();
167: String sessionToken = (String) session.get(tokenName);
168:
169: if (!token.equals(sessionToken)) {
170: LOG
171: .warn(LocalizedTextUtil
172: .findText(
173: TokenHelper.class,
174: "struts.internal.invalid.token",
175: ActionContext.getContext()
176: .getLocale(),
177: "Form token {0} does not match the session token {1}.",
178: new Object[] { token, sessionToken }));
179:
180: return false;
181: }
182:
183: // remove the token so it won't be used again
184: session.remove(tokenName);
185:
186: return true;
187: }
188:
189: public static String generateGUID() {
190: return new BigInteger(165, RANDOM).toString(36).toUpperCase();
191: }
192: }
|