Home | Trees | Indices | Help |
|
---|
|
1 # Copyright (C) 2012 Vaadin Ltd. 2 # Copyright (C) 2012 Richard Lincoln 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 try: 17 from cStringIO import StringIO 18 except ImportError, e: 19 from StringIO import StringIO 20 21 from muntjac.ui.component import Event 22 from muntjac.ui.embedded import Embedded 23 from muntjac.ui.custom_component import CustomComponent 24 from muntjac.terminal.application_resource import IApplicationResource 25 from muntjac.terminal.uri_handler import IUriHandler 26 from muntjac.terminal.download_stream import DownloadStream 27 from muntjac.terminal.parameter_handler import IParameterHandler 28 29 from muntjac.terminal.gwt.client.application_connection import \ 30 ApplicationConnection 31 3234 """This event is sent when login form is submitted.""" 35 39 4050 51 61 62 63 _ON_LOGIN_METHOD = getattr(ILoginListener, 'onLogin') 64 6542 """Access method to form values by field names. 43 44 @return: value in given field 45 """ 46 if name in self._params: 47 return self._params.get(name) 48 else: 49 return None67 """LoginForm is a Muntjac component to handle common problem among Ajax 68 applications: browsers password managers don't fill dynamically created 69 forms like all those UI elements created by Muntjac. 70 71 For developer it is easy to use: add component to a desired place in you 72 UI and add ILoginListener to validate form input. Behind the curtain 73 LoginForm creates an iframe with static html that browsers detect. 74 75 Login form is by default 100% width and height, so consider using it 76 inside a sized L{Panel} or L{Window}. 77 78 Login page html can be overridden by replacing protected getLoginHTML 79 method. As the login page is actually an iframe, styles must be handled 80 manually. By default component tries to guess the right place for theme 81 css. 82 83 Note, this is a new Ajax terminal specific component and is likely to 84 change. 85 """ 86287 28888 self._usernameCaption = 'Username' 89 self._passwordCaption = 'Password' 90 self._loginButtonCaption = 'Login' 91 self._iframe = Embedded() 92 93 self._window = None 94 95 super(LoginForm, self).__init__() 96 97 self._iframe.setType(Embedded.TYPE_BROWSER) 98 self._iframe.setSizeFull() 99 self.setSizeFull() 100 self.setCompositionRoot(self._iframe) 101 self.addStyleName('v-loginform') 102 103 self.loginPage = LoginPage(self) 104 self.parameterHandler = ParameterHandler(self) 105 self.uriHandler = UriHandler(self)106 107109 """Returns byte array containing login page html. If you need to 110 override the login html, use the default html as basis. Login page 111 sets its target with javascript. 112 113 @return: byte array containing login page html 114 """ 115 appUri = str(self.getApplication().getURL()) \ 116 + self.getWindow().getName() + '/' 117 118 return ('<!DOCTYPE html PUBLIC \"-//W3C//DTD ' 119 'XHTML 1.0 Transitional//EN\" ' 120 '\"http://www.w3.org/TR/xhtml1/' 121 'DTD/xhtml1-transitional.dtd\">\n' 122 '<html>' 123 '<head><script type=\'text/javascript\'>' 124 'var setTarget = function() {' 125 'var uri = \'' 126 + appUri + 127 'loginHandler' 128 '\'; var f = document.getElementById(\'loginf\');' 129 'document.forms[0].action = uri;document.forms[0].username.focus();};' 130 '' + 'var styles = window.parent.document.styleSheets;' 131 'for(var j = 0; j < styles.length; j++) {\n' 132 'if(styles[j].href) {' 133 'var stylesheet = document.createElement(\'link\');\n' 134 'stylesheet.setAttribute(\'rel\', \'stylesheet\');\n' 135 'stylesheet.setAttribute(\'type\', \'text/css\');\n' 136 'stylesheet.setAttribute(\'href\', styles[j].href);\n' 137 'document.getElementsByTagName(\'head\')[0].appendChild(stylesheet);\n' 138 '}' 139 '}\n' 140 'function submitOnEnter(e) { var keycode = e.keyCode || e.which;' 141 ' if (keycode == 13) {document.forms[0].submit();} } \n' 142 '</script>' 143 '</head><body onload=\'setTarget();\' style=\'margin:0;padding:0; background:transparent;\' class=\"' 144 + ApplicationConnection.GENERATED_BODY_CLASSNAME + 145 '\">' + '<div class=\'v-app v-app-loginpage\' style=\"background:transparent;\">' 146 '<iframe name=\'logintarget\' style=\'width:0;height:0;' 147 'border:0;margin:0;padding:0;\'></iframe>' 148 '<form id=\'loginf\' target=\'logintarget\' onkeypress=\"submitOnEnter(event)\" method=\"post\">' 149 '<div>' 150 + self._usernameCaption + 151 '</div><div >' 152 '<input class=\'v-textfield\' style=\'display:block;\' type=\'text\' name=\'username\'></div>' 153 '<div>' 154 + self._passwordCaption + 155 '</div>' 156 '<div><input class=\'v-textfield\' style=\'display:block;\' type=\'password\' name=\'password\'></div>' 157 '<div><div onclick=\"document.forms[0].submit();\" tabindex=\"0\" class=\"v-button\" role=\"button\" ><span class=\"v-button-wrap\"><span class=\"v-button-caption\">' 158 + self._loginButtonCaption + 159 '</span></span></div></div></form></div>' 160 '</body></html>').encode('utf-8')161 162164 super(LoginForm, self).attach() 165 self.getApplication().addResource(self.loginPage) 166 self.getWindow().addParameterHandler(self.parameterHandler) 167 self._iframe.setSource(self.loginPage)168 169171 self.getApplication().removeResource(self.loginPage) 172 self.getWindow().removeParameterHandler(self.parameterHandler) 173 # store window temporary to properly remove uri handler once 174 # response is handled. (May happen if login handler removes login 175 # form 176 self._window = self.getWindow() 177 if self._window.getParent() is not None: 178 self._window = self._window.getParent() 179 super(LoginForm, self).detach()180 181 182 _UNDEFINED_HEIGHT = '140px' 183 _UNDEFINED_WIDTH = '200px' 184 185187 """Adds ILoginListener to handle login logic. 188 """ 189 if (isinstance(listener, ILoginListener) and 190 (iface is None or issubclass(iface, ILoginListener))): 191 self.registerListener(LoginEvent, listener, _ON_LOGIN_METHOD) 192 193 super(LoginForm, self).addListener(listener, iface)194 195197 if eventType is None: 198 eventType = callback._eventType 199 200 if issubclass(eventType, LoginEvent): 201 self.registerCallback(LoginEvent, callback, None, *args) 202 else: 203 super(LoginForm, self).addCallback(callback, eventType, *args)204 205207 """Removes ILoginListener. 208 """ 209 if (isinstance(listener, ILoginListener) and 210 (iface is None or issubclass(iface, ILoginListener))): 211 self.withdrawListener(LoginEvent, listener, _ON_LOGIN_METHOD) 212 213 super(LoginForm, self).removeListener(listener, iface)214 215217 if eventType is None: 218 eventType = callback._eventType 219 220 if issubclass(eventType, LoginEvent): 221 self.withdrawCallback(LoginEvent, callback) 222 else: 223 super(LoginForm, self).removeCallback(callback, eventType)224 225227 if unit is not None: 228 super(LoginForm, self).setWidth(width, unit) 229 if self._iframe is not None: 230 if width < 0: 231 self._iframe.setWidth(self._UNDEFINED_WIDTH) 232 else: 233 self._iframe.setWidth('100%') 234 else: 235 super(LoginForm, self).setWidth(width)236 237239 if unit is not None: 240 super(LoginForm, self).setHeight(height, unit) 241 if self._iframe is not None: 242 if height < 0: 243 self._iframe.setHeight(self._UNDEFINED_HEIGHT) 244 else: 245 self._iframe.setHeight('100%') 246 else: 247 super(LoginForm, self).setHeight(height)248 249 254 255257 """Sets the caption to show for the user name field. The caption 258 cannot be changed after the form has been shown to the user. 259 """ 260 self._usernameCaption = usernameCaption261 262 267 268270 """Sets the caption to show for the password field. The caption 271 cannot be changed after the form has been shown to the user. 272 """ 273 self._passwordCaption = passwordCaption274 275 280 281290318 319292 self._form = form293 294296 return self._form.getApplication()297 298300 return len(self._form.getLoginHTML())301 302 305 306 309 310312 return DownloadStream(StringIO(self._form.getLoginHTML()), 313 self.getMIMEType(), self.getFilename())314 315321336 337323 self._form = form324 325327 if 'username' in parameters: 328 self._form.getWindow().addURIHandler(self._form.uriHandler) 329 params = dict() 330 # expecting single params 331 for key in parameters: 332 value = parameters.get(key) 333 params[key] = value 334 event = LoginEvent(params, self._form) 335 self._form.fireEvent(event)339357341 self._form = form 342 self._responce = ('<html><body>Login form handeled.' 343 + '<script type=\'text/javascript\'>top.vaadin.forceSync();' 344 + '</script></body></html>')345 346348 if relativeUri is not None and 'loginHandler' in relativeUri: 349 if self._form._window is not None: 350 self._form._window.removeURIHandler(self) 351 downloadStream = DownloadStream(StringIO(self._responce), 352 'text/html', 'loginSuccesfull') 353 downloadStream.setCacheTime(-1) 354 return downloadStream 355 else: 356 return None
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Fri Jun 5 20:45:23 2015 | http://epydoc.sourceforge.net |