Mod xml curl Python example

From FreeSWITCH Wiki
Jump to: navigation, search

Configuring mod_xml_curl

  • cd /usr/local/src/freeswitch
  • make mod_xml_curl-install
  • cd /usr/local/freeswitch/conf/autoload_configs
  • Edit modules.conf.xml and uncomment mod_xml_curl
  • Edit xml_curl.conf.xml and edit or add a gateway-url line like:
<param name="gateway-url" value="http://127.0.0.1/cgi-bin/fs-directory.py" bindings="directory"/>
  • In fs_cli run reloadxml and xml_curl debug_on

Account authentication with Python

This code will output the xml needed to authenticate users. Uses the lxml and hashlib modules, so make sure you install them before running.

#!/usr/bin/env python
print "Content-Type: text/xml"
print

from lxml.builder import E
from lxml import etree
import hashlib
import cgi

def create_base_directory_xml_doc():
    doc = (
        E.document(
            E.section(name="directory")
        ,type="freeswitch/xml")
    )
    return doc

def hash_password(domain, username, password):
     hash = hashlib.md5()
     hash.update(username + ":" + domain + ":" + password)
     password_hash = hash.hexdigest()
     password_param = "a1-hash"
     return password_param, password_hash

def add_directory_domain_user(doc, domain, username, password):
    password_param = "password"
    # comment out the line below to test with plain text passwords
    password_param, password = hash_password(domain, username, password)

    section = doc.find("section")

    # search for a domain tag for the indicated domain
    # if the domain is not found, add it
    searchStr = 'domain[@name="{}"]'.format(domain)
    results = section.xpath(searchStr)
    if len(results) > 0:
        dom = results[0]
    else:
        dom = (
            E.domain(
                E.params(
                    E.param(
                        name="dial-string", 
                        value='{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}'
                    )
                ),
                E.groups(
                )
            ,name=domain)
        )
        section.append(dom)

   # search for a group tag (for the "default" context)
   # if the group is not found, add it
   groups = dom.find("groups")
   searchStr = 'group[@name="{}"]'.format("default")
   results = groups.xpath(searchStr)
   if len(results) > 0:
       grp = results[0]
   else: 
       grp = E.group(
           E.users()
       ,name="default")
       groups.append(grp)

   # add the new user 
   grp.find("users").append(
       E.user(
           E.params(
               E.param(name=password_param, value=password)
           )
       ,id=username)
   )
 
form = cgi.FieldStorage()

if (form['section'].value == 'directory'):
   document = create_base_directory_xml_doc()
   add_directory_domain_user(document, "10.0.0.1", "1000", "1234")
   add_directory_domain_user(document, "10.0.0.1", "1001", "1234")
   add_directory_domain_user(document, "domain234.blah.testtld", "1000", "1234")

print(etree.tostring(document, pretty_print=True))

sample output

Content-Type: text/xml

 <document type="freeswitch/xml">
  <section name="directory">
   <domain name="10.0.0.1">
     <params>
       <param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/>
     </params>
     <groups>
       <group name="default">
         <users>
           <user id="1000">
             <params>
               <param name="a1-hash" value="c16b463e4aed7f04f102f2b6a8b7471d"/>
             </params>
           </user>
           <user id="1001">
             <params>
               <param name="a1-hash" value="46cdbbc544649c2889ab9a7fa3e8a48a"/>
             </params>
           </user>
         </users>
       </group>
     </groups>
   </domain>
   <domain name="domain234.blah.testtld">
     <params>
       <param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/>
     </params>
     <groups>
       <group name="default">
         <users>
           <user id="1000">
             <params>
               <param name="a1-hash" value="7a02a48f6b45f3d8cf76423db6ef562c"/>
             </params>
           </user>
         </users>
       </group>
     </groups>
   </domain>
  </section>
</document>