def testLoginForWithRememberMe(self): form = BasicHtmlLoginForm( action='/action', loginPath='/login', home='/home', rememberMeCookie=True) result = asString(form.loginForm(session={}, path='/page/login2')) self.assertEqualsWS("""<div id="login-form"> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/page/login2"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dt> </dt><dd class="rememberMe"><input type="checkbox" name="rememberMe" id="rememberMe" /><label for="rememberMe">Remember me</label></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Login"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result)
class BasicHtmlLoginFormTest(SeecrTestCase): def setUp(self): SeecrTestCase.setUp(self) self.form = BasicHtmlLoginForm(action='/action', loginPath='/login', home='/home') def testLoginFormEnglish(self): result = asString(self.form.loginForm(session={}, path='/page/login2')) self.assertEqualsWS("""<div id="login-form"> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/page/login2"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Login"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result) def testLoginFormDutch(self): result = asString(self.form.loginForm(session={}, path='/page/login2', lang='nl')) self.assertEqualsWS("""<div id="login-form"> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/page/login2"/> <dl> <dt>Gebruikersnaam</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Wachtwoord</dt> <dd><input type="password" name="password"/></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Inloggen"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result) def testNewUserFormEN(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.newUserFormValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.newUserForm(session=session, path='/page/login2', returnUrl='/return')) self.assertEqualsWS("""<div id="login-new-user-form"> <p class="error">BAD BOY</p> <form method="POST" name="newUser" action="/action/newUser"> <input type="hidden" name="formUrl" value="/page/login2"/> <input type="hidden" name="returnUrl" value="/return"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dt>Retype password</dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Create"/></dd> </dl> </form> </div>""", result) def testNewUserFormNL(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.newUserFormValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.newUserForm(session=session, path='/page/login2', returnUrl='/return', lang="nl")) self.assertEqualsWS("""<div id="login-new-user-form"> <p class="error">BAD BOY</p> <form method="POST" name="newUser" action="/action/newUser"> <input type="hidden" name="formUrl" value="/page/login2"/> <input type="hidden" name="returnUrl" value="/return"/> <dl> <dt>Gebruikersnaam</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Wachtwoord</dt> <dd><input type="password" name="password"/></dd> <dt>Herhaal wachtwoord </dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Aanmaken"/></dd> </dl> </form> </div>""", result) def testRedirectOnGet(self): result = asString(self.form.handleRequest(path='/whatever', Client=('127.0.0.1', 3451), Method='GET')) header, body = result.split(CRLF*2) self.assertTrue('405' in header) def testLoginWithPOSTsucceedsRedirectsToOriginalPath(self): observer = CallTrace(onlySpecifiedMethods=True, returnValues={'hasUser': True}) self.form.addObserver(observer) observer.returnValues['validateUser'] = True Body = urlencode(dict(username='******', password='******')) session = {ORIGINAL_PATH:'/please/go/here'} result = asString(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals('user', session['user'].name) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /please/go/here' in header) user = session['user'] self.assertFalse(user.isAdmin()) self.assertEquals(['validateUser', 'hasUser'], [m.name for m in observer.calledMethods]) self.assertEquals({'username': '******', 'password':'******'}, observer.calledMethods[0].kwargs) def testLoginWithPOSTsucceedsRedirectsToOriginalPathOnlyOnce(self): observer = CallTrace(onlySpecifiedMethods=True, returnValues={'hasUser': True}) self.form.addObserver(observer) observer.returnValues['validateUser'] = True Body = urlencode(dict(username='******', password='******')) session = {ORIGINAL_PATH:'/please/go/here'} result = asString(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals('user', session['user'].name) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /please/go/here' in header) self.assertFalse(session['user'].isAdmin()) self.assertEquals(['validateUser', 'hasUser'], [m.name for m in observer.calledMethods]) self.assertEquals({'username': '******', 'password':'******'}, observer.calledMethods[0].kwargs) result = asString(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /home' in header, header) def testLoginWithPOSTsucceeds(self): observer = CallTrace(onlySpecifiedMethods=True, returnValues={'hasUser': True}) self.form = BasicHtmlLoginForm(action='/action', loginPath='/login', home='/home') self.form.addObserver(observer) observer.returnValues['validateUser'] = True Body = urlencode(dict(username='******', password='******')) session = {} result = asString(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals('admin', session['user'].name) self.assertEquals(True, session['user'].isAdmin()) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /home' in header) self.assertEquals(['validateUser', 'hasUser'], [m.name for m in observer.calledMethods]) self.assertEquals({'username': '******', 'password':'******'}, observer.calledMethods[0].kwargs) def testLoginWithPOSTfails(self): observer = CallTrace() self.form.addObserver(observer) observer.returnValues['validateUser'] = False Body = urlencode(dict(username='******', password='******')) session = {} result = asString(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertFalse('user' in session) self.assertEquals({'username':'******', 'errorMessage': 'Invalid username or password'}, session['BasicHtmlLoginForm.formValues']) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /login' in header, header) self.assertEquals(['validateUser'], [m.name for m in observer.calledMethods]) self.assertEquals({'username': '******', 'password':'******'}, observer.calledMethods[0].kwargs) def testLoginEnrichesAUserByAnObserver(self): observer = CallTrace(returnValues={'hasUser': True, 'validateUser': True}) def enrichUser(user): user.title = lambda: "Full username" user.additionalInfo = "more info" observer.methods['enrichUser'] = enrichUser self.form.addObserver(observer) Body = urlencode(dict(username='******', password='******')) session = {} consume(self.form.handleRequest(path='/login', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals("more info", session['user'].additionalInfo) self.assertEquals('Full username', session['user'].title()) self.assertEquals(['validateUser', 'hasUser', 'enrichUser'], observer.calledMethodNames()) def testLoginFormWithError(self): session = {} session['BasicHtmlLoginForm.formValues']={'username': '******', 'errorMessage': 'Invalid <username> or "password"'} result = asString(self.form.loginForm(session=session, path='/show/login')) self.assertEqualsWS("""<div id="login-form"> <p class="error">Invalid <username> or "password"</p> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/show/login"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value='<us"er>'/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Login"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result) def testShowChangePasswordFormEn(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.formValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.changePasswordForm(session=session, path='/show/changepasswordform', arguments={})) self.assertEqualsWS("""<div id="login-change-password-form"> <p class="error">BAD BOY</p> <form method="POST" name="changePassword" action="/action/changepassword"> <input type="hidden" name="formUrl" value="/show/changepasswordform"/> <input type="hidden" name="returnUrl" value="/show/changepasswordform"/> <input type="hidden" name="username" value="username"/> <dl> <dt>Old password</dt> <dd><input type="password" name="oldPassword"/></dd> <dt>New password</dt> <dd><input type="password" name="newPassword"/></dd> <dt>Retype new password</dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Change"/></dd> </dl> </form> </div>""", result) def testShowChangePasswordFormNl(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.formValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.changePasswordForm(session=session, path='/show/changepasswordform', lang="nl", arguments={})) self.assertEqualsWS("""<div id="login-change-password-form"> <p class="error">BAD BOY</p> <form method="POST" name="changePassword" action="/action/changepassword"> <input type="hidden" name="formUrl" value="/show/changepasswordform"/> <input type="hidden" name="returnUrl" value="/show/changepasswordform"/> <input type="hidden" name="username" value="username"/> <dl> <dt>Oud wachtwoord</dt> <dd><input type="password" name="oldPassword"/></dd> <dt>Nieuw wachtwoord</dt> <dd><input type="password" name="newPassword"/></dd> <dt>Herhaal nieuw wachtwoord</dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Aanpassen"/></dd> </dl> </form> </div>""", result) def testShowChangePasswordFormForSpecifiedUser(self): session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.formValues': {'errorMessage': 'BAD BOY'}, } result = asString(self.form.changePasswordForm(session=session, path='/show/changepasswordform', lang="nl", arguments=dict(user=['myuser']), user='******', onlyNewPassword=True)) self.assertEqualsWS("""<div id="login-change-password-form"> <p class="error">BAD BOY</p> <form method="POST" name="changePassword" action="/action/changepassword"> <input type="hidden" name="formUrl" value="/show/changepasswordform?user=myuser"/> <input type="hidden" name="returnUrl" value="/show/changepasswordform"/> <input type="hidden" name="username" value="myuser"/> <dl> <dt>Nieuw wachtwoord</dt> <dd><input type="password" name="newPassword"/></dd> <dt>Herhaal nieuw wachtwoord</dt> <dd><input type="password" name="retypedPassword"/></dd> <dd class="submit"><input type="submit" value="Aanpassen"/></dd> </dl> </form> </div>""", result) def testShowChangePasswordFormErrorWithoutUser(self): session = {} result = asString(self.form.changePasswordForm(session=session, path='/show/changepasswordform', arguments={})) self.assertEqualsWS("""<div id="login-change-password-form"> <p class="error">Please login to change password.</p> </div>""", result) def testChangePasswordMismatch(self): Body = urlencode(dict(username='******', oldPassword='******', newPassword="******", retypedPassword="******", formUrl='/show/changepasswordform')) session = {'user': BasicHtmlLoginForm.User('user')} result = asString(self.form.handleRequest(path='/login/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals({'username':'******', 'errorMessage': 'New passwords do not match'}, session['BasicHtmlLoginForm.formValues']) self.assertEqualsWS("""HTTP/1.0 302 Found\r\nLocation: /show/changepasswordform\r\n\r\n""", result) def testChangePasswordWrongOld(self): observer = CallTrace() self.form.addObserver(observer) observer.returnValues['validateUser'] = False Body = urlencode(dict(username='******', oldPassword='******', newPassword="******", retypedPassword="******", formUrl='/show/changepasswordform')) session = {'user': BasicHtmlLoginForm.User('user')} result = asString(self.form.handleRequest(path='/login/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals({'username':'******', 'errorMessage': 'Username and password do not match'}, session['BasicHtmlLoginForm.formValues']) self.assertEquals("HTTP/1.0 302 Found\r\nLocation: /show/changepasswordform\r\n\r\n", result) def testChangePasswordNoOldNotAllowed(self): observer = CallTrace() self.form.addObserver(observer) observer.returnValues['validateUser'] = False Body = urlencode(dict(username='******', newPassword="******", retypedPassword="******", formUrl='/show/changepasswordform')) session = { 'user': BasicHtmlLoginForm.User('username'), 'BasicHtmlLoginForm.formValues': {} } result = asString(self.form.handleRequest(path='/login/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals({'username':'******', 'errorMessage': 'Username and password do not match'}, session['BasicHtmlLoginForm.formValues']) self.assertEquals("HTTP/1.0 302 Found\r\nLocation: /show/changepasswordform\r\n\r\n", result) def testChangePasswordNoOldForAdminOnlyAllowedForOtherUsers(self): observer = CallTrace() self.form.addObserver(observer) observer.returnValues['validateUser'] = False Body = urlencode(dict(username='******', newPassword="******", retypedPassword="******", formUrl='/show/changepasswordform', returnUrl='/home')) session = { 'user': BasicHtmlLoginForm.User('admin'), 'BasicHtmlLoginForm.formValues': {} } result = asString(self.form.handleRequest(path='/login/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals(['setPassword'], [m.name for m in observer.calledMethods]) self.assertEquals("HTTP/1.0 302 Found\r\nLocation: /home\r\n\r\n", result) def testChangePasswordNoOldForAdminNotAllowed(self): observer = CallTrace() self.form.addObserver(observer) observer.returnValues['validateUser'] = False Body = urlencode(dict(username='******', newPassword="******", retypedPassword="******", formUrl='/show/changepasswordform')) session = { 'user': BasicHtmlLoginForm.User('admin'), 'BasicHtmlLoginForm.formValues': {} } result = asString(self.form.handleRequest(path='/login/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals({'username':'******', 'errorMessage': 'Username and password do not match'}, session['BasicHtmlLoginForm.formValues']) self.assertEquals("HTTP/1.0 302 Found\r\nLocation: /show/changepasswordform\r\n\r\n", result) def testChangePassword(self): observer = CallTrace() self.form.addObserver(observer) observer.returnValues['validateUser'] = True Body = urlencode(dict( username='******', oldPassword='******', newPassword="******", retypedPassword="******", formUrl='/show/changepasswordform', returnUrl='/home')) session = {'user': BasicHtmlLoginForm.User('user')} result = asString(self.form.handleRequest(path='/login/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) self.assertEquals(['validateUser', 'setPassword'], [m.name for m in observer.calledMethods]) self.assertEquals("HTTP/1.0 302 Found\r\nLocation: /home\r\n\r\n", result) def testDeleteUserNoAdmin(self): observer = CallTrace(returnValues={'hasUser': True}) self.form.addObserver(observer) result = asString(self.form.handleRequest( path='/login/remove', Client=('127.0.0.1', 3451), Method='POST', Body=urlencode(dict(username='******', formUrl='/show/userlist')), session={})) self.assertEquals(['hasUser', 'enrichUser'], [m.name for m in observer.calledMethods]) self.assertEquals('HTTP/1.0 401 Unauthorized\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nUnauthorized access.', result) def testDeleteUserAsAdmin(self): observer = CallTrace(returnValues={'hasUser': True}) self.form.addObserver(observer) result = asString(self.form.handleRequest( path='/login/remove', Client=('127.0.0.1', 3451), Method='POST', Body=urlencode(dict(username='******', formUrl='/show/userlist')), session={'user': BasicHtmlLoginForm.User('admin')})) self.assertEquals(['hasUser', 'enrichUser', 'removeUser', 'removeCookies', 'removeCookies'], [m.name for m in observer.calledMethods]) self.assertEquals("HTTP/1.0 302 Found\r\nLocation: /show/userlist\r\n\r\n", result) def testDeleteNonExistingUser(self): observer = CallTrace(returnValues={'hasUser': False}, ) self.form.addObserver(observer) session = {'user': BasicHtmlLoginForm.User('admin')} result = asString(self.form.handleRequest( path='/login/remove', Client=('127.0.0.1', 3451), Method='POST', Body=urlencode(dict(username='******', formUrl='/show/userlist')), session=session)) self.assertEquals(['hasUser'], [m.name for m in observer.calledMethods]) self.assertEquals('HTTP/1.0 401 Unauthorized\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nUnauthorized access.', result) def testDeleteByAdministriveUser(self): observer = CallTrace(returnValues={'hasUser': True, 'removeUser': None}, onlySpecifiedMethods=True) self.form.addObserver(observer) session = {'user': self.form.loginAsUser('admin')} observer.calledMethods.reset() result = asString(self.form.handleRemove(session=session, Body=urlencode(dict(username='******')))) self.assertEquals("HTTP/1.0 302 Found\r\nLocation: /home\r\n\r\n", result) self.assertEquals(['hasUser', 'removeUser'], [m.name for m in observer.calledMethods]) def testDeleteByUserOfAdminNotAllowed(self): observer = CallTrace(returnValues={'hasUser': True, 'removeUser': None}, onlySpecifiedMethods=True) self.form.addObserver(observer) session = {'user': self.form.loginAsUser('user')} observer.calledMethods.reset() result = asString(self.form.handleRemove(session=session, Body=urlencode(dict(username='******')))) self.assertEquals('HTTP/1.0 401 Unauthorized\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nUnauthorized access.', result) self.assertEquals(['hasUser'], [m.name for m in observer.calledMethods]) def testDeleteSelfNotAllowed(self): observer = CallTrace(returnValues={'hasUser': True, 'removeUser': None}, onlySpecifiedMethods=True) self.form.addObserver(observer) session = {'user': self.form.loginAsUser('admin')} observer.calledMethods.reset() result = asString(self.form.handleRemove(session=session, Body=urlencode(dict(username='******')))) self.assertEquals('HTTP/1.0 401 Unauthorized\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nUnauthorized access.', result) self.assertEquals(['hasUser'], [m.name for m in observer.calledMethods]) @stdout_replaced def testNewUserWithPOSTsucceeds(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) observer = CallTrace() self.form.addObserver(observer) pf.addUser('existing', 'password') Body = urlencode(dict(username='******', password='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) session = {'user': BasicHtmlLoginForm.User('admin')} result = asString(self.form.handleRequest(path='/action/newUser', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /return' in header) self.assertEquals(set(['existing', 'newuser', 'admin']), set(pf.listUsernames())) self.assertTrue(pf.validateUser('newuser', 'secret')) self.assertEquals('Added user "newuser"', session['BasicHtmlLoginForm.newUserFormValues']['successMessage']) self.assertEqual(['addUser', 'handleNewUser'], observer.calledMethodNames()) self.assertEqual({'username': '******', 'password': '******'}, observer.calledMethods[0].kwargs) self.assertEqual({'Body': 'username=newuser&formUrl=%2Fpage%2FnewUser&password=secret&returnUrl=%2Freturn&retypedPassword=secret', 'username': '******'}, observer.calledMethods[1].kwargs) @stdout_replaced def testNewUserWithoutAnyUser(self): session = {} pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) Body = urlencode(dict(username='******', password='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) result = asString(self.form.handleRequest(path='/action/newUser', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertEquals(['admin'], pf.listUsernames()) self.assertTrue('401' in header) @stdout_replaced def testNewUserWithoutRights(self): session = {'user': BasicHtmlLoginForm.User('auser')} pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) Body = urlencode(dict(username='******', password='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) result = asString(self.form.handleRequest(path='/action/newUser', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertEquals(['admin'], pf.listUsernames()) self.assertTrue('401' in header) @stdout_replaced def testNewUserWithPOSTFails(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('existing', 'password') pf.addUser('newuser', 'oldpassword') Body = urlencode(dict(username='******', password='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) session = {'user': BasicHtmlLoginForm.User('admin')} result = asString(self.form.handleRequest(path='/action/newUser', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /page/newUser' in header) self.assertEquals(set(['existing', 'newuser', 'admin']), set(pf.listUsernames())) self.assertTrue(pf.validateUser('newuser', 'oldpassword')) self.assertFalse(pf.validateUser('newuser', 'newpassword')) self.assertEquals({'errorMessage':'User already exists.', 'username':'******'}, session['BasicHtmlLoginForm.newUserFormValues']) @stdout_replaced def testNewEmptyPassword(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('existing', 'password') Body = urlencode(dict(username='******', oldPassword='******', newPassword='', retypedPassword='', formUrl='/page/newUser', returnUrl='/return')) session = {'user': BasicHtmlLoginForm.User('admin')} result = asString(self.form.handleRequest(path='/action/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /page/newUser' in header) self.assertEquals(set(['existing', 'admin']), set(pf.listUsernames())) self.assertTrue(pf.validateUser('existing', 'password')) self.assertEquals({'errorMessage':'New password is invalid.', 'username':'******'}, session['BasicHtmlLoginForm.formValues']) @stdout_replaced def testChangePassword_withEmptySession(self): # A.k.a. not logged-in. pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('existing', 'password') Body = urlencode(dict(username='******', oldPassword='******', newPassword='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) session = {} result = asString(self.form.handleRequest(path='/action/changepassword', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /page/newUser' in header) self.assertEquals(set(['existing', 'admin']), set(pf.listUsernames())) self.assertTrue(pf.validateUser('existing', 'password')) self.assertEquals( {'errorMessage': 'Login required for "change password".', 'username': '******'}, session['BasicHtmlLoginForm.formValues']) @stdout_replaced def testNewUserWithPOSTFailsDifferentPasswords(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('existing', 'password') Body = urlencode(dict(username='******', password='******', retypedPassword='******', formUrl='/page/newUser', returnUrl='/return')) session = {'user': BasicHtmlLoginForm.User('admin')} result = asString(self.form.handleRequest(path='/action/newUser', Client=('127.0.0.1', 3451), Method='POST', Body=Body, session=session)) header, body = result.split(CRLF*2) self.assertTrue('302' in header) self.assertTrue('Location: /page/newUser' in header) self.assertEquals(set(['existing', 'admin']), set(pf.listUsernames())) self.assertEquals({'errorMessage':'Passwords do not match', 'username':'******'}, session['BasicHtmlLoginForm.newUserFormValues']) @stdout_replaced def testShowUserList(self): pf = PasswordFile(join(self.tempdir, 'passwd')) self.form.addObserver(pf) pf.addUser('one', 'password') pf.addUser('two', 'password') pf.addUser('three', 'password') def enrichUser(user): user.title = lambda: user.name.title() o = CallTrace(onlySpecifiedMethods=True, methods=dict(enrichUser=enrichUser)) self.form.addObserver(o) session = {'user': self.form.loginAsUser('two')} session['user'].canEdit = lambda username=None: username not in ['two', 'admin'] result = asString(self.form.userList(session=session, path='/show/login')) self.assertEqualsWS("""<div id="login-user-list"> <script type="text/javascript"> function deleteUser(username) { if (confirm("Are you sure?")) { document.removeUser.username.value = username; document.removeUser.submit(); } } </script> <form name="removeUser" method="POST" action="/action/remove"> <input type="hidden" name="formUrl" value="/show/login"/> <input type="hidden" name="username"/> </form> <ul> <li>Admin</li> <li>One <a href="javascript:deleteUser('one');">delete</a></li> <li>Three <a href="javascript:deleteUser('three');">delete</a></li> <li>Two</li> </ul> </div>""", result) result = asString(self.form.userList(session=session, path='/show/login', userLink='/user')) self.assertEqualsWS("""<div id="login-user-list"> <script type="text/javascript"> function deleteUser(username) { if (confirm("Are you sure?")) { document.removeUser.username.value = username; document.removeUser.submit(); } } </script> <form name="removeUser" method="POST" action="/action/remove"> <input type="hidden" name="formUrl" value="/show/login"/> <input type="hidden" name="username"/> </form> <ul> <li><a href="/user?user=admin">Admin</a></li> <li><a href="/user?user=one">One</a> <a href="javascript:deleteUser('one');">delete</a></li> <li><a href="/user?user=three">Three</a> <a href="javascript:deleteUser('three');">delete</a></li> <li><a href="/user?user=two">Two</a></li> </ul> </div>""", result) def testBroadcastAddUserToAllObservers(self): values = [] dna = be( (Observable(), (BasicHtmlLoginForm(action="/action", loginPath="/"), (CallTrace(methods={'addUser': lambda *args, **kwargs: values.append(("1st", args, kwargs))}),), (CallTrace(methods={'addUser': lambda *args, **kwargs: values.append(("2nd", args, kwargs))}),), (CallTrace(methods={'addUser': lambda *args, **kwargs: values.append(("3rd", args, kwargs))}),), ) ) ) asString(dna.all.handleNewUser(session={'user': BasicHtmlLoginForm.User('admin')}, Body=urlencode(dict(password="******", retypedPassword="******", username='******')))) self.assertEquals(3, len(values)) def testSetRememberMeCookie(self): observer = CallTrace( methods={ 'validateUser': lambda username, password: True, 'createCookie': lambda user: dict( cookie='THIS IS THE COOKIE VALUE', header='Set-Cookie: somevalue', ) }, onlySpecifiedMethods=True, returnValues={'hasUser': True}) basicHtmlLoginForm = BasicHtmlLoginForm( action="/action", loginPath="/", home="/index", rememberMeCookie=True) basicHtmlLoginForm._now = lambda: 3600 dna = be( (Observable(), (basicHtmlLoginForm, (observer, ) ) ) ) session = {} header, _ = asString(dna.all.handleRequest( Method="POST", path="/", session=session, Body=urlencode(dict(username="******", password="******", rememberMe="on")) )).split('\r\n\r\n', 1) self.assertTrue('user' in session, session) headers = headerToDict(header) self.assertEquals("/index", headers['Location']) self.assertTrue('Set-Cookie' in headers, headers) self.assertEquals("somevalue", headers['Set-Cookie']) def testLoginForWithRememberMe(self): form = BasicHtmlLoginForm( action='/action', loginPath='/login', home='/home', rememberMeCookie=True) result = asString(form.loginForm(session={}, path='/page/login2')) self.assertEqualsWS("""<div id="login-form"> <form method="POST" name="login" action="/action"> <input type="hidden" name="formUrl" value="/page/login2"/> <dl> <dt>Username</dt> <dd><input type="text" name="username" value=""/></dd> <dt>Password</dt> <dd><input type="password" name="password"/></dd> <dt> </dt><dd class="rememberMe"><input type="checkbox" name="rememberMe" id="rememberMe" /><label for="rememberMe">Remember me</label></dd> <dd class="submit"><input type="submit" id="submitLogin" value="Login"/></dd> </dl> </form> <script type="text/javascript"> document.getElementById("submitLogin").focus() </script> </div>""", result) def testLogout(self): session = {'user': '******', 'someother': 'value'} result = asString(self.form.logout(session=session, ignored='kwarg', Headers={})) self.assertEquals(redirectHttp % '/home', result) self.assertEqual({'someother': 'value'}, session) def testLogoutWithRememberMe(self): form = BasicHtmlLoginForm(action='/action', loginPath='/login', home='/home', rememberMeCookie=True) observer = CallTrace(onlySpecifiedMethods=True) observer.returnValues['cookieName'] = 'remember-cookie' observer.returnValues['removeCookie'] = None form.addObserver(observer) session = {'user': '******', 'someother': 'value'} result = asString(form.logout(session=session, ignored='kwarg', Headers={'Cookie':'remember-cookie=cookieId;othercookie=value'})) self.assertEquals('HTTP/1.0 302 Found\r\nSet-Cookie: remember-cookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/\r\nLocation: /home\r\n\r\n', result) self.assertEqual({'someother': 'value'}, session) self.assertEqual(['cookieName', 'removeCookie'], observer.calledMethodNames()) self.assertEquals(('cookieId',), observer.calledMethods[1].args) def testCanEdit(self): admin = BasicHtmlLoginForm.User('admin') other = BasicHtmlLoginForm.User('other') self.assertTrue(admin.canEdit('other')) self.assertTrue(admin.canEdit(other)) self.assertTrue(other.canEdit('other')) self.assertTrue(other.canEdit(other)) self.assertFalse(other.canEdit('admin')) self.assertFalse(other.canEdit(admin))