Commit 9257b5ea authored by Etienne Allovon's avatar Etienne Allovon

Merge branch 'master' into 2415-confgend-can-not-generate-conf-due-to-sqlalchemy-security-update

parents 50600ecd 3f7fcd14
......@@ -47,7 +47,7 @@ CREATE DATABASE asterisktest;
CREATE USER asterisk WITH PASSWORD 'asterisk';
GRANT ALL ON DATABASE asterisktest TO asterisk;
CREATE SCHEMA xc AUTHORIZATION asterisk;
CREATE EXTENSION IF NOT EXISTS 'uuid-ossp';
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
```
#### Launching the tests
......
xivo-dao (2018.16.09) xivo-borealis; urgency=medium
xivo-dao (2019.04.00) xivo-callisto; urgency=medium
* Fix incompatibility with security patch of SQLAlechemy
* 2371 Fix agent api by porting the following fixes
* 2375 Add a CtiProfile to user when it's not set and a login is set
* 2352 Add api to create func key destination for agent
* 2400 Add route tables for outcall application
* 2415 Fix incompatibility with security patch of SQLAlechemy
-- Jirka HLAVACEK <jhlavacek@avencall.com> Mon, 25 Mar 2019 13:21:17 +0100
-- Jean-Pierre Thomasset <jpthomasset@gmail.com> Fri, 22 Feb 2019 09:44:53 +0000
xivo-dao (2018.16.08) xivo-borealis; urgency=medium
xivo-dao (2019.03.00) xivo-callisto; urgency=medium
* 2375 Add a CtiProfile to user when it's not set and a login is set
[ Laurent Meiller ]
* 2345 Add site to existing group with search feature
* 2347 Add find queue settings by queuefeatures or groupfeatures
* 2348 Extend is_extension_on_current_mds to filter on groupfeatures
-- Jean-Pierre Thomasset <jpthomasset@gmail.com> Fri, 22 Feb 2019 09:44:53 +0000
[ Vojtech Sodoma ]
* 2359 Be able to set mds0 only for SIP Trunk configuration
* 2361 Generate SIP registration only for local trunks of the MDS
xivo-dao (2018.16.06) xivo-borealis; urgency=medium
-- Laurent Meiller <lmeiller@avencall.com> Mon, 25 Feb 2019 14:44:06 +0100
* 2352 Add api to create func key destination for agent
xivo-dao (2019.02.00) xivo-callisto; urgency=medium
* 2338 Add column mediaserverid to trunkfeatures
* 2353 Add query to test if trunk should be generated on this mds
-- Jean-Pierre Thomasset <jpthomasset@gmail.com> Fri, 15 Feb 2019 16:16:07 +0000
-- Vojtech Sodoma <vsodoma@avencall.com> Thu, 07 Feb 2019 11:13:22 +0100
xivo-dao (2018.16.04) xivo-borealis; urgency=medium
......@@ -143,7 +155,7 @@ xivo-dao (2017.03.09) xivo-dev; urgency=medium
* Fix return value on get user id from channel when protocol is not sip or return value is not int
-- Tomas Taraba <ttaraba@tt-reactcall> Thu, 20 Jul 2017 15:47:24 +0200
-- Tomas Taraba <ttaraba@avencall.com> Thu, 20 Jul 2017 15:47:24 +0200
xivo-dao (2017.03.08) xivo-dev; urgency=medium
......
......@@ -15,9 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.schema import Column, PrimaryKeyConstraint, Index
from sqlalchemy.schema import Column, PrimaryKeyConstraint, ForeignKey, Index
from sqlalchemy.types import Integer, String
from sqlalchemy.orm import relationship
from xivo_dao.alchemy.mediaserver import MediaServer
from xivo_dao.helpers.db_manager import Base
......@@ -43,3 +45,6 @@ class GroupFeatures(Base):
timeout = Column(Integer)
preprocess_subroutine = Column(String(39))
deleted = Column(Integer, nullable=False, server_default='0')
mediaserverid = Column(Integer, ForeignKey('mediaserver.id', ondelete="RESTRICT"), nullable=False)
mediaserver = relationship(MediaServer)
......@@ -14,8 +14,9 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.schema import Column, PrimaryKeyConstraint, UniqueConstraint
from sqlalchemy.types import Integer, String
from sqlalchemy.types import Integer, String, Boolean
from xivo_dao.helpers.db_manager import Base
......@@ -30,4 +31,5 @@ class MediaServer(Base):
id = Column(Integer, nullable=False)
name = Column(String(128), nullable=False)
display_name = Column(String(128), nullable=False)
voip_ip = Column(String(39), nullable=False)
voip_ip = Column(String(39), nullable=True)
read_only = Column(Boolean, nullable=False, server_default='False')
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.schema import Column, PrimaryKeyConstraint
from sqlalchemy.types import Integer, String, Text
from xivo_dao.helpers.db_manager import Base
class Route(Base):
__tablename__ = 'route'
__table_args__ = (
PrimaryKeyConstraint('id'),
)
id = Column(Integer, nullable=False)
pattern = Column(String, nullable=False)
regexp = Column(String, nullable=True)
subroutine = Column(String, nullable=True)
description = Column(Text)
priority = Column(Integer, nullable=False)
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.schema import Column, PrimaryKeyConstraint, ForeignKeyConstraint
from sqlalchemy.types import Integer, String
from xivo_dao.helpers.db_manager import Base
class RouteContext(Base):
__tablename__ = 'routecontext'
__table_args__ = (
PrimaryKeyConstraint('id'),
ForeignKeyConstraint(('routeid',),
('route.id',),
ondelete='RESTRICT'),
ForeignKeyConstraint(('contextname',),
('context.name',),
ondelete='RESTRICT'),
)
routeid = Column(Integer, nullable=False)
contextname = Column(String, nullable=False)
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.schema import Column, PrimaryKeyConstraint, ForeignKeyConstraint
from sqlalchemy.types import Integer
from xivo_dao.helpers.db_manager import Base
class RouteMediaServer(Base):
__tablename__ = 'routemediaserver'
__table_args__ = (
PrimaryKeyConstraint('id'),
ForeignKeyConstraint(('routeid',),
('route.id',),
ondelete='RESTRICT'),
ForeignKeyConstraint(('mdsid',),
('mediaserver.id',),
ondelete='RESTRICT'),
)
routeid = Column(Integer, nullable=False)
mdsid = Column(Integer, nullable=False)
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.schema import Column, PrimaryKeyConstraint, ForeignKeyConstraint
from sqlalchemy.types import Integer
from xivo_dao.helpers.db_manager import Base
class RouteTrunk(Base):
__tablename__ = 'routetrunk'
__table_args__ = (
PrimaryKeyConstraint('id'),
ForeignKeyConstraint(('routeid',),
('route.id',),
ondelete='RESTRICT'),
ForeignKeyConstraint(('trunkid',),
('trunkfeatures.id',),
ondelete='RESTRICT'),
)
routeid = Column(Integer, nullable=False)
trunkid = Column(Integer, nullable=False)
priority = Column(Integer, nullable=False)
......@@ -16,10 +16,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.schema import Column, PrimaryKeyConstraint, UniqueConstraint, \
Index
ForeignKey, Index
from sqlalchemy.types import Integer, Text
from sqlalchemy.orm import relationship
from xivo_dao.alchemy import enum
from xivo_dao.alchemy.mediaserver import MediaServer
from xivo_dao.helpers.db_manager import Base
......@@ -39,3 +41,6 @@ class TrunkFeatures(Base):
registerid = Column(Integer, nullable=False, server_default='0')
registercommented = Column(Integer, nullable=False, server_default='0')
description = Column(Text)
mediaserverid = Column(Integer, ForeignKey('mediaserver.id', ondelete="RESTRICT"), nullable=False)
mediaserver = relationship(MediaServer)
......@@ -59,6 +59,8 @@ from xivo_dao.alchemy.agentqueueskill import AgentQueueSkill
from xivo_dao.alchemy.queuepenaltychange import QueuePenaltyChange
from xivo_dao.alchemy.func_key_mapping import FuncKeyMapping
from xivo_dao.alchemy.func_key_dest_custom import FuncKeyDestCustom
from xivo_dao.alchemy.trunkfeatures import TrunkFeatures
from xivo_dao.alchemy.mediaserver import MediaServer
@daosession
......@@ -326,16 +328,43 @@ def find_exten_settings(session, context_name):
@daosession
def is_extension_on_current_mds(session, exten_number, exten_context, mds_name):
linefeatures = (
session.query(LineFeatures)
.filter(LineFeatures.number == exten_number)
.filter(LineFeatures.context == exten_context)
.filter(LineFeatures.configregistrar == mds_name)
.first()
)
def is_extension_on_current_mds(session, exten_number, exten_context, current_mds_name, exten_type = 'user'):
if exten_type == 'group':
extensions = (
session.query(GroupFeatures)
.join(MediaServer, MediaServer.id == GroupFeatures.mediaserverid)
.filter(GroupFeatures.number == exten_number)
.filter(GroupFeatures.context == exten_context)
.filter(MediaServer.name == current_mds_name)
.first()
)
else:
extensions = (
session.query(LineFeatures)
.filter(LineFeatures.number == exten_number)
.filter(LineFeatures.context == exten_context)
.filter(LineFeatures.configregistrar == current_mds_name)
.first()
)
if extensions:
return True
else:
return False
if linefeatures:
@daosession
def is_sip_trunk_on_current_mds(session, trunk_name, current_mds_name):
match = (session.query(TrunkFeatures)
.join(UserSIP, UserSIP.id == TrunkFeatures.protocolid)
.join(MediaServer, and_(MediaServer.id == TrunkFeatures.mediaserverid,
or_(MediaServer.name == current_mds_name,
MediaServer.name == 'all_mds')))
.filter(UserSIP.name == trunk_name)
.first())
if match:
return True
else:
return False
......@@ -378,8 +407,24 @@ def find_voicemail_general_settings(session):
@daosession
def find_sip_general_settings(session):
rows = session.query(StaticSIP).filter(StaticSIP.commented == 0).all()
def find_sip_general_settings(session, current_mds_name):
rows = session.query(
StaticSIP
).outerjoin(
TrunkFeatures, StaticSIP.id == TrunkFeatures.registerid
).outerjoin(
MediaServer, TrunkFeatures.mediaserverid == MediaServer.id
).filter(
and_(
StaticSIP.id != None, # noqa
StaticSIP.commented == 0,
or_(
MediaServer.name == None,
MediaServer.name == 'all_mds',
MediaServer.name == current_mds_name
)
)
).all()
res = []
for row in rows:
......@@ -598,6 +643,32 @@ def find_queue_settings(session):
return [row.todict() for row in rows]
@daosession
def find_queue_queuefeatures_settings(session):
rows = session.query(
Queue,
).join(
QueueFeatures, Queue.name == QueueFeatures.name
).filter(
Queue.commented == 0
).order_by(Queue.name).all()
return [row.todict() for row in rows]
@daosession
def find_queue_groupfeatures_settings(session, current_mds_name):
rows = session.query(
Queue,
).join(
GroupFeatures, Queue.name == GroupFeatures.name
).join(
MediaServer, and_(MediaServer.name == current_mds_name,
(MediaServer.id == GroupFeatures.mediaserverid))
).filter(
Queue.commented == 0
).order_by(Queue.name).all()
return [row.todict() for row in rows]
@daosession
def find_queue_skillrule_settings(session):
......
......@@ -401,7 +401,8 @@ class TestDelete(DAOTestCase):
def test_delete_references_to_other_tables(self):
user = self.add_user()
group = self.add_group()
mediaserver = self.add_mediaserver()
group = self.add_groupfeatures(mediaserverid=mediaserver.id)
incall = self.add_incall()
outcall = self.add_outcall()
call_permission = call_permission_dao.create(CallPermission(name='Delete'))
......
......@@ -175,7 +175,8 @@ class FuncKeyHelper(object):
return self.add_user_destination(user_row.id)
def create_group_func_key(self):
group_row = self.add_group()
mediaserver = self.add_mediaserver()
group_row = self.add_groupfeatures(mediaserverid=mediaserver.id)
return self.add_group_destination(group_row.id)
def create_queue_func_key(self):
......
......@@ -30,7 +30,8 @@ class TestGroupExist(DAOTestCase):
assert_that(result, equal_to(False))
def test_given_group_exists_then_return_true(self):
group_row = self.add_group()
mediaserver = self.add_mediaserver()
group_row = self.add_groupfeatures(mediaserverid=mediaserver.id)
result = group_dao.exists(group_row.id)
......
......@@ -109,7 +109,8 @@ class TestFindAllBy(DAOTestCase):
def test_find_all_by_when_group_associate_to_call_permission(self):
call_permission = self.add_call_permission()
user = self.add_user()
group = self.add_group()
mediaserver = self.add_mediaserver()
group = self.add_groupfeatures(mediaserverid=mediaserver.id)
self.add_user_call_permission(user_id=user.id,
call_permission_id=call_permission.id)
self.add_group_call_permission(typeval=group.id,
......
This diff is collapsed.
......@@ -77,6 +77,7 @@ from xivo_dao.alchemy.staticmeetme import StaticMeetme
from xivo_dao.alchemy.staticqueue import StaticQueue
from xivo_dao.alchemy.staticsip import StaticSIP
from xivo_dao.alchemy.staticvoicemail import StaticVoicemail
from xivo_dao.alchemy.trunkfeatures import TrunkFeatures
from xivo_dao.alchemy.user import User
from xivo_dao.alchemy.user_line import UserLine
from xivo_dao.alchemy.usercustom import UserCustom as UserCustomSchema
......@@ -367,11 +368,21 @@ class DAOTestCase(unittest.TestCase):
def add_mediaserver(self, **kwargs):
kwargs.setdefault('id', self._generate_int())
kwargs.setdefault('name', self._random_name())
kwargs.setdefault('display_name', 'Test MDS')
kwargs.setdefault('voip_ip', '10.10.0.1')
mediaserver = MediaServer(**kwargs)
self.add_me(mediaserver)
return mediaserver
def add_sip_trunk(self, **kwargs):
kwargs.setdefault('id', self._generate_int())
sip_trunk = TrunkFeatures(**kwargs)
self.add_me(sip_trunk)
return sip_trunk
def add_netiface(self, **kwargs):
kwargs.setdefault('id', self._generate_int())
kwargs.setdefault('networktype', 'data')
......@@ -431,7 +442,7 @@ class DAOTestCase(unittest.TestCase):
self.add_me(agent)
return agent
def add_group(self, **kwargs):
def add_groupfeatures(self, **kwargs):
kwargs.setdefault('id', self._generate_int())
kwargs.setdefault('name', self._random_name())
kwargs.setdefault('context', '')
......
......@@ -24,7 +24,8 @@ from xivo_dao.tests.test_dao import DAOTestCase
class TestGroupDAO(DAOTestCase):
def test_get_name_number(self):
group = self._insert_group('test_name', '1234', 'my_ctx')
mediaserver = self.add_mediaserver()
group = self.add_groupfeatures(name='test_name', number='1234', context='my_ctx', mediaserverid=mediaserver.id)
name, number = group_dao.get_name_number(group.id)
......@@ -33,7 +34,8 @@ class TestGroupDAO(DAOTestCase):
def test_is_user_member_of_group_when_present(self):
user_id = 1
group = self._insert_group('foobar', '1234', 'default')
mediaserver = self.add_mediaserver()
group = self.add_groupfeatures(name='test_name', number='1234', context='default', mediaserverid=mediaserver.id)
self._insert_group_member(group.name, 'user', user_id)
result = group_dao.is_user_member_of_group(user_id, group.id)
......@@ -42,22 +44,13 @@ class TestGroupDAO(DAOTestCase):
def test_is_user_member_of_group_when_not_present(self):
user_id = 1
group = self._insert_group('foobar', '1234', 'default')
mediaserver = self.add_mediaserver()
group = self.add_groupfeatures(name='foobar', number='1234', context='default', mediaserverid=mediaserver.id)
result = group_dao.is_user_member_of_group(user_id, group.id)
self.assertFalse(result)
def _insert_group(self, name, number, context):
group = GroupFeatures()
group.name = name
group.number = number
group.context = context
self.add_me(group)
return group
def _insert_group_member(self, group_name, user_type, user_id):
queue_member = QueueMember()
queue_member.queue_name = group_name
......
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