def addIncoming(self, IN, emailAddress): IN.isActive = True IN.host = u"imap.test.com" IN.replyToAddress = emailAddress IN.username = u"test" IN.password = password.Password(itsView=IN.itsView, itsParent=IN) waitForDeferred(IN.password.encryptPassword(u'test')) self.calc()
def addOutgoing(self, OUT, emailAddress): OUT.isActive = True OUT.host = u"host.test.com" OUT.fromAddress = emailAddress OUT.username = u"test" OUT.password = password.Password(itsView=OUT.itsView, itsParent=OUT) waitForDeferred(OUT.password.encryptPassword(u'test')) OUT.userAuth = True self.calc()
def _setCurAccount(self, settings): self.smtpAccount.host = self.hostname self.smtpAccount.port = settings['port'] self.smtpAccount.connectionSecurity = settings['connectionSecurity'] #Reset all username and password info self.smtpAccount.useAuth = False self.smtpAccount.username = u"" if not hasattr(self.smtpAccount, 'password'): self.smtpAccount.password = password.Password( itsView=self.smtpAccount.itsView, itsParent=self.smtpAccount) waitForDeferred(self.smtpAccount.password.clear()) self.curAccount = self.smtpAccount
def __populateAccount(self, account): #XXX: i18n usernames and passwords can be non-ascii. # Need to investigate how best to deal with this as # there is no standard. It is server implementation dependent. account.username = uw("test") account.password = password.Password(itsView=account.itsView, itsParent=account) waitForDeferred(account.password.encryptPassword(uw("test"))) account.host = uw("test") if type(account) == Mail.AccountBase: account.port = 1 account.connectionSecurity = "NONE" if type(account) == Mail.SMTPAccount: account.fullName = uw("test") account.replyToAddress = Mail.EmailAddress(itsView=account.itsView) account.replyToAddress.emailAddress = "*****@*****.**"
def _setCurAccount(self, settings): if settings['type'] == "IMAP": self.imapAccount.host = self.hostname self.imapAccount.port = settings['port'] self.imapAccount.connectionSecurity = settings[ 'connectionSecurity'] self.curAccount = self.imapAccount elif settings['type'] == "POP": self.popAccount.host = self.hostname self.popAccount.port = settings['port'] self.popAccount.connectionSecurity = settings['connectionSecurity'] self.curAccount = self.popAccount else: #XXX this should never be reached raise Exception() # reset all username and password info self.curAccount.username = u"" if not hasattr(self.curAccount, 'password'): self.curAccount.password = password.Password( itsView=self.curAccount.itsView, itsParent=self.curAccount) waitForDeferred(self.curAccount.password.clear())
def testPassword(self): self.loadParcel("osaf.framework.MasterPassword") self.loadParcel("osaf.framework.password") pword = uw('my secr3t p4ssw0rd') masterPassword = uw('M0r3 s3cr3t') self.assertEqual(masterPassword, unicode(masterPassword.encode('utf8'), 'utf8')) # create pw = password.Password(itsView=self.view) # check that we can't get password yet self.assertFalse(waitForDeferred(pw.initialized())) # Check that empty values lead to uninitialized as well pw.ciphertext = '' pw.iv = '' pw.salt = '' self.assertFalse(waitForDeferred(pw.initialized())) # And that bad values leads to DecryptionError pw.ciphertext = \ unhexlify('0001efa4bd154ee415b9413a421cedf04359fff945a30e7c115465b1c780a85b65c0e45c') pw.iv = unhexlify('5cd148eeaf680d4ff933aed83009cad4110162f53ef89fd44fad09611b0524d4') pw.salt = unhexlify('a48e09ba0530422c7e96fe62643e149efce2a17e026ba98da8ee51a895ead25b') self.assertRaises(password.DecryptionError, waitForDeferred, pw.decryptPassword(masterPassword)) # What happens if we supply wrong master password? pw.ciphertext = unhexlify('908ed5801146c55f7305dd8a07fa468f68fd0e3e7e075c6e42a9f922f8f5b461a2d32cc2eda4130085fa27c2a124d89f6e1c004245f3a1f9f101cb9bb30b6bcfe8685d01bffa2e659f567c9d1c44d564e87b469884de3dd070e9611be4666391') pw.iv = unhexlify('2a4c722617afd356bc0dc9c2cb26aa0013fbaf81928769485ed7c01d333f2952') pw.salt = unhexlify('0ee664ffa11c6856d5c6dc553413b6a3ee7d43b3b2c4252c1b8a4ca308387b9c') self.assertEqual(waitForDeferred(pw.decryptPassword(masterPassword=masterPassword)), pword) self.assertRaises(password.DecryptionError, waitForDeferred, pw.decryptPassword(masterPassword=uw('M0r3 wrongt'))) self.assertRaises(password.DecryptionError, waitForDeferred, pw.decryptPassword(masterPassword='')) # check that we can use even empty master password waitForDeferred(pw.encryptPassword(pword, masterPassword='')) # make sure we didn't do anything stupid self._dontBeStupid(pw, pword, masterPassword='') # confirm we can get the password out self.assertEqual(waitForDeferred(pw.decryptPassword(masterPassword='')), pword) # check normal waitForDeferred(pw.encryptPassword(pword, masterPassword=masterPassword)) # make sure we didn't do anything stupid self._dontBeStupid(pw, pword, masterPassword) # confirm we can get the password out self.assertEqual(waitForDeferred(pw.decryptPassword(masterPassword=masterPassword)), pword) # and double check... self._dontBeStupid(pw, pword, masterPassword) # check long password waitForDeferred(pw.encryptPassword('12345678901234567890123456789012345678901234567890123456789012345678901234567890', masterPassword=masterPassword)) # make sure we didn't do anything stupid self._dontBeStupid(pw, '12345678901234567890123456789012345678901234567890123456789012345678901234567890', masterPassword, 320) # confirm we can get the password out self.assertEqual(waitForDeferred(pw.decryptPassword(masterPassword=masterPassword)), '12345678901234567890123456789012345678901234567890123456789012345678901234567890') waitForDeferred(pw.encryptPassword('A'*959, masterPassword=masterPassword)) self.assertRaises(password.PasswordTooLong, waitForDeferred, pw.encryptPassword('A'*960, masterPassword=masterPassword)) # check empty passwords waitForDeferred(pw.encryptPassword('', masterPassword='')) # make sure we didn't do anything stupid self._dontBeStupid(pw, '', '', 160) # confirm we can get the password out self.assertEqual(waitForDeferred(pw.decryptPassword(masterPassword='')), '') # test async deferred (in our case more like sync...) d = pw.decryptPassword(masterPassword='') self.called = False def callback(passwordString): self.assertEqual(passwordString, '') self.called = True d.addCallback(callback) self.assertTrue(self.called) # clear waitForDeferred(pw.clear()) self.assertFalse(waitForDeferred(pw.initialized())) d = pw.clear() self.called = False def nonecallback(a): self.assertTrue(a is None) self.called = True d.addCallback(nonecallback) self.assertTrue(self.called)
def testMasterPassword(self): self.loadParcel("osaf.framework.MasterPassword") self.loadParcel("osaf.framework.password") self.loadParcel("osaf.app") # Include default Passwords in count # Check master password when it is not set masterPassword = waitForDeferred(MasterPassword.get(self.view)) self.assertEqual(masterPassword, '') prefs = schema.ns("osaf.framework.MasterPassword", self.view).masterPasswordPrefs # check prefs self.assertEqual(prefs.masterPassword, False) self.assertEqual(prefs.timeout, 15) prefs.masterPassword = True # make sure that get at least tries to use wx, and creates MasterPassword self.assertRaises(wx.PyNoAppError, waitForDeferred, MasterPassword.get(self.view)) self.assertTrue(MasterPassword._masterPassword is None) self.assertTrue(MasterPassword._timer is None) # make sure we get the password ok when it's set MasterPassword._masterPassword = '******' self.assertEqual(waitForDeferred(MasterPassword.get(self.view)), 'pass') # timeout prefs.timeout = 1.0/60.0 # 1 second MasterPassword._setTimedPassword('pass', 1) self.assertEqual(waitForDeferred(MasterPassword.get(self.view)), 'pass') time.sleep(1.1) # XXX Don't know how to test timeout, _clear is called and d.addCallback has been called # XXX but what do we need to do to process those callbacks? #self.assertRaises(wx.PyNoAppError, waitForDeferred, MasterPassword.get(self.view)) prefs.timeout = 15 waitForDeferred(MasterPassword.clear()) # make sure that change at least tries to use wx, and creates MasterPassword self.assertRaises(wx.PyNoAppError, waitForDeferred, MasterPassword.change(self.view)) self.assertTrue(MasterPassword._masterPassword is None) self.assertTrue(MasterPassword._timer is None) # change for real # make some passwords to change pw1 = password.Password(itsView=self.view) pw2 = password.Password(itsView=self.view) waitForDeferred(pw1.encryptPassword('foobar', masterPassword='')) waitForDeferred(pw2.encryptPassword('barfoo', masterPassword='')) # try with bad old password first self.assertFalse(MasterPassword._change('dont know', 'secret', self.view, prefs)) # now change self.assertTrue(MasterPassword._change('', 'secret', self.view, prefs)) # verify that the new password works self.assertEqual(waitForDeferred(pw1.decryptPassword(masterPassword='******')), u'foobar') self.assertEqual(waitForDeferred(pw2.decryptPassword(masterPassword='******')), u'barfoo') # and that the old raises the correct exception self.assertRaises(password.DecryptionError, waitForDeferred, pw1.decryptPassword(masterPassword='')) self.assertRaises(password.DecryptionError, waitForDeferred, pw2.decryptPassword(masterPassword='')) # clear MasterPassword._masterPassword = '******' waitForDeferred(MasterPassword.clear()) self.assertTrue(MasterPassword._masterPassword is None) self.assertTrue(MasterPassword._timer is None) # reset count = 0 for item in password.Password.iterItems(self.view): count += 1 self.assertEqual(count, 8) # dummy + 2 above + 6 default MasterPassword.reset(self.view) # now reset self.assertTrue(MasterPassword._masterPassword is None) self.assertTrue(MasterPassword._timer is None) # we should have just one initialized password (the dummy) count = 0 for item in password.Password.iterItems(self.view): if not waitForDeferred(item.initialized()): continue waitForDeferred(item.decryptPassword(masterPassword='')) self.assertEqual(item.itsName, 'dummyPassword') count += 1 self.assertEqual(count, 1) # quality tests self.assertEqual(MasterPassword.quality(''), (0, 35)) self.assertEqual(MasterPassword.quality('a'), (0, 35)) self.assertEqual(MasterPassword.quality('abb'), (6, 35)) self.assertEqual(MasterPassword.quality('aghj5s'), (14, 35)) self.assertEqual(MasterPassword.quality('aGhj5s'), (16, 35)) self.assertEqual(MasterPassword.quality('aGh!5s'), (21, 35)) self.assertEqual(MasterPassword.quality('aGh!5s.Vos2dd'), (34, 35)) self.assertEqual(MasterPassword.quality('aGh!5s.Vos2ddd'), (35, 35)) self.assertEqual(MasterPassword.quality('aGh!5s.Vos2dddF#@8'), (35, 35)) self.assertEqual(MasterPassword.quality(uw('aghj5s')), (18, 35)) #i18n
def installParcel(parcel, oldVersion=None): view = parcel.itsView # Create our one collection of indexDefinition mappings; when each gets # created, its __init__ will add it to this collection automagically. AllIndexDefinitions.update(parcel, "allIndexDefinitions") Reference.update(parcel, 'currentContact') MailPreferences.update(parcel, 'MailPrefs') Reference.update(parcel, 'currentMeEmailAddress') cur = Reference.update(parcel, 'currentIncomingAccount') cur1 = Reference.update(parcel, 'currentOutgoingAccount') if cur.item is None: cur.item = IMAPAccount(itsView=view, displayName=_(u'Incoming Mail'), replyToAddress=EmailAddress(itsView=view), password=password.Password(itsView=view)) if cur1.item is None: cur1.item = SMTPAccount( itsView=view, displayName=_(u'Outgoing Mail'), password=password.Password(itsView=view), ) trashCollection = ListCollection.update(parcel, 'trashCollection', displayName=_(u"Trash")) notes = KindCollection.update(parcel, 'noteCollection', kind=Note.getKind(view), recursive=True) mine = UnionCollection.update(parcel, 'mine') # it would be nice to get rid of these intermediate fully-fledged # item collections, and replace them with lower level Set objects mineNotes = IntersectionCollection.update(parcel, 'mineNotes', sources=[mine, notes]) nonOccurrenceFilter = NonOccurrenceFilter(None, parcel) nonRecurringNotes = FilteredCollection.update( parcel, 'nonRecurringNotes', source=mineNotes, filterMethod=(nonOccurrenceFilter, 'isNonOccurrence'), filterAttributes=[ EventStamp.occurrenceFor.name, EventStamp.modificationFor.name, EventStamp.occurrences.name ]) nonRecurringNotes.addIndex('__adhoc__', 'numeric') allContentItems = KindCollection.update(parcel, 'allContentItems', kind=ContentItem.getKind(view), recursive=True) contentItems = FilteredCollection.update( parcel, 'contentItems', source=allContentItems, filterMethod=(nonOccurrenceFilter, 'isNotPureOccurrence'), filterAttributes=[ EventStamp.occurrenceFor.name, EventStamp.modificationFor.name ]) allReminders = KindCollection.update(parcel, 'allReminders', kind=Reminder.getKind(view), recursive=True) allFutureReminders = FilteredCollection.update( parcel, 'allFutureReminders', source=allReminders, filterMethod=(UnexpiredFilter(None, parcel), 'notExpired'), filterAttributes=[UnexpiredFilter.findValuePair[0]], ) allFutureReminders.addIndex('reminderPoll', 'method', method=(UnexpiredFilter(None, parcel), 'compare'), monitor=[UnexpiredFilter.findValuePair[0]]) # the "All" / "My" collection allCollection = SmartCollection.update( parcel, 'allCollection', displayName=_(u"Dashboard"), source=nonRecurringNotes, exclusions=trashCollection, trash=None, ) # kludge to improve on bug 4144 (not a good long term fix but fine for 0.6) allCollection.addIndex('__adhoc__', 'numeric') events = EventStamp.getCollection(view) eventComparator = EventComparator.update(parcel, 'eventComparator') EventStamp.addIndex(events, 'effectiveStart', 'method', method=(eventComparator, 'cmpStartTime'), monitor=(EventStamp.startTime, EventStamp.allDay, EventStamp.anyTime), kind=ContentItem.getKind(view)) EventStamp.addIndex(events, 'effectiveEnd', 'method', method=(eventComparator, 'cmpEndTime'), monitor=(EventStamp.startTime, EventStamp.allDay, EventStamp.anyTime, EventStamp.duration), kind=ContentItem.getKind(view)) # floatingEvents need to be reindexed in effectiveStart and effectiveEnd # when the floating timezone changes filterAttributes = [entry[0] for entry in _FILTER_ATTRIBUTES] floatingEvents = FilteredCollection.update( parcel, 'floatingEvents', source=events, filterMethod=(FloatingEventFilter(None, parcel), 'isFloatingEvent'), filterAttributes=filterAttributes) floatingEvents.addIndex('__adhoc__', 'numeric') # UTCEvents need to be reindexed in effectiveStartNoTZ and effectiveEndNoTZ # when the floating timezone changes, because UTC events are treated # specially UTCEvents = FilteredCollection.update(parcel, 'UTCEvents', source=events, filterMethod=(UTCEventFilter( None, parcel), 'isUTCEvent'), filterAttributes=filterAttributes) UTCEvents.addIndex('__adhoc__', 'numeric') longEvents = FilteredCollection.update( parcel, 'longEvents', source=events, filterMethod=(LongEventFilter(None, parcel), 'isLongEvent'), filterAttributes=[EventStamp.duration.name]) longEvents.addIndex('effectiveStart', 'subindex', superindex=(events, events.__collection__, 'effectiveStart')) longEvents.addIndex('effectiveEnd', 'subindex', superindex=(events, events.__collection__, 'effectiveEnd')) filterAttributes = (EventStamp.rruleset.name, EventStamp.occurrences.name) masterFilter = "view.hasTrueValues(uuid, '%s', '%s')" % filterAttributes nonMasterFilter = "not " + masterFilter masterEvents = FilteredCollection.update( parcel, 'masterEvents', source=events, filterExpression=masterFilter, filterAttributes=list(filterAttributes)) nonMasterEvents = FilteredCollection.update( parcel, 'nonMasterEvents', source=events, filterExpression=nonMasterFilter, filterAttributes=list(filterAttributes)) MasterEventWatcher.update(parcel, 'masterEventWatcher', targetCollection=masterEvents) EventStamp.addIndex(masterEvents, "recurrenceEnd", 'method', method=(eventComparator, 'cmpRecurEnd'), monitor=(EventStamp.recurrenceEnd, )) EventStamp.addIndex(masterEvents, 'effectiveStart', 'subindex', superindex=(events, events.__collection__, 'effectiveStart')) locations = KindCollection.update(parcel, 'locations', kind=Location.getKind(view), recursive=True) locations.addIndex('locationName', 'value', attribute='displayName', nodefer=True) mailCollection = mail.MailStamp.getCollection(view) kind = mail.EmailAddress.getKind(view) emailAddressCollection = \ KindCollection.update(parcel, 'emailAddressCollection', kind=kind, recursive=True) emailComparator = EmailComparator.update(parcel, 'emailComparator') emailAddressCollection.addIndex('emailAddress', 'method', method=(emailComparator, 'cmpAddress'), monitor='emailAddress', nodefer=True) emailAddressCollection.addIndex('fullName', 'method', method=(emailComparator, 'cmpFullName'), monitor='fullName', nodefer=True) emailAddressCollection.addIndex('both', 'method', method=(emailComparator, 'cmpBoth'), monitor=('emailAddress', 'fullName'), nodefer=True, kind=kind) # Contains all current me addresses (that is, referenced by an account) currentMeEmailAddresses = ListCollection.update(parcel, 'currentMeEmailAddresses') currentMeEmailAddresses.addIndex('emailAddress', 'method', method=(emailComparator, 'cmpAddress'), monitor='emailAddress') # Contains all current and former me addresses meEmailAddressCollection = ListCollection.update( parcel, 'meEmailAddressCollection') meEmailAddressCollection.addIndex('emailAddress', 'method', method=(emailComparator, 'cmpAddress'), monitor='emailAddress') inSource = ToMeFilter.makeCollection(parcel, 'inSource', mailCollection) # this index must be added to shield from the duplicate # source (mailCollection) that is going to be in mine inSource.addIndex('__adhoc__', 'numeric') # The "In" collection inCollection = SmartCollection.update(parcel, 'inCollection', displayName=_(u"In"), source=inSource, trash=trashCollection, visible=True) mine.addSource(inCollection) outSource = FromMeFilter.makeCollection(parcel, 'outSource', mailCollection) # this index must be added to shield from the duplicate # source (mailCollection) that is going to be in mine outSource.addIndex('__adhoc__', 'numeric') # The "Out" collection outCollection = SmartCollection.update( parcel, 'outCollection', displayName=_(u"Out"), visible=True, source=outSource, trash=trashCollection, ) mine.addSource(outCollection) allEventsCollection = IntersectionCollection.update( parcel, 'allEventsCollection', sources=[allCollection, events]) searchResultsUnfiltered = SmartCollection.update( parcel, 'searchResultsUnfiltered', displayName=messages.UNTITLED) searchResults = DifferenceCollection.update( parcel, 'searchResults', sources=[searchResultsUnfiltered, masterEvents], displayName=messages.UNTITLED) TriageStatusReminder.update(parcel, 'triageStatusReminder') startup.Startup.update(parcel, "installWatchers", invoke=__name__ + ".installWatchers") tzInstallParcel(parcel)