root / snf-astakos-client / astakosclient / __init__.py @ 8fe6475a
History | View | Annotate | Download (12.7 kB)
1 | 99165736 | Christos Stavrakakis | # Copyright (C) 2012, 2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 99165736 | Christos Stavrakakis | #
|
3 | 99165736 | Christos Stavrakakis | # Redistribution and use in source and binary forms, with or
|
4 | 99165736 | Christos Stavrakakis | # without modification, are permitted provided that the following
|
5 | 99165736 | Christos Stavrakakis | # conditions are met:
|
6 | 99165736 | Christos Stavrakakis | #
|
7 | 99165736 | Christos Stavrakakis | # 1. Redistributions of source code must retain the above
|
8 | 99165736 | Christos Stavrakakis | # copyright notice, this list of conditions and the following
|
9 | 99165736 | Christos Stavrakakis | # disclaimer.
|
10 | 99165736 | Christos Stavrakakis | #
|
11 | 99165736 | Christos Stavrakakis | # 2. Redistributions in binary form must reproduce the above
|
12 | 99165736 | Christos Stavrakakis | # copyright notice, this list of conditions and the following
|
13 | 99165736 | Christos Stavrakakis | # disclaimer in the documentation and/or other materials
|
14 | 99165736 | Christos Stavrakakis | # provided with the distribution.
|
15 | 99165736 | Christos Stavrakakis | #
|
16 | 99165736 | Christos Stavrakakis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 99165736 | Christos Stavrakakis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 99165736 | Christos Stavrakakis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 99165736 | Christos Stavrakakis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 99165736 | Christos Stavrakakis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 99165736 | Christos Stavrakakis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 99165736 | Christos Stavrakakis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 99165736 | Christos Stavrakakis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 99165736 | Christos Stavrakakis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 99165736 | Christos Stavrakakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 99165736 | Christos Stavrakakis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 99165736 | Christos Stavrakakis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 99165736 | Christos Stavrakakis | #
|
29 | 99165736 | Christos Stavrakakis | # The views and conclusions contained in the software and
|
30 | 99165736 | Christos Stavrakakis | # documentation are those of the authors and should not be
|
31 | 99165736 | Christos Stavrakakis | # interpreted as representing official policies, either expressed
|
32 | 99165736 | Christos Stavrakakis | # or implied, of GRNET S.A.
|
33 | cbc0b438 | Ilias Tsitsimpis | |
34 | cbc0b438 | Ilias Tsitsimpis | import logging |
35 | cbc0b438 | Ilias Tsitsimpis | import urlparse |
36 | cbc0b438 | Ilias Tsitsimpis | import httplib |
37 | bc5032a4 | Ilias Tsitsimpis | import urllib |
38 | 6f64b6d0 | Ilias Tsitsimpis | import hashlib |
39 | 8f2d7ede | Ilias Tsitsimpis | from copy import copy |
40 | cbc0b438 | Ilias Tsitsimpis | |
41 | cbc0b438 | Ilias Tsitsimpis | import simplejson |
42 | cbc0b438 | Ilias Tsitsimpis | import objpool.http |
43 | cbc0b438 | Ilias Tsitsimpis | |
44 | cbc0b438 | Ilias Tsitsimpis | |
45 | 4490d7b5 | Ilias Tsitsimpis | # --------------------------------------------------------------------
|
46 | 4490d7b5 | Ilias Tsitsimpis | # Astakos Client Exception
|
47 | 4490d7b5 | Ilias Tsitsimpis | class AstakosClientException(Exception): |
48 | 4490d7b5 | Ilias Tsitsimpis | def __init__(self, message, status=0): |
49 | 4490d7b5 | Ilias Tsitsimpis | self.message = message
|
50 | 4490d7b5 | Ilias Tsitsimpis | self.status = status
|
51 | 4490d7b5 | Ilias Tsitsimpis | |
52 | 4490d7b5 | Ilias Tsitsimpis | def __str__(self): |
53 | 4490d7b5 | Ilias Tsitsimpis | return repr(self.message) |
54 | cbc0b438 | Ilias Tsitsimpis | |
55 | cbc0b438 | Ilias Tsitsimpis | |
56 | 8fe6475a | Ilias Tsitsimpis | class AstakosClientEInvalid(AstakosClientException): |
57 | 8fe6475a | Ilias Tsitsimpis | def __init__(self, message): |
58 | 8fe6475a | Ilias Tsitsimpis | """Invalid X-Auth-Token"""
|
59 | 8fe6475a | Ilias Tsitsimpis | super(AstakosClientEInvalid, self).__init__(message, 401) |
60 | 8fe6475a | Ilias Tsitsimpis | |
61 | 8fe6475a | Ilias Tsitsimpis | |
62 | 8fe6475a | Ilias Tsitsimpis | class AstakosClientEMethod(AstakosClientException): |
63 | 8fe6475a | Ilias Tsitsimpis | def __init__(self, message): |
64 | 8fe6475a | Ilias Tsitsimpis | """Method not allowed"""
|
65 | 8fe6475a | Ilias Tsitsimpis | super(AstakosClientEMethod, self).__init__(message, 400) |
66 | 8fe6475a | Ilias Tsitsimpis | |
67 | 8fe6475a | Ilias Tsitsimpis | |
68 | 8fe6475a | Ilias Tsitsimpis | class AstakosClientENotFound(AstakosClientException): |
69 | 8fe6475a | Ilias Tsitsimpis | def __init__(self, message): |
70 | 8fe6475a | Ilias Tsitsimpis | """404 Not Found"""
|
71 | 8fe6475a | Ilias Tsitsimpis | super(AstakosClientENotFound, self).__init__(message, 404) |
72 | 8fe6475a | Ilias Tsitsimpis | |
73 | 8fe6475a | Ilias Tsitsimpis | |
74 | cbc0b438 | Ilias Tsitsimpis | # --------------------------------------------------------------------
|
75 | 4490d7b5 | Ilias Tsitsimpis | # Astakos Client Class
|
76 | bc5032a4 | Ilias Tsitsimpis | |
77 | bc5032a4 | Ilias Tsitsimpis | def getTokenFromCookie(request, cookie_name): |
78 | bc5032a4 | Ilias Tsitsimpis | """Extract token from the cookie name provided
|
79 | bc5032a4 | Ilias Tsitsimpis |
|
80 | bc5032a4 | Ilias Tsitsimpis | Cookie should be in the same form as astakos
|
81 | bc5032a4 | Ilias Tsitsimpis | service sets its cookie contents:
|
82 | bc5032a4 | Ilias Tsitsimpis | <user_uniq>|<user_token>
|
83 | bc5032a4 | Ilias Tsitsimpis |
|
84 | bc5032a4 | Ilias Tsitsimpis | """
|
85 | bc5032a4 | Ilias Tsitsimpis | try:
|
86 | bc5032a4 | Ilias Tsitsimpis | cookie_content = urllib.unquote(request.COOKIE.get(cookie_name, None))
|
87 | bc5032a4 | Ilias Tsitsimpis | return cookie_content.split("|")[1] |
88 | bc5032a4 | Ilias Tsitsimpis | except:
|
89 | bc5032a4 | Ilias Tsitsimpis | return None |
90 | bc5032a4 | Ilias Tsitsimpis | |
91 | bc5032a4 | Ilias Tsitsimpis | |
92 | 4490d7b5 | Ilias Tsitsimpis | class AstakosClient(): |
93 | 4490d7b5 | Ilias Tsitsimpis | """AstakosClient Class Implementation"""
|
94 | 4490d7b5 | Ilias Tsitsimpis | |
95 | 4490d7b5 | Ilias Tsitsimpis | # ----------------------------------
|
96 | 98752f06 | Ilias Tsitsimpis | def __init__(self, astakos_url, use_pool=False, retry=0, logger=None): |
97 | 4490d7b5 | Ilias Tsitsimpis | """Intialize AstakosClient Class
|
98 | 4490d7b5 | Ilias Tsitsimpis |
|
99 | 4490d7b5 | Ilias Tsitsimpis | Keyword arguments:
|
100 | 4490d7b5 | Ilias Tsitsimpis | astakos_url -- i.e https://accounts.example.com (string)
|
101 | 4490d7b5 | Ilias Tsitsimpis | use_pool -- use objpool for http requests (boolean)
|
102 | 949baf4d | Ilias Tsitsimpis | retry -- how many time to retry (integer)
|
103 | 4490d7b5 | Ilias Tsitsimpis | logger -- pass a different logger
|
104 | 4490d7b5 | Ilias Tsitsimpis |
|
105 | 4490d7b5 | Ilias Tsitsimpis | """
|
106 | 4490d7b5 | Ilias Tsitsimpis | if logger is None: |
107 | 7eb32034 | Ilias Tsitsimpis | logging.basicConfig( |
108 | 7eb32034 | Ilias Tsitsimpis | format='%(asctime)s [%(levelname)s] %(name)s %(message)s',
|
109 | 7eb32034 | Ilias Tsitsimpis | datefmt='%Y-%m-%d %H:%M:%S',
|
110 | 7eb32034 | Ilias Tsitsimpis | level=logging.INFO) |
111 | 4490d7b5 | Ilias Tsitsimpis | logger = logging.getLogger("astakosclient")
|
112 | 8f2d7ede | Ilias Tsitsimpis | logger.debug("Intialize AstakosClient: astakos_url = %s, "
|
113 | 4490d7b5 | Ilias Tsitsimpis | "use_pool = %s" % (astakos_url, use_pool))
|
114 | 4490d7b5 | Ilias Tsitsimpis | |
115 | 4490d7b5 | Ilias Tsitsimpis | if not astakos_url: |
116 | 4490d7b5 | Ilias Tsitsimpis | m = "Astakos url not given"
|
117 | 4490d7b5 | Ilias Tsitsimpis | logger.error(m) |
118 | 4490d7b5 | Ilias Tsitsimpis | raise ValueError(m) |
119 | 4490d7b5 | Ilias Tsitsimpis | |
120 | 4490d7b5 | Ilias Tsitsimpis | # Check for supported scheme
|
121 | 4490d7b5 | Ilias Tsitsimpis | p = urlparse.urlparse(astakos_url) |
122 | e169a337 | Ilias Tsitsimpis | conn_class = _scheme_to_class(p.scheme, use_pool) |
123 | e169a337 | Ilias Tsitsimpis | if conn_class is None: |
124 | 4490d7b5 | Ilias Tsitsimpis | m = "Unsupported scheme: %s" % p.scheme
|
125 | 4490d7b5 | Ilias Tsitsimpis | logger.error(m) |
126 | 4490d7b5 | Ilias Tsitsimpis | raise ValueError(m) |
127 | 4490d7b5 | Ilias Tsitsimpis | |
128 | 98752f06 | Ilias Tsitsimpis | # Save astakos_url etc. in our class
|
129 | 949baf4d | Ilias Tsitsimpis | self.retry = retry
|
130 | 4490d7b5 | Ilias Tsitsimpis | self.logger = logger
|
131 | 4490d7b5 | Ilias Tsitsimpis | self.netloc = p.netloc
|
132 | 4490d7b5 | Ilias Tsitsimpis | self.scheme = p.scheme
|
133 | e169a337 | Ilias Tsitsimpis | self.conn_class = conn_class
|
134 | 4490d7b5 | Ilias Tsitsimpis | |
135 | 4490d7b5 | Ilias Tsitsimpis | # ----------------------------------
|
136 | 949baf4d | Ilias Tsitsimpis | def retry(func): |
137 | 949baf4d | Ilias Tsitsimpis | def decorator(self, *args, **kwargs): |
138 | 949baf4d | Ilias Tsitsimpis | attemps = 0
|
139 | 949baf4d | Ilias Tsitsimpis | while True: |
140 | 949baf4d | Ilias Tsitsimpis | try:
|
141 | 949baf4d | Ilias Tsitsimpis | return func(self, *args, **kwargs) |
142 | 949baf4d | Ilias Tsitsimpis | except AstakosClientException as err: |
143 | 949baf4d | Ilias Tsitsimpis | is_last_attempt = attemps == self.retry
|
144 | 949baf4d | Ilias Tsitsimpis | if is_last_attempt:
|
145 | 949baf4d | Ilias Tsitsimpis | raise err
|
146 | 949baf4d | Ilias Tsitsimpis | if err.status == 401 or err.status == 404: |
147 | 949baf4d | Ilias Tsitsimpis | # In case of Unauthorized response
|
148 | 949baf4d | Ilias Tsitsimpis | # or Not Found return immediately
|
149 | 949baf4d | Ilias Tsitsimpis | raise err
|
150 | 6f64b6d0 | Ilias Tsitsimpis | self.logger.info("AstakosClient request failed..retrying") |
151 | 949baf4d | Ilias Tsitsimpis | attemps += 1
|
152 | 949baf4d | Ilias Tsitsimpis | return decorator
|
153 | 949baf4d | Ilias Tsitsimpis | |
154 | 949baf4d | Ilias Tsitsimpis | # ----------------------------------
|
155 | 949baf4d | Ilias Tsitsimpis | @retry
|
156 | 98752f06 | Ilias Tsitsimpis | def _callAstakos(self, token, request_path, |
157 | 8f2d7ede | Ilias Tsitsimpis | headers=None, body=None, method="GET"): |
158 | 4490d7b5 | Ilias Tsitsimpis | """Make the actual call to Astakos Service"""
|
159 | 6f64b6d0 | Ilias Tsitsimpis | hashed_token = hashlib.sha1() |
160 | 6f64b6d0 | Ilias Tsitsimpis | hashed_token.update(token) |
161 | 4490d7b5 | Ilias Tsitsimpis | self.logger.debug(
|
162 | 6f64b6d0 | Ilias Tsitsimpis | "Make a %s request to %s using token %s "
|
163 | 6f64b6d0 | Ilias Tsitsimpis | "with headers %s and body %s"
|
164 | 6f64b6d0 | Ilias Tsitsimpis | % (method, request_path, hashed_token.hexdigest(), headers, body)) |
165 | 4490d7b5 | Ilias Tsitsimpis | |
166 | 98752f06 | Ilias Tsitsimpis | # Check Input
|
167 | 98752f06 | Ilias Tsitsimpis | if not token: |
168 | 98752f06 | Ilias Tsitsimpis | m = "Token not given"
|
169 | 98752f06 | Ilias Tsitsimpis | self.logger.error(m)
|
170 | 98752f06 | Ilias Tsitsimpis | raise ValueError(m) |
171 | 8f2d7ede | Ilias Tsitsimpis | if headers is None: |
172 | 8f2d7ede | Ilias Tsitsimpis | headers = {} |
173 | 8f2d7ede | Ilias Tsitsimpis | if body is None: |
174 | 8f2d7ede | Ilias Tsitsimpis | body = {} |
175 | 3f8d6b11 | Ilias Tsitsimpis | if request_path[0] != '/': |
176 | 3f8d6b11 | Ilias Tsitsimpis | request_path = "/" + request_path
|
177 | 98752f06 | Ilias Tsitsimpis | |
178 | 4490d7b5 | Ilias Tsitsimpis | # Build request's header and body
|
179 | 4490d7b5 | Ilias Tsitsimpis | kwargs = {} |
180 | 8f2d7ede | Ilias Tsitsimpis | kwargs['headers'] = copy(headers)
|
181 | 98752f06 | Ilias Tsitsimpis | kwargs['headers']['X-Auth-Token'] = token |
182 | 4490d7b5 | Ilias Tsitsimpis | if body:
|
183 | 8f2d7ede | Ilias Tsitsimpis | kwargs['body'] = copy(body)
|
184 | 4490d7b5 | Ilias Tsitsimpis | kwargs['headers'].setdefault(
|
185 | 4490d7b5 | Ilias Tsitsimpis | 'content-type', 'application/octet-stream') |
186 | 4490d7b5 | Ilias Tsitsimpis | kwargs['headers'].setdefault('content-length', |
187 | 4490d7b5 | Ilias Tsitsimpis | len(body) if body else 0) |
188 | 4490d7b5 | Ilias Tsitsimpis | |
189 | 4490d7b5 | Ilias Tsitsimpis | # Get the connection object
|
190 | e169a337 | Ilias Tsitsimpis | conn = self.conn_class(self.netloc) |
191 | 4490d7b5 | Ilias Tsitsimpis | |
192 | 4490d7b5 | Ilias Tsitsimpis | # Send request
|
193 | 4490d7b5 | Ilias Tsitsimpis | try:
|
194 | 4490d7b5 | Ilias Tsitsimpis | (data, status) = _doRequest(conn, method, request_path, **kwargs) |
195 | 4490d7b5 | Ilias Tsitsimpis | except Exception as err: |
196 | 4490d7b5 | Ilias Tsitsimpis | self.logger.error("Failed to send request: %s" % err) |
197 | 4490d7b5 | Ilias Tsitsimpis | raise AstakosClientException(str(err)) |
198 | 4490d7b5 | Ilias Tsitsimpis | finally:
|
199 | 4490d7b5 | Ilias Tsitsimpis | conn.close() |
200 | 4490d7b5 | Ilias Tsitsimpis | |
201 | 4490d7b5 | Ilias Tsitsimpis | # Return
|
202 | 4490d7b5 | Ilias Tsitsimpis | self.logger.debug("Request returned with status %s" % status) |
203 | 8fe6475a | Ilias Tsitsimpis | if status == 400: |
204 | 8fe6475a | Ilias Tsitsimpis | raise AstakosClientEMethod(data)
|
205 | 8fe6475a | Ilias Tsitsimpis | if status == 401: |
206 | 8fe6475a | Ilias Tsitsimpis | raise AstakosClientEInvalid(data)
|
207 | 8fe6475a | Ilias Tsitsimpis | if status == 404: |
208 | 8fe6475a | Ilias Tsitsimpis | raise AstakosClientENotFound(data)
|
209 | 4490d7b5 | Ilias Tsitsimpis | if status < 200 or status >= 300: |
210 | 4490d7b5 | Ilias Tsitsimpis | raise AstakosClientException(data, status)
|
211 | 4490d7b5 | Ilias Tsitsimpis | return simplejson.loads(unicode(data)) |
212 | 4490d7b5 | Ilias Tsitsimpis | |
213 | 4490d7b5 | Ilias Tsitsimpis | # ------------------------
|
214 | 98752f06 | Ilias Tsitsimpis | def authenticate(self, token, usage=False): |
215 | 4490d7b5 | Ilias Tsitsimpis | """Check if user is authenticated Astakos user
|
216 | 4490d7b5 | Ilias Tsitsimpis |
|
217 | 4490d7b5 | Ilias Tsitsimpis | Keyword arguments:
|
218 | 98752f06 | Ilias Tsitsimpis | token -- user's token (string)
|
219 | 4490d7b5 | Ilias Tsitsimpis | usage -- return usage information for user (boolean)
|
220 | 4490d7b5 | Ilias Tsitsimpis |
|
221 | 4490d7b5 | Ilias Tsitsimpis | In case of success return user information (json parsed format).
|
222 | 4490d7b5 | Ilias Tsitsimpis | Otherwise raise an AstakosClientException.
|
223 | 4490d7b5 | Ilias Tsitsimpis |
|
224 | 4490d7b5 | Ilias Tsitsimpis | """
|
225 | 98752f06 | Ilias Tsitsimpis | # Send request
|
226 | 4490d7b5 | Ilias Tsitsimpis | auth_path = "/im/authenticate"
|
227 | 4490d7b5 | Ilias Tsitsimpis | if usage:
|
228 | 4490d7b5 | Ilias Tsitsimpis | auth_path += "?usage=1"
|
229 | 98752f06 | Ilias Tsitsimpis | return self._callAstakos(token, auth_path) |
230 | 4490d7b5 | Ilias Tsitsimpis | |
231 | 4490d7b5 | Ilias Tsitsimpis | # ----------------------------------
|
232 | 1c26b500 | Ilias Tsitsimpis | def _uuidCatalog(self, token, uuids, req_path): |
233 | 1c26b500 | Ilias Tsitsimpis | req_headers = {'content-type': 'application/json'} |
234 | 1c26b500 | Ilias Tsitsimpis | req_body = simplejson.dumps({'uuids': uuids})
|
235 | 1c26b500 | Ilias Tsitsimpis | data = self._callAstakos(
|
236 | 1c26b500 | Ilias Tsitsimpis | token, req_path, req_headers, req_body, "POST")
|
237 | 1c26b500 | Ilias Tsitsimpis | # XXX: check if exists
|
238 | 1c26b500 | Ilias Tsitsimpis | return data.get("uuid_catalog") |
239 | 1c26b500 | Ilias Tsitsimpis | |
240 | 98752f06 | Ilias Tsitsimpis | def getDisplayNames(self, token, uuids): |
241 | 4490d7b5 | Ilias Tsitsimpis | """Return a uuid_catalog dictionary for the given uuids
|
242 | 4490d7b5 | Ilias Tsitsimpis |
|
243 | 4490d7b5 | Ilias Tsitsimpis | Keyword arguments:
|
244 | 98752f06 | Ilias Tsitsimpis | token -- user's token (string)
|
245 | 4490d7b5 | Ilias Tsitsimpis | uuids -- list of user ids (list of strings)
|
246 | 4490d7b5 | Ilias Tsitsimpis |
|
247 | 4490d7b5 | Ilias Tsitsimpis | The returned uuid_catalog is a dictionary with uuids as
|
248 | 4490d7b5 | Ilias Tsitsimpis | keys and the corresponding user names as values
|
249 | 4490d7b5 | Ilias Tsitsimpis |
|
250 | 4490d7b5 | Ilias Tsitsimpis | """
|
251 | 4490d7b5 | Ilias Tsitsimpis | req_path = "/user_catalogs"
|
252 | 1c26b500 | Ilias Tsitsimpis | return self._uuidCatalog(token, uuids, req_path) |
253 | 4490d7b5 | Ilias Tsitsimpis | |
254 | 98752f06 | Ilias Tsitsimpis | def getDisplayName(self, token, uuid): |
255 | 4490d7b5 | Ilias Tsitsimpis | """Return the displayName of a uuid (see getDisplayNames)"""
|
256 | 4490d7b5 | Ilias Tsitsimpis | if not uuid: |
257 | 4490d7b5 | Ilias Tsitsimpis | m = "No uuid was given"
|
258 | 4490d7b5 | Ilias Tsitsimpis | self.logger.error(m)
|
259 | 4490d7b5 | Ilias Tsitsimpis | raise ValueError(m) |
260 | 98752f06 | Ilias Tsitsimpis | uuid_dict = self.getDisplayNames(token, [uuid])
|
261 | 4490d7b5 | Ilias Tsitsimpis | # XXX: check if exists
|
262 | 4490d7b5 | Ilias Tsitsimpis | return uuid_dict.get(uuid)
|
263 | 4490d7b5 | Ilias Tsitsimpis | |
264 | 1c26b500 | Ilias Tsitsimpis | def getServiceDisplayNames(self, token, uuids): |
265 | 1c26b500 | Ilias Tsitsimpis | """Return a uuid_catalog dict using a service's token"""
|
266 | 1c26b500 | Ilias Tsitsimpis | req_path = "/service/api/user_catalogs"
|
267 | 1c26b500 | Ilias Tsitsimpis | return self._uuidCatalog(token, uuids, req_path) |
268 | 1c26b500 | Ilias Tsitsimpis | |
269 | 1c26b500 | Ilias Tsitsimpis | def getServiceDisplayName(self, token, uuid): |
270 | 1c26b500 | Ilias Tsitsimpis | """Return the displayName of a uuid using a service's token"""
|
271 | 1c26b500 | Ilias Tsitsimpis | if not uuid: |
272 | 1c26b500 | Ilias Tsitsimpis | m = "No uuid was given"
|
273 | 1c26b500 | Ilias Tsitsimpis | self.logger.error(m)
|
274 | 1c26b500 | Ilias Tsitsimpis | raise ValueError(m) |
275 | 1c26b500 | Ilias Tsitsimpis | uuid_dict = self.getServiceDisplayNames(token, [uuid])
|
276 | 1c26b500 | Ilias Tsitsimpis | # XXX: check if exists
|
277 | 1c26b500 | Ilias Tsitsimpis | return uuid_dict.get(uuid)
|
278 | 1c26b500 | Ilias Tsitsimpis | |
279 | aaf0a42c | Ilias Tsitsimpis | # ----------------------------------
|
280 | 1c26b500 | Ilias Tsitsimpis | def _displayNameCatalog(self, token, display_names, req_path): |
281 | 1c26b500 | Ilias Tsitsimpis | req_headers = {'content-type': 'application/json'} |
282 | 1c26b500 | Ilias Tsitsimpis | req_body = simplejson.dumps({'displaynames': display_names})
|
283 | 1c26b500 | Ilias Tsitsimpis | data = self._callAstakos(
|
284 | 1c26b500 | Ilias Tsitsimpis | token, req_path, req_headers, req_body, "POST")
|
285 | 1c26b500 | Ilias Tsitsimpis | # XXX: check if exists
|
286 | 1c26b500 | Ilias Tsitsimpis | return data.get("displayname_catalog") |
287 | 1c26b500 | Ilias Tsitsimpis | |
288 | aaf0a42c | Ilias Tsitsimpis | def getUUIDs(self, token, display_names): |
289 | aaf0a42c | Ilias Tsitsimpis | """Return a displayname_catalog for the given names
|
290 | aaf0a42c | Ilias Tsitsimpis |
|
291 | aaf0a42c | Ilias Tsitsimpis | Keyword arguments:
|
292 | aaf0a42c | Ilias Tsitsimpis | token -- user's token (string)
|
293 | aaf0a42c | Ilias Tsitsimpis | display_names -- list of user names (list of strings)
|
294 | aaf0a42c | Ilias Tsitsimpis |
|
295 | aaf0a42c | Ilias Tsitsimpis | The returned displayname_catalog is a dictionary with
|
296 | aaf0a42c | Ilias Tsitsimpis | the names as keys and the corresponding uuids as values
|
297 | aaf0a42c | Ilias Tsitsimpis |
|
298 | aaf0a42c | Ilias Tsitsimpis | """
|
299 | aaf0a42c | Ilias Tsitsimpis | req_path = "/user_catalogs"
|
300 | 1c26b500 | Ilias Tsitsimpis | return self._displayNameCatalog(token, display_names, req_path) |
301 | aaf0a42c | Ilias Tsitsimpis | |
302 | aaf0a42c | Ilias Tsitsimpis | def getUUID(self, token, display_name): |
303 | aaf0a42c | Ilias Tsitsimpis | """Return the uuid of a name (see getUUIDs)"""
|
304 | aaf0a42c | Ilias Tsitsimpis | if not display_name: |
305 | aaf0a42c | Ilias Tsitsimpis | m = "No display_name was given"
|
306 | aaf0a42c | Ilias Tsitsimpis | self.logger.error(m)
|
307 | aaf0a42c | Ilias Tsitsimpis | raise ValueError(m) |
308 | aaf0a42c | Ilias Tsitsimpis | name_dict = self.getUUIDs(token, [display_name])
|
309 | aaf0a42c | Ilias Tsitsimpis | # XXX: check if exists
|
310 | aaf0a42c | Ilias Tsitsimpis | return name_dict.get(display_name)
|
311 | aaf0a42c | Ilias Tsitsimpis | |
312 | 1c26b500 | Ilias Tsitsimpis | def getServiceUUIDs(self, token, display_names): |
313 | 1c26b500 | Ilias Tsitsimpis | """Return a display_name catalog using a service's token"""
|
314 | 1c26b500 | Ilias Tsitsimpis | req_path = "/service/api/user_catalogs"
|
315 | 1c26b500 | Ilias Tsitsimpis | return self._displayNameCatalog(token, display_names, req_path) |
316 | 1c26b500 | Ilias Tsitsimpis | |
317 | 1c26b500 | Ilias Tsitsimpis | def getServiceUUID(self, token, display_name): |
318 | 1c26b500 | Ilias Tsitsimpis | """Return the uuid of a name using a service's token"""
|
319 | 1c26b500 | Ilias Tsitsimpis | if not display_name: |
320 | 1c26b500 | Ilias Tsitsimpis | m = "No display_name was given"
|
321 | 1c26b500 | Ilias Tsitsimpis | self.logger.error(m)
|
322 | 1c26b500 | Ilias Tsitsimpis | raise ValueError(m) |
323 | 1c26b500 | Ilias Tsitsimpis | name_dict = self.getServiceUUIDs(token, [display_name])
|
324 | 1c26b500 | Ilias Tsitsimpis | # XXX: check if exists
|
325 | 1c26b500 | Ilias Tsitsimpis | return name_dict.get(display_name)
|
326 | 1c26b500 | Ilias Tsitsimpis | |
327 | 3f8d6b11 | Ilias Tsitsimpis | # ----------------------------------
|
328 | 3f8d6b11 | Ilias Tsitsimpis | def getServices(self): |
329 | 3f8d6b11 | Ilias Tsitsimpis | """Return a list of dicts with the registered services"""
|
330 | 3f8d6b11 | Ilias Tsitsimpis | return self._callAstakos("dummy token", "/im/get_services") |
331 | 3f8d6b11 | Ilias Tsitsimpis | |
332 | f54cf5e4 | Ilias Tsitsimpis | |
333 | f54cf5e4 | Ilias Tsitsimpis | # --------------------------------------------------------------------
|
334 | cbc0b438 | Ilias Tsitsimpis | # Private functions
|
335 | 4490d7b5 | Ilias Tsitsimpis | def _scheme_to_class(scheme, use_pool): |
336 | 4490d7b5 | Ilias Tsitsimpis | """Return the appropriate conn class for given scheme"""
|
337 | cbc0b438 | Ilias Tsitsimpis | if scheme == "http": |
338 | 4490d7b5 | Ilias Tsitsimpis | if use_pool:
|
339 | 4490d7b5 | Ilias Tsitsimpis | return _objpoolHttpScheme
|
340 | 4490d7b5 | Ilias Tsitsimpis | else:
|
341 | 4490d7b5 | Ilias Tsitsimpis | return httplib.HTTPConnection
|
342 | cbc0b438 | Ilias Tsitsimpis | elif scheme == "https": |
343 | 4490d7b5 | Ilias Tsitsimpis | if use_pool:
|
344 | 4490d7b5 | Ilias Tsitsimpis | return _objpoolHttpsScheme
|
345 | 4490d7b5 | Ilias Tsitsimpis | else:
|
346 | 4490d7b5 | Ilias Tsitsimpis | return httplib.HTTPSConnection
|
347 | cbc0b438 | Ilias Tsitsimpis | else:
|
348 | cbc0b438 | Ilias Tsitsimpis | return None |
349 | cbc0b438 | Ilias Tsitsimpis | |
350 | cbc0b438 | Ilias Tsitsimpis | |
351 | 4490d7b5 | Ilias Tsitsimpis | def _objpoolHttpScheme(netloc): |
352 | 4490d7b5 | Ilias Tsitsimpis | """Intialize the appropriate objpool.http class"""
|
353 | 4490d7b5 | Ilias Tsitsimpis | return objpool.http.get_http_connection(netloc, "http") |
354 | 4490d7b5 | Ilias Tsitsimpis | |
355 | 4490d7b5 | Ilias Tsitsimpis | |
356 | 4490d7b5 | Ilias Tsitsimpis | def _objpoolHttpsScheme(netloc): |
357 | 4490d7b5 | Ilias Tsitsimpis | """Intialize the appropriate objpool.http class"""
|
358 | 4490d7b5 | Ilias Tsitsimpis | return objpool.http.get_http_connection(netloc, "https") |
359 | 4490d7b5 | Ilias Tsitsimpis | |
360 | 4490d7b5 | Ilias Tsitsimpis | |
361 | f8388a90 | Ilias Tsitsimpis | def _doRequest(conn, method, url, **kwargs): |
362 | f8388a90 | Ilias Tsitsimpis | """The actual request. This function can easily be mocked"""
|
363 | f8388a90 | Ilias Tsitsimpis | conn.request(method, url, **kwargs) |
364 | f8388a90 | Ilias Tsitsimpis | response = conn.getresponse() |
365 | f8388a90 | Ilias Tsitsimpis | length = response.getheader('content-length', None) |
366 | f8388a90 | Ilias Tsitsimpis | data = response.read(length) |
367 | f8388a90 | Ilias Tsitsimpis | status = int(response.status)
|
368 | 4490d7b5 | Ilias Tsitsimpis | return (data, status) |