|
32 |
# <http://www.gnu.org/licenses/>. |
32 |
# <http://www.gnu.org/licenses/>. |
33 |
|
33 |
|
34 |
# stdlib |
34 |
# stdlib |
35 |
from httplib import HTTPSConnection, HTTPException |
35 |
from httplib import HTTPSConnection, HTTPException, OK as HTTP_OK, FORBIDDEN |
36 |
from json import loads, dumps |
36 |
from json import loads, dumps |
37 |
from socket import error as SocketError |
37 |
from socket import error as SocketError |
38 |
|
38 |
|
39 |
# univention |
39 |
# univention |
40 |
from univention.config_registry import ConfigRegistry |
40 |
from univention.config_registry import ConfigRegistry |
41 |
ucr = ConfigRegistry() |
41 |
|
42 |
ucr.load() |
42 |
|
|
|
43 |
class UMCConnectionError(HTTPException): |
44 |
pass |
45 |
|
46 |
|
47 |
class UMCConnectionUnknownCommand(UMCConnectionError): |
48 |
pass |
49 |
|
50 |
|
51 |
class UMCConnectionRequestError(UMCConnectionError): |
52 |
pass |
53 |
|
54 |
|
55 |
class UMCConnectionAuthenticationError(UMCConnectionRequestError): |
56 |
pass |
57 |
|
43 |
|
58 |
|
44 |
class UMCConnection(object): |
59 |
class UMCConnection(object): |
45 |
def __init__(self, host, username=None, password=None, error_handler=None): |
60 |
def __init__(self, host, username=None, password=None, error_handler=None): |
46 |
self._host = host |
61 |
self._host = host |
47 |
self._headers = { |
62 |
self._headers = { |
48 |
'Content-Type' : 'application/json; charset=UTF-8' |
63 |
'Content-Type': 'application/json; charset=UTF-8' |
49 |
} |
64 |
} |
50 |
self._error_handler=error_handler |
65 |
self._error_handler = error_handler |
51 |
if username is not None: |
66 |
if username is not None: |
52 |
self.auth(username, password) |
67 |
self.auth(username, password) |
53 |
|
68 |
|
Lines 61-66
class UMCConnection(object):
|
Link Here
|
---|
|
61 |
def get_machine_connection(cls, error_handler=None): |
76 |
def get_machine_connection(cls, error_handler=None): |
62 |
'''Creates a connection with the credentials of the local host |
77 |
'''Creates a connection with the credentials of the local host |
63 |
to the DC Master''' |
78 |
to the DC Master''' |
|
|
79 |
ucr = ConfigRegistry() |
80 |
ucr.load() |
81 |
|
64 |
username = '%s$' % ucr.get('hostname') |
82 |
username = '%s$' % ucr.get('hostname') |
65 |
password = '' |
83 |
password = '' |
66 |
try: |
84 |
try: |
Lines 82-88
class UMCConnection(object):
|
Link Here
|
---|
|
82 |
'''Tries to authenticate against the host and preserves the |
100 |
'''Tries to authenticate against the host and preserves the |
83 |
cookie. Has to be done only once (but keep in mind that the |
101 |
cookie. Has to be done only once (but keep in mind that the |
84 |
session probably expires after 10 minutes of inactivity)''' |
102 |
session probably expires after 10 minutes of inactivity)''' |
85 |
data = self.build_data({'username' : username, 'password' : password}) |
103 |
data = self.build_data({'username': username, 'password': password}) |
86 |
con = self.get_connection() |
104 |
con = self.get_connection() |
87 |
try: |
105 |
try: |
88 |
con.request('POST', '/umcp/auth', data) |
106 |
con.request('POST', '/umcp/auth', data) |
Lines 91-113
class UMCConnection(object):
|
Link Here
|
---|
|
91 |
if self._error_handler: |
109 |
if self._error_handler: |
92 |
self._error_handler(str(e)) |
110 |
self._error_handler(str(e)) |
93 |
error_message = '%s: Authentication failed while contacting: %s' % (self._host, e) |
111 |
error_message = '%s: Authentication failed while contacting: %s' % (self._host, e) |
94 |
raise HTTPException(error_message) |
112 |
raise UMCConnectionAuthenticationError(error_message) |
95 |
else: |
113 |
else: |
96 |
try: |
114 |
try: |
97 |
response = con.getresponse() |
115 |
response = con.getresponse() |
98 |
cookie = response.getheader('set-cookie') |
116 |
cookie = response.getheader('set-cookie') |
99 |
if cookie is None: |
117 |
if cookie is None: |
100 |
raise ValueError('No cookie') |
118 |
raise UMCConnectionAuthenticationError('No cookie') |
101 |
self._headers['Cookie'] = cookie |
119 |
self._headers['Cookie'] = cookie |
102 |
except Exception as e: |
120 |
except Exception as e: |
103 |
if self._error_handler: |
121 |
if self._error_handler: |
104 |
self._error_handler(str(e)) |
122 |
self._error_handler(str(e)) |
105 |
error_message = '%s: Authentication failed: %s' % (self._host, response.read()) |
123 |
error_message = '%s: Authentication failed: %s' % (self._host, response.read()) |
106 |
raise HTTPException(error_message) |
124 |
raise UMCConnectionAuthenticationError(error_message) |
107 |
|
125 |
|
108 |
def build_data(self, data, flavor=None): |
126 |
def build_data(self, data, flavor=None): |
109 |
'''Returns a dictionary as expected by the UMC Server''' |
127 |
'''Returns a dictionary as expected by the UMC Server''' |
110 |
data = {'options' : data} |
128 |
data = {'options': data} |
111 |
if flavor: |
129 |
if flavor: |
112 |
data['flavor'] = flavor |
130 |
data['flavor'] = flavor |
113 |
return dumps(data) |
131 |
return dumps(data) |
Lines 130-144
class UMCConnection(object):
|
Link Here
|
---|
|
130 |
umcp_command = '%s/%s' % (umcp_command, url) |
148 |
umcp_command = '%s/%s' % (umcp_command, url) |
131 |
con.request('POST', umcp_command, data, headers=self._headers) |
149 |
con.request('POST', umcp_command, data, headers=self._headers) |
132 |
response = con.getresponse() |
150 |
response = con.getresponse() |
133 |
if response.status != 200: |
151 |
if response.status != HTTP_OK: # 200 |
134 |
error_message = '%s on %s (%s): %s' % (response.status, self._host, url, response.read()) |
152 |
error_message = '%s on %s (%s): %s' % (response.status, self._host, url, response.read()) |
135 |
if response.status == 403: |
153 |
if response.status == FORBIDDEN: # 403 |
136 |
# 403 is either command is unknown |
154 |
# 403 is either command is unknown |
137 |
# or command is known but forbidden |
155 |
# or command is known but forbidden |
138 |
if self._error_handler: |
156 |
if self._error_handler: |
139 |
self._error_handler(error_message) |
157 |
self._error_handler(error_message) |
140 |
raise NotImplementedError('command forbidden: %s' % url) |
158 |
raise UMCConnectionUnknownCommand('command forbidden: %s' % url) |
141 |
raise HTTPException(error_message) |
159 |
raise UMCConnectionRequestError(error_message) |
142 |
content = response.read() |
160 |
content = response.read() |
143 |
return loads(content)['result'] |
161 |
return loads(content)['result'] |
144 |
|
|
|