comparison src/plugins/plugin_misc_account.py @ 938:fc7e0828b18e

plugin account, groupblog: user can erase all their microblogs at once
author souliane <souliane@mailoo.org>
date Thu, 27 Mar 2014 02:24:20 +0100
parents 34dd9287dfe5
children abd3a75d629c
comparison
equal deleted inserted replaced
937:255e6953b2c3 938:fc7e0828b18e
32 "name": "Account Plugin", 32 "name": "Account Plugin",
33 "import_name": "MISC-ACCOUNT", 33 "import_name": "MISC-ACCOUNT",
34 "type": "MISC", 34 "type": "MISC",
35 "protocols": [], 35 "protocols": [],
36 "dependencies": [], 36 "dependencies": [],
37 "recommendations": ['GROUPBLOG'],
37 "main": "MiscAccount", 38 "main": "MiscAccount",
38 "handler": "no", 39 "handler": "no",
39 "description": _(u"""SàT account creation""") 40 "description": _(u"""SàT account creation""")
40 } 41 }
41 42
131 info(_('Prosody path found: %s') % (self._prosody_path, )) 132 info(_('Prosody path found: %s') % (self._prosody_path, ))
132 133
133 self.__account_cb_id = host.registerCallback(self._accountDialogCb, with_data=True) 134 self.__account_cb_id = host.registerCallback(self._accountDialogCb, with_data=True)
134 self.__delete_account_id = host.registerCallback(self.__deleteAccountCb, with_data=True) 135 self.__delete_account_id = host.registerCallback(self.__deleteAccountCb, with_data=True)
135 136
137 def deleteBlogCallback(posts, comments):
138 return lambda data, profile: self.__deleteBlogPostsCb(posts, comments, data, profile)
139
140 self.__delete_posts_comments_id = host.registerCallback(deleteBlogCallback(True, True), with_data=True)
141 self.__delete_posts_id = host.registerCallback(deleteBlogCallback(True, False), with_data=True)
142 self.__delete_comments_id = host.registerCallback(deleteBlogCallback(False, True), with_data=True)
143
136 def getConfig(self, name): 144 def getConfig(self, name):
137 return self.host.memory.getConfig(CONFIG_SECTION, name) or default_conf[name] 145 return self.host.memory.getConfig(CONFIG_SECTION, name) or default_conf[name]
138 146
139 def _registerAccount(self, email, password, profile): 147 def _registerAccount(self, email, password, profile):
140 148
237 @param profile: %(doc_profile)s 245 @param profile: %(doc_profile)s
238 @return XML of the dialog 246 @return XML of the dialog
239 """ 247 """
240 form_ui = xml_tools.XMLUI("form", "tabs", title=D_("Manage your XMPP account"), submit_id=self.__account_cb_id) 248 form_ui = xml_tools.XMLUI("form", "tabs", title=D_("Manage your XMPP account"), submit_id=self.__account_cb_id)
241 tab_container = form_ui.current_container 249 tab_container = form_ui.current_container
250
242 tab_container.addTab("update", D_("Change your password"), container=xml_tools.PairsContainer) 251 tab_container.addTab("update", D_("Change your password"), container=xml_tools.PairsContainer)
243 form_ui.addLabel(D_("Current password")) 252 form_ui.addLabel(D_("Current password"))
244 form_ui.addPassword("current_passwd", value="") 253 form_ui.addPassword("current_passwd", value="")
245 form_ui.addLabel(D_("New password")) 254 form_ui.addLabel(D_("New password"))
246 form_ui.addPassword("new_passwd1", value="") 255 form_ui.addPassword("new_passwd1", value="")
247 form_ui.addLabel(D_("New password (again)")) 256 form_ui.addLabel(D_("New password (again)"))
248 form_ui.addPassword("new_passwd2", value="") 257 form_ui.addPassword("new_passwd2", value="")
258
259 if 'GROUPBLOG' in self.host.plugins:
260 tab_container.addTab("delete_posts", D_("Delete your posts"), container=xml_tools.PairsContainer)
261 form_ui.addLabel(D_("Current password"))
262 form_ui.addPassword("delete_posts_passwd", value="")
263 form_ui.addLabel(D_("Delete all your posts and their comments"))
264 form_ui.addBool("delete_posts_checkbox", "false")
265 form_ui.addLabel(D_("Delete all your comments on other's posts"))
266 form_ui.addBool("delete_comments_checkbox", "false")
267
249 tab_container.addTab("delete", D_("Delete your account"), container=xml_tools.PairsContainer) 268 tab_container.addTab("delete", D_("Delete your account"), container=xml_tools.PairsContainer)
250 form_ui.addLabel(D_("Current password")) 269 form_ui.addLabel(D_("Current password"))
251 form_ui.addPassword("delete_passwd", value="") 270 form_ui.addPassword("delete_passwd", value="")
252 form_ui.addLabel(D_("Delete your account")) 271 form_ui.addLabel(D_("Delete your account"))
253 form_ui.addBool("delete_checkbox", "false") 272 form_ui.addBool("delete_checkbox", "false")
259 @param profile 278 @param profile
260 """ 279 """
261 password = self.host.memory.getParamA("Password", "Connection", profile_key=profile) 280 password = self.host.memory.getParamA("Password", "Connection", profile_key=profile)
262 281
263 def error_ui(): 282 def error_ui():
264 error_ui = xml_tools.XMLUI("popup", title="Error") 283 error_ui = xml_tools.XMLUI("popup", title=D_("Error"))
265 error_ui.addText(D_("Passwords don't match!")) 284 error_ui.addText(D_("Passwords don't match!"))
266 return defer.succeed({'xmlui': error_ui.toXml()}) 285 return defer.succeed({'xmlui': error_ui.toXml()})
267 286
268 # check for account deletion 287 # check for account deletion
269 delete_passwd = data[xml_tools.SAT_FORM_PREFIX + 'delete_passwd'] 288 delete_passwd = data[xml_tools.SAT_FORM_PREFIX + 'delete_passwd']
270 delete_checkbox = data[xml_tools.SAT_FORM_PREFIX + 'delete_checkbox'] 289 delete_checkbox = data[xml_tools.SAT_FORM_PREFIX + 'delete_checkbox']
271 if delete_checkbox == 'true': 290 if delete_checkbox == 'true':
272 if password == delete_passwd: 291 if password == delete_passwd:
273 return self.__deleteAccount(profile) 292 return self.__deleteAccount(profile)
274 return error_ui() 293 return error_ui()
294
295 # check for blog posts deletion
296 if 'GROUPBLOG' in self.host.plugins:
297 delete_posts_passwd = data[xml_tools.SAT_FORM_PREFIX + 'delete_posts_passwd']
298 delete_posts_checkbox = data[xml_tools.SAT_FORM_PREFIX + 'delete_posts_checkbox']
299 delete_comments_checkbox = data[xml_tools.SAT_FORM_PREFIX + 'delete_comments_checkbox']
300 posts = delete_posts_checkbox == 'true'
301 comments = delete_comments_checkbox == 'true'
302 if posts or comments:
303 if password == delete_posts_passwd:
304 return self.__deleteBlogPosts(posts, comments, profile)
305 return error_ui()
275 306
276 # check for password modification 307 # check for password modification
277 current_passwd = data[xml_tools.SAT_FORM_PREFIX + 'current_passwd'] 308 current_passwd = data[xml_tools.SAT_FORM_PREFIX + 'current_passwd']
278 new_passwd1 = data[xml_tools.SAT_FORM_PREFIX + 'new_passwd1'] 309 new_passwd1 = data[xml_tools.SAT_FORM_PREFIX + 'new_passwd1']
279 new_passwd2 = data[xml_tools.SAT_FORM_PREFIX + 'new_passwd2'] 310 new_passwd2 = data[xml_tools.SAT_FORM_PREFIX + 'new_passwd2']
289 @param password: new password 320 @param password: new password
290 @profile 321 @profile
291 """ 322 """
292 def passwordChanged(result): 323 def passwordChanged(result):
293 self.host.memory.setParam("Password", password, "Connection", profile_key=profile) 324 self.host.memory.setParam("Password", password, "Connection", profile_key=profile)
294 confirm_ui = xml_tools.XMLUI("popup", title="Confirmation") 325 confirm_ui = xml_tools.XMLUI("popup", title=D_("Confirmation"))
295 confirm_ui.addText(D_("Your password has been changed.")) 326 confirm_ui.addText(D_("Your password has been changed."))
296 return defer.succeed({'xmlui': confirm_ui.toXml()}) 327 return defer.succeed({'xmlui': confirm_ui.toXml()})
297 328
298 def errback(failure): 329 def errback(failure):
299 error_ui = xml_tools.XMLUI("popup", title="Error") 330 error_ui = xml_tools.XMLUI("popup", title=D_("Error"))
300 error_ui.addText(D_("Your password could not be changed: %s") % failure.getErrorMessage()) 331 error_ui.addText(D_("Your password could not be changed: %s") % failure.getErrorMessage())
301 return defer.succeed({'xmlui': error_ui.toXml()}) 332 return defer.succeed({'xmlui': error_ui.toXml()})
302 333
303 d = ProsodyRegisterProtocol.prosodyctl(self, 'passwd', password, profile=profile) 334 d = ProsodyRegisterProtocol.prosodyctl(self, 'passwd', password, profile=profile)
304 d.addCallbacks(passwordChanged, errback) 335 d.addCallbacks(passwordChanged, errback)
306 337
307 def __deleteAccount(self, profile): 338 def __deleteAccount(self, profile):
308 """Ask for a confirmation before deleting the XMPP account and SàT profile 339 """Ask for a confirmation before deleting the XMPP account and SàT profile
309 @param profile 340 @param profile
310 """ 341 """
311 form_ui = xml_tools.XMLUI("form", title=D_("Delete your account ?"), submit_id=self.__delete_account_id) 342 form_ui = xml_tools.XMLUI("form", title=D_("Delete your account?"), submit_id=self.__delete_account_id)
312 form_ui.addText(D_("If you confirm this dialog, you will be disconnected and then your XMPP account AND your SàT profile will both be DELETED.")) 343 form_ui.addText(D_("If you confirm this dialog, you will be disconnected and then your XMPP account AND your SàT profile will both be DELETED."))
344 target = D_('contact list, messages history, blog posts and comments' if 'GROUPBLOG' in self.host.plugins else D_('contact list and messages history'))
345 form_ui.addText(D_("All your data stored on %(server)s, including your %(target)s will be erased.") % {'server': self._getNewAccountDomain(), 'target': target})
313 form_ui.addText(D_("There is no other confirmation dialog, this is the very last one! Are you sure?")) 346 form_ui.addText(D_("There is no other confirmation dialog, this is the very last one! Are you sure?"))
314 return {'xmlui': form_ui.toXml()} 347 return {'xmlui': form_ui.toXml()}
315 348
316 def __deleteAccountCb(self, data, profile): 349 def __deleteAccountCb(self, data, profile):
317 """Actually delete the XMPP account and SàT profile 350 """Actually delete the XMPP account and SàT profile
325 client.presence.unsubscribe(jid_) 358 client.presence.unsubscribe(jid_)
326 359
327 for jid_ in self.host.memory.getWaitingSub(profile): # delete waiting subscriptions 360 for jid_ in self.host.memory.getWaitingSub(profile): # delete waiting subscriptions
328 self.host.memory.delWaitingSub(jid_) 361 self.host.memory.delWaitingSub(jid_)
329 362
330 self.host.disconnect(profile) 363 delete_profile = lambda: self.host.memory.asyncDeleteProfile(profile, force=True)
331 self.host.memory.asyncDeleteProfile(profile, force=True) 364 if 'GROUPBLOG' in self.host.plugins:
365 d = self.host.plugins['GROUPBLOG'].deleteAllGroupBlogsAndComments(profile_key=profile)
366 d.addCallback(lambda dummy: delete_profile())
367 else:
368 delete_profile()
369
332 return defer.succeed({}) 370 return defer.succeed({})
333 371
334 def errback(failure): 372 def errback(failure):
335 error_ui = xml_tools.XMLUI("popup", title="Error") 373 error_ui = xml_tools.XMLUI("popup", title=D_("Error"))
336 error_ui.addText(D_("Your XMPP account could not be deleted: %s") % failure.getErrorMessage()) 374 error_ui.addText(D_("Your XMPP account could not be deleted: %s") % failure.getErrorMessage())
337 return defer.succeed({'xmlui': error_ui.toXml()}) 375 return defer.succeed({'xmlui': error_ui.toXml()})
338 376
339 d = ProsodyRegisterProtocol.prosodyctl(self, 'deluser', profile=profile) 377 d = ProsodyRegisterProtocol.prosodyctl(self, 'deluser', profile=profile)
340 d.addCallbacks(userDeleted, errback) 378 d.addCallbacks(userDeleted, errback)
341 return d 379 return d
380
381 def __deleteBlogPosts(self, posts, comments, profile):
382 """Ask for a confirmation before deleting the blog posts
383 @param posts: delete all posts of the user (and their comments)
384 @param comments: delete all the comments of the user on other's posts
385 @param data
386 @param profile
387 """
388 if posts:
389 if comments: # delete everything
390 form_ui = xml_tools.XMLUI("form", title=D_("Delete all your (micro-)blog posts and comments?"), submit_id=self.__delete_posts_comments_id)
391 form_ui.addText(D_("If you confirm this dialog, all the (micro-)blog data you submitted will be erased."))
392 form_ui.addText(D_("These are the public and private posts and comments you sent to any group."))
393 form_ui.addText(D_("There is no other confirmation dialog, this is the very last one! Are you sure?"))
394 else: # delete only the posts
395 form_ui = xml_tools.XMLUI("form", title=D_("Delete all your (micro-)blog posts?"), submit_id=self.__delete_posts_id)
396 form_ui.addText(D_("If you confirm this dialog, all the public and private posts you sent to any group will be erased."))
397 form_ui.addText(D_("There is no other confirmation dialog, this is the very last one! Are you sure?"))
398 elif comments: # delete only the comments
399 form_ui = xml_tools.XMLUI("form", title=D_("Delete all your (micro-)blog comments?"), submit_id=self.__delete_comments_id)
400 form_ui.addText(D_("If you confirm this dialog, all the public and private comments you made on other people's posts will be erased."))
401 form_ui.addText(D_("There is no other confirmation dialog, this is the very last one! Are you sure?"))
402
403 return {'xmlui': form_ui.toXml()}
404
405 def __deleteBlogPostsCb(self, posts, comments, data, profile):
406 """Actually delete the XMPP account and SàT profile
407 @param posts: delete all posts of the user (and their comments)
408 @param comments: delete all the comments of the user on other's posts
409 @param profile
410 """
411 if posts:
412 if comments:
413 target = D_('blog posts and comments')
414 d = self.host.plugins['GROUPBLOG'].deleteAllGroupBlogsAndComments(profile_key=profile)
415 else:
416 target = D_('blog posts')
417 d = self.host.plugins['GROUPBLOG'].deleteAllGroupBlogs(profile_key=profile)
418 elif comments:
419 target = D_('comments')
420 d = self.host.plugins['GROUPBLOG'].deleteAllGroupBlogsComments(profile_key=profile)
421
422 def deleted(result):
423 ui = xml_tools.XMLUI("popup", title=D_("Deletion confirmation"))
424 # TODO: change the message when delete/retract notifications are done with XEP-0060
425 ui.addText(D_("Your %(target)s have been deleted.") % {'target': target})
426 ui.addText(D_("Known issue of the demo version: you need to refresh the page to make the deleted posts actually disappear."))
427 return defer.succeed({'xmlui': ui.toXml()})
428
429 def errback(failure):
430 error_ui = xml_tools.XMLUI("popup", title=D_("Error"))
431 error_ui.addText(D_("Your %(target)s could not be deleted: %(message)s") % {'target': target, 'message': failure.getErrorMessage()})
432 return defer.succeed({'xmlui': error_ui.toXml()})
433
434 d.addCallbacks(deleted, errback)
435 return d
436