1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.passwordStrength;
20
21 import org.apache.commons.lang.StringUtils;
22 import org.apache.myfaces.renderkit.html.util.AddResource;
23 import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
24 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
25 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
26 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
27 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
28 import org.apache.myfaces.shared_tomahawk.util.MessageUtils;
29
30 import javax.faces.component.UIComponent;
31 import javax.faces.component.UIInput;
32 import javax.faces.component.html.HtmlInputText;
33 import javax.faces.context.FacesContext;
34 import javax.faces.context.ResponseWriter;
35 import javax.faces.render.Renderer;
36 import java.io.IOException;
37 import java.util.Map;
38
39
40
41
42
43
44 public class PasswordStrengthRenderer extends Renderer {
45
46
47
48
49
50
51
52
53
54 private String getJavascriptVar(FacesContext context, UIComponent component) {
55 return JAVASCRIPT_VAR_PREFIX + component.getClientId(context).replaceAll("\\:", "_");
56 }
57
58 ;
59
60 private void addResources(FacesContext context, UIComponent component,
61 ResponseWriter writer) throws IOException {
62 PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
63 AddResource addResource = AddResourceFactory.getInstance(context);
64
65
66 String styleLocation = (String) component.getAttributes().get(
67 JSFAttr.STYLE_LOCATION);
68 if (StringUtils.isNotBlank(styleLocation)) {
69 addResource.addStyleSheet(context, AddResource.HEADER_BEGIN,
70 styleLocation + "/passwordStrength.css");
71 } else {
72 addResource.addStyleSheet(context, AddResource.HEADER_BEGIN,
73 PasswordStrengthRenderer.class, "css/passwordStrength.css");
74 }
75
76
77 String javascriptLocation = (String) component.getAttributes().get(
78 JSFAttr.JAVASCRIPT_LOCATION);
79 if (javascriptLocation != null) {
80 addResource.addJavaScriptAtPosition(context,
81 AddResource.HEADER_BEGIN, javascriptLocation
82 + "/genericProgressbarProvider.js");
83 addResource.addJavaScriptAtPosition(context,
84 AddResource.HEADER_BEGIN, javascriptLocation
85 + "/passwordStrength.js");
86 } else {
87 addResource.addJavaScriptAtPosition(context,
88 AddResource.HEADER_BEGIN, PasswordStrengthRenderer.class,
89 "genericProgressbarProvider.js");
90 addResource.addJavaScriptAtPosition(context,
91 AddResource.HEADER_BEGIN, PasswordStrengthRenderer.class,
92 "passwordStrength.js");
93 }
94
95
96
97 String messageId = getMessageID(context, passwordStrength);
98 writer.write("<script type=\"text/javascript\">");
99 writer.write("var " + getJavascriptVar(context, component) + " = new " + JAVASCRIPT_CLASS + "();");
100
101 String addOnStartUP = "window.addEventListener('load',function() {"
102 + getJavascriptVar(context, component)
103 + ".startUpPasswordStrength('"
104 + messageId
105 + "'); }, false);";
106 writer.write(addOnStartUP);
107 writer.write("</script>");
108 }
109
110 private String getMessageID(FacesContext context,
111 PasswordStrengthComponent passwordStrength) {
112 String clientID = passwordStrength.getClientId(context);
113 String messageId = "";
114 if (TextIndicatorType.TEXT
115 .equalsIgnoreCase(getStrengthIndicatorTypeValue(passwordStrength))) {
116 messageId = getIndicatorMessageId(clientID);
117 } else {
118 messageId = getProgressBarContainerID(clientID);
119 }
120 return messageId;
121 }
122
123
124
125 private void renderStartDiv(UIComponent component, ResponseWriter writer)
126 throws IOException {
127 writer.startElement(HTML.DIV_ELEM, component);
128 writer.startElement(HTML.TABLE_ELEM, component);
129 writer.startElement(HTML.TR_ELEM, component);
130 writer.startElement(HTML.TD_ELEM, component);
131 }
132
133 private void renderEndDiv(UIComponent component, ResponseWriter writer)
134 throws IOException {
135 writer.endElement(HTML.TD_ELEM);
136 writer.endElement(HTML.TR_ELEM);
137 writer.endElement(HTML.TABLE_ELEM);
138 writer.endElement(HTML.DIV_ELEM);
139 }
140
141 private String getDefaultTextDesc() {
142 return MessageUtils.getMessage(BUNDLE_BASE_NAME,
143 MessageUtils.getCurrentLocale(),
144 "org.apache.myfaces.custom.passwordStrength.DESC", null)
145 .getDetail();
146 }
147
148 private String getDefaultShowDetails() {
149 return "true";
150 }
151
152 private String getDefaultUseCustomSecurity() {
153 return "false";
154 }
155
156 private String getDefaultCustomSecurityRule() {
157 return "A1";
158 }
159
160 private String getDefaultPenaltyRatio() {
161 return "50";
162 }
163
164 private String getDefaultPrefix() {
165 return MessageUtils.getMessage(BUNDLE_BASE_NAME,
166 MessageUtils.getCurrentLocale(),
167 "org.apache.myfaces.custom.passwordStrength.PREFIX", null)
168 .getDetail();
169 }
170
171 private String getLeftCharactersString() {
172 return "'" + MessageUtils.getMessage(BUNDLE_BASE_NAME,
173 MessageUtils.getCurrentLocale(),
174 "org.apache.myfaces.custom.passwordStrength.LEFT_CHARS", null)
175 .getDetail() + "'";
176 }
177
178 private String getDefaultStrengthIndicatorType() {
179 return TextIndicatorType.TEXT;
180 }
181
182 private void createTextSpan(PasswordStrengthComponent passwordStrength,
183 FacesContext context, String clientID) throws IOException {
184 ResponseWriter writer = context.getResponseWriter();
185 String preferredLength = passwordStrength.getPreferredPasswordLength();
186 String prefixText = (passwordStrength.getPrefixText() == null) ? "'" + getDefaultPrefix() + "'"
187 : "'" + passwordStrength.getPrefixText() + "'";
188 String textStrengthDescriptions = (passwordStrength
189 .getTextStrengthDescriptions() == null) ? "'"
190 + getDefaultTextDesc() + "'" : "'"
191 + passwordStrength.getTextStrengthDescriptions() + "'";
192 String textID = "'" + clientID + "'";
193 String showDetails = (passwordStrength.getShowDetails() == null) ? "'"
194 + getDefaultShowDetails() + "'" : "'"
195 + passwordStrength.getShowDetails().toLowerCase() + "'";
196 String useCustomSecurity = (passwordStrength.getUseCustomSecurity() == null) ? "'"
197 + getDefaultUseCustomSecurity() + "'"
198 : "'" + passwordStrength.getUseCustomSecurity().toLowerCase()
199 + "'";
200 String customSecurityExpression = (passwordStrength
201 .getCustomSecurityExpression() == null) ? "'"
202 + getDefaultCustomSecurityRule() + "'" : "'"
203 + passwordStrength.getCustomSecurityExpression() + "'";
204 String penaltyRatio = (passwordStrength
205 .getPenaltyRatio() == null) ? "'"
206 + getDefaultPenaltyRatio() + "'" : "'"
207 + passwordStrength.getPenaltyRatio() + "'";
208 writer.startElement(HTML.SPAN_ELEM, passwordStrength);
209 writer.startElement(HTML.INPUT_ELEM, passwordStrength);
210 writer.writeAttribute(HTML.TYPE_ATTR, "password", HTML.TYPE_ATTR);
211 writer.writeAttribute(HTML.ID_ATTR, clientID, HTML.ID_ATTR);
212 writer.writeAttribute(HTML.NAME_ATTR, clientID, HTML.NAME_ATTR);
213 String value = "";
214 Object objValue = ((UIInput) passwordStrength).getSubmittedValue();
215 if (objValue != null) {
216 value = passwordStrength.getValue().toString();
217 }
218 writer.writeAttribute("value", value, "value");
219
220 String onKeyUpString = createOnKeyUpString(context,
221 passwordStrength, textID, preferredLength, prefixText,
222 textStrengthDescriptions, true, showDetails, useCustomSecurity,
223 customSecurityExpression, penaltyRatio);
224 String onKeyUpAttr = passwordStrength.getOnkeyup();
225 passwordStrength.setOnkeyup(constructJSFunction(onKeyUpString, onKeyUpAttr));
226
227 String onBlurString = getOnBlurString(context, passwordStrength);
228 String onBlurAttr = passwordStrength.getOnblur();
229 passwordStrength.setOnblur(constructJSFunction(onBlurString, onBlurAttr));
230
231 HtmlRendererUtils.renderHTMLAttributes(writer, passwordStrength, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
232 if (isDisabled(context, passwordStrength))
233 {
234 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
235 }
236
237 writer.endElement(HTML.INPUT_ELEM);
238 writer.endElement(HTML.SPAN_ELEM);
239 }
240
241
242
243
244
245 private String constructJSFunction(String function, String attrFunction)
246 {
247 if(attrFunction != null && attrFunction.length() > 0)
248 {
249 if(!attrFunction.endsWith(";"))
250 {
251 attrFunction += ";";
252 }
253 return (function+attrFunction);
254 }
255 else
256 {
257 return function;
258 }
259 }
260
261
262
263
264 private void createProgressbar(UIComponent component,
265 FacesContext context, ResponseWriter writer) throws IOException {
266 String clientID = component.getClientId(context);
267 writer.startElement(HTML.DIV_ELEM, component);
268 writer.writeAttribute(HTML.ID_ATTR, getProgressBarContainerID(clientID),
269 HTML.ID_ATTR);
270 writer.writeAttribute(HTML.CLASS_ATTR, "org_apache_myfaces_passwordStrength_progress",
271 HTML.CLASS_ATTR);
272
273
274 writer.startElement(HTML.DIV_ELEM, component);
275 writer.writeAttribute(HTML.ID_ATTR, getProgressBarID(clientID),
276 HTML.ID_ATTR);
277
278 writer.writeAttribute(HTML.CLASS_ATTR, "progressStart",
279 HTML.CLASS_ATTR);
280
281 writer.endElement(HTML.DIV_ELEM);
282 writer.endElement(HTML.DIV_ELEM);
283 }
284
285 private void createTextIndicatorMessage(UIComponent component,
286 FacesContext context, ResponseWriter writer) throws IOException {
287 String clientID = component.getClientId(context);
288 writer.startElement(HTML.SPAN_ELEM, component);
289 writer.writeAttribute(HTML.ID_ATTR, getIndicatorMessageId(clientID),
290 HTML.ID_ATTR);
291 writer.writeAttribute(HTML.CLASS_ATTR, "org_apache_myfaces_passwordStrength_progress_indicatorMessage",
292 HTML.CLASS_ATTR);
293 writer.endElement(HTML.SPAN_ELEM);
294 }
295
296 private void createIndicatorSpan(UIComponent component,
297 FacesContext context, ResponseWriter writer) throws IOException {
298 PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
299 String clientID = passwordStrength.getClientId(context);
300 String strengthIndicatorType = getStrengthIndicatorTypeValue(passwordStrength);
301 writer.endElement(HTML.TD_ELEM);
302 writer.startElement(HTML.TD_ELEM, component);
303 if (TextIndicatorType.TEXT.equalsIgnoreCase(strengthIndicatorType)) {
304 createTextIndicatorMessage(component, context, writer);
305 } else {
306
307 createProgressbar(component, context, writer);
308 }
309 writer.endElement(HTML.TD_ELEM);
310 writer.endElement(HTML.TR_ELEM);
311 writer.startElement(HTML.TR_ELEM, component);
312 writer.startElement(HTML.TD_ELEM, component);
313 writer.startElement("div", component);
314 writer.writeAttribute("id", getleftCharsMessageId(clientID), "id");
315 writer.endElement("div");
316 }
317
318 private String getStrengthIndicatorType(
319 PasswordStrengthComponent passwordStrength) {
320 return (passwordStrength.getStrengthIndicatorType() == null) ? "'"
321 + getDefaultStrengthIndicatorType() + "'" : "'"
322 + passwordStrength.getStrengthIndicatorType() + "'";
323 }
324
325 private String getStrengthIndicatorTypeValue(
326 PasswordStrengthComponent passwordStrength) {
327 return (passwordStrength.getStrengthIndicatorType() == null) ? getDefaultStrengthIndicatorType()
328 : passwordStrength.getStrengthIndicatorType();
329 }
330
331
332 private void createHTMLComponents(FacesContext facesContext,
333 UIComponent component, ResponseWriter writer, String clientID)
334 throws IOException {
335 PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
336 renderStartDiv(component, writer);
337 createTextSpan(passwordStrength, facesContext, clientID);
338 createIndicatorSpan(component, facesContext, writer);
339 renderEndDiv(component, writer);
340 }
341
342 public void encodeBegin(FacesContext context, UIComponent component)
343 throws IOException {
344 RendererUtils.checkParamValidity(context, component,
345 PasswordStrengthComponent.class);
346 if (HtmlRendererUtils.isDisplayValueOnly(component)
347 || isDisabled(context, component)) {
348 super.encodeEnd(context, component);
349 return;
350 }
351 String clientID = component.getClientId(context);
352 ResponseWriter writer = context.getResponseWriter();
353 addResources(context, component, writer);
354 createHTMLComponents(context, component, writer, clientID);
355 }
356
357 public void encodeEnd(FacesContext context, UIComponent component)
358 throws IOException {
359 }
360
361 public void decode(FacesContext context, UIComponent component) {
362 Map requestMap = context.getExternalContext().getRequestParameterMap();
363 String clientID = component.getClientId(context);
364 String newValue = (String) requestMap.get(clientID);
365 ((UIInput) component).setSubmittedValue(newValue);
366 }
367
368 protected boolean isDisabled(FacesContext facesContext,
369 UIComponent component) {
370 if (component instanceof HtmlInputText) {
371 return ((HtmlInputText) component).isDisabled();
372 } else {
373 return org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils
374 .getBooleanAttribute(component, HTML.DISABLED_ATTR, false);
375 }
376 }
377
378 private String createOnKeyUpString(FacesContext context,
379 UIComponent component, String textID, String preferredLength,
380 String prefix, String textStrengthDescriptions,
381 boolean showMessageIndicator, String showDetails,
382 String useCustomSecurity, String customSecurityExpression,
383 String penaltyRatio) {
384 PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
385 String clientID = component.getClientId(context);
386 String showMessageIndicatorString = "";
387 String strengthIndicatorType = getStrengthIndicatorType(passwordStrength);
388 String progressBarId = "'" + getProgressBarID(clientID) + "'";
389 String indicatorMessageID = "'" + getIndicatorMessageId(clientID) + "'";
390 String leftCharsMessageID = "'" + getleftCharsMessageId(clientID) + "'";
391 if (showMessageIndicator == true) {
392 showMessageIndicatorString = getJavascriptVar(context, component) + ".show('"
393 + getMessageID(context, passwordStrength) + "');";
394 }
395 return updateStatusValue(context, component, textID, preferredLength, prefix,
396 textStrengthDescriptions, indicatorMessageID,
397 leftCharsMessageID, showMessageIndicatorString,
398 strengthIndicatorType, progressBarId, showDetails,
399 getLeftCharactersString(), useCustomSecurity,
400 customSecurityExpression, penaltyRatio);
401 }
402
403 private String updateStatusValue(FacesContext context,
404 UIComponent component,
405 String textID, String preferredLength,
406 String prefix, String textStrengthDescriptions,
407 String indicatorMessageID, String leftCharsMessageID,
408 String showMessageIndicatorString,
409 String strengthIndicatorType, String progressBarId,
410 String showDetails, String leftCharactersString,
411 String useCustomSecurity, String customSecurityExpression,
412 String penaltyRatio) {
413 return getJavascriptVar(context, component) + ".updateStatusValue("
414 + textID + "," + preferredLength + ", "
415 + prefix + ", " + textStrengthDescriptions + ", "
416 + indicatorMessageID + ", " + leftCharsMessageID + ", "
417 + strengthIndicatorType + ", " + progressBarId + ", "
418 + showDetails + ", " + leftCharactersString + ", "
419 + useCustomSecurity + ", " + customSecurityExpression + ", "
420 + penaltyRatio
421 + ");"
422 + showMessageIndicatorString;
423 }
424
425 private String getIndicatorMessageId(String clientID) {
426 return clientID + "indicatorMessage";
427 }
428
429 private String getleftCharsMessageId(String clientID) {
430 return clientID + "leftCharsMessage";
431 }
432
433 private String getProgressBarID(String clientID) {
434 return clientID + PROGRESSBAR_SUFFIX;
435 }
436
437 private String getProgressBarContainerID(String clientID) {
438 return getProgressBarID(clientID) + PROGRESSBAR_CONTAINER_SUFFIX;
439 }
440
441 private String getOnBlurString(FacesContext context, UIComponent component) {
442 PasswordStrengthComponent passwordStrength = (PasswordStrengthComponent) component;
443 String clientID = passwordStrength.getClientId(context);
444 return getJavascriptVar(context, component) + ".hide('" + getMessageID(context, passwordStrength) + "');" + getJavascriptVar(context, component) + ".hide('"
445 + getleftCharsMessageId(clientID) + "');";
446 }
447
448 final String BUNDLE_BASE_NAME = "org.apache.myfaces.custom.passwordStrength.resource.PasswordStrength";
449 final String DEFAULT_PROGRESSBAR_WIDTH = "150";
450 final String DEFAULT_PROGRESSBAR_HEIGHT = "20";
451 final String PROGRESSBAR_SUFFIX = "_PROGRESSBAR";
452 final String PROGRESSBAR_CONTAINER_SUFFIX = "_CONTAINER";
453 final String DEFAULT_PROGRESSBAR_VALUE = "20";
454
455
456
457
458
459 static final String JAVASCRIPT_CLASS = "org.apache.myfaces.passwordStrength";
460
461
462
463 static final String JAVASCRIPT_VAR_PREFIX = "myfaces_";
464 }