~ubuntu-branches/debian/sid/openchange/sid

« back to all changes in this revision

Viewing changes to mapiproxy/services/client/OCSManager/Network.py

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij
  • Date: 2012-04-12 20:07:57 UTC
  • mfrom: (11 sid)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20120412200757-k933d9trljmxj1l4
Tags: 1:1.0-4
* openchangeserver: Add dependency on openchangeproxy.
* Rebuild against newer version of Samba 4.
* Use dpkg-buildflags.
* Migrate to Git, update Vcs-Git header.
* Switch to debhelper 9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import os
 
4
import tempfile
 
5
import StringIO
 
6
import pycurl
 
7
import urllib
 
8
from lxml import etree
 
9
from OCSManager import ClientAuthentication
 
10
from OCSManager import ClientNotification
 
11
 
 
12
"""
 
13
OCSManager Network documentation
 
14
"""
 
15
 
 
16
class Network(object):
 
17
    """Network class documentation. Perform authentication and network
 
18
    operation on OpenChange Service Manager.
 
19
    """
 
20
 
 
21
    def __init__(self, host=None, port=None, verbose=False):
 
22
        """Initialize OCSManager Network instance.
 
23
        """
 
24
 
 
25
        if host is None: return None
 
26
        if port is None: return None
 
27
 
 
28
        self.auth = ClientAuthentication.ClientAuthentication()
 
29
        self.curl = pycurl.Curl()
 
30
        self.host = host
 
31
        self.port = port
 
32
        self.verbose = verbose
 
33
        self.token = None
 
34
        self.base_uri = 'http://%s:%s' % (host, port)
 
35
        (self.fp,self.cookie) = tempfile.mkstemp()
 
36
 
 
37
    def __del__(self):
 
38
        self.curl.close()
 
39
        
 
40
 
 
41
    def __make_url(self, service=None):
 
42
        """Generate the URL to connect to."""
 
43
        if service is None: return None
 
44
        return "%s/%s" % (self.base_uri, service)
 
45
 
 
46
    def __get_error(self, data):
 
47
        """Retrieve error code and associated string if available.
 
48
        """
 
49
        if data is None: return (None, None)
 
50
 
 
51
        try:
 
52
            dataXML = etree.XML(data)
 
53
        except etree.XMLSyntaxError:
 
54
            return (None, None)
 
55
 
 
56
        error = dataXML.find('error')
 
57
        if error is None: return (None, None)
 
58
 
 
59
        if not "code" in error.attrib: return (None, None)
 
60
        if error.text is None: return (None, None)
 
61
        code = error.attrib["code"]
 
62
        string = error.text
 
63
        return (code, string)
 
64
 
 
65
    def __make_request(self, url=None, postfields=None, headers=None, data=None):
 
66
        """Build common part of the PyCurl request.
 
67
        """
 
68
        if data is None: return (True, 'Invalid StringIO buffer')
 
69
        if url is None: return (True, 'Missing URL')
 
70
 
 
71
        if self.verbose is True: print postfields
 
72
 
 
73
        self.curl.setopt(pycurl.URL, url)
 
74
        if headers is not None:
 
75
            self.curl.setopt(pycurl.HTTPHEADER, headers)
 
76
        else:
 
77
            self.curl.setopt(pycurl.HTTPHEADER, ['Content-Type: text/xml'])
 
78
        self.curl.setopt(pycurl.FOLLOWLOCATION, 1)
 
79
        self.curl.setopt(pycurl.COOKIEFILE, self.cookie)
 
80
        self.curl.setopt(pycurl.COOKIEJAR, self.cookie)
 
81
        self.curl.setopt(pycurl.WRITEFUNCTION, data.write)
 
82
        self.curl.setopt(pycurl.VERBOSE, self.verbose)
 
83
        return (False, None)
 
84
 
 
85
    def __exec_request(self, data=None):
 
86
        """Execute the request and perform HTTP error code and error
 
87
        XML payload sanity checks. Return response payload on success"""
 
88
        try:
 
89
            self.curl.perform()
 
90
        except pycurl.error, e:
 
91
            return (True, "(code=%s): %s" % (e.args[0], e.args[1]))
 
92
 
 
93
        if self.verbose is True: print data.getvalue()
 
94
 
 
95
        if self.curl.getinfo(self.curl.HTTP_CODE) != 200:
 
96
            return (True, self.curl.getinfo(self.curl.HTTP_CODE))
 
97
 
 
98
        (code, string) = self.__get_error(data.getvalue())
 
99
        if code is not None and int(code) != 200:
 
100
            return (True, "[%s]: %s" % (code, string))
 
101
        return (False, data.getvalue())
 
102
        
 
103
 
 
104
    def __put(self, url=None, postfields=None, headers=None):
 
105
        """Make a HTTP PUT request.
 
106
        """
 
107
        if postfields is None: return (True, 'Empty PUT payload')
 
108
 
 
109
        data = StringIO.StringIO()
 
110
        (error, msg) = self.__make_request(url, postfields, headers, data)
 
111
        if error is True: return (error, msg)
 
112
        self.curl.setopt(pycurl.PUT, 1)
 
113
        self.curl.setopt(pycurl.INFILESIZE, len(postfields))
 
114
        self.curl.setopt(pycurl.READFUNCTION, StringIO.StringIO(postfields).read)
 
115
        return self.__exec_request(data)
 
116
 
 
117
 
 
118
    def __post(self, url=None, postfields=None, headers=None):
 
119
        """Make a HTTP POST request.
 
120
        """
 
121
        if postfields is None: return (True, 'Empty POST payload')
 
122
 
 
123
        data = StringIO.StringIO()
 
124
        (error, msg) = self.__make_request(url, postfields, headers, data)
 
125
        if error is True: return (error, msg)
 
126
        self.curl.setopt(pycurl.POSTFIELDS, postfields)
 
127
        self.curl.setopt(pycurl.POST, 1)
 
128
        return self.__exec_request(data)
 
129
 
 
130
    def __login_token(self, login):
 
131
        """First stage of the authentication process.
 
132
        """
 
133
        postfields = self.auth.setTokenPayload(login)
 
134
        url = self.__make_url('authenticate/token')
 
135
        return self.__post(url, postfields, None)
 
136
 
 
137
    def __login(self, d):
 
138
        """Second stage of the authentication process.
 
139
        """
 
140
        (error, payload) = self.auth.setLoginPayload(d)
 
141
        if error is True: return (error, payload)
 
142
 
 
143
        url = self.__make_url('authenticate/login')
 
144
        return self.__post(url, payload, None)
 
145
 
 
146
    def login(self, username=None, password=None, encryption=None):
 
147
        """Log onto OCSManager service. Returns (False, None) tupple on
 
148
        success, otherwise (True, reason)
 
149
        """
 
150
        if username is None: return (True, 'Missing username parameter')
 
151
        if password is None: return (True, 'Missing password parameter')
 
152
        if encryption is None: return (True, 'Missing encryption parameter')
 
153
 
 
154
        (error, data) = self.__login_token(username)
 
155
        if error is True: return (error, data)
 
156
 
 
157
        # Retrieve parameters from reply
 
158
        (error, d) = self.auth.getTokenPayload(data)
 
159
        if error is True: return (error, d)
 
160
 
 
161
        d["username"] = username
 
162
        d["password"] = password
 
163
        d["encryption"] = encryption
 
164
 
 
165
        (error, data) = self.__login(d)
 
166
        if error is True: return (error, data)
 
167
 
 
168
        (error,tokenLogin) = self.auth.getTokenLogin(data)
 
169
        if error is True: return (error, data)
 
170
        self.token = tokenLogin
 
171
 
 
172
        return (False, None)
 
173
        
 
174
    def newmail(self, newmail):
 
175
        """Sends a newmail notification to OCSManager service.
 
176
        """
 
177
        
 
178
        if self.token is None: return (True, 'User not authenticated')
 
179
 
 
180
        notif = ClientNotification.ClientNotification()
 
181
        (error, payload) = notif.setNewMailPayload(self.token, newmail)
 
182
        if error is True: return (error, payload)
 
183
 
 
184
        url = self.__make_url('notification/newmail')
 
185
        return self.__put(url, payload, None)
 
186
        
 
187