1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application.viewstate;
20
21 import javax.faces.context.ExternalContext;
22 import javax.faces.context.FacesContext;
23
24 import org.apache.myfaces.application.StateCache;
25 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
26 import org.apache.myfaces.shared.util.WebConfigParamUtils;
27
28 class ClientSideStateCacheImpl extends StateCache<Object, Object>
29 {
30
31
32
33
34
35
36 @JSFWebConfigParam(since="2.1.9, 2.0.15", defaultValue="0", group="state")
37 public static final String INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT =
38 "org.apache.myfaces.CLIENT_VIEW_STATE_TIMEOUT";
39 public static final Long INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT_DEFAULT = 0L;
40
41 private static final int STATE_PARAM = 0;
42 private static final int VIEWID_PARAM = 1;
43 private static final int TIMESTAMP_PARAM = 2;
44
45 private static final Object[] EMPTY_STATES = new Object[]{null, null};
46
47 private Long _clientViewStateTimeout;
48
49 private CsrfSessionTokenFactory csrfSessionTokenFactory;
50
51 public ClientSideStateCacheImpl()
52 {
53 FacesContext facesContext = FacesContext.getCurrentInstance();
54
55 String csrfRandomMode = WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(),
56 RANDOM_KEY_IN_CSRF_SESSION_TOKEN_PARAM,
57 RANDOM_KEY_IN_CSRF_SESSION_TOKEN_PARAM_DEFAULT);
58 if (RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM.equals(csrfRandomMode))
59 {
60 csrfSessionTokenFactory = new SecureRandomCsrfSessionTokenFactory(facesContext);
61 }
62 else
63 {
64 csrfSessionTokenFactory = new RandomCsrfSessionTokenFactory(facesContext);
65 }
66 }
67
68 @Override
69 public Object saveSerializedView(FacesContext facesContext,
70 Object serializedView)
71 {
72
73
74
75 return encodeSerializedState(facesContext, serializedView);
76 }
77
78 @Override
79 public Object restoreSerializedView(FacesContext facesContext,
80 String viewId, Object viewState)
81 {
82 Object[] state = (Object[]) viewState;
83 long clientViewStateTimeout = getClientViewStateTimeout(facesContext.getExternalContext());
84
85 if (clientViewStateTimeout > 0L)
86 {
87 Long timeStamp = (Long) state[TIMESTAMP_PARAM];
88 if (timeStamp == null)
89 {
90
91 return null;
92 }
93 long passedTime = (System.currentTimeMillis() - timeStamp.longValue()) / 60000;
94
95 if (passedTime > clientViewStateTimeout)
96 {
97
98 return null;
99 }
100 }
101
102 String restoredViewId = (String) state[VIEWID_PARAM];
103
104 if (viewId != null && !viewId.equals(restoredViewId))
105 {
106
107 return null;
108 }
109
110
111 if (state[STATE_PARAM] == null)
112 {
113 return EMPTY_STATES;
114 }
115 else
116 {
117 Object serializedView = state[STATE_PARAM];
118 if (serializedView instanceof Object[] &&
119 ((Object[])serializedView).length == 2 &&
120 ((Object[])serializedView)[0] == null &&
121 ((Object[])serializedView)[1] == null)
122 {
123
124 return null;
125 }
126
127 return state[STATE_PARAM];
128 }
129 }
130
131 @Override
132 public Object encodeSerializedState(FacesContext facesContext,
133 Object serializedView)
134 {
135 Object[] state = null;
136
137 if (getClientViewStateTimeout(facesContext.getExternalContext()).longValue() > 0L)
138 {
139 state = new Object[3];
140 state[TIMESTAMP_PARAM] = System.currentTimeMillis();
141 }
142 else
143 {
144 state = new Object[2];
145 }
146
147 if (serializedView == null)
148 {
149 state[STATE_PARAM] = EMPTY_STATES;
150 }
151 else if (serializedView instanceof Object[] &&
152 ((Object[])serializedView).length == 2 &&
153 ((Object[])serializedView)[0] == null &&
154 ((Object[])serializedView)[1] == null)
155 {
156
157
158 state[STATE_PARAM] = null;
159 }
160 else
161 {
162 state[STATE_PARAM] = serializedView;
163 }
164
165 state[VIEWID_PARAM] = facesContext.getViewRoot().getViewId();
166
167 return state;
168 }
169
170 @Override
171 public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext)
172 {
173 return true;
174 }
175
176
177
178
179 protected Long getClientViewStateTimeout(ExternalContext context)
180 {
181 if (_clientViewStateTimeout == null)
182 {
183 _clientViewStateTimeout = WebConfigParamUtils.getLongInitParameter(
184 context, INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT,
185 INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT_DEFAULT);
186 if (_clientViewStateTimeout.longValue() < 0L)
187 {
188 _clientViewStateTimeout = 0L;
189 }
190 }
191 return _clientViewStateTimeout;
192 }
193
194 @Override
195 public String createCryptographicallyStrongTokenFromSession(FacesContext context)
196 {
197 return csrfSessionTokenFactory.createCryptographicallyStrongTokenFromSession(context);
198 }
199 }