def start_client(self):
        soledad_test_folder = self._generate_soledad_test_folder_name()
        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.cleanup = lambda: shutil.rmtree(soledad_test_folder)

        self.soledad = yield initialize_soledad(tempdir=soledad_test_folder)

        self.keymanager = mock()

        self.search_engine = SearchEngine(self.INDEX_KEY,
                                          agent_home=soledad_test_folder)
        self.mail_sender = self._create_mail_sender()

        self.mail_store = SearchableMailStore(LeapMailStore(self.soledad),
                                              self.search_engine)

        account_ready_cb = defer.Deferred()
        self.account = IMAPAccount(self.ACCOUNT, self.soledad,
                                   account_ready_cb)
        yield account_ready_cb
        self.draft_service = DraftService(self.mail_store)
        self.leap_session = mock()
        self.feedback_service = FeedbackService(self.leap_session)

        self.mail_service = self._create_mail_service(self.mail_sender,
                                                      self.mail_store,
                                                      self.search_engine)
        mails = yield self.mail_service.all_mails()
        self.search_engine.index_mails(mails)

        self.resource = RootResource()
        self.resource.initialize(self.keymanager, self.search_engine,
                                 self.mail_service, self.draft_service,
                                 self.feedback_service)
示例#2
0
    def start_client(self, mode=UserAgentMode(is_single_user=True)):
        self._initialize()
        self._mode = mode
        self._test_account = AppTestAccount(self.ACCOUNT, self._tmp_dir.name)

        yield self._test_account.start()

        self.cleanup = lambda: self._tmp_dir.dissolve()

        # copy fields for single user tests
        self.soledad = self._test_account.soledad
        self.search_engine = self._test_account.search_engine
        self.keymanager = self._test_account.keymanager
        self.mail_sender = self._test_account.mail_sender
        self.mail_store = self._test_account.mail_store
        self.attachment_store = self._test_account.attachment_store
        self.draft_service = self._test_account.draft_service
        self.leap_session = self._test_account.leap_session
        self.feedback_service = self._test_account.feedback_service
        self.mail_service = self._test_account.mail_service
        self.account = self._test_account.account

        if mode.is_single_user:
            self.service_factory = SingleUserServicesFactory(mode)
            services = self._test_account.services
            self.service_factory.add_session('someuserid', services)

            self.resource = RootResource(self.service_factory)
            self.resource.initialize()
        else:
            self.service_factory = StubServicesFactory(self.accounts, mode)
            provider = mock()
            provider.config = LeapConfig(self._tmp_dir.name)

            self.resource = set_up_protected_resources(RootResource(self.service_factory), provider, self.service_factory, checker=StubSRPChecker(provider))
    def setUp(self):
        self.mail_service = mock()
        self.services_factory = mock()
        self.services_factory.mode = UserAgentMode(is_single_user=True)
        self.services = mock()
        self.services.mail_service = self.mail_service
        self.services_factory._services_by_user = {'someuserid': self.mail_service}
        when(self.services_factory).services(ANY()).thenReturn(self.services)
        self.mail_service.account_email = self.MAIL_ADDRESS

        root_resource = RootResource(self.services_factory)
        root_resource._html_template = "<html><head><title>$account_email</title></head></html>"
        root_resource._mode = root_resource
        self.web = DummySite(root_resource)
    def setUp(self):
        self.mail_service = mock()
        self.services_factory = mock()
        self.services_factory.mode = UserAgentMode(is_single_user=True)
        self.services = mock()
        self.services.mail_service = self.mail_service
        self.services_factory._services_by_user = {'someuserid': self.mail_service}
        when(self.services_factory).services(ANY()).thenReturn(self.services)
        self.mail_service.account_email = self.MAIL_ADDRESS

        root_resource = RootResource(self.services_factory)
        root_resource._html_template = "<html><head><title>$account_email</title></head></html>"
        root_resource._mode = root_resource
        self.web = DummySite(root_resource)
        self.root_resource = root_resource
    def start_client(self):
        soledad_test_folder = self._generate_soledad_test_folder_name()
        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.cleanup = lambda: shutil.rmtree(soledad_test_folder)

        PixelatedMail.from_email_address = self.MAIL_ADDRESS

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.soledad_querier = self._create_soledad_querier(
            self.soledad, self.INDEX_KEY)
        self.keymanager = mock()

        self.search_engine = SearchEngine(self.soledad_querier,
                                          agent_home=soledad_test_folder)
        self.mail_sender = self._create_mail_sender()

        self.account = SoledadBackedAccount(self.ACCOUNT, self.soledad,
                                            MagicMock())
        self.mailboxes = Mailboxes(self.account, self.soledad_querier,
                                   self.search_engine)
        self.draft_service = DraftService(self.mailboxes)

        self.mail_service = self._create_mail_service(self.mailboxes,
                                                      self.mail_sender,
                                                      self.soledad_querier,
                                                      self.search_engine)
        self.search_engine.index_mails(self.mail_service.all_mails())

        self.app = App()
        self.app.resource = RootResource()
        self.app.resource.initialize(self.soledad_querier, self.keymanager,
                                     self.search_engine, self.mail_service,
                                     self.draft_service)
示例#6
0
def start_pixelated_user_agent(userid, soledad, keymanager, account):

    try:
        leap_session = LeapSessionAdapter(userid, soledad, keymanager, account)
    except Exception as exc:
        log.error("Got error! %r" % exc)

    config = Config()
    leap_home = os.path.join(get_path_prefix(), 'leap')
    config.leap_home = leap_home
    leap_session.config = config

    services_factory = SingleUserServicesFactory(
        UserAgentMode(is_single_user=True))

    if getattr(sys, 'frozen', False):
        # we are running in a |PyInstaller| bundle
        static_folder = os.path.join(sys._MEIPASS, 'leap', 'pixelated_www')
    else:
        static_folder = os.path.abspath(leap.pixelated_www.__path__[0])

    set_static_folder(static_folder)
    resource = RootResource(services_factory, static_folder=static_folder)

    config.host = 'localhost'
    config.port = 9090
    config.sslkey = None
    config.sslcert = None
    config.manhole = False

    d = leap_session.account.callWhenReady(
        lambda _: _start_in_single_user_mode(leap_session, config, resource,
                                             services_factory))
    return d
    def start_client(self):
        soledad_test_folder = self._generate_soledad_test_folder_name()
        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.cleanup = lambda: shutil.rmtree(soledad_test_folder)

        self.soledad = yield initialize_soledad(tempdir=soledad_test_folder)

        self.keymanager = mock()

        self.search_engine = SearchEngine(self.INDEX_KEY, agent_home=soledad_test_folder)
        self.mail_sender = self._create_mail_sender()

        self.mail_store = SearchableMailStore(LeapMailStore(self.soledad), self.search_engine)

        account_ready_cb = defer.Deferred()
        self.account = IMAPAccount(self.ACCOUNT, self.soledad, account_ready_cb)
        yield account_ready_cb
        self.draft_service = DraftService(self.mail_store)
        self.leap_session = mock()
        self.feedback_service = FeedbackService(self.leap_session)

        self.mail_service = self._create_mail_service(self.mail_sender, self.mail_store, self.search_engine)
        mails = yield self.mail_service.all_mails()
        self.search_engine.index_mails(mails)

        self.resource = RootResource()
        self.resource.initialize(
            self.keymanager, self.search_engine, self.mail_service, self.draft_service, self.feedback_service
        )
    def start_client(self, mode=UserAgentMode(is_single_user=True)):
        self._initialize()
        self._mode = mode
        self._test_account = AppTestAccount(self.ACCOUNT, self._tmp_dir.name)

        yield self._test_account.start()

        self.cleanup = lambda: self._tmp_dir.dissolve()

        # copy fields for single user tests
        self.soledad = self._test_account.soledad
        self.search_engine = self._test_account.search_engine
        self.keymanager = self._test_account.keymanager
        self.mail_sender = self._test_account.mail_sender
        self.mail_store = self._test_account.mail_store
        self.attachment_store = self._test_account.attachment_store
        self.draft_service = self._test_account.draft_service
        self.leap_session = self._test_account.leap_session
        self.feedback_service = self._test_account.feedback_service
        self.mail_service = self._test_account.mail_service
        self.account = self._test_account.account

        if mode.is_single_user:
            self.service_factory = SingleUserServicesFactory(mode)
            services = self._test_account.services
            self.service_factory.add_session('someuserid', services)

            self.resource = RootResource(self.service_factory)
            self.resource.initialize()
        else:
            self.service_factory = StubServicesFactory(self.accounts, mode)
            provider = mock()
            provider.config = LeapConfig(self._tmp_dir.name)

            self.resource = set_up_protected_resources(RootResource(self.service_factory), provider, self.service_factory, checker=StubSRPChecker(provider))
示例#9
0
def initialize():
    args = arguments.parse_user_agent_args()
    logger.init(debug=args.debug)
    resource = RootResource()

    start_site(args, resource)

    deferred = initialize_leap(args.leap_provider_cert,
                               args.leap_provider_cert_fingerprint,
                               args.credentials_file, args.organization_mode,
                               args.leap_home)

    deferred.addCallback(lambda leap_session: start_user_agent(
        resource, args.leap_home, leap_session))

    def _quit_on_error(failure):
        failure.printTraceback()
        reactor.stop()

    def _register_shutdown_on_token_expire(leap_session):
        register(events.SOLEDAD_INVALID_AUTH_TOKEN, lambda _: reactor.stop())
        return leap_session

    deferred.addCallback(_register_shutdown_on_token_expire)
    deferred.addErrback(_quit_on_error)

    reactor.run()
    def __init__(self, soledad_test_folder='/tmp/soledad-test/test'):

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.mail_address = "*****@*****.**"

        # setup app
        PixelatedMail.from_email_address = self.mail_address

        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.app = App()

        self.soledad_querier = SoledadQuerier(self.soledad)
        self.soledad_querier.get_index_masterkey = lambda: self.INDEX_KEY

        self.account = SoledadBackedAccount('test', self.soledad, MagicMock())
        self.mailboxes = Mailboxes(self.account, self.soledad_querier)
        self.mail_sender = Mock()
        self.tag_service = TagService()
        self.draft_service = DraftService(self.mailboxes)
        self.mail_service = MailService(self.mailboxes, self.mail_sender,
                                        self.tag_service, self.soledad_querier)
        self.search_engine = SearchEngine(self.soledad_querier)
        self.search_engine.index_mails(self.mail_service.all_mails())

        self.app.resource = RootResource()

        self.app.resource.initialize(self.soledad_querier, self.search_engine,
                                     self.mail_service, self.draft_service)
示例#11
0
def create_app(app, args, leap_session):
    app.resource = RootResource()
    init_app(app, args.home, leap_session)
    if args.sslkey and args.sslcert:
        listen_with_ssl(app, args)
    else:
        listen_without_ssl(app, args)
def start_user_agent(loading_app, host, port, sslkey, sslcert, leap_home, leap_session):
    yield loading_app.stopListening()

    services = Services(leap_home, leap_session)

    resource = RootResource()

    resource.initialize(
        services.keymanager,
        services.search_engine,
        services.mail_service,
        services.draft_service)

    if sslkey and sslcert:
        reactor.listenSSL(port, Site(resource), _ssl_options(sslkey, sslcert), interface=host)
    else:
        reactor.listenTCP(port, Site(resource), interface=host)

    # soledad needs lots of threads
    reactor.threadpool.adjustPoolsize(5, 15)
示例#13
0
def initialize():
    log.info('Starting the Pixelated user agent')
    args = arguments.parse_user_agent_args()
    logger.init(debug=args.debug)
    services_factory = _create_service_factory(args)
    resource = RootResource(services_factory)

    start_async = _start_mode(args, resource, services_factory)
    add_top_level_system_callbacks(start_async, services_factory)
    log.info('Running the reactor')
    reactor.run()
示例#14
0
def start_user_agent(loading_app, host, port, sslkey, sslcert, leap_home, leap_session):
    yield loading_app.stopListening()

    services = Services(leap_home, leap_session)
    yield services.setup(leap_home, leap_session)

    resource = RootResource()

    resource.initialize(
        services.keymanager,
        services.search_engine,
        services.mail_service,
        services.draft_service)

    if sslkey and sslcert:
        reactor.listenSSL(port, Site(resource), _ssl_options(sslkey, sslcert), interface=host)
    else:
        reactor.listenTCP(port, Site(resource), interface=host)

    # soledad needs lots of threads
    reactor.threadpool.adjustPoolsize(5, 15)
    def start_client(self, mode=UserAgentMode(is_single_user=True)):
        self._initialize()
        self._test_account = AppTestAccount('test', self._tmp_dir.name)

        yield self._test_account.start()

        self.cleanup = lambda: self._test_account.cleanup()
        self.soledad = self._test_account.soledad

        self.service_factory = ServicesFactory(UserAgentMode(is_single_user=False))

        root_resource = RootResource(self.service_factory)
        leap_provider = mock()
        self.resource = set_up_protected_resources(root_resource, leap_provider, self.service_factory)
示例#16
0
def initialize():
    log.info('Starting the Pixelated user agent')
    args = arguments.parse_user_agent_args()
    logger.init(debug=args.debug)
    services_factory = _create_service_factory(args)
    resource = RootResource(services_factory)

    deferred = _start_mode(args, resource, services_factory)

    def _quit_on_error(failure):
        failure.printTraceback()
        reactor.stop()

    def _register_shutdown_on_token_expire(leap_session):
        register(events.SOLEDAD_INVALID_AUTH_TOKEN,
                 lambda *unused: reactor.stop())
        return leap_session

    deferred.addCallback(_register_shutdown_on_token_expire)
    deferred.addErrback(_quit_on_error)

    log.info('Running the reactor')

    reactor.run()
    def start_client(self):
        soledad_test_folder = self._generate_soledad_test_folder_name()
        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.cleanup = lambda: shutil.rmtree(soledad_test_folder)

        PixelatedMail.from_email_address = self.MAIL_ADDRESS

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.soledad_querier = self._create_soledad_querier(self.soledad, self.INDEX_KEY)
        self.keymanager = mock()

        self.search_engine = SearchEngine(self.INDEX_KEY, agent_home=soledad_test_folder)
        self.mail_sender = self._create_mail_sender()

        self.account = SoledadBackedAccount(self.ACCOUNT, self.soledad, MagicMock())
        self.mailboxes = Mailboxes(self.account, self.soledad_querier, self.search_engine)
        self.draft_service = DraftService(self.mailboxes)

        self.mail_service = self._create_mail_service(self.mailboxes, self.mail_sender, self.soledad_querier, self.search_engine)
        self.search_engine.index_mails(self.mail_service.all_mails())

        self.resource = RootResource()
        self.resource.initialize(self.keymanager, self.search_engine, self.mail_service, self.draft_service)
class AppTestClient(object):
    INDEX_KEY = '\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI' \
                '\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad'
    ACCOUNT = 'test'
    MAIL_ADDRESS = '*****@*****.**'

    def __init__(self):
        self.start_client()

    def start_client(self):
        soledad_test_folder = self._generate_soledad_test_folder_name()
        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.cleanup = lambda: shutil.rmtree(soledad_test_folder)

        PixelatedMail.from_email_address = self.MAIL_ADDRESS

        self.soledad = initialize_soledad(tempdir=soledad_test_folder)
        self.soledad_querier = self._create_soledad_querier(self.soledad, self.INDEX_KEY)
        self.keymanager = mock()

        self.search_engine = SearchEngine(self.INDEX_KEY, agent_home=soledad_test_folder)
        self.mail_sender = self._create_mail_sender()

        self.account = SoledadBackedAccount(self.ACCOUNT, self.soledad, MagicMock())
        self.mailboxes = Mailboxes(self.account, self.soledad_querier, self.search_engine)
        self.draft_service = DraftService(self.mailboxes)

        self.mail_service = self._create_mail_service(self.mailboxes, self.mail_sender, self.soledad_querier, self.search_engine)
        self.search_engine.index_mails(self.mail_service.all_mails())

        self.resource = RootResource()
        self.resource.initialize(self.keymanager, self.search_engine, self.mail_service, self.draft_service)

    def _render(self, request, as_json=True):
        def get_str(_str):
            return json.loads(_str) if as_json else _str

        def get_request_written_data(_=None):
            written_data = request.getWrittenData()
            if written_data:
                return get_str(written_data)

        resource = getChildForRequest(self.resource, request)
        result = resource.render(request)

        if isinstance(result, basestring):
            return get_str(result), request

        # result is NOT_DONE_YET
        d = succeed(request) if request.finished else request.notifyFinish()
        d.addCallback(get_request_written_data)
        return d, request

    def run_on_a_thread(self, logfile='/tmp/app_test_client.log', port=4567, host='0.0.0.0'):
        def _start():
            reactor.listenTCP(port, Site(self.resource), interface=host)
            reactor.run()
        process = multiprocessing.Process(target=_start)
        process.start()
        time.sleep(1)
        return lambda: process.terminate()

    def get(self, path, get_args='', as_json=True):
        request = request_mock(path)
        request.args = get_args
        return self._render(request, as_json)

    def post(self, path, body=''):
        request = request_mock(path=path, method="POST", body=body, headers={'Content-Type': ['application/json']})
        return self._render(request)

    def put(self, path, body):
        request = request_mock(path=path, method="PUT", body=body, headers={'Content-Type': ['application/json']})
        return self._render(request)

    def delete(self, path, body=""):
        request = request_mock(path=path, body=body, headers={'Content-Type': ['application/json']}, method="DELETE")
        return self._render(request)

    def add_document_to_soledad(self, _dict):
        self.soledad_querier.soledad.create_doc(_dict)

    def add_mail_to_inbox(self, input_mail):
        mail = self.mailboxes.inbox.add(input_mail)
        if input_mail.tags:
            mail.update_tags(input_mail.tags)
            self.search_engine.index_mail(mail)

    def add_multiple_to_mailbox(self, num, mailbox='', flags=[], tags=[], to='*****@*****.**', cc='*****@*****.**', bcc='*****@*****.**'):
        mails = []
        for _ in range(num):
            input_mail = MailBuilder().with_status(flags).with_tags(tags).with_to(to).with_cc(cc).with_bcc(bcc).build_input_mail()
            mail = self.mailboxes._create_or_get(mailbox).add(input_mail)
            mails.append(mail)
            mail.update_tags(input_mail.tags) if tags else None
        self.search_engine.index_mails(mails) if tags else None
        return mails

    def _create_soledad_querier(self, soledad, index_key):
        soledad_querier = SoledadQuerier(soledad)
        soledad_querier.get_index_masterkey = lambda: index_key
        return soledad_querier

    def _create_mail_sender(self):
        mail_sender = Mock()
        mail_sender.sendmail.side_effect = lambda mail: succeed(mail)
        return mail_sender

    def _create_mail_service(self, mailboxes, mail_sender, soledad_querier, search_engine):
        mail_service = MailService(mailboxes, mail_sender, soledad_querier, search_engine)
        return mail_service

    def _generate_soledad_test_folder_name(self, soledad_test_folder='/tmp/soledad-test/test'):
        return os.path.join(soledad_test_folder, str(uuid.uuid4()))

    def get_mails_by_tag(self, tag, page=1, window=100):
        tags = 'tag:%s' % tag
        return self.search(tags, page, window)

    def search(self, query, page=1, window=100):
        res, req = self.get("/mails", {
            'q': [query],
            'w': [str(window)],
            'p': [str(page)]
        })
        return [ResponseMail(m) for m in res['mails']]

    def get_attachment(self, ident, encoding):
        res, req = self.get("/attachment/%s" % ident, {'encoding': [encoding]}, as_json=False)
        return res

    def put_mail(self, data):
        res, req = self.put('/mails', data)
        return res, req

    def post_tags(self, mail_ident, tags_json):
        res, req = self.post("/mail/%s/tags" % mail_ident, tags_json)
        return res

    def get_tags(self, **kwargs):
        res, req = self.get('/tags', kwargs)
        return res

    def get_mail(self, mail_ident):
        res, req = self.get('/mail/%s' % mail_ident)
        return res

    def delete_mail(self, mail_ident):
        res, req = self.delete("/mail/%s" % mail_ident)
        return req

    def delete_mails(self, idents):
        res, req = self.post("/mails/delete", json.dumps({'idents': idents}))
        return req

    def mark_many_as_unread(self, idents):
        res, req = self.post('/mails/unread', json.dumps({'idents': idents}))
        return req

    def mark_many_as_read(self, idents):
        res, req = self.post('/mails/read', json.dumps({'idents': idents}))
        return req

    def get_contacts(self, query):
        res, req = self.get('/contacts', get_args={'q': query})
        return res
class AppTestClient(object):
    INDEX_KEY = (
        "\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI"
        "\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad"
    )
    ACCOUNT = "test"
    MAIL_ADDRESS = "*****@*****.**"

    def _initialize(self):
        self._tmp_dir = TempDir()
        self.accounts = {}

    @defer.inlineCallbacks
    def start_client(self, mode=UserAgentMode(is_single_user=True)):
        self._initialize()
        self._mode = mode
        self._test_account = AppTestAccount(self.ACCOUNT, self._tmp_dir.name)

        yield self._test_account.start()

        self.cleanup = lambda: self._tmp_dir.dissolve()

        # copy fields for single user tests
        self.soledad = self._test_account.soledad
        self.search_engine = self._test_account.search_engine
        self.keymanager = self._test_account.keymanager
        self.mail_sender = self._test_account.mail_sender
        self.mail_store = self._test_account.mail_store
        self.attachment_store = self._test_account.attachment_store
        self.draft_service = self._test_account.draft_service
        self.leap_session = self._test_account.leap_session
        self.feedback_service = self._test_account.feedback_service
        self.mail_service = self._test_account.mail_service
        self.account = self._test_account.account

        if mode.is_single_user:
            self.service_factory = SingleUserServicesFactory(mode)
            services = self._test_account.services
            self.service_factory.add_session("someuserid", services)

            self.resource = RootResource(self.service_factory)
            self.resource.initialize()
        else:
            self.service_factory = StubServicesFactory(self.accounts, mode)
            provider = mock()
            provider.config = LeapConfig(self._tmp_dir.name)

            self.resource = set_up_protected_resources(
                RootResource(self.service_factory), provider, self.service_factory, checker=StubSRPChecker(provider)
            )

    @defer.inlineCallbacks
    def create_user(self, account_name):
        if self._mode.is_single_user:
            raise Exception("Not supported in single user mode")

        account = AppTestAccount(account_name, self._tmp_dir.name)
        yield account.start()

        self.accounts[account_name] = account

    def _render(self, request, as_json=True):
        def get_str(_str):
            return json.loads(_str) if as_json else _str

        def get_request_written_data(_=None):
            written_data = request.getWrittenData()
            if written_data:
                return get_str(written_data)

        resource = getChildForRequest(self.resource, request)
        result = resource.render(request)

        if isinstance(result, basestring):
            return get_str(result), request

        # result is NOT_DONE_YET
        d = succeed(request) if request.finished else request.notifyFinish()
        d.addCallback(get_request_written_data)
        return d, request

    def listenTCP(self, port=4567, host="127.0.0.1"):
        reactor.listenTCP(port, PixelatedSite(self.resource), interface=host)

    def run_on_a_thread(self, logfile="/tmp/app_test_client.log", port=4567, host="127.0.0.1"):
        def _start():
            self.listenTCP(port, host)
            reactor.run()

        process = multiprocessing.Process(target=_start)
        process.start()
        time.sleep(1)
        return lambda: process.terminate()

    def stop(self):
        reactor.stop()

    def get(self, path, get_args="", as_json=True, ajax=True, csrf="token"):
        request = request_mock(path, ajax=ajax, csrf=csrf)
        request.args = get_args
        return self._render(request, as_json)

    def post(self, path, body="", headers=None, ajax=True, csrf="token"):
        headers = headers or {"Content-Type": "application/json"}
        request = request_mock(path=path, method="POST", body=body, headers=headers, ajax=ajax, csrf=csrf)
        return self._render(request)

    def put(self, path, body, ajax=True, csrf="token"):
        request = request_mock(
            path=path, method="PUT", body=body, headers={"Content-Type": ["application/json"]}, ajax=ajax, csrf=csrf
        )
        return self._render(request)

    def delete(self, path, body="", ajax=True, csrf="token"):
        request = request_mock(
            path=path, body=body, headers={"Content-Type": ["application/json"]}, method="DELETE", ajax=ajax, csrf=csrf
        )
        return self._render(request)

    @defer.inlineCallbacks
    def add_mail_to_inbox(self, input_mail):
        mail = yield self.mail_store.add_mail("INBOX", input_mail.raw)
        defer.returnValue(mail)

    def account_for(self, username):
        return self.accounts[username]

    def add_mail_to_user_inbox(self, input_mail, username):
        return self.account_for(username).mail_store.add_mail("INBOX", input_mail.raw)

    @defer.inlineCallbacks
    def add_multiple_to_mailbox(
        self, num, mailbox="", flags=[], tags=[], to="*****@*****.**", cc="*****@*****.**", bcc="*****@*****.**"
    ):
        mails = []
        yield self.mail_store.add_mailbox(mailbox)
        for _ in range(num):
            builder = MailBuilder().with_status(flags).with_tags(tags).with_to(to).with_cc(cc).with_bcc(bcc)
            builder.with_body(str(random.random()))
            input_mail = builder.build_input_mail()
            mail = yield self.mail_store.add_mail(mailbox, input_mail.raw)
            if tags:
                mail.tags |= set(tags)
            if flags:
                for flag in flags:
                    mail.flags.add(flag)
            if tags or flags:
                yield self.mail_store.update_mail(mail)
            mails.append(mail)

        defer.returnValue(mails)

    def _create_mail_sender(self):
        mail_sender = Mock()
        mail_sender.sendmail.side_effect = lambda mail: succeed(mail)
        return mail_sender

    def _generate_soledad_test_folder_name(self, soledad_test_folder="/tmp/soledad-test/test"):
        return os.path.join(soledad_test_folder, str(uuid.uuid4()))

    def get_mails_by_tag(self, tag, page=1, window=100):
        tags = "tag:%s" % tag
        return self.search(tags, page, window)

    @defer.inlineCallbacks
    def search(self, query, page=1, window=100):
        res, _ = self.get("/mails", {"q": [query], "w": [str(window)], "p": [str(page)]})
        res = yield res
        defer.returnValue([ResponseMail(m) for m in res["mails"]])

    @defer.inlineCallbacks
    def get_mails_by_mailbox_name(self, mbox_name):
        mail_ids = yield self.mail_store.get_mailbox_mail_ids(mbox_name)
        mails = yield self.mail_store.get_mails(mail_ids)
        defer.returnValue(mails)

    @defer.inlineCallbacks
    def get_attachment(self, ident, encoding, filename=None, content_type=None, ajax=True, csrf="token"):
        params = {"encoding": [encoding]}
        if filename:
            params["filename"] = [filename]
        if content_type:
            params["content_type"] = [content_type]
        deferred_result, req = self.get("/attachment/%s" % ident, params, as_json=False, ajax=ajax, csrf=csrf)
        res = yield deferred_result
        defer.returnValue((res, req))

    @defer.inlineCallbacks
    def post_attachment(self, data, headers):
        deferred_result, req = self.post("/attachment", body=data, headers=headers)
        res = yield deferred_result
        defer.returnValue((res, req))

    def put_mail(self, data):
        res, req = self.put("/mails", data)
        return res, req

    def post_tags(self, mail_ident, tags_json):
        res, req = self.post("/mail/%s/tags" % mail_ident, tags_json)
        return res

    def get_tags(self, **kwargs):
        res, req = self.get("/tags", kwargs)
        return res

    def get_mail(self, mail_ident):
        res, req = self.get("/mail/%s" % mail_ident)
        return res

    def delete_mail(self, mail_ident):
        res, req = self.delete("/mail/%s" % mail_ident)
        return res

    def delete_mails(self, idents):
        res, req = self.post("/mails/delete", json.dumps({"idents": idents}))
        return res

    def mark_many_as_unread(self, idents):
        res, req = self.post("/mails/unread", json.dumps({"idents": idents}))
        return res

    def mark_many_as_read(self, idents):
        res, req = self.post("/mails/read", json.dumps({"idents": idents}))
        return res

    def get_contacts(self, query):
        res, req = self.get("/contacts", get_args={"q": query})
        return res
class AppTestClient(object):
    INDEX_KEY = (
        "\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI"
        "\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad"
    )
    ACCOUNT = "test"
    MAIL_ADDRESS = "*****@*****.**"

    # def __init__(self):
    #     self.start_client()

    @defer.inlineCallbacks
    def start_client(self):
        soledad_test_folder = self._generate_soledad_test_folder_name()
        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.cleanup = lambda: shutil.rmtree(soledad_test_folder)

        self.soledad = yield initialize_soledad(tempdir=soledad_test_folder)

        self.keymanager = mock()

        self.search_engine = SearchEngine(self.INDEX_KEY, agent_home=soledad_test_folder)
        self.mail_sender = self._create_mail_sender()

        self.mail_store = SearchableMailStore(LeapMailStore(self.soledad), self.search_engine)

        account_ready_cb = defer.Deferred()
        self.account = IMAPAccount(self.ACCOUNT, self.soledad, account_ready_cb)
        yield account_ready_cb
        self.draft_service = DraftService(self.mail_store)
        self.leap_session = mock()
        self.feedback_service = FeedbackService(self.leap_session)

        self.mail_service = self._create_mail_service(self.mail_sender, self.mail_store, self.search_engine)
        mails = yield self.mail_service.all_mails()
        self.search_engine.index_mails(mails)

        self.resource = RootResource()
        self.resource.initialize(
            self.keymanager, self.search_engine, self.mail_service, self.draft_service, self.feedback_service
        )

    def _render(self, request, as_json=True):
        def get_str(_str):
            return json.loads(_str) if as_json else _str

        def get_request_written_data(_=None):
            written_data = request.getWrittenData()
            if written_data:
                return get_str(written_data)

        resource = getChildForRequest(self.resource, request)
        result = resource.render(request)

        if isinstance(result, basestring):
            return get_str(result), request

        # result is NOT_DONE_YET
        d = succeed(request) if request.finished else request.notifyFinish()
        d.addCallback(get_request_written_data)
        return d, request

    def listenTCP(self, port=4567, host="127.0.0.1"):
        reactor.listenTCP(port, PixelatedSite(self.resource), interface=host)

    def run_on_a_thread(self, logfile="/tmp/app_test_client.log", port=4567, host="127.0.0.1"):
        def _start():
            self.listenTCP(port, host)
            reactor.run()

        process = multiprocessing.Process(target=_start)
        process.start()
        time.sleep(1)
        return lambda: process.terminate()

    def get(self, path, get_args="", as_json=True):
        request = request_mock(path)
        request.args = get_args
        return self._render(request, as_json)

    def post(self, path, body=""):
        request = request_mock(path=path, method="POST", body=body, headers={"Content-Type": ["application/json"]})
        return self._render(request)

    def put(self, path, body):
        request = request_mock(path=path, method="PUT", body=body, headers={"Content-Type": ["application/json"]})
        return self._render(request)

    def delete(self, path, body=""):
        request = request_mock(path=path, body=body, headers={"Content-Type": ["application/json"]}, method="DELETE")
        return self._render(request)

    @defer.inlineCallbacks
    def add_mail_to_inbox(self, input_mail):
        mail = yield self.mail_store.add_mail("INBOX", input_mail.raw)
        defer.returnValue(mail)

    @defer.inlineCallbacks
    def add_multiple_to_mailbox(
        self, num, mailbox="", flags=[], tags=[], to="*****@*****.**", cc="*****@*****.**", bcc="*****@*****.**"
    ):
        mails = []
        yield self.mail_store.add_mailbox(mailbox)
        for _ in range(num):
            builder = MailBuilder().with_status(flags).with_tags(tags).with_to(to).with_cc(cc).with_bcc(bcc)
            builder.with_body(str(random.random()))
            input_mail = builder.build_input_mail()
            mail = yield self.mail_store.add_mail(mailbox, input_mail.raw)
            if tags:
                mail.tags |= set(tags)
            if flags:
                for flag in flags:
                    mail.flags.add(flag)
            if tags or flags:
                yield self.mail_store.update_mail(mail)
            mails.append(mail)

        defer.returnValue(mails)

    def _create_mail_sender(self):
        mail_sender = Mock()
        mail_sender.sendmail.side_effect = lambda mail: succeed(mail)
        return mail_sender

    def _create_mail_service(self, mail_sender, mail_store, search_engine):
        mail_service = MailService(mail_sender, mail_store, search_engine)
        return mail_service

    def _generate_soledad_test_folder_name(self, soledad_test_folder="/tmp/soledad-test/test"):
        return os.path.join(soledad_test_folder, str(uuid.uuid4()))

    def get_mails_by_tag(self, tag, page=1, window=100):
        tags = "tag:%s" % tag
        return self.search(tags, page, window)

    @defer.inlineCallbacks
    def search(self, query, page=1, window=100):
        res, _ = self.get("/mails", {"q": [query], "w": [str(window)], "p": [str(page)]})
        res = yield res
        defer.returnValue([ResponseMail(m) for m in res["mails"]])

    @defer.inlineCallbacks
    def get_attachment(self, ident, encoding):
        deferred_result, req = self.get("/attachment/%s" % ident, {"encoding": [encoding]}, as_json=False)
        res = yield deferred_result
        defer.returnValue((res, req))

    def put_mail(self, data):
        res, req = self.put("/mails", data)
        return res, req

    def post_tags(self, mail_ident, tags_json):
        res, req = self.post("/mail/%s/tags" % mail_ident, tags_json)
        return res

    def get_tags(self, **kwargs):
        res, req = self.get("/tags", kwargs)
        return res

    def get_mail(self, mail_ident):
        res, req = self.get("/mail/%s" % mail_ident)
        return res

    def delete_mail(self, mail_ident):
        res, req = self.delete("/mail/%s" % mail_ident)
        return res

    def delete_mails(self, idents):
        res, req = self.post("/mails/delete", json.dumps({"idents": idents}))
        return res

    def mark_many_as_unread(self, idents):
        res, req = self.post("/mails/unread", json.dumps({"idents": idents}))
        return res

    def mark_many_as_read(self, idents):
        res, req = self.post("/mails/read", json.dumps({"idents": idents}))
        return res

    def get_contacts(self, query):
        res, req = self.get("/contacts", get_args={"q": query})
        return res
示例#21
0
class AppTestClient(object):
    INDEX_KEY = '\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI' \
                '\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad'
    ACCOUNT = 'test'
    MAIL_ADDRESS = '*****@*****.**'

    def _initialize(self):
        self._tmp_dir = TempDir()
        self.accounts = {}

    @defer.inlineCallbacks
    def start_client(self, mode=UserAgentMode(is_single_user=True)):
        self._initialize()
        self._mode = mode
        self._test_account = AppTestAccount(self.ACCOUNT, self._tmp_dir.name)

        yield self._test_account.start()

        self.cleanup = lambda: self._tmp_dir.dissolve()

        # copy fields for single user tests
        self.soledad = self._test_account.soledad
        self.search_engine = self._test_account.search_engine
        self.keymanager = self._test_account.keymanager
        self.mail_sender = self._test_account.mail_sender
        self.mail_store = self._test_account.mail_store
        self.attachment_store = self._test_account.attachment_store
        self.draft_service = self._test_account.draft_service
        self.leap_session = self._test_account.leap_session
        self.feedback_service = self._test_account.feedback_service
        self.mail_service = self._test_account.mail_service
        self.account = self._test_account.account

        if mode.is_single_user:
            self.service_factory = SingleUserServicesFactory(mode)
            services = self._test_account.services
            self.service_factory.add_session('someuserid', services)

            self.resource = RootResource(self.service_factory)
            self.resource.initialize()
        else:
            self.service_factory = StubServicesFactory(self.accounts, mode)
            provider = mock()
            provider.config = LeapConfig(self._tmp_dir.name)

            self.resource = set_up_protected_resources(RootResource(self.service_factory), provider, self.service_factory, checker=StubSRPChecker(provider))

    @defer.inlineCallbacks
    def create_user(self, account_name):
        if self._mode.is_single_user:
            raise Exception('Not supported in single user mode')

        account = AppTestAccount(account_name, self._tmp_dir.name)
        yield account.start()

        self.accounts[account_name] = account

    def _render(self, request, as_json=True):
        def get_str(_str):
            return json.loads(_str) if as_json else _str

        def get_request_written_data(_=None):
            written_data = request.getWrittenData()
            if written_data:
                return get_str(written_data)

        resource = getChildForRequest(self.resource, request)
        result = resource.render(request)

        if isinstance(result, basestring):
            return get_str(result), request

        # result is NOT_DONE_YET
        d = succeed(request) if request.finished else request.notifyFinish()
        d.addCallback(get_request_written_data)
        return d, request

    def listenTCP(self, port=4567, host='127.0.0.1'):
        reactor.listenTCP(port, PixelatedSite(self.resource), interface=host)

    def run_on_a_thread(self, logfile='/tmp/app_test_client.log', port=4567, host='127.0.0.1'):
        def _start():
            self.listenTCP(port, host)
            reactor.run()
        process = multiprocessing.Process(target=_start)
        process.start()
        time.sleep(1)
        return lambda: process.terminate()

    def stop(self):
        reactor.stop()

    def get(self, path, get_args='', as_json=True, ajax=True, csrf='token'):
        request = request_mock(path, ajax=ajax, csrf=csrf)
        request.args = get_args
        return self._render(request, as_json)

    def post(self, path, body='', headers=None, ajax=True, csrf='token'):
        headers = headers or {'Content-Type': 'application/json'}
        request = request_mock(path=path, method="POST", body=body, headers=headers, ajax=ajax, csrf=csrf)
        return self._render(request)

    def put(self, path, body, ajax=True, csrf='token'):
        request = request_mock(path=path, method="PUT", body=body, headers={'Content-Type': ['application/json']}, ajax=ajax, csrf=csrf)
        return self._render(request)

    def delete(self, path, body="", ajax=True, csrf='token'):
        request = request_mock(path=path, body=body, headers={'Content-Type': ['application/json']}, method="DELETE", ajax=ajax, csrf=csrf)
        return self._render(request)

    @defer.inlineCallbacks
    def add_mail_to_inbox(self, input_mail):
        mail = yield self.mail_store.add_mail('INBOX', input_mail.raw)
        defer.returnValue(mail)

    def account_for(self, username):
        return self.accounts[username]

    def add_mail_to_user_inbox(self, input_mail, username):
        return self.account_for(username).mail_store.add_mail('INBOX', input_mail.raw)

    @defer.inlineCallbacks
    def add_multiple_to_mailbox(self, num, mailbox='', flags=[], tags=[], to='*****@*****.**', cc='*****@*****.**', bcc='*****@*****.**'):
        mails = []
        yield self.mail_store.add_mailbox(mailbox)
        for _ in range(num):
            builder = MailBuilder().with_status(flags).with_tags(tags).with_to(to).with_cc(cc).with_bcc(bcc)
            builder.with_body(str(random.random()))
            input_mail = builder.build_input_mail()
            mail = yield self.mail_store.add_mail(mailbox, input_mail.raw)
            if tags:
                mail.tags |= set(tags)
            if flags:
                for flag in flags:
                    mail.flags.add(flag)
            if tags or flags:
                yield self.mail_store.update_mail(mail)
            mails.append(mail)

        defer.returnValue(mails)

    def _create_mail_sender(self):
        mail_sender = Mock()
        mail_sender.sendmail.side_effect = lambda mail: succeed(mail)
        return mail_sender

    def _generate_soledad_test_folder_name(self, soledad_test_folder='/tmp/soledad-test/test'):
        return os.path.join(soledad_test_folder, str(uuid.uuid4()))

    def get_mails_by_tag(self, tag, page=1, window=100):
        tags = 'tag:%s' % tag
        return self.search(tags, page, window)

    @defer.inlineCallbacks
    def search(self, query, page=1, window=100):
        res, _ = self.get("/mails", {
            'q': [query],
            'w': [str(window)],
            'p': [str(page)]
        })
        res = yield res
        defer.returnValue([ResponseMail(m) for m in res['mails']])

    @defer.inlineCallbacks
    def get_mails_by_mailbox_name(self, mbox_name):
        mail_ids = yield self.mail_store.get_mailbox_mail_ids(mbox_name)
        mails = yield self.mail_store.get_mails(mail_ids)
        defer.returnValue(mails)

    @defer.inlineCallbacks
    def get_attachment(self, ident, encoding, filename=None, content_type=None, ajax=True, csrf='token'):
        params = {'encoding': [encoding]}
        if filename:
            params['filename'] = [filename]
        if content_type:
            params['content_type'] = [content_type]
        deferred_result, req = self.get("/attachment/%s" % ident, params, as_json=False, ajax=ajax, csrf=csrf)
        res = yield deferred_result
        defer.returnValue((res, req))

    @defer.inlineCallbacks
    def post_attachment(self, data, headers):
        deferred_result, req = self.post('/attachment', body=data, headers=headers)
        res = yield deferred_result
        defer.returnValue((res, req))

    def put_mail(self, data):
        res, req = self.put('/mails', data)
        return res, req

    def post_tags(self, mail_ident, tags_json):
        res, req = self.post("/mail/%s/tags" % mail_ident, tags_json)
        return res

    def get_tags(self, **kwargs):
        res, req = self.get('/tags', kwargs)
        return res

    def get_mail(self, mail_ident):
        res, req = self.get('/mail/%s' % mail_ident)
        return res

    def delete_mail(self, mail_ident):
        res, req = self.delete("/mail/%s" % mail_ident)
        return res

    def delete_mails(self, idents):
        res, req = self.post("/mails/delete", json.dumps({'idents': idents}))
        return res

    def mark_many_as_unread(self, idents):
        res, req = self.post('/mails/unread', json.dumps({'idents': idents}))
        return res

    def mark_many_as_read(self, idents):
        res, req = self.post('/mails/read', json.dumps({'idents': idents}))
        return res

    def get_contacts(self, query):
        res, req = self.get('/contacts', get_args={'q': query})
        return res
示例#22
0
 def setUp(self):
     root_resource = RootResource()
     root_resource._mode = root_resource
     root_resource.account_email = self.MAIL_ADDRESS
     root_resource._html_template = "<html><head><title>$account_email</title></head></html>"
     self.web = DummySite(root_resource)
示例#23
0
class AppTestClient(object):
    INDEX_KEY = '\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI' \
                '\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad'
    ACCOUNT = 'test'
    MAIL_ADDRESS = '*****@*****.**'

    # def __init__(self):
    #     self.start_client()

    @defer.inlineCallbacks
    def start_client(self):
        soledad_test_folder = self._generate_soledad_test_folder_name()
        SearchEngine.DEFAULT_INDEX_HOME = soledad_test_folder

        self.cleanup = lambda: shutil.rmtree(soledad_test_folder)

        PixelatedMail.from_email_address = self.MAIL_ADDRESS

        self.soledad = yield initialize_soledad(tempdir=soledad_test_folder)

        self.soledad_querier = self._create_soledad_querier(
            self.soledad, self.INDEX_KEY)
        self.keymanager = mock()

        self.search_engine = SearchEngine(self.INDEX_KEY,
                                          agent_home=soledad_test_folder)
        self.mail_sender = self._create_mail_sender()

        self.mail_store = SearchableMailStore(LeapMailStore(self.soledad),
                                              self.search_engine)

        account_ready_cb = defer.Deferred()
        self.account = IMAPAccount(self.ACCOUNT, self.soledad,
                                   account_ready_cb)
        yield account_ready_cb
        self.mailboxes = Mailboxes(self.account, self.mail_store,
                                   self.soledad_querier, self.search_engine)
        self.draft_service = DraftService(self.mail_store)

        self.mail_service = self._create_mail_service(self.mailboxes,
                                                      self.mail_sender,
                                                      self.mail_store,
                                                      self.soledad_querier,
                                                      self.search_engine)
        mails = yield self.mail_service.all_mails()
        self.search_engine.index_mails(mails)

        self.resource = RootResource()
        self.resource.initialize(self.keymanager, self.search_engine,
                                 self.mail_service, self.draft_service)

    def _render(self, request, as_json=True):
        def get_str(_str):
            return json.loads(_str) if as_json else _str

        def get_request_written_data(_=None):
            written_data = request.getWrittenData()
            if written_data:
                return get_str(written_data)

        resource = getChildForRequest(self.resource, request)
        result = resource.render(request)

        if isinstance(result, basestring):
            return get_str(result), request

        # result is NOT_DONE_YET
        d = succeed(request) if request.finished else request.notifyFinish()
        d.addCallback(get_request_written_data)
        return d, request

    def listenTCP(self, port=4567, host='127.0.0.1'):
        reactor.listenTCP(port, Site(self.resource), interface=host)

    def run_on_a_thread(self,
                        logfile='/tmp/app_test_client.log',
                        port=4567,
                        host='127.0.0.1'):
        def _start():
            self.listenTCP(port, host)
            reactor.run()

        process = multiprocessing.Process(target=_start)
        process.start()
        time.sleep(1)
        return lambda: process.terminate()

    def get(self, path, get_args='', as_json=True):
        request = request_mock(path)
        request.args = get_args
        return self._render(request, as_json)

    def post(self, path, body=''):
        request = request_mock(path=path,
                               method="POST",
                               body=body,
                               headers={'Content-Type': ['application/json']})
        return self._render(request)

    def put(self, path, body):
        request = request_mock(path=path,
                               method="PUT",
                               body=body,
                               headers={'Content-Type': ['application/json']})
        return self._render(request)

    def delete(self, path, body=""):
        request = request_mock(path=path,
                               body=body,
                               headers={'Content-Type': ['application/json']},
                               method="DELETE")
        return self._render(request)

    def add_document_to_soledad(self, _dict):
        return self.soledad_querier.soledad.create_doc(_dict)

    @defer.inlineCallbacks
    def add_mail_to_inbox(self, input_mail):
        mail = yield self.mail_store.add_mail('INBOX', input_mail.raw)
        defer.returnValue(mail)
        # inbox = yield self.mailboxes.inbox
        # mail = yield inbox.add(input_mail)
        # if input_mail.tags:
        #     mail.update_tags(input_mail.tags)
        #     self.search_engine.index_mail(mail)

    @defer.inlineCallbacks
    def add_multiple_to_mailbox(self,
                                num,
                                mailbox='',
                                flags=[],
                                tags=[],
                                to='*****@*****.**',
                                cc='*****@*****.**',
                                bcc='*****@*****.**'):
        mails = []
        yield self.mail_store.add_mailbox(mailbox)
        for _ in range(num):
            builder = MailBuilder().with_status(flags).with_tags(tags).with_to(
                to).with_cc(cc).with_bcc(bcc)
            builder.with_body(str(random.random()))
            input_mail = builder.build_input_mail()
            mail = yield self.mail_store.add_mail(mailbox, input_mail.raw)
            if tags:
                mail.tags |= set(tags)
            if flags:
                for flag in flags:
                    mail.flags.add(flag)
            if tags or flags:
                yield self.mail_store.update_mail(mail)
            mails.append(mail)

        #     mbx = yield self.mailboxes._create_or_get(mailbox)
        #     mail = yield mbx.add(input_mail)
        #     mails.append(mail)
        #     mail.update_tags(input_mail.tags) if tags else None
        # self.search_engine.index_mails(mails) if tags else None

        defer.returnValue(mails)

    def _create_soledad_querier(self, soledad, index_key):
        soledad_querier = SoledadQuerier(soledad)
        soledad_querier.get_index_masterkey = lambda: index_key
        return soledad_querier

    def _create_mail_sender(self):
        mail_sender = Mock()
        mail_sender.sendmail.side_effect = lambda mail: succeed(mail)
        return mail_sender

    def _create_mail_service(self, mailboxes, mail_sender, mail_store,
                             soledad_querier, search_engine):
        mail_service = MailService(mailboxes, mail_sender, mail_store,
                                   soledad_querier, search_engine)
        return mail_service

    def _generate_soledad_test_folder_name(
            self, soledad_test_folder='/tmp/soledad-test/test'):
        return os.path.join(soledad_test_folder, str(uuid.uuid4()))

    def get_mails_by_tag(self, tag, page=1, window=100):
        tags = 'tag:%s' % tag
        return self.search(tags, page, window)

    @defer.inlineCallbacks
    def search(self, query, page=1, window=100):
        res, _ = self.get("/mails", {
            'q': [query],
            'w': [str(window)],
            'p': [str(page)]
        })
        res = yield res
        defer.returnValue([ResponseMail(m) for m in res['mails']])

    def get_attachment(self, ident, encoding):
        res, req = self.get("/attachment/%s" % ident, {'encoding': [encoding]},
                            as_json=False)
        return res

    def put_mail(self, data):
        res, req = self.put('/mails', data)
        return res, req

    def post_tags(self, mail_ident, tags_json):
        res, req = self.post("/mail/%s/tags" % mail_ident, tags_json)
        return res

    def get_tags(self, **kwargs):
        res, req = self.get('/tags', kwargs)
        return res

    def get_mail(self, mail_ident):
        res, req = self.get('/mail/%s' % mail_ident)
        return res

    def delete_mail(self, mail_ident):
        res, req = self.delete("/mail/%s" % mail_ident)
        return res

    def delete_mails(self, idents):
        res, req = self.post("/mails/delete", json.dumps({'idents': idents}))
        return res

    def mark_many_as_unread(self, idents):
        res, req = self.post('/mails/unread', json.dumps({'idents': idents}))
        return res

    def mark_many_as_read(self, idents):
        res, req = self.post('/mails/read', json.dumps({'idents': idents}))
        return res

    def get_contacts(self, query):
        res, req = self.get('/contacts', get_args={'q': query})
        return res