Commit 51aa3526 authored by Nicolas Chauvat's avatar Nicolas Chauvat
Browse files

merge 3.26.21 into 3.27

--HG--
branch : 3.27
Pipeline #62146 failed with stages
in 2 minutes and 19 seconds
......@@ -614,6 +614,8 @@ d238badfc268ad4440b3238a24690858bad3fbdd debian/3.25.3-1
b8567725c473b701fe9352e578ad6e05c523c1f2 3.25.4
b8567725c473b701fe9352e578ad6e05c523c1f2 centos/3.25.4-1
b8567725c473b701fe9352e578ad6e05c523c1f2 debian/3.25.4-1
2b12cb5f470a14bb313830353bcffd49ac1534a8 3.25.5
2b12cb5f470a14bb313830353bcffd49ac1534a8 debian/3.25.5
199851fcddd4b45e3d7f40efcd1739134c33db2a 3.26.0
199851fcddd4b45e3d7f40efcd1739134c33db2a debian/3.26.0-1
199851fcddd4b45e3d7f40efcd1739134c33db2a centos/3.26.0-1
......@@ -655,6 +657,7 @@ fb6aecd654a34b68b81a444340d5c6c8a7c80664 debian/3.26.16-1
2d1d6c5ab3c3b8f8a348d79fe92d2e897eccc698 debian/3.26.18-1
d5fb8ecdd5c0cdc6c3df757f2bb8826ec99aa866 3.26.19
d5fb8ecdd5c0cdc6c3df757f2bb8826ec99aa866 debian/3.26.19-1
09a1f898e5eb170e4c9b5cfa6dca59f6419af5a3 3.26.20
e77900f19390fdf38515afdd212d21ac2592693d 3.27.0
e77900f19390fdf38515afdd212d21ac2592693d debian/3.27.0-1
917601bb5b1ba13eb92296f5bd82eaa89e99bdad 3.27.1
......
......@@ -174,7 +174,7 @@ from os.path import (exists, join, expanduser, abspath,
basename, dirname, splitext, realpath)
import pkgutil
import pkg_resources
from smtplib import SMTP
from smtplib import SMTP, SMTPAuthenticationError
import stat
import sys
from threading import Lock
......@@ -843,6 +843,16 @@ class CubicWebConfiguration(CubicWebNoAppConfiguration):
'help': 'listening port of the SMTP mail server',
'group': 'email', 'level': 1,
}),
('smtp-username',
{'default': '',
'help': 'username for SMTP mail server if auth is required',
'group': 'email', 'level': 2,
}),
('smtp-password',
{'default': '',
'help': 'password for SMTP mail server if auth is required',
'group': 'email', 'level': 2,
}),
('sender-name',
{'type' : 'string',
'default': Method('default_instance_id'),
......@@ -1237,12 +1247,21 @@ the repository',
if connection to the smtp server failed, else True.
"""
server, port = self['smtp-host'], self['smtp-port']
smtp_user, smtp_password = self['smtp-username'], self['smtp-password']
if fromaddr is None:
fromaddr = '%s <%s>' % (self['sender-name'], self['sender-addr'])
SMTP_LOCK.acquire()
try:
try:
smtp = SMTP(server, port)
if smtp_user and smtp_password:
try:
smtp.login(smtp_user, smtp_password)
except SMTPAuthenticationError as exception:
self.exception(
"cannot log in to SMTP server %s:%s (%s)",
server, port, exception,
)
except Exception as ex:
self.exception("can't connect to smtp server %s:%s (%s)",
server, port, ex)
......
# -*- coding: iso-8859-1 -*-
# -*- coding: utf-8 -*-
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
......@@ -47,7 +47,7 @@ def decompose_b26(index, ascii=False):
"""return a letter (base-26) decomposition of index"""
if ascii:
return base_decompose_b26(index)
return base_decompose_b26(index, u'abcdefghijklmnopqrstuvwxyz')
return base_decompose_b26(index, u'éabcdefghijklmnopqrstuvwxyz')
def get_max_length(eschema, attrname):
"""returns the maximum length allowed for 'attrname'"""
......@@ -120,7 +120,7 @@ class _ValueGenerator(object):
# always use plain text when no format is specified
attrprefix = attrname[:max(attrlength-num_len-1, 0)]
if format == 'text/html':
value = u'<span>%s<b>%d</b></span>' % (attrprefix, index)
value = u'<span>é%s<b>%d</b></span>' % (attrprefix, index)
elif format == 'text/rest':
value = u"""
title
......@@ -128,10 +128,10 @@ title
* %s
* %d
* &
* é&
""" % (attrprefix, index)
else:
value = u'&%s%d' % (attrprefix, index)
value = u'é&%s%d' % (attrprefix, index)
return value[:attrlength]
def generate_password(self, entity, attrname, index):
......
......@@ -50,6 +50,8 @@ from getpass import getpass
from os.path import basename
from time import clock
from six.moves import input
from logilab.common.fileutils import lines
from logilab.common.ureports import Table, TextWriter
......@@ -162,7 +164,7 @@ def run(args):
usage(1)
queries = [query for query in lines(args[1]) if not query.startswith('#')]
if user is None:
user = raw_input('login: ')
user = input('login: ')
if password is None:
password = getpass('password: ')
from cubicweb.cwconfig import instance_configuration
......
# -*- coding: iso-8859-1 -*-
# -*- coding: utf-8 -*-
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
......@@ -66,7 +66,7 @@ class ValueGeneratorTC(TestCase):
def test_string(self):
"""test string generation"""
surname = self.person_valgen.generate_attribute_value({}, 'surname', 12)
self.assertEqual(surname, u'&surname12')
self.assertEqual(surname, u'é&surname12')
def test_domain_value(self):
"""test value generation from a given domain value"""
......
......@@ -47,7 +47,8 @@ class DevCtlTC(TestCase):
expected_project_content = ['setup.py', 'test', 'MANIFEST.in',
'cubicweb_foo',
'cubicweb-foo.spec', 'debian', 'README',
'tox.ini']
'tox.ini', '.gitlab-ci.yml',
'.hgignore']
expected_package_content = ['i18n', 'hooks.py', 'views.py',
'migration', 'entities.py', 'schema.py',
'__init__.py', 'data', '__pkginfo__.py']
......
# -*- coding: iso-8859-1 -*-
# -*- coding: utf-8 -*-
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
......
......@@ -701,11 +701,11 @@ class ServerMigrationHelper(MigrationHelper):
# remove cubes'entity and relation types
for rschema in fsschema.relations():
if rschema not in removedcubes_schema and rschema in reposchema:
self.cmd_drop_relation_type(rschema.type)
self.cmd_drop_relation_type(rschema.type, commit=False)
toremove = [eschema for eschema in fsschema.entities()
if eschema not in removedcubes_schema and eschema in reposchema]
for eschema in reversed(order_eschemas(toremove)):
self.cmd_drop_entity_type(eschema.type)
self.cmd_drop_entity_type(eschema.type, commit=False)
for rschema in fsschema.relations():
if rschema in removedcubes_schema and rschema in reposchema:
# check if attributes/relations has been added to entities from
......@@ -714,13 +714,13 @@ class ServerMigrationHelper(MigrationHelper):
if (fromtype, totype) not in removedcubes_schema[rschema.type].rdefs and \
(fromtype, totype) in reposchema[rschema.type].rdefs:
self.cmd_drop_relation_definition(
str(fromtype), rschema.type, str(totype))
str(fromtype), rschema.type, str(totype), commit=False)
# execute post-remove files
for cube in reversed(removedcubes):
self.cmd_exec_event_script('postremove', cube)
self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s',
{'pk': u'system.version.' + cube}, ask_confirm=False)
self.commit()
self.commit()
# schema migration actions ################################################
......
......@@ -54,7 +54,7 @@ def group_mapping(cnx, interactive=True):
print('or just type enter to skip permissions granted to a group')
for group in missing:
while True:
value = raw_input('eid for group %s: ' % group).strip()
value = input('eid for group %s: ' % group).strip()
if not value:
continue
try:
......
......@@ -133,6 +133,15 @@ def repo_cnx(config):
"""return a in-memory repository and a repoapi connection to it"""
from cubicweb import repoapi
from cubicweb.server.utils import manager_userpasswd
db_driver = config.system_source_config.get('db-driver')
if db_driver == "sqlite":
if not os.path.exists(config.system_source_config.get('db-name')):
print("Your database does not exist.")
sys.exit(1)
from sqlite3 import OperationalError
else:
from psycopg2 import OperationalError
try:
login = config.default_admin_config['login']
pwd = config.default_admin_config['password']
......@@ -147,6 +156,9 @@ def repo_cnx(config):
print('-> Error: wrong user/password.')
# reset cubes else we'll have an assertion error on next retry
config._cubes = None
except OperationalError as exc: # sqlite or psycopg2 driver, depending on db_driver
print("OperationalError: %s" % exc)
sys.exit(1)
login, pwd = manager_userpasswd()
......@@ -928,10 +940,11 @@ option is set to "y" or "yes" (may be long for large database).'}
config.repairing = self.config.force
repo, _cnx = repo_cnx(config)
with repo.internal_cnx() as cnx:
checkintegrity.check(repo, cnx,
self.config.checks,
self.config.reindex,
self.config.autofix)
checkintegrity.check(
repo, cnx,
self.config.checks,
self.config.reindex,
self.config.autofix)
class DBIndexSanityCheckCommand(Command):
......
# -*- coding: iso-8859-1 -*-
# -*- coding: utf-8 -*-
# copyright 2003 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
......@@ -690,18 +690,18 @@ class QuerierTC(BaseQuerierTC):
## self.assertEqual(rset.rows[0][0], 'admin')
def test_select_searchable_text_1(self):
rset = self.qexecute(u"INSERT Personne X: X nom 'bidle'")
rset = self.qexecute(u"INSERT Societe X: X nom 'bidle'")
rset = self.qexecute(u"INSERT Personne X: X nom 'bidüle'")
rset = self.qexecute(u"INSERT Societe X: X nom 'bidüle'")
rset = self.qexecute("INSERT Societe X: X nom 'chouette'")
rset = self.qexecute('Any X where X has_text %(text)s', {'text': u'bidle'})
rset = self.qexecute('Any X where X has_text %(text)s', {'text': u'bidüle'})
self.assertEqual(len(rset.rows), 2, rset.rows)
rset = self.qexecute(u'Any N where N has_text "bidle"')
rset = self.qexecute(u'Any N where N has_text "bidüle"')
self.assertEqual(len(rset.rows), 2, rset.rows)
biduleeids = [r[0] for r in rset.rows]
rset = self.qexecute(u'Any N where NOT N has_text "bidle"')
rset = self.qexecute(u'Any N where NOT N has_text "bidüle"')
self.assertFalse([r[0] for r in rset.rows if r[0] in biduleeids])
# duh?
rset = self.qexecute('Any X WHERE X has_text %(text)s', {'text': u'a'})
rset = self.qexecute('Any X WHERE X has_text %(text)s', {'text': u'ça'})
def test_select_searchable_text_2(self):
rset = self.qexecute("INSERT Personne X: X nom 'bidule'")
......@@ -718,11 +718,11 @@ class QuerierTC(BaseQuerierTC):
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_multiple_searchable_text(self):
self.qexecute(u"INSERT Personne X: X nom 'bidle'")
self.qexecute(u"INSERT Personne X: X nom 'bidüle'")
self.qexecute("INSERT Societe X: X nom 'chouette', S travaille X")
self.qexecute(u"INSERT Personne X: X nom 'bidle'")
self.qexecute(u"INSERT Personne X: X nom 'bidüle'")
rset = self.qexecute('Personne X WHERE X has_text %(text)s, X travaille S, S has_text %(text2)s',
{'text': u'bidle',
{'text': u'bidüle',
'text2': u'chouette',}
)
self.assertEqual(len(rset.rows), 1, rset.rows)
......@@ -1495,7 +1495,7 @@ Any P1,B,E WHERE P1 identity P2 WITH
self.qexecute("INSERT Tag X: X name %(name)s,"
"X modification_date %(modification_date)s,"
"X creation_date %(creation_date)s",
{'name': u'name0',
{'name': u'éname0',
'modification_date': '2003/03/12 11:00',
'creation_date': '2000/07/03 11:00'})
rset = self.qexecute('Any lower(N) ORDERBY LOWER(N) WHERE X is Tag, X name N,'
......
# -*- coding: iso-8859-1 -*-
# -*- coding: utf-8 -*-
# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
......@@ -95,10 +95,10 @@ class RepositoryTC(CubicWebTC):
with self.admin_access.repo_cnx() as cnx:
cnx.execute('INSERT CWUser X: X login %(login)s, X upassword %(passwd)s, '
'X in_group G WHERE G name "users"',
{'login': u"barnab", 'passwd': u"hhh".encode('UTF8')})
{'login': u"barnabé", 'passwd': u"héhéhé".encode('UTF8')})
cnx.commit()
repo = self.repo
self.assertTrue(repo.authenticate_user(cnx, u"barnab", password=u"hhh".encode('UTF8')))
self.assertTrue(repo.authenticate_user(cnx, u"barnabé", password=u"héhéhé".encode('UTF8')))
def test_rollback_on_execute_validation_error(self):
class ValidationErrorAfterHook(Hook):
......
......@@ -8,6 +8,7 @@ from cubicweb.server.serverctl import (
DBDumpCommand,
RepositorySchedulerCommand,
SynchronizeSourceCommand,
repo_cnx,
)
from cubicweb.server.serverconfig import ServerConfiguration
......@@ -80,6 +81,16 @@ class ServerCTLTC(testlib.CubicWebTC):
self.assertEqual(str(exc.exception), 'All sources where not synced')
self.assertEqual(len(cnx.find('Card', title=u'fail')), 0)
def test_db_check_no_db(self):
init_db_name = self.config.system_source_config["db-name"]
self.config.system_source_config["db-name"] = "not existing db"
try:
with self.assertRaises(SystemExit) as ctx:
repo_cnx(self.config)
self.assertEqual(ctx.exception.code, 1)
finally:
self.config.system_source_config["db-name"] = init_db_name
if __name__ == '__main__':
from unittest import main
......
......@@ -89,6 +89,12 @@ cubicweb (3.27.0~a0-1) unstable; urgency=medium
-- Denis Laxalde <denis.laxalde@logilab.fr> Wed, 24 Jul 2019 16:08:43 +0200
cubicweb (3.26.21-1) unstable; urgency=medium
* New upstream release
-- Nicola Spanti <nspanti@logilab.fr> Tue, 27 Apr 2021 15:52:47 +0200
cubicweb (3.26.20-1) unstable; urgency=medium
* New patch release
......@@ -210,6 +216,12 @@ cubicweb (3.26.0-1) unstable; urgency=medium
-- Denis Laxalde <denis.laxalde@logilab.fr> Thu, 01 Feb 2018 09:24:01 +0100
cubicweb (3.25.5-1) unstable; urgency=medium
* backport SMTP authentication from 3.28
-- Carine Dengler <carine.dengler@logilab.fr> Fri, 23 Apr 2021 15:22:48 +0200
cubicweb (3.25.4-1) unstable; urgency=medium
* New upstream release.
......
......@@ -30,7 +30,7 @@ Build-Depends:
sphinx-common,
Standards-Version: 4.3.0
Homepage: https://www.cubicweb.org
X-Python3-Version: >= 3.4
X-Python3-Version: >= 3.7
Package: python3-cubicweb
......
......@@ -28,7 +28,7 @@ def ren(a,b):
names = glob.glob('%s*'%a)
for name in names :
print('rename %s to %s' % (name, name.replace(a,b)))
if raw_input('accept [y/N]?').lower() =='y':
if input('accept [y/N]?').lower() =='y':
for name in names:
os.system('hg mv %s %s' % (name, name.replace(a,b)))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment