Example #1
0
    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()
Example #2
0
    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()
Example #3
0
    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
Example #4
0
    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 = "*****@*****.**"
Example #5
0
    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)