root/apps/python/trunk/telsoap.py
@
543
| Revision 543, 6.7 kB (checked in by nadya, 4 years ago) |
|---|
| Line | |
|---|---|
| 1 | #!/usr/bin/env python |
| 2 | |
| 3 | # SOAP support functions for .tel telfriends functionality |
| 4 | |
| 5 | # Copyright (c) 2009, Andrew McDonald |
| 6 | # All rights reserved. |
| 7 | # |
| 8 | # Redistribution and use in source and binary forms, with or without |
| 9 | # modification, are permitted provided that the following conditions |
| 10 | # are met: |
| 11 | # |
| 12 | # * Redistributions of source code must retain the above copyright |
| 13 | # notice, this list of conditions and the following disclaimer. |
| 14 | # |
| 15 | # * Redistributions in binary form must reproduce the above |
| 16 | # copyright notice, this list of conditions and the following |
| 17 | # disclaimer in the documentation and/or other materials provided |
| 18 | # with the distribution. |
| 19 | # |
| 20 | # * The name of the author may not be used to endorse or promote |
| 21 | # products derived from this software without specific prior |
| 22 | # written permission. |
| 23 | # |
| 24 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 25 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 26 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 27 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 28 | # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 29 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 30 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 31 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| 32 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 33 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| 34 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 35 | # POSSIBILITY OF SUCH DAMAGE. |
| 36 | |
| 37 | import sys |
| 38 | import urllib2 |
| 39 | import base64 |
| 40 | import xml.dom.minidom |
| 41 | from M2Crypto import RSA |
| 42 | |
| 43 | initurl = "https://soap.telfriends.tel/init?wsdl" |
| 44 | memburl = "https://soap.telfriends.tel/member?wsdl" |
| 45 | |
| 46 | def getText(nodelist): |
| 47 | rc = "" |
| 48 | for node in nodelist: |
| 49 | if node.nodeType == node.TEXT_NODE: |
| 50 | rc = rc + node.data |
| 51 | return rc |
| 52 | |
| 53 | def extractChallQuestion(stream): |
| 54 | dom = xml.dom.minidom.parse(stream) |
| 55 | chall = getText(dom.getElementsByTagName("ns2:challengeQuestion")[0].childNodes) |
| 56 | return chall |
| 57 | |
| 58 | def extractAPICredentials(stream, password): |
| 59 | dom = xml.dom.minidom.parse(stream) |
| 60 | soid = getText(dom.getElementsByTagName("ns2:soid")[0].childNodes) |
| 61 | enc_api_pass = getText(dom.getElementsByTagName("ns2:apiPassword")[0].childNodes) |
| 62 | enc_private_key = getText(dom.getElementsByTagName("privateKey")[0].childNodes) |
| 63 | epk = "" |
| 64 | while len(enc_private_key) > 0: |
| 65 | epk = epk + '\n' |
| 66 | epk = epk + enc_private_key[:76] |
| 67 | if len(enc_private_key) > 76: |
| 68 | enc_private_key = enc_private_key[76:] |
| 69 | else: |
| 70 | enc_private_key = "" |
| 71 | pem_private_key = str("-----BEGIN ENCRYPTED PRIVATE KEY-----"+epk+"\n-----END ENCRYPTED PRIVATE KEY-----\n") |
| 72 | pk = RSA.load_key_string(pem_private_key, lambda *args: password) |
| 73 | api_pass = pk.private_decrypt(base64.decodestring(enc_api_pass), |
| 74 | RSA.pkcs1_padding) |
| 75 | |
| 76 | return (soid, api_pass, pk) |
| 77 | |
| 78 | def extractPublishers(stream): |
| 79 | dom = xml.dom.minidom.parse(stream) |
| 80 | entries = dom.getElementsByTagName("ns3:entry") |
| 81 | pubs = [] |
| 82 | for e in entries: |
| 83 | pub = getText(e.getElementsByTagName("ns3:publisher")[0].childNodes) |
| 84 | label = getText(e.getElementsByTagName("ns3:label")[0].childNodes) |
| 85 | pubs.append((pub,label)) |
| 86 | return pubs |
| 87 | |
| 88 | def getChallenge(username, password): |
| 89 | authdata = base64.encodestring('%s:%s' % (username, password))[:-1] |
| 90 | authheader = "Basic %s" % authdata |
| 91 | |
| 92 | req = urllib2.Request(initurl) |
| 93 | req.add_header("User-Agent", "PyTel/1.0") |
| 94 | req.add_header("Authorization", authheader) |
| 95 | req.add_header("Content-Type", "application/soap+xml; charset=utf-8") |
| 96 | |
| 97 | req.add_data('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:typ="http://xmlns.telnic.org/ws/so/init/types-1.0"><soap:Header/><soap:Body>'+\ |
| 98 | '<getChallengeQuestionRequest xmlns="http://xmlns.telnic.org/ws/so/init/types-1.0"/>'+\ |
| 99 | '</soap:Body></soap:Envelope>') |
| 100 | |
| 101 | try: |
| 102 | response = urllib2.urlopen(req) |
| 103 | except urllib2.HTTPError, e: |
| 104 | if e.code == 401: |
| 105 | return None |
| 106 | raise e |
| 107 | return extractChallQuestion(response) |
| 108 | |
| 109 | def getAPICredentials(username, password, challresp): |
| 110 | authdata = base64.encodestring('%s:%s' % (username, password))[:-1] |
| 111 | authheader = "Basic %s" % authdata |
| 112 | |
| 113 | req = urllib2.Request(initurl) |
| 114 | req.add_header("User-Agent", "PyTel/1.0") |
| 115 | req.add_header("Authorization", authheader) |
| 116 | req.add_header("Content-Type", "application/soap+xml; charset=utf-8") |
| 117 | |
| 118 | req.add_data('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:typ="http://xmlns.telnic.org/ws/so/init/types-1.0"><soap:Header/><soap:Body>' + \ |
| 119 | '<getAPICredentialsRequest xmlns="http://xmlns.telnic.org/ws/so/init/types-1.0"><challengeAnswer>%s</challengeAnswer>' % challresp + \ |
| 120 | '</getAPICredentialsRequest></soap:Body></soap:Envelope>') |
| 121 | |
| 122 | try: |
| 123 | response = urllib2.urlopen(req) |
| 124 | except urllib2.HTTPError, e: |
| 125 | if e.code == 401: |
| 126 | return None |
| 127 | if e.code == 500: |
| 128 | # probably ought to look at the xml passed back |
| 129 | return None |
| 130 | raise e |
| 131 | return extractAPICredentials(response, password) |
| 132 | |
| 133 | def listPublishers(username, password): |
| 134 | authdata = base64.encodestring('%s:%s' % (username, password))[:-1] |
| 135 | authheader = "Basic %s" % authdata |
| 136 | |
| 137 | req = urllib2.Request(memburl) |
| 138 | req.add_header("User-Agent", "PyTel/1.0") |
| 139 | req.add_header("Authorization", authheader) |
| 140 | req.add_header("Content-Type", "application/soap+xml; charset=utf-8") |
| 141 | |
| 142 | req.add_data('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:typ="http://xmlns.telnic.org/ws/so/member/publisherstore/types-1.0"><soap:Header/><soap:Body>'+\ |
| 143 | '<listPublishersRequest xmlns="http://xmlns.telnic.org/ws/so/member/publisherstore/types-1.0"/>'+\ |
| 144 | '</soap:Body></soap:Envelope>') |
| 145 | |
| 146 | try: |
| 147 | response = urllib2.urlopen(req) |
| 148 | except urllib2.HTTPError, e: |
| 149 | if e.code == 401: |
| 150 | return None |
| 151 | raise e |
| 152 | return extractPublishers(response) |
| 153 | |
| 154 | def main(username, password, challengeresp): |
| 155 | chall = getChallenge(username, password) |
| 156 | print "Challenge Question: %s" % chall |
| 157 | (soid, api_pass, priv_key) = getAPICredentials(username, password, challengeresp) |
| 158 | print soid |
| 159 | print api_pass |
| 160 | print priv_key |
| 161 | pubs = listPublishers(soid, api_pass) |
| 162 | print pubs |
| 163 | |
| 164 | priv_key.save_pem("telkey.pem", None) |
| 165 | csvfile = open("friendlist.csv", "w+") |
| 166 | for (p,l) in pubs: |
| 167 | csvfile.write("%s,%s\n" % (p,l)) |
| 168 | csvfile.close() |
| 169 | |
| 170 | if __name__ == "__main__": |
| 171 | main(sys.argv[1], sys.argv[2], sys.argv[3]) |
Note: See TracBrowser
for help on using the browser.








