Example #1
0
    def setUp(self):
        super().setUp()

        self.domain = d = Domain(name='example.com', catchall='catchall')
        DBSession.add(d)
        DBSession.flush()

        self.mailbox = Address(domain_id=d.id, local_part='mb')
        self.mailbox.set_password('pw')
        self.redirect = Address(domain_id=d.id, local_part='alias',
                                redirect='redirect@test')
        self.redirect.set_password('pw')
        DBSession.add_all([self.mailbox, self.redirect])
        DBSession.flush()
Example #2
0
    def setUp(self):
        super().setUp()

        d = Domain(name="example.com")
        DBSession.add(d)
        DBSession.flush()

        self.address = Address(domain_id=d.id, local_part="test")
        self.address.set_password("pw")
        DBSession.add(self.address)
        DBSession.flush()

        self.valid_token = PwResetToken(address_id=self.address.id)
        self.expired_token = PwResetToken(address_id=self.address.id)
        self.expired_token.create_date = datetime.now() - timedelta(days=10)

        DBSession.add_all([self.valid_token, self.expired_token])

        DBSession.flush()
Example #3
0
    def setUp(self):
        super().setUp()

        d = Domain(name="example.com")
        DBSession.add(d)
        DBSession.flush()

        self.user = User(username="******")
        self.user.set_password("pw")
        DBSession.add(self.user)

        self.duser = User(username="******", enabled=False)
        self.duser.set_password("pw")
        DBSession.add(self.duser)

        self.luser = User(username="******")
        self.luser.password = False
        DBSession.add(self.luser)

        self.address = Address(domain_id=d.id, local_part="test")
        self.address.set_password("pw")
        DBSession.add(self.address)

        DBSession.flush()
Example #4
0
def main(argv=sys.argv):
    parser = ArgumentParser(description=__doc__)
    parser.add_argument('config')
    parser.add_argument('csvfile', type=str, action='store',
                        help="CSV file")
    parser.add_argument('-q', dest='quiet', action='store_true',
                        help="Dont print every address")

    commit = parser.add_mutually_exclusive_group()
    commit.add_argument('-n', dest='commit_never', action='store_true',
                        help="Dont commit changes and dont ask")
    commit.add_argument('-y', dest='commit_always', action='store_true',
                        help="Commit changes without asking")

    args = parser.parse_args()

    config_uri = args.config
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)

    transaction.begin()

    known_domains = {}
    counter = 0

    with open(args.csvfile, 'r') as csvfile:
        reader = csv.reader(csvfile)
        for row in reader:
            local, password, redirect, dname = row

            if dname in known_domains:
                domain = known_domains[dname]
            else:
                try:
                    domain = Domain.query(name=dname).one()
                except NoResultFound:
                    domain = Domain(name=dname)
                    DBSession.add(domain)
                known_domains[domain.name] = domain

            if not local:
                if not redirect:
                    print('Invalid address: catch-all without redirect')
                    return 1
                domain.catchall = redirect
                print('*@%s -> %s' % (domain.name, domain.catchall))
                continue

            address = Address()
            address.local_part = local
            address.password = password or None
            address.redirect = redirect or None
            address.domain = domain
            address.domain_id = domain.id

            DBSession.add(address)

            if not args.quiet:
                print(address.address, end='')
                if address.password:
                    print(' [...%s]' % address.password[-8:], end='')
                if address.redirect:
                    print(' -> %s' % address.redirect, end='')
                print()

            counter += 1

    if args.commit_always:
        transaction.commit()
        print('saved.')
    elif args.commit_never:
        transaction.abort()
        print('aborted.')
    else:
        r = input('Commit %d addresses? ' % counter)
        if r.strip().lower() == 'y':
            transaction.commit()
            print('saved.')
        else:
            transaction.abort()
            print('aborted.')
Example #5
0
class TestConfigQuery(TestCase):
    def setUp(self):
        super().setUp()

        self.domain = d = Domain(name='example.com', catchall='catchall')
        DBSession.add(d)
        DBSession.flush()

        self.mailbox = Address(domain_id=d.id, local_part='mb')
        self.mailbox.set_password('pw')
        self.redirect = Address(domain_id=d.id, local_part='alias',
                                redirect='redirect@test')
        self.redirect.set_password('pw')
        DBSession.add_all([self.mailbox, self.redirect])
        DBSession.flush()


    def run_postfix_domains_query(self, domain):
        sql = config.postfix_domains_query
        sql = sql.replace('%s', domain)
        return list(self.conn.execute(sql))

    def run_postfix_mailboxes_query(self, address):
        sql = config.postfix_aliases_query
        sql = sql.replace('%s', address.address)
        sql = sql.replace('%u', address.local_part)
        sql = sql.replace('%d', address.domain.name)
        return list(self.conn.execute(sql))


    def test_dovecot_query(self):
        def query(address):
            sql = config.dovecot_query
            sql = sql.replace('%u', address.address)
            sql = sql.replace('%n', address.local_part)
            sql = sql.replace('%d', address.domain.name)
            return list(self.conn.execute(sql))

        result = query(self.mailbox)
        self.assertEqual(len(result), 1)
        self.assertEqual(len(result[0]), 2)
        self.assertEqual(result[0], (self.mailbox.address, self.mailbox.password))

        result = query(self.redirect)
        self.assertEqual(len(result), 1)
        self.assertEqual(len(result[0]), 2)
        self.assertEqual(result[0], (self.redirect.address, self.redirect.password))

        not_found = Address(domain=self.domain, local_part='aaaaaa')
        result = query(not_found)
        self.assertEqual(len(result), 0)

    def test_postfix_aliases_query(self):
        def query(address):
            sql = config.postfix_aliases_query
            sql = sql.replace('%s', address.address)
            sql = sql.replace('%u', address.local_part)
            sql = sql.replace('%d', address.domain.name)
            return list(self.conn.execute(sql))

        result = query(self.mailbox)
        self.assertEqual(len(result), 1)
        self.assertEqual(len(result[0]), 1)
        self.assertIsNone(result[0][0])

        result = query(self.redirect)
        self.assertEqual(len(result), 1)
        self.assertEqual(len(result[0]), 1)
        self.assertEqual(result[0][0], self.redirect.redirect)

        not_found = Address(domain=self.domain, local_part='aaaaaa')
        result = query(not_found)
        self.assertEqual(len(result), 1)
        self.assertEqual(len(result[0]), 1)
        self.assertEqual(result[0][0], self.domain.catchall)

    def test_postfix_mailboxes_query(self):
        def query(address):
            sql = config.postfix_mailboxes_query
            sql = sql.replace('%s', address.address)
            sql = sql.replace('%u', address.local_part)
            sql = sql.replace('%d', address.domain.name)
            return list(self.conn.execute(sql))

        result = query(self.mailbox)
        path = self.mailbox.domain.name + '/' + self.mailbox.local_part
        self.assertEqual(len(result), 1)
        self.assertEqual(len(result[0]), 1)
        self.assertEqual(result[0][0], path)

        result = query(self.redirect)
        self.assertEqual(len(result), 0)

        not_found = Address(domain=self.domain, local_part='aaaaaa')
        result = query(not_found)
        self.assertEqual(len(result), 0)

    def test_postfix_domains_query(self):
        def query(domain_name):
            sql = config.postfix_domains_query
            sql = sql.replace('%s', domain_name)
            return list(self.conn.execute(sql))

        result = query(self.mailbox.domain.name)
        self.assertEqual(len(result), 1)
        self.assertEqual(len(result[0]), 1)
        self.assertEqual(result[0][0], self.mailbox.domain.name)

        result = query('not-example.com')
        self.assertEqual(len(result), 0)
Example #6
0
class TestAuthView(TestCase):
    def setUp(self):
        super().setUp()

        d = Domain(name="example.com")
        DBSession.add(d)
        DBSession.flush()

        self.user = User(username="******")
        self.user.set_password("pw")
        DBSession.add(self.user)

        self.duser = User(username="******", enabled=False)
        self.duser.set_password("pw")
        DBSession.add(self.duser)

        self.luser = User(username="******")
        self.luser.password = False
        DBSession.add(self.luser)

        self.address = Address(domain_id=d.id, local_part="test")
        self.address.set_password("pw")
        DBSession.add(self.address)

        DBSession.flush()

    def test_auth_get(self):
        r = views.auth(DummyRequest())
        self.assertEqual(r, {})

    def test_auth_redirect(self):
        r = views.auth(DummyRequest(user=self.user))
        self.assertIsInstance(r, HTTPSeeOther)

    def test_auth_as_user(self):
        request = DummyRequest(post=dict(username="******", password="******"))
        r = views.auth_post(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertEqual(request.session["auth_type"], "User")
        self.assertEqual(request.session["auth_id"], self.user.id)

        request = DummyRequest(session=dict(auth_type="User", auth_id=42, keep="me"))
        r = views.logout(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertNotIn("auth_type", request.session)
        self.assertNotIn("auth_id", request.session)
        self.assertIn("keep", request.session)
        self.assertEqual(request.session["keep"], "me")

    def test_auth_as_address(self):
        request = DummyRequest(post=dict(username="******", password="******"))
        r = views.auth_post(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertEqual(request.session["auth_type"], "Address")
        self.assertEqual(request.session["auth_id"], self.address.id)

    def test_auth_fail(self):
        request = DummyRequest(post=dict(username="******", password="******"))
        r = views.auth_post(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertNotIn("auth_type", request.session)
        self.assertNotIn("auth_id", request.session)

    def test_auth_disabled(self):
        request = DummyRequest(post=dict(username="******", password="******"))
        r = views.auth_post(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertNotIn("auth_type", request.session)
        self.assertNotIn("auth_id", request.session)

        request = DummyRequest(post=dict(username="******", password=""))
        r = views.auth_post(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertNotIn("auth_type", request.session)
        self.assertNotIn("auth_id", request.session)
Example #7
0
class TestResetView(TestCase):
    def setUp(self):
        super().setUp()

        d = Domain(name="example.com")
        DBSession.add(d)
        DBSession.flush()

        self.address = Address(domain_id=d.id, local_part="test")
        self.address.set_password("pw")
        DBSession.add(self.address)
        DBSession.flush()

        self.valid_token = PwResetToken(address_id=self.address.id)
        self.expired_token = PwResetToken(address_id=self.address.id)
        self.expired_token.create_date = datetime.now() - timedelta(days=10)

        DBSession.add_all([self.valid_token, self.expired_token])

        DBSession.flush()

    def test_not_found(self):
        request = DummyRequest(matchdict=dict(token="invalid"))
        r = views.reset(request)
        self.assertIsInstance(r, HTTPNotFound)

    def test_form(self):
        request = DummyRequest(matchdict=dict(token=self.valid_token.token))
        r = views.reset(request)
        self.assertIsInstance(r, dict)
        self.assertIn("address", r)
        self.assertEqual(r["address"], self.address)

    def test_expired(self):
        request = DummyRequest(matchdict=dict(token=self.expired_token.token))
        r = views.reset(request)
        self.assertIsInstance(r, HTTPSeeOther)

    def test_reset(self):
        # Wrong input, should not be changed
        request = DummyRequest(matchdict=dict(token=self.valid_token.token), post=dict(password="******"))
        r = views.reset(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertFalse(self.address.check_password("newpw"))

        # Wrong input, should not be changed
        request = DummyRequest(
            matchdict=dict(token=self.valid_token.token), post=dict(password="******", password2="NOTnewpw")
        )
        r = views.reset(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertFalse(self.address.check_password("newpw"))

        # Valid input, should be changed
        request = DummyRequest(
            matchdict=dict(token=self.valid_token.token), post=dict(password="******", password2="newpw")
        )
        r = views.reset(request)
        self.assertIsInstance(r, HTTPSeeOther)
        self.assertTrue(self.address.check_password("newpw"))

        # Already used token, should not be changed
        request = DummyRequest(
            matchdict=dict(token=self.valid_token.token), post=dict(password="******", password2="lastpw")
        )
        r = views.reset(request)
        self.assertIsInstance(r, HTTPNotFound)
        self.assertTrue(self.address.check_password("newpw"))