def find_extension(account, dest_num, caller_id=None): """ find the first matching extension. returns a tuple, (ext, groups), where groups is an array of regex groups which can be used for replacing $1 $2 etc found in the xml """ exts = Extension.objects.filter(account=account) exts = exts.order_by("priority_position") for ext in exts: # Match data for destination number. match_data = [[]] * 2 match_data[0].append(dest_num) match_data[1].append(ext.dest_num) groups = ext.dest_num_matches(dest_num) match = groups if groups: # We have a matching destination. if ext.callerid_num: # This extension has callerid_num setting. if caller_id: match = re.match(ext.callerid_num, caller_id) else: match = None match_data[0].insert(0, unicode(caller_id)) match_data[1].insert(1, unicode(ext.callerid_num)) # Build log message. matches = [ ('|%s|' % ','.join(m for m in data)) for data in match_data] match_string = (' == ' if match else ' != ').join(matches) if match: match_string += ' (MATCH!)' logger.debug(match_string) if match: # Match succeded, build XML dialplan. # Load Extension actions actions = Action.objects.filter( extensionaction__extension=ext ).order_by("extensionaction__order") # If any Action configured override dialplan XML from Extension if actions: ext.actions_xml = build_action_xml(actions, account) gateway_security_check(account, ext) return (ext, groups) else: # No extensions matched. return (None, None)
def create_accounts(root_elt, sipprofile): # create accounts logger.debug("create accounts") account_elt_set = root_elt.getElementsByTagName('account') for account_elt in account_elt_set: logger.debug("account: %s" % account_elt.toxml()) name = account_elt.getAttribute("name") logger.debug("account name: %s" % name) if Account.objects.filter(name=name): raise Exception("Already have an account named: %s defined" % name) enabled_str = account_elt.getAttribute("enabled") enabled = (enabled_str.lower() == "true") domain = account_elt.getAttribute("domain") if not domain or len(domain) == 0: logger.debug("Warning: no domain for profile, using name. " " You will need to fix this") domain = name account = Account.objects.create(name=name, enabled=enabled, domain=domain, dialout_profile=sipprofile, aliased=True)
def sip_dialout_url(sip_url, account, mods=None): if not mods: mods = {} # see extension_url() for comments on why we set domain_name mods['domain_name'] = account.domain namevalpairs = ["%s=%s" % (name,val) for name, val in mods.items()] mods_string = ",".join(namevalpairs) sipprofile_name = get_sip_profile_or_domain(account) retval = "{%s}sofia/%s/%s" % (mods_string, sipprofile_name, sip_url) logger.debug(retval) return retval
def create_userprofiles(dom, sipprofile): logger.debug("create user profiles") userprofile_elt_set = dom.getElementsByTagName('userprofile') for userprofile_elt in userprofile_elt_set: logger.debug("userprofile: %s" % userprofile_elt.toxml()) email = userprofile_elt.getAttribute("email") logger.debug("email: %s" % email) account_name = userprofile_elt.getAttribute("account") account = Account.objects.get(name=account_name) logger.debug("account: %s" % account) first_name = userprofile_elt.getAttribute("first_name") last_name = userprofile_elt.getAttribute("last_name") is_acct_admin_str = userprofile_elt.getAttribute("is_account_admin") is_acct_admin = is_acct_admin_str.lower() == 'true' is_active_str = userprofile_elt.getAttribute("is_active") is_active = is_active_str.lower() == 'true' is_superuser_str = userprofile_elt.getAttribute("is_superuser") is_superuser = is_superuser_str.lower() == 'true' password = userprofile_elt.getAttribute("password") logger.debug("creating user with email: %s" % str(email)) user = User.objects.create_user(email, email, "password") user.first_name = first_name user.last_name = last_name user.is_staff = False user.is_active = is_active user.is_superuser = is_superuser user.save() userprof = UserProfile.objects.create( user=user, account=account) if is_acct_admin: account.admins.add(userprof) account.save() from django.db import connection cursor = connection.cursor() cursor.execute("update auth_user set password = '******' where id=%s" % (str(password), user.id))
def create_userprofiles(dom, sipprofile): logger.debug("create user profiles") userprofile_elt_set = dom.getElementsByTagName('userprofile') for userprofile_elt in userprofile_elt_set: logger.debug("userprofile: %s" % userprofile_elt.toxml()) email = userprofile_elt.getAttribute("email") logger.debug("email: %s" % email) account_name = userprofile_elt.getAttribute("account") account = Account.objects.get(name=account_name) logger.debug("account: %s" % account) first_name = userprofile_elt.getAttribute("first_name") last_name = userprofile_elt.getAttribute("last_name") is_acct_admin_str = userprofile_elt.getAttribute("is_account_admin") is_acct_admin = is_acct_admin_str.lower() == 'true' is_active_str = userprofile_elt.getAttribute("is_active") is_active = is_active_str.lower() == 'true' is_superuser_str = userprofile_elt.getAttribute("is_superuser") is_superuser = is_superuser_str.lower() == 'true' password = userprofile_elt.getAttribute("password") logger.debug("creating user with email: %s" % str(email)) user = User.objects.create_user(email, email, "password") user.first_name = first_name user.last_name = last_name user.is_staff = False user.is_active = is_active user.is_superuser = is_superuser user.save() userprof = UserProfile.objects.create(user=user, account=account) if is_acct_admin: account.admins.add(userprof) account.save() from django.db import connection cursor = connection.cursor() cursor.execute("update auth_user set password = '******' where id=%s" % (str(password), user.id))
def find_extension(account, dest_num): """ find the first matching extension. returns a tuple, (ext, groups), where groups is an array of regex groups which can be used for replacing $1 $2 etc found in the xml """ exts = Extension.objects.filter(account=account) exts = exts.order_by("priority_position") for ext in exts: groups = ext.dest_num_matches(dest_num) if groups: logger.debug("|%s| == |%s| (MATCH!)" % (dest_num, ext.dest_num)) gateway_security_check(account, ext) return (ext, groups) else: logger.debug("|%s| != |%s|" % (dest_num, ext.dest_num)) return (None, None)
def get_actions_xml(extension_elt): actions_xml_elts = extension_elt.getElementsByTagName("actions_xml") if not actions_xml_elts: logger.debug("No actionss_xml_elts!!") else: actions_xml_elt = actions_xml_elts[0] # print "actions_xml_elt: %s" % actions_xml_elt.toxml() children = actions_xml_elt.childNodes #print "children: %s len: %s" % (children, len(children)) for child in children: #print "child: %s" % child if child.nodeType == child.CDATA_SECTION_NODE: #print "CDATA: %s" % child.nodeValue return child.nodeValue elif child.nodeType == child.TEXT_NODE: #print "Text: %s" % child.nodeValue pass
def create_endpoints(dom, sipprofile): logger.debug("create endpoints") endpoint_elt_set = dom.getElementsByTagName('endpoint') for endpoint_elt in endpoint_elt_set: logger.debug("endpoint: %s" % endpoint_elt.toxml()) userid = endpoint_elt.getAttribute("userid") password = endpoint_elt.getAttribute("password") account_name = endpoint_elt.getAttribute("account") account = Account.objects.get(name=account_name) logger.debug("account: %s" % account) email = endpoint_elt.getAttribute("userprofile") logger.debug("looking up user with email: %s" % email) user = User.objects.get(email=email) logger.debug("found user with email: %s" % email) userprofile = user.get_profile() Endpoint.objects.create(userid=userid, password=password, account=account, userprofile=userprofile)
def create_extensions(dom, sipprofile): logger.debug("create extensions") extension_elt_set = dom.getElementsByTagName('extension') for extension_elt in extension_elt_set: logger.debug("extension: %s" % extension_elt.toxml()) account_name = extension_elt.getAttribute("account") account = Account.objects.get(name=account_name) logger.debug("account: %s" % account) # default to True, users can open up extensions as needed auth_call = True dest_num = extension_elt.getAttribute("dest_num") desc = extension_elt.getAttribute("desc") endpoint = None endpoint_userid = extension_elt.getAttribute("endpoint_userid") if endpoint_userid: endpoint = Endpoint.objects.get(account=account, userid=endpoint_userid) priority_position = extension_elt.getAttribute("priority_position") logger.debug("priority_position: %s" % priority_position) if not priority_position: priority_position = 0 actions_xml = get_actions_xml(extension_elt) Extension.objects.create(account=account, auth_call=auth_call, dest_num=dest_num, desc=desc, endpoint=endpoint, priority_position=int(priority_position), actions_xml=actions_xml)
def create_gateways(dom, sipprofile): logger.debug("create gateways") gateway_elt_set = dom.getElementsByTagName('gateway') for gateway_elt in gateway_elt_set: logger.debug("gateway: %s" % gateway_elt.toxml()) name = gateway_elt.getAttribute("name") account_name = gateway_elt.getAttribute("account") account = Account.objects.get(name=account_name) logger.debug("account: %s" % account) username = gateway_elt.getAttribute("username") password = gateway_elt.getAttribute("password") proxy = gateway_elt.getAttribute("proxy") register_str = gateway_elt.getAttribute("register") register = (register_str.lower() == "true") extension = gateway_elt.getAttribute("extension") realm = gateway_elt.getAttribute("realm") from_domain = gateway_elt.getAttribute("from_domain") expire_seconds = gateway_elt.getAttribute("expire_seconds") retry_seconds = gateway_elt.getAttribute("retry_seconds") caller_id_in_from = gateway_elt.getAttribute("caller_id_in_from") SofiaGateway.objects.create(name=name, sip_profile=sipprofile, account=account, username=username, password=password, proxy=proxy, register=register, extension=extension, realm=realm, from_domain=from_domain, expire_seconds=expire_seconds, retry_seconds=retry_seconds, caller_id_in_from=caller_id_in_from, accessible_all_accts=False)
def delete(self): logger.debug("deleting userprofile") self.user.delete() super(UserProfile, self).delete() # Call the "real" delete() method
def process(cdr_xml_str): """ take an xml string, parse it, and use the information to create a Cdr object and return it <cdr> <variables> <local_media_ip>192.168.1.201</local_media_ip> <sip_call_id>c477994b-9f62-122a-43a0-000f1fc8e441</sip_call_id> <remote_media_ip>67.65.105.29</remote_media_ip> <hangup_cause>NORMAL_CLEARING</hangup_cause> <endpoint_disposition>ANSWER</endpoint_disposition> <switch_r_sdp>v%3D0%20%..........etc</switch_r_sdp> <local_media_port>13780</local_media_port> <remote_media_port>13780</remote_media_port> <ignore_early_media>true</ignore_early_media> </variables> <app_log> <application app_name="conference" app_data="221"></application> </app_log> <callflow dialplan=""> <extension name="221" number="221"> <application app_name="conference" app_data="221"></application> </extension> <caller_profile> <username></username> <dialplan></dialplan> <caller_id_name>FreeSWITCH</caller_id_name> <ani></ani> <aniii></aniii> <caller_id_number>0000000000</caller_id_number> <network_addr></network_addr> <rdnis></rdnis> <destination_number>mydomain.com/[email protected]</destination_number> <uuid>ed18eda4-24bf-11dc-913a-37ac3cdbbaa7</uuid> <source>src/switch_ivr_originate.c</source> <context>default</context> <chan_name>sofia/mydomain.com/[email protected]</chan_name> </caller_profile> <times> <created_time>1182956764946190</created_time> <answered_time>1182956765107959</answered_time> <hangup_time>1182956785394251</hangup_time> <transfer_time>0</transfer_time> </times> </callflow> </cdr> """ cleaned = cdr_xml_str.encode("ascii", "replace") logger.debug(cleaned) dom = minidom.parseString(cleaned) # first try to use the account_id (which is set in the dialplan.xml # template). if that fails, fallback to "domain_name", which # is set in the "web dialout string" and possibly by freeswitch # in some cases. # After that look for dialplan context account_id = get_account_id(dom) domain_name = get_domain_name(dom) context = get_context(dom) # Get Account Id from the context string context_account_id = Account.context_account(context) sq = {} account = None if account_id: sq = dict(pk=account_id) elif domain_name: sq = dict(domain=domain_name) elif context_account_id: sq = dict(pk=context_account_id) else: msg = ( "WARN: Cannot associate this CDR with an account. " "Did not find either a valid account_id, " "domain_name or context channel variable" ) logger.warn(msg) now = datetime.datetime.now() ServerLog.objects.create(logtime=now, message=msg) if sq: try: account = Account.objects.get(**sq) except Account.DoesNotExist: msg = "WARN: No account found. account_id=%s, " "domain_name=%s, context=%s" % ( account_id, domain_name, context, ) logger.warn(msg) now = datetime.datetime.now() ServerLog.objects.create(logtime=now, message=msg) dest_num = get_destination_number_field(dom) caller_id_number = get_callerid_number_field(dom) answered_time = get_answered_time(dom) hangup_time = get_hangup_time(dom) uuid = get_uuid(dom) if not settings.CDR_SAVE_XML: cdr_xml_str = "Saving raw CDR XML disabled in settings.py" completed_call = CompletedCall( account=account, uuid=uuid, destination_number=dest_num, caller_id_number=caller_id_number, chan_name=get_chan_name(dom), cdr_xml=cdr_xml_str, answered_time=answered_time, hangup_time=hangup_time, ) completed_call.save() return completed_call
def process(cdr_xml_str): """ take an xml string, parse it, and use the information to create a Cdr object and return it <cdr> <variables> <local_media_ip>192.168.1.201</local_media_ip> <sip_call_id>c477994b-9f62-122a-43a0-000f1fc8e441</sip_call_id> <remote_media_ip>67.65.105.29</remote_media_ip> <hangup_cause>NORMAL_CLEARING</hangup_cause> <endpoint_disposition>ANSWER</endpoint_disposition> <switch_r_sdp>v%3D0%20%..........etc</switch_r_sdp> <local_media_port>13780</local_media_port> <remote_media_port>13780</remote_media_port> <ignore_early_media>true</ignore_early_media> </variables> <app_log> <application app_name="conference" app_data="221"></application> </app_log> <callflow dialplan=""> <extension name="221" number="221"> <application app_name="conference" app_data="221"></application> </extension> <caller_profile> <username></username> <dialplan></dialplan> <caller_id_name>FreeSWITCH</caller_id_name> <ani></ani> <aniii></aniii> <caller_id_number>0000000000</caller_id_number> <network_addr></network_addr> <rdnis></rdnis> <destination_number>mydomain.com/[email protected]</destination_number> <uuid>ed18eda4-24bf-11dc-913a-37ac3cdbbaa7</uuid> <source>src/switch_ivr_originate.c</source> <context>default</context> <chan_name>sofia/mydomain.com/[email protected]</chan_name> </caller_profile> <times> <created_time>1182956764946190</created_time> <answered_time>1182956765107959</answered_time> <hangup_time>1182956785394251</hangup_time> <transfer_time>0</transfer_time> </times> </callflow> </cdr> """ cleaned = cdr_xml_str.encode('ascii', 'replace') logger.debug(cleaned) dom = minidom.parseString(cleaned) # first try to use the account_id (which is set in the dialplan.xml # template). if that fails, fallback to "domain_name", which # is set in the "web dialout string" and possibly by freeswitch # in some cases. # After that look for dialplan context account_id = get_account_id(dom) domain_name = get_domain_name(dom) context = get_context(dom) # Get Account Id from the context string context_account_id = Account.context_account(context) sq = {} account = None if account_id: sq = dict(pk=account_id) elif domain_name: sq = dict(domain=domain_name) elif context_account_id: sq = dict(pk=context_account_id) else: msg = ("WARN: Cannot associate this CDR with an account. " "Did not find either a valid account_id, " "domain_name or context channel variable") logger.warn(msg) now = datetime.datetime.now() ServerLog.objects.create(logtime=now, message=msg) if sq: try: account = Account.objects.get(**sq) except Account.DoesNotExist: msg = ("WARN: No account found. account_id=%s, " "domain_name=%s, context=%s" % (account_id, domain_name, context)) logger.warn(msg) now = datetime.datetime.now() ServerLog.objects.create(logtime=now, message=msg) dest_num = get_destination_number_field(dom) caller_id_number = get_callerid_number_field(dom) answered_time = get_answered_time(dom) hangup_time = get_hangup_time(dom) uuid = get_uuid(dom) if not settings.CDR_SAVE_XML: cdr_xml_str = "Saving raw CDR XML disabled in settings.py" completed_call = CompletedCall(account=account, uuid=uuid, destination_number=dest_num, caller_id_number=caller_id_number, chan_name=get_chan_name(dom), cdr_xml=cdr_xml_str, answered_time=answered_time, hangup_time=hangup_time) completed_call.save() return completed_call
def process(cdr_xml_str): """ take an xml string, parse it, and use the information to create a Cdr object and return it <cdr> <variables> <local_media_ip>192.168.1.201</local_media_ip> <sip_call_id>c477994b-9f62-122a-43a0-000f1fc8e441</sip_call_id> <remote_media_ip>67.65.105.29</remote_media_ip> <hangup_cause>NORMAL_CLEARING</hangup_cause> <endpoint_disposition>ANSWER</endpoint_disposition> <switch_r_sdp>v%3D0%20%..........etc</switch_r_sdp> <local_media_port>13780</local_media_port> <remote_media_port>13780</remote_media_port> <ignore_early_media>true</ignore_early_media> </variables> <app_log> <application app_name="conference" app_data="221"></application> </app_log> <callflow dialplan=""> <extension name="221" number="221"> <application app_name="conference" app_data="221"></application> </extension> <caller_profile> <username></username> <dialplan></dialplan> <caller_id_name>FreeSWITCH</caller_id_name> <ani></ani> <aniii></aniii> <caller_id_number>0000000000</caller_id_number> <network_addr></network_addr> <rdnis></rdnis> <destination_number>mydomain.com/[email protected]</destination_number> <uuid>ed18eda4-24bf-11dc-913a-37ac3cdbbaa7</uuid> <source>src/switch_ivr_originate.c</source> <context>default</context> <chan_name>sofia/mydomain.com/[email protected]</chan_name> </caller_profile> <times> <created_time>1182956764946190</created_time> <answered_time>1182956765107959</answered_time> <hangup_time>1182956785394251</hangup_time> <transfer_time>0</transfer_time> </times> </callflow> </cdr> """ cleaned = cdr_xml_str.encode('ascii', 'replace') logger.debug(cleaned) dom = minidom.parseString(cleaned) # first try to use the account_id (which is set in the dialplan.xml # template). if that fails, fallback to "domain_name", which # is set in the "web dialout string" and possibly by freeswitch # in some cases. account_id = get_account_id(dom) if account_id: accounts = Account.objects.filter(pk=account_id) if not accounts: raise Exception("No account found with domain: %s" % domain_name) account=accounts[0] else: domain_name = get_domain_name(dom) if not domain_name: raise Exception("Cannot associate this CDR with an account. " "Did not find either a valid account_id or " "domain_name channel variable") else: accounts = Account.objects.filter(domain=domain_name) if not accounts: raise Exception("No account found with domain: %s" % domain_name) account=accounts[0] dest_num = get_destination_number_field(dom) caller_id_number = get_callerid_number_field(dom) answered_time = get_answered_time(dom) hangup_time = get_hangup_time(dom) uuid = get_uuid(dom) if not settings.CDR_SAVE_XML: cdr_xml_str = "Saving raw CDR XML disabled in settings.py" completed_call = CompletedCall(account=account, uuid=uuid, destination_number=dest_num, caller_id_number=caller_id_number, chan_name=get_chan_name(dom), cdr_xml=cdr_xml_str, answered_time=answered_time, hangup_time=hangup_time) completed_call.save() return completed_call
def data_import_from_version_pt_5(path2xml, sipprofilename2use=None): """ Main entry point .. """ # are there any sip profiles defined? sipprofiles = SipProfile.objects.all() if not sipprofiles: raise Exception("No sip profiles defined. Please define one " "and try again") # are there multiple sip profiles defined but no sipprofile2use? if len(sipprofiles) > 1 and not sipprofile2use: raise Exception("Multiple sip profiles and sipprofile2use not " "passed in") if len(sipprofiles) == 1: sipprofile = sipprofiles[0] logger.debug("Will use sip profile: %s" % sipprofile) else: # lookup actual profile with given name sipprofile = SipProfile.objects.get(name=sipprofilename2use) if not sipprofile: raise Exception("Could not find sip profile with name: %s" % sipprofile2use) # does file exist? if not os.path.exists(path2xml): raise Exception("Did not find file: %s. Did you upload to server?" % path2xml) # parse in the contents in path2xml into a dom object dom = minidom.parse(path2xml) # get root elt root_elt = get_root(dom) logger.debug("elt: %s" % root_elt.localName) try: transaction.enter_transaction_management() transaction.managed(True) create_accounts(root_elt, sipprofile) create_userprofiles(dom, sipprofile) create_endpoints(dom, sipprofile) create_extensions(dom, sipprofile) create_gateways(dom, sipprofile) if DRY_RUN: raise Exception("Dry Run") transaction.commit() transaction.leave_transaction_management() except Exception, e: try: logger.debug("!!CRITICAL ERROR!! ROLLING BACK ALL CHANGES") logger.debug("Exception: %s" % e) transaction.rollback() logger.debug("Transaction rollback completed successfully") except Exception, e2: logger.debug("Exception trying to rollback!!") transaction.leave_transaction_management()