4
from twisted.internet.defer import Deferred
7
class InvalidCredentialsError(Exception):
9
Raised when an invalid account title and/or registration password
10
is used with L{RegistrationManager.register}.
14
def persist_property(name):
16
return self._persist.get(name)
18
self._persist.set(name, value)
19
return property(get, set)
21
def config_property(name):
23
return getattr(self._config, name)
27
class Identity(object):
28
"""Maintains details about the identity of this Landscape client."""
30
secure_id = persist_property("secure-id")
31
insecure_id = persist_property("insecure-id")
32
computer_title = config_property("computer_title")
33
account_name = config_property("account_name")
34
registration_password = config_property("registration_password")
36
def __init__(self, config, persist):
38
self._persist = persist.root_at("registration")
41
class RegistrationHandler(object):
43
An object from which registration can be requested of the server,
44
and which will handle forced ID changes from the server.
46
L{register} should be used to initial registration.
49
def __init__(self, identity, reactor, exchange, message_store):
50
self._identity = identity
51
self._reactor = reactor
52
self._exchange = exchange
53
self._message_store = message_store
54
self._reactor.call_on("pre-exchange", self._handle_pre_exchange)
55
self._reactor.call_on("exchange-done", self._handle_exchange_done)
56
self._reactor.call_on("message", self._handle_message)
57
self._should_register = None
59
def should_register(self):
61
return bool(not id.secure_id and id.computer_title and id.account_name
62
and self._message_store.accepts("register"))
65
"""Attempt to register with the Landscape server.
67
@return: A L{Deferred} which will either be fired with None if
68
registration was successful or will fail with an
69
L{InvalidCredentialsError} if not.
71
self._identity.secure_id = None
72
self._identity.insecure_id = None
73
# This was the original code, it works as well but it
74
# takes longer due to the urgent exchange interval.
75
#self._exchange.schedule_exchange(urgent=True)
76
result = RegistrationResponse(self._reactor).deferred
77
self._exchange.exchange()
80
def _handle_message(self, message):
81
message_type = message["type"]
82
if message_type == "set-id":
83
self._handle_set_id(message)
84
elif message_type == "unknown-id":
85
self._handle_unknown_id(message)
86
elif message_type == "registration":
87
self._handle_registration(message)
89
def _handle_exchange_done(self):
90
if self.should_register() and not self._should_register:
91
# This was the original code, it works as well but it
92
# takes longer due to the urgent exchange interval.
93
#self._exchange.schedule_exchange(urgent=True)
94
self._exchange.exchange()
96
def _handle_pre_exchange(self):
98
An exchange is about to happen. If we don't have a secure id
99
already set, and we have the needed information available,
100
queue a registration message with the server.
103
# The point of storing this flag is that if we should *not*
104
# register now, and then after the exchange we *should*, we
105
# schedule an urgent exchange again. Without this flag we
106
# would just spin trying to connect to the server when
107
# something is clearly preventing the registration.
108
self._should_register = self.should_register()
110
if self._should_register:
113
with_word = ["without", "with"][bool(id.registration_password)]
114
logging.info("Queueing message to register with account %r %s "
115
"a password." % (id.account_name, with_word))
117
self._message_store.delete_all_messages()
119
message = {"type": "register",
120
"computer_title": id.computer_title,
121
"account_name": id.account_name,
122
"registration_password": id.registration_password,
123
"hostname": socket.gethostname()}
125
self._exchange.send(message)
127
def _handle_set_id(self, message):
129
Record and start using the secure and insecure IDs from the given
133
id.secure_id = message.get("id")
134
id.insecure_id = message.get("insecure-id")
135
logging.info("Using new secure-id ending with %s for account %s.",
136
id.secure_id[-10:], id.account_name)
137
logging.debug("Using new secure-id: %s", id.secure_id)
138
self._reactor.fire("registration-done")
139
self._reactor.fire("resynchronize-clients")
141
def _handle_registration(self, message):
142
if message["info"] == "unknown-account":
143
self._reactor.fire("registration-failed")
145
def _handle_unknown_id(self, message):
147
logging.info("Client has unknown secure-id for account %s."
150
id.insecure_id = None
153
class RegistrationResponse(object):
154
"""A helper for dealing with the response of a single registration request.
156
@ivar deferred: The L{Deferred} that will be fired as per
157
L{RegistrationHandler.register}.
160
def __init__(self, reactor):
161
self._reactor = reactor
162
self._done_id = reactor.call_on("registration-done", self._done)
163
self._failed_id = reactor.call_on("registration-failed", self._failed)
164
self.deferred = Deferred()
166
def _cancel_calls(self):
167
self._reactor.cancel_call(self._done_id)
168
self._reactor.cancel_call(self._failed_id)
171
self.deferred.callback(None)
175
self.deferred.errback(InvalidCredentialsError())