def get_unsubscribe_link(handler, person, email, ttl=7*24*3600): """Returns a link that will remove the given email address from the list of subscribers for the given person, default ttl is one week""" data = 'unsubscribe:%s' % email token = reveal.sign(data, ttl) return handler.get_url('/unsubscribe', token=token, email=email, id=person.record_id)
def get_restore_url(self, person, ttl=3 * 24 * 3600): """Returns a URL to be used for restoring a deleted person record. The default TTL for a restoration URL is 3 days.""" key_name = person.key().name() data = 'restore:%s' % key_name token = reveal.sign(data, ttl) return self.get_url('/restore', token=token, id=key_name)
def get_enable_notes_url(handler, person, ttl=3*24*3600): """Returns a URL to be used for disabling comments to a person record.""" key_name = person.key().name() data = 'enable_notes:%s' % key_name token = reveal.sign(data, ttl) return handler.get_url('/confirm_enable_notes', token=token, id=key_name)
def get_restore_url(self, person, ttl=3*24*3600): """Returns a URL to be used for restoring a deleted person record. The default TTL for a restoration URL is 3 days.""" key_name = person.key().name() data = 'restore:%s' % key_name token = reveal.sign(data, ttl) return self.get_url('/restore', token=token, id=key_name)
def get_confirm_post_note_with_bad_words_url(handler, note, ttl=3*24*3600): note_id = note.get_record_id() data = 'confirm_post_note_with_bad_words:%s' % note_id token = reveal.sign(data, ttl) return handler.get_url('/confirm_post_flagged_note', token=token, id=note_id, repo=handler.repo)
def post(self): if self.params.operation == 'delete': # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action)) elif self.params.operation == 'subdomain_create': Subdomain(key_name=self.params.subdomain_new).put() config.set_for_subdomain( # Provide some defaults. self.params.subdomain_new, language_menu_options=['en', 'fr'], subdomain_titles={'en': 'Earthquake', 'fr': u'S\xe9isme'}, keywords='person finder, people finder, person, people, ' + 'crisis, survivor, family', use_family_name=True, use_postal_code=True, min_query_word_length=2, map_default_zoom=6, map_default_center=[0, 0], map_size_pixels=[400, 280], read_auth_key_required=True, search_auth_key_required=True, deactivated=False, deactivation_message_html='', main_page_custom_html='', results_page_custom_html='', view_page_custom_html='', ) self.redirect('/admin', subdomain=self.params.subdomain_new) elif self.params.operation == 'subdomain_save': values = {} for name in [ # These settings are all entered in JSON. 'language_menu_options', 'subdomain_titles', 'use_family_name', 'family_name_first', 'use_postal_code', 'min_query_word_length', 'map_default_zoom', 'map_default_center', 'map_size_pixels', 'read_auth_key_required', 'search_auth_key_required', 'deactivated' ]: try: values[name] = simplejson.loads(self.request.get(name)) except: return self.error( 400, 'The setting for %s was not valid JSON.' % name) for name in ['keywords', 'deactivation_message_html', 'main_page_custom_html', 'results_page_custom_html', 'view_page_custom_html']: # These settings are literal strings (not JSON). values[name] = self.request.get(name) config.set_for_subdomain(self.subdomain, **values) self.redirect('/admin', subdomain=self.subdomain)
def get_restore_url(handler, person, ttl=3 * 24 * 3600): """Returns a URL to be used for restoring a deleted person record. The default TTL for a restoration URL is 3 days.""" key_name = person.key().name() data = 'restore:%s' % key_name token = reveal.sign(data, ttl) if person.is_original(): return handler.get_url('/restore', token=token, id=key_name) else: return None
def get_restore_url(handler, person, ttl=3*24*3600): """Returns a URL to be used for restoring a deleted person record. The default TTL for a restoration URL is 3 days.""" key_name = person.key().name() data = 'restore:%s' % key_name token = reveal.sign(data, ttl) if person.is_original(): return handler.get_url('/restore', token=token, id=key_name) else: return None
def post(self, request, *args, **kwargs): """Sends the user to the deletion page with a valid signature.""" del request, args, kwargs # unused self.enforce_xsrf(self.ACTION_ID) action = ('delete', self.params.id) path = '/delete?' + utils.urlencode({ 'id': self.params.id, 'signature': reveal.sign(action), }) return django.shortcuts.redirect( self.build_absolute_uri(path, self.env.repo))
def post(self): xsrf_tool = XsrfTool() user = users.get_current_user() if not (self.params.xsrf_token and xsrf_tool.verify_token( self.params.xsrf_token, user.user_id(), 'admin_delete_record')): self.error(403) return False # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action))
def post(self): """If no signature is present, send out a deletion code. If a signature is present, carry out the deletion.""" person = Person.get(self.subdomain, self.params.id) if not person: return self.error(400, 'No person with ID: %r' % self.params.id) action = ('delete', str(self.params.id)) if self.params.signature: if reveal.verify(action, self.params.signature): db.delete(get_entities_to_delete(person)) # i18n: Message telling the user that a record has been deleted. return self.error(200, _('The record has been deleted.')) else: # i18n: Message for an unauthorized attempt to delete a record. return self.error(403, _('The authorization code was invalid.')) else: mail.send_mail( sender='do not reply <do-not-reply@%s>' % self.env.domain, to='<%s>' % person.author_email, # i18n: Subject line of an e-mail message that gives the # i18n: user a link to delete a record subject=_( 'Deletion request for %(given_name)s %(family_name)s' ) % {'given_name': person.first_name, 'family_name': person.last_name}, # i18n: Body text of an e-mail message that gives the user # i18n: a link to delete a record body = _(''' We have received a deletion request for a missing person record at %(domain_name)s. Your e-mail address was entered as the author of this record, so we are contacting you to confirm whether you want to delete it. To delete this record, use this link: %(delete_url)s To view the record, use this link: %(view_url)s ''') % {'domain_name': self.env.domain, 'delete_url': self.get_url('/delete', id=self.params.id, signature=reveal.sign(action, 24*3600)), 'view_url': self.get_url('/view', id=self.params.id)} ) # i18n: Message explaining to the user that the e-mail message # i18n: containing a link to delete a record has been sent out. return self.error(200, _('An e-mail message with a deletion code has been sent. The code will expire in one day.'))
def post(self): if self.params.operation == 'delete': # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action)) elif self.params.operation == 'subdomain_create': Subdomain(key_name=self.params.subdomain_new).put() config.set_for_subdomain( # Provide some defaults. self.params.subdomain_new, language_menu_options=['en', 'fr'], subdomain_titles={ 'en': 'Earthquake', 'fr': u'S\xe9isme' }, keywords='person finder, people finder, person, people, ' + 'crisis, survivor, family', use_family_name=True, use_postal_code=True, min_query_word_length=2, map_default_zoom=6, map_default_center=[0, 0], map_size_pixels=[400, 280], read_auth_key_required=True, search_auth_key_required=True, deactivated=False, deactivation_message_html='', main_page_custom_html='', results_page_custom_html='', view_page_custom_html='', ) self.redirect('/admin', subdomain=self.params.subdomain_new) elif self.params.operation == 'subdomain_save': values = {} for name in [ # These settings are all entered in JSON. 'language_menu_options', 'subdomain_titles', 'use_family_name', 'family_name_first', 'use_postal_code', 'min_query_word_length', 'map_default_zoom', 'map_default_center', 'map_size_pixels', 'read_auth_key_required', 'search_auth_key_required', 'deactivated' ]: try: values[name] = simplejson.loads(self.request.get(name)) except: return self.error( 400, 'The setting for %s was not valid JSON.' % name) for name in [ 'keywords', 'deactivation_message_html', 'main_page_custom_html', 'results_page_custom_html', 'view_page_custom_html' ]: # These settings are literal strings (not JSON). values[name] = self.request.get(name) config.set_for_subdomain(self.subdomain, **values) self.redirect('/admin', subdomain=self.subdomain)
def post(self): if self.params.operation == "delete": # Redirect to the deletion handler with a valid signature. action = ("delete", str(self.params.id)) self.redirect("/delete", id=self.params.id, signature=reveal.sign(action)) elif self.params.operation == "create_repo": new_repo = self.params.new_repo Repo(key_name=new_repo).put() config.set_for_repo( # Provide some defaults. new_repo, language_menu_options=["en", "fr"], repo_titles={"en": "Earthquake", "fr": u"S\xe9isme"}, keywords="person finder, people finder, person, people, " + "crisis, survivor, family", use_family_name=True, use_alternate_names=True, use_postal_code=True, allow_believed_dead_via_ui=False, min_query_word_length=2, show_profile_entry=False, profile_websites=DEFAULT_PROFILE_WEBSITES, map_default_zoom=6, map_default_center=[0, 0], map_size_pixels=[400, 280], read_auth_key_required=True, search_auth_key_required=True, deactivated=False, launched=False, deactivation_message_html="", start_page_custom_htmls={"en": "", "fr": ""}, results_page_custom_htmls={"en": "", "fr": ""}, view_page_custom_htmls={"en": "", "fr": ""}, seek_query_form_custom_htmls={"en": "", "fr": ""}, footer_custom_htmls={"en": "", "fr": ""}, bad_words="", published_date=get_utcnow_timestamp(), updated_date=get_utcnow_timestamp(), test_mode=False, force_https=False, zero_rating_mode=False, ) self.redirect("/admin", new_repo) elif self.params.operation == "save_repo": if not self.repo: self.redirect("/admin") return if self.__update_config( self.repo, # These settings are all entered in JSON. It can be either: # - JSON object e.g., {"k1": "v1", "k2": "v2"} # - JSON boolean literal i.e., true or false json_config_names=[ "allow_believed_dead_via_ui", "family_name_first", "footer_custom_htmls", "force_https", "language_menu_options", "map_default_center", "map_default_zoom", "map_size_pixels", "min_query_word_length", "profile_websites", "read_auth_key_required", "repo_titles", "results_page_custom_htmls", "search_auth_key_required", "seek_query_form_custom_htmls", "show_profile_entry", "start_page_custom_htmls", "test_mode", "use_alternate_names", "use_family_name", "use_postal_code", "view_page_custom_htmls", "zero_rating_mode", ], # These settings are literal strings (not JSON). literal_config_names=["bad_words", "deactivation_message_html", "keywords", "launch_status"], # Update updated_date if any of the following settings are # changed. updating_config_names=["launch_status", "test_mode"], ): self.redirect("/admin") elif self.params.operation == "save_global": if self.__update_config( "*", # These settings are all entered in JSON. json_config_names=["sms_number_to_repo", "repo_aliases"], # These settings are literal strings (not JSON). literal_config_names=[], ): self.redirect("/admin")
def post(self): if self.params.operation == 'delete': # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action)) elif self.params.operation == 'create_repo': new_repo = self.params.new_repo Repo(key_name=new_repo).put() config.set_for_repo( # Provide some defaults. new_repo, language_menu_options=['en', 'fr'], repo_titles={'en': 'Earthquake', 'fr': u'S\xe9isme'}, keywords='person finder, people finder, person, people, ' + 'crisis, survivor, family', use_family_name=True, use_alternate_names=True, use_postal_code=True, allow_believed_dead_via_ui=False, min_query_word_length=2, show_profile_entry=False, profile_websites=DEFAULT_PROFILE_WEBSITES, map_default_zoom=6, map_default_center=[0, 0], map_size_pixels=[400, 280], read_auth_key_required=True, search_auth_key_required=True, deactivated=False, deactivation_message_html='', start_page_custom_htmls={'en': '', 'fr': ''}, results_page_custom_htmls={'en': '', 'fr': ''}, view_page_custom_htmls={'en': '', 'fr': ''}, seek_query_form_custom_htmls={'en': '', 'fr': ''}, bad_words='', published_date=get_utcnow_timestamp(), updated_date=get_utcnow_timestamp(), test_mode=False, force_https=False, ) self.redirect('/admin', new_repo) elif self.params.operation == 'save_repo': values = {} for name in [ # These settings are all entered in JSON. 'language_menu_options', 'repo_titles', 'use_family_name', 'family_name_first', 'use_alternate_names', 'use_postal_code', 'allow_believed_dead_via_ui', 'min_query_word_length', 'map_default_zoom', 'show_profile_entry', 'profile_websites', 'map_default_center', 'map_size_pixels', 'read_auth_key_required', 'search_auth_key_required', 'deactivated', 'start_page_custom_htmls', 'results_page_custom_htmls', 'view_page_custom_htmls', 'seek_query_form_custom_htmls', 'test_mode', 'force_https', ]: try: values[name] = simplejson.loads(self.request.get(name)) except: return self.error( 400, 'The setting for %s was not valid JSON.' % name) for name in ['keywords', 'deactivation_message_html', 'bad_words']: # These settings are literal strings (not JSON). values[name] = self.request.get(name) # Update updated_date if any of the following settings are changed. for name in ['deactivated', 'test_mode']: if config.get_for_repo(self.repo, name) != values[name]: values['updated_date'] = get_utcnow_timestamp() break config.set_for_repo(self.repo, **values) self.redirect('/admin')
def get_disable_notes_url(handler, person, ttl=3 * 24 * 3600): """Returns a URL to be used for disabling notes to a person record.""" key_name = person.key().name() data = "disable_notes:%s" % key_name token = reveal.sign(data, ttl) return handler.get_url("/confirm_disable_notes", token=token, id=key_name)
def post(self): if self.params.operation == 'delete': # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action)) elif self.params.operation == 'create_repo': new_repo = self.params.new_repo Repo(key_name=new_repo).put() config.set_for_repo( # Provide some defaults. new_repo, language_menu_options=['en', 'fr'], repo_titles={ 'en': 'Earthquake', 'fr': u'S\xe9isme' }, keywords='person finder, people finder, person, people, ' + 'crisis, survivor, family', use_family_name=True, use_alternate_names=True, use_postal_code=True, allow_believed_dead_via_ui=False, min_query_word_length=2, show_profile_entry=False, profile_websites=DEFAULT_PROFILE_WEBSITES, map_default_zoom=6, map_default_center=[0, 0], map_size_pixels=[400, 280], read_auth_key_required=True, search_auth_key_required=True, deactivated=False, deactivation_message_html='', start_page_custom_htmls={ 'en': '', 'fr': '' }, results_page_custom_htmls={ 'en': '', 'fr': '' }, view_page_custom_htmls={ 'en': '', 'fr': '' }, seek_query_form_custom_htmls={ 'en': '', 'fr': '' }, footer_custom_htmls={ 'en': '', 'fr': '' }, bad_words='', published_date=get_utcnow_timestamp(), updated_date=get_utcnow_timestamp(), test_mode=False, force_https=False, ) self.redirect('/admin', new_repo) elif self.params.operation == 'save_repo': if not self.repo: self.redirect('/admin') return values = {} for name in [ # These settings are all entered in JSON. 'language_menu_options', 'repo_titles', 'use_family_name', 'family_name_first', 'use_alternate_names', 'use_postal_code', 'allow_believed_dead_via_ui', 'min_query_word_length', 'map_default_zoom', 'show_profile_entry', 'profile_websites', 'map_default_center', 'map_size_pixels', 'read_auth_key_required', 'search_auth_key_required', 'deactivated', 'start_page_custom_htmls', 'results_page_custom_htmls', 'view_page_custom_htmls', 'seek_query_form_custom_htmls', 'footer_custom_htmls', 'test_mode', 'force_https', ]: try: values[name] = simplejson.loads(self.request.get(name)) except: return self.error( 400, 'The setting for %s was not valid JSON.' % name) for name in ['keywords', 'deactivation_message_html', 'bad_words']: # These settings are literal strings (not JSON). values[name] = self.request.get(name) # Update updated_date if any of the following settings are changed. for name in ['deactivated', 'test_mode']: if config.get_for_repo(self.repo, name) != values[name]: values['updated_date'] = get_utcnow_timestamp() break config.set_for_repo(self.repo, **values) self.redirect('/admin')
def post(self): # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action))
def post(self): if self.params.operation == 'delete': # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action)) elif self.params.operation == 'create_repo': new_repo = self.params.new_repo Repo(key_name=new_repo).put() config.set_for_repo( # Provide some defaults. new_repo, language_menu_options=['en', 'fr'], repo_titles={'en': 'Earthquake', 'fr': u'S\xe9isme'}, keywords='person finder, people finder, person, people, ' + 'crisis, survivor, family', use_family_name=True, use_alternate_names=True, use_postal_code=True, allow_believed_dead_via_ui=False, min_query_word_length=2, show_profile_entry=False, profile_websites=DEFAULT_PROFILE_WEBSITES, map_default_zoom=6, map_default_center=[0, 0], map_size_pixels=[400, 280], read_auth_key_required=True, search_auth_key_required=True, deactivated=False, deactivation_message_html='', start_page_custom_htmls={'en': '', 'fr': ''}, results_page_custom_htmls={'en': '', 'fr': ''}, view_page_custom_htmls={'en': '', 'fr': ''}, seek_query_form_custom_htmls={'en': '', 'fr': ''}, footer_custom_htmls={'en': '', 'fr': ''}, bad_words='', published_date=get_utcnow_timestamp(), updated_date=get_utcnow_timestamp(), test_mode=False, force_https=False, ) self.redirect('/admin', new_repo) elif self.params.operation == 'save_repo': if not self.repo: self.redirect('/admin') return if self.__update_config( self.repo, # These settings are all entered in JSON. json_config_names=[ 'allow_believed_dead_via_ui', 'deactivated', 'family_name_first', 'footer_custom_htmls', 'force_https', 'language_menu_options', 'map_default_center', 'map_default_zoom', 'map_size_pixels', 'min_query_word_length', 'profile_websites', 'read_auth_key_required', 'repo_titles', 'results_page_custom_htmls', 'search_auth_key_required', 'seek_query_form_custom_htmls', 'show_profile_entry', 'start_page_custom_htmls', 'test_mode', 'use_alternate_names', 'use_family_name', 'use_postal_code', 'view_page_custom_htmls', ], # These settings are literal strings (not JSON). literal_config_names=[ 'bad_words', 'deactivation_message_html', 'keywords', ], # Update updated_date if any of the following settings are changed. updating_config_names=[ 'deactivated', 'test_mode', ]): self.redirect('/admin') elif self.params.operation == 'save_global': if self.__update_config( '*', # These settings are all entered in JSON. json_config_names=[ 'sms_number_to_repo', ], # These settings are literal strings (not JSON). literal_config_names=[ ]): self.redirect('/admin')
def post(self): if self.params.operation == 'delete': # Redirect to the deletion handler with a valid signature. action = ('delete', str(self.params.id)) self.redirect('/delete', id=self.params.id, signature=reveal.sign(action)) elif self.params.operation == 'create_repo': new_repo = self.params.new_repo Repo(key_name=new_repo).put() config.set_for_repo( # Provide some defaults. new_repo, language_menu_options=['en', 'fr'], repo_titles={'en': 'Earthquake', 'fr': u'S\xe9isme'}, keywords='person finder, people finder, person, people, ' + 'crisis, survivor, family', use_family_name=True, use_alternate_names=True, use_postal_code=True, allow_believed_dead_via_ui=False, min_query_word_length=2, show_profile_entry=False, profile_websites=DEFAULT_PROFILE_WEBSITES, map_default_zoom=6, map_default_center=[0, 0], map_size_pixels=[400, 280], read_auth_key_required=True, search_auth_key_required=True, deactivated=False, launched=False, deactivation_message_html='', start_page_custom_htmls={'en': '', 'fr': ''}, results_page_custom_htmls={'en': '', 'fr': ''}, view_page_custom_htmls={'en': '', 'fr': ''}, seek_query_form_custom_htmls={'en': '', 'fr': ''}, footer_custom_htmls={'en': '', 'fr': ''}, bad_words='', published_date=get_utcnow_timestamp(), updated_date=get_utcnow_timestamp(), test_mode=False, force_https=False, ) self.redirect('/admin', new_repo) elif self.params.operation == 'save_repo': if not self.repo: self.redirect('/admin') return if self.__update_config( self.repo, # These settings are all entered in JSON. json_config_names=[ 'allow_believed_dead_via_ui', 'family_name_first', 'footer_custom_htmls', 'force_https', 'language_menu_options', 'map_default_center', 'map_default_zoom', 'map_size_pixels', 'min_query_word_length', 'profile_websites', 'read_auth_key_required', 'repo_titles', 'results_page_custom_htmls', 'search_auth_key_required', 'seek_query_form_custom_htmls', 'show_profile_entry', 'start_page_custom_htmls', 'test_mode', 'use_alternate_names', 'use_family_name', 'use_postal_code', 'view_page_custom_htmls', ], # These settings are literal strings (not JSON). literal_config_names=[ 'bad_words', 'deactivation_message_html', 'keywords', 'launch_status', ], # Update updated_date if any of the following settings are # changed. updating_config_names=[ 'launch_status', 'test_mode', ]): self.redirect('/admin') elif self.params.operation == 'save_global': if self.__update_config( '*', # These settings are all entered in JSON. json_config_names=[ 'sms_number_to_repo', 'repo_aliases', ], # These settings are literal strings (not JSON). literal_config_names=[ ]): self.redirect('/admin')