def test_uuid4_debug(self): GLSetting.debug_option_UUID_human = "antani" self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000001") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000002") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000003") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000004") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000005")
def test_uuid4_debug(self): GLSettings.debug_option_UUID_human = "antani" self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000001") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000002") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000003") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000004") self.assertEqual(utility.uuid4(), "antani00-0000-0000-0000-000000000005")
def fix_field_pass_1(field): new_child_id = uuid4() id_map[field['id']] = new_child_id field['id'] = new_child_id # Tweak the fiel in order to make a raw copy field['instance'] = 'instance' field['template_id'] = field['template_override_id'] = '' # Rewrite the option ID if it exists for option in field['options']: option_id = option.get('id', None) if option_id is not None: new_option_id = uuid4() id_map[option['id']] = new_option_id option['id'] = new_option_id # And now we need to keep going down the latter for attr in field['attrs'].values(): attr['id'] = uuid4() # Recursion! for child in field['children']: child['field_id'] = new_child_id fix_field_pass_1(child)
def test_put_invalid_context_id(self): self.dummyReceiver_1['contexts'] = [unicode(uuid4())] handler = self.request(self.dummyReceiver_1, role='admin') yield self.assertFailure(handler.put(self.dummyReceiver_1['id']), sqlite3.IntegrityError)
def test_put_invalid_context_id(self): self.dummyReceiver_1['contexts'] = [unicode(uuid4())] handler = self.request(self.dummyReceiver_1, role='admin') yield self.assertFailure(handler.put(self.dummyReceiver_1['id']), errors.ContextIdNotFound)
def db_create_receiver(store, request, language): """ Creates a new receiver. Returns: (dict) the configured receiver """ fill_localized_keys(request, models.Receiver.localized_strings, language) password = request['password'] if len(password) and password != GLSettings.default_password: security.check_password_format(password) else: password = GLSettings.default_password receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}')) receiver_password = security.hash_password(password, receiver_salt) # ping_mail_address is duplicated at creation time from mail_address request.update({'ping_mail_address': request['mail_address']}) receiver = models.Receiver(request) receiver_user_dict = { 'username': uuid4(), 'password': receiver_password, 'salt': receiver_salt, 'role': u'receiver', 'state': u'enabled', 'language': u'en', 'timezone': 0, 'password_change_needed': True, 'mail_address': request['mail_address'] } receiver_user = models.User(receiver_user_dict) # The various options related in manage PGP keys are used here. pgp_options_parse(receiver, request) # Set receiver.id = receiver.user.username = receiver.user.id receiver.id = receiver_user.username = receiver_user.id store.add(receiver_user) store.add(receiver) create_random_receiver_portrait(receiver.id) contexts = request.get('contexts', []) for context_id in contexts: context = models.Context.get(store, context_id) if not context: log.err("Creation error: invalid Context can't be associated") raise errors.ContextIdNotFound context.receivers.add(receiver) log.debug("Created receiver %s" % receiver.user.username) return admin_serialize_receiver(receiver, language)
def db_create_receiver(store, request, language): """ Creates a new receiver. Returns: (dict) the configured receiver """ fill_localized_keys(request, models.Receiver.localized_strings, language) password = request['password'] if len(password) and password != GLSetting.default_password: security.check_password_format(password) else: password = GLSetting.default_password receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}')) receiver_password = security.hash_password(password, receiver_salt) receiver_user_dict = { 'username': uuid4(), 'password': receiver_password, 'salt': receiver_salt, 'role': u'receiver', 'state': u'enabled', 'language': u"en", 'timezone': 0, 'password_change_needed': True, } receiver_user = models.User(receiver_user_dict) receiver_user.last_login = datetime_null() receiver_user.password_change_date = datetime_null() store.add(receiver_user) # ping_mail_address is duplicated at creation time from mail_address request.update({'ping_mail_address': request['mail_address']}) receiver = models.Receiver(request) receiver.user = receiver_user # The various options related in manage GPG keys are used here. gpg_options_parse(receiver, request) log.debug("Creating receiver %s" % receiver.user.username) store.add(receiver) create_random_receiver_portrait(receiver.id) contexts = request.get('contexts', []) for context_id in contexts: context = models.Context.get(store, context_id) if not context: log.err("Creation error: invalid Context can't be associated") raise errors.ContextIdNotFound context.receivers.add(receiver) return admin_serialize_receiver(receiver, language)
def db_create_user(session, state, tid, request, language): request['tid'] = tid fill_localized_keys(request, models.User.localized_keys, language) if request['username']: user = session.query(models.User).filter( models.User.username == text_type(request['username']), models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == tid).one_or_none() if user is not None: raise errors.InputValidationError('Username already in use') user = models.User({ 'tid': tid, 'username': request['username'], 'role': request['role'], 'state': u'enabled', 'name': request['name'], 'description': request['description'], 'language': language, 'password_change_needed': request['password_change_needed'], 'mail_address': request['mail_address'], 'can_edit_general_settings': request['can_edit_general_settings'] }) if not request['username']: user.username = user.id = uuid4() if request['password']: password = request['password'] else: password = u'password' user.salt = security.generateRandomSalt() user.password = security.hash_password(password, user.salt) # The various options related in manage PGP keys are used here. parse_pgp_options(state, user, request) session.add(user) session.flush() db_create_usertenant_association(session, user.id, tid) return user
def test_object_expire(self): """ call the expire and checks that the object is expired """ c = task.Clock() # deterministic clock objs_dict = {} obj = TempObj(objs_dict, uuid4(), 1, c) obj.expire() self.assertIsNone(obj._expireCall)
def test_put_invalid_context_id(self): self.dummyReceiver_1['name'] = u'justalazyupdate' self.dummyReceiver_1['contexts'] = [unicode(uuid4())] self.dummyReceiver_1['name'] = u'another unique name %d' % random.randint(1, 10000) self.dummyReceiver_1['mail_address'] = u'*****@*****.**' % random.randint(1, 1000) self.dummyReceiver_1['password'] = u'12345678andaletter' for attrname in Receiver.localized_strings: self.dummyReceiver_1[attrname] = stuff handler = self.request(self.dummyReceiver_1, role='admin') yield self.assertFailure(handler.put(self.dummyReceiver_1['id']), errors.ContextIdNotFound)
def test_put_invalid_context_id(self): self.dummyReceiver_1['name'] = u'justalazyupdate' # keep the context ID wrong but matching eventually regexp self.dummyReceiver_1['contexts'] = [ unicode(uuid4()) ] self.dummyReceiver_1['name'] = u'another unique name %d' % random.randint(1, 10000) self.dummyReceiver_1['mail_address'] = u'*****@*****.**' % random.randint(1, 1000) self.dummyReceiver_1['password'] = u'12345678andaletter' for attrname in Receiver.localized_strings: self.dummyReceiver_1[attrname] = stuff handler = self.request(self.dummyReceiver_1, role='admin') yield self.assertFailure(handler.put(self.dummyReceiver_1['id']), errors.ContextIdNotFound)
def db_create_user(session, tid, request, language): request['tid'] = tid fill_localized_keys(request, models.User.localized_keys, language) if request['username']: user = session.query(models.User).filter(models.User.username == text_type(request['username']), models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == tid).one_or_none() if user is not None: raise errors.InputValidationError('Username already in use') user = models.User({ 'tid': tid, 'username': request['username'], 'role': request['role'], 'state': u'enabled', 'name': request['name'], 'description': request['description'], 'language': language, 'password_change_needed': request['password_change_needed'], 'mail_address': request['mail_address'], 'can_edit_general_settings': request['can_edit_general_settings'] }) if not request['username']: user.username = user.id = uuid4() password = u'password' if request['password']: password = request['password'] user.hash_alg = GCE.HASH user.salt = GCE.generate_salt() user.password = GCE.hash_password(password, user.salt) # The various options related in manage PGP keys are used here. parse_pgp_options(user, request) session.add(user) session.flush() db_create_usertenant_association(session, user.id, tid) return user
def post(self, id): if id != 'custom': sf = self.state.get_tmp_file_by_path(self.uploaded_file['path']) with sf.open('r') as encrypted_file: data = encrypted_file.read() data = base64.b64encode(data) d = add_file(self.request.tid, id, u'', data) else: id = uuid4() path = os.path.join(self.state.settings.files_path, id) d = threads.deferToThread(self.write_upload_plaintext_to_disk, path) d.addCallback(lambda x: add_file(self.request.tid, id, self. uploaded_file['name'], u'')) return d
def post(self, id): yield self.permission_check(id) if id != 'custom': sf = self.state.get_tmp_file_by_name(self.uploaded_file['filename']) with sf.open('r') as encrypted_file: data = encrypted_file.read() data = base64.b64encode(data).decode() d = yield add_file(self.request.tid, id, '', data) else: id = uuid4() path = os.path.join(self.state.settings.files_path, id) d = yield self.write_upload_plaintext_to_disk(path) yield add_file(self.request.tid, id, self.uploaded_file['name'], '') returnValue(d)
def test_object_touch_and_expiry(self): """ reproduced the test pattern of twisted/test/test_task.py: testCallLaterResetLater """ c = task.Clock() # deterministic clock objs_dict = {} obj = TempObj(objs_dict, uuid4(), 2, c) obj.touch() c.advance(1) obj.touch() c.advance(1) obj.touch() c.advance(1) self.assertIsNotNone(obj._expireCall) c.advance(1) self.assertIsNone(obj._expireCall)
def default_fields(self, appdata_fields): """ @param appdata_fields: the content of the ApplicationData.fields @return: """ # first, get the amount of translated languages for block in appdata_fields: # this is just to init variable, we don't collect text here. for langcode, transtring in block['localized_name'].iteritems(): self._localization[langcode] = dict() self._langcodes.append(langcode) break for original_order, block in enumerate(appdata_fields): key = unicode(uuid4()) self._fields[key] = { 'required': False, 'incremental_number' : block['incremental_number'], 'presentation_order' : original_order, 'trigger' : block['trigger'], 'preview': False, 'type': block['type'] } for lang in self._langcodes: if not self._localization[lang].has_key(key): self._localization[lang].update({ key : { 'name' : block['localized_name'][lang], 'hint' : block['localized_hint'][lang] } }) # { "order":1, "value":"a", "localized_name": # {"en":"chief","it":"capo"}}, # { "order":2, "value":"b", "localized_name": # {"en":"slave","it":"schiavo"}}, # { "order":3, "value":"c", "localized_name": # {"en":"consultant","it":"consulente"}} self.debug_status('after update')
def default_fields(self, appdata_fields): """ @param appdata_fields: the content of the ApplicationData.fields @return: """ # first, get the amount of translated languages for block in appdata_fields: # this is just to init variable, we don't collect text here. for langcode, transtring in block['localized_name'].iteritems(): self._localization[langcode] = dict() self._langcodes.append(langcode) break for original_order, block in enumerate(appdata_fields): key = unicode(uuid4()) self._fields[key] = { 'required': False, 'incremental_number': block['incremental_number'], 'presentation_order': original_order, 'trigger': block['trigger'], 'preview': False, 'type': block['type'] } for lang in self._langcodes: if not self._localization[lang].has_key(key): self._localization[lang].update({ key: { 'name': block['localized_name'][lang], 'hint': block['localized_hint'][lang] } }) # { "order":1, "value":"a", "localized_name": # {"en":"chief","it":"capo"}}, # { "order":2, "value":"b", "localized_name": # {"en":"slave","it":"schiavo"}}, # { "order":3, "value":"c", "localized_name": # {"en":"consultant","it":"consulente"}} self.debug_status('after update')
def post(self, name): yield self.permission_check(name) if name in special_files or re.match(requests.uuid_regexp, name): self.uploaded_file['name'] = name id = uuid4() path = os.path.join(self.state.settings.files_path, id) if os.path.exists(path): return yield tw(db_add_file, self.request.tid, id, self.uploaded_file['name'], path) yield self.write_upload_plaintext_to_disk(path) returnValue(id)
def test_object_creation_and_expiry(self): """ creates two temporary objects and verify that they expire with the expected sequence reproduced the test pattern of twisted/test/test_task.py: testCallLater """ c = task.Clock() # deterministic clock objs_dict = {} obj = {} for x in range(1, 4): obj[x] = TempObj(objs_dict, uuid4(), x, c) self.failUnless(interfaces.IDelayedCall.providedBy(obj[x]._expireCall)) self.assertEqual(len(obj), x) y = len(obj) for x in range(1, 4): c.advance(1) self.assertEqual(len(objs_dict), y - x)
def test_object_notifyOnExpire(self): """ add 3 notifyOnExpire and checks that they are called """ c = task.Clock() # deterministic clock events = [] objs_dict = {} obj = TempObj(objs_dict, uuid4(), 2, c) for x in range(0, 3): obj.notifyOnExpire(lambda: events.append((x))) c.advance(1) self.assertEqual(0, len(events)) c.advance(1) self.assertEqual(3, len(events))
def migrate_File(self): for old_obj in self.session_old.query(self.model_from['File']): new_obj = self.model_to['File']() for key in new_obj.__table__.columns._data.keys(): if hasattr(old_obj, key): setattr(new_obj, key, getattr(old_obj, key)) if old_obj.id in special_files: new_obj.id = uuid4() new_obj.name = old_obj.id data = base64.b64decode(old_obj.data) filepath = os.path.join(State.settings.files_path, new_obj.id) with open(filepath, 'wb') as out_file: out_file.write(data) if not new_obj.name: new_obj.name = new_obj.id self.session_new.add(new_obj) for model in [('ContextImg', 'Context'), ('UserImg', 'User')]: for old_obj, tid in self.session_old.query(self.model_from[model[0]], self.model_from[model[1]].tid) \ .filter(self.model_from[model[0]].id == self.model_from[model[1]].id): new_obj = self.model_to['File']() for key in new_obj.__table__.columns._data.keys(): new_obj.tid = tid new_obj.id = old_obj.id new_obj.name = old_obj.id data = base64.b64decode(old_obj.data) filepath = os.path.join(State.settings.files_path, old_obj.id) with open(filepath, 'wb') as out_file: out_file.write(data) self.session_new.add(new_obj) self.entries_count['File'] += 1
def db_create_user(session, tid, request, language): """ Transaction for creating a new user :param session: An ORM session :param tid: A tenant ID :param request: The request data :param language: The language of the request :return: The serialized descriptor of the created object """ request['tid'] = tid fill_localized_keys(request, models.User.localized_keys, language) if not request['public_name']: request['public_name'] = request['name'] user = models.User(request) if not request['username']: user.username = user.id = uuid4() user.salt = GCE.generate_salt() user.language = request['language'] # The various options related in manage PGP keys are used here. parse_pgp_options(user, request) session.add(user) session.flush() if request.get('send_account_activation_link', False): db_generate_password_reset_token(session, user) return user
def migrate_InternalTip(self): steps = [self.appdata['default_questionnaire'][0]] i = 1 for step in steps: step['number'] = i step['label'] = step['label']['en'] step['description'] = step['description']['en'] step['children'] = [] # wipe out default fields old_itips = self.store_old.find(self.model_from['InternalTip']) context_model = self.model_to['Context'] for old_itip in old_itips: new_itip = self.model_to['InternalTip']() try: wb_steps = copy.deepcopy(steps) wb_fields_copy = copy.deepcopy(old_itip.wb_fields) for wb_field in wb_fields_copy: wb_fields_copy[wb_field]["id"] = "" wb_fields_copy[wb_field]["step_id"] = "" wb_fields_copy[wb_field]["fieldgroup_id"] = "" wb_fields_copy[wb_field]["description"] = "" wb_fields_copy[wb_field]["hint"] = "" wb_fields_copy[wb_field]["multi_entry"] = False wb_fields_copy[wb_field]["stats_enabled"] = False wb_fields_copy[wb_field]["required"] = False wb_fields_copy[wb_field]["is_template"] = False wb_fields_copy[wb_field]["options"] = [] wb_fields_copy[wb_field]["y"] = wb_fields_copy[wb_field]['answer_order'] wb_fields_copy[wb_field]["x"] = 0 wb_fields_copy[wb_field]["preview"] = False wb_fields_copy[wb_field]["children"] = [] wb_fields_copy[wb_field]["options"] = [] del wb_fields_copy[wb_field]['answer_order'] c = self.store_old.find(context_model, context_model.id == old_itip.context_id).one() for f in c.unique_fields: if f == wb_field: wb_fields_copy[wb_field]['label'] = c.unique_fields[f]['name'] if c.unique_fields[f]['type'] in ['email', 'phone', 'url', 'number', 'text']: wb_fields_copy[wb_field]['type'] = 'inputbox' elif c.unique_fields[f]['type'] in ['radio', 'select']: wb_fields_copy[wb_field]['type'] = 'selectbox' elif c.unique_fields[f]['type'] in ['multiple', 'checkboxes']: wb_fields_copy[wb_field]['type'] = 'checkbox' else: wb_fields_copy[wb_field]['type'] = c.unique_fields[f]['type'] if wb_fields_copy[wb_field]['type'] in ['selectbox', 'checkbox'] and \ 'options' in c.unique_fields[f]: val = {} j = 1 for o in c.unique_fields[f]['options']: opt_dict = {} opt_dict['id'] = uuid4() opt_dict['attrs'] = {} opt_dict['attrs']['name'] = o['name'] opt_dict['value'] = '' wb_fields_copy[wb_field]['options'].append(opt_dict) if wb_fields_copy[wb_field]['type'] == 'checkbox': opt_name = o['name'] if opt_name in wb_fields_copy[wb_field]["value"] and \ wb_fields_copy[wb_field]["value"][opt_name]: opt_val = True else: opt_val = False val[opt_dict['id']] = { 'order': j, 'value': opt_val, 'name': o['name'] } j += 1 if wb_fields_copy[wb_field]['type'] == 'checkbox': wb_fields_copy[wb_field]["value"] = val # else: it's already initialized with copy for f in wb_fields_copy: wb_steps[0]['children'].append(wb_fields_copy[f]) for _, v in new_itip._storm_columns.iteritems(): if v.name == 'wb_steps': new_itip.wb_steps = wb_steps continue setattr(new_itip, v.name, getattr(old_itip, v.name)) except Exception: self.entries_count['InternalTip'] -= 1 continue self.store_new.add(new_itip)
def __init__(self): self.dummyReceiverUser = { 'username': u'*****@*****.**', 'password': VALID_HASH1, 'salt': VALID_SALT1, 'role': u'receiver', 'state': u'enabled', 'last_login': datetime_null(), } self.dummyReceiver = { 'id': unicode(uuid4()), 'password': VALID_PASSWORD1, 'name': u'Ned Stark', 'description': u'King MockDummy Receiver', # Email can be different from the user, but at the creation time is used # the same address, therefore we keep the same of dummyReceiver.username 'mail_address': self.dummyReceiverUser['username'], 'can_delete_submission': True, 'postpone_superpower': False, 'receiver_level': 1, 'contexts': [], 'tags': [u'first', u'second', u'third'], 'tip_notification': True, 'file_notification': True, 'comment_notification': True, 'message_notification': True, 'gpg_key_info': u'', 'gpg_key_fingerprint': u'', 'gpg_key_status': models.Receiver._gpg_types[0], # disabled 'gpg_key_armor': u'', 'gpg_enable_notification': False, 'gpg_key_remove': False, 'presentation_order': 0, } self.dummyContext = { 'id': unicode(uuid4()), # localized stuff 'name': u'Already localized name', 'description': u'Already localized desc', # fields, usually filled in content by fill_random_fields 'fields': default_context_fields(), 'selectable_receiver': False, 'select_all_receivers': True, 'tip_max_access': 10, # tip_timetolive is expressed in days 'tip_timetolive': 20, # submission_timetolive is expressed in hours 'submission_timetolive': 48, 'file_max_download': 1, 'escalation_threshold': 1, 'receivers': [], 'tags': [], 'file_required': False, 'receiver_introduction': u'These are our receivers', 'fields_introduction': u'These are our fields', 'postpone_superpower': False, 'can_delete_submission': False, 'maximum_selectable_receivers': 0, 'require_file_description': False, 'delete_consensus_percentage': 0, 'require_pgp': False, 'show_small_cards': False, 'presentation_order': 0, } self.dummySubmission = { 'context_id': '', 'wb_fields': fill_random_fields(self.dummyContext), 'finalize': False, 'receivers': [], 'files': [], } self.dummyNode = { 'name': u"Please, set me: name/title", 'description': u"Pleæs€, set m€: d€scription", 'presentation': u'This is whæt æpp€ærs on top', 'footer': u'check it out https://www.youtube.com/franksentus ;)', 'subtitle': u'https://twitter.com/TheHackersNews/status/410457372042092544/photo/1', 'hidden_service': u"http://1234567890123456.onion", 'public_site': u"https://globaleaks.org", 'email': u"*****@*****.**", 'receipt_regexp': u'[0-9]{16}', 'stats_update_time': 2, # hours, 'languages_supported': [], # ignored 'languages_enabled': ["it", "en"], 'default_language': 'en', 'password': '', 'old_password': '', 'salt': 'OMG!, the Rains of Castamere ;( ;(', 'salt_receipt': '<<the Lannisters send their regards>>', 'maximum_filesize': GLSetting.defaults.maximum_filesize, 'maximum_namesize': GLSetting.defaults.maximum_namesize, 'maximum_textsize': GLSetting.defaults.maximum_textsize, 'tor2web_admin': True, 'tor2web_submission': True, 'tor2web_receiver': True, 'tor2web_unauth': True, 'postpone_superpower': False, 'can_delete_submission': False, 'exception_email': GLSetting.defaults.exception_email, 'reset_css': False, 'ahmia': False, 'anomaly_checks': False, 'allow_unencrypted': True, 'configured': False, 'wizard_done': False, } self.generic_template_keywords = [ '%NodeName%', '%HiddenService%', '%PublicSite%', '%ReceiverName%', '%ContextName%' ] self.tip_template_keywords = [ '%TipTorURL%', '%TipT2WURL%', '%EventTime%' ] self.comment_template_keywords = ['%CommentSource%', '%EventTime%'] self.file_template_keywords = [ '%FileName%', '%EventTime%', '%FileSize%', '%FileType%' ] self.dummyNotification = { 'server': u'mail.foobar.xxx', 'port': 12345, 'username': u'[email protected]', 'password': u'antani', 'security': u'SSL', 'source_name': u'UnitTest Helper Name', 'source_email': u'*****@*****.**', 'encrypted_tip_template': template_keys(self.tip_template_keywords, self.generic_template_keywords, "Tip"), 'plaintext_tip_template': template_keys(self.tip_template_keywords, self.generic_template_keywords, "Tip"), 'encrypted_tip_mail_title': u'xXx', 'plaintext_tip_mail_title': u'XxX', 'encrypted_file_template': template_keys(self.file_template_keywords, self.generic_template_keywords, "File"), 'plaintext_file_template': template_keys(self.file_template_keywords, self.generic_template_keywords, "File"), 'encrypted_file_mail_title': u'kkk', 'plaintext_file_mail_title': u'kkk', 'encrypted_comment_template': template_keys(self.comment_template_keywords, self.generic_template_keywords, "Comment"), 'plaintext_comment_template': template_keys(self.comment_template_keywords, self.generic_template_keywords, "Comment"), 'encrypted_comment_mail_title': u'yyy', 'plaintext_comment_mail_title': u'yyy', 'encrypted_message_template': u'%B EventTime% %TipUN%', 'plaintext_message_template': u'%B EventTime% %TipUN%', 'encrypted_message_mail_title': u'T %EventTime %TipUN', 'plaintext_message_mail_title': u'T %EventTime %TipUN', 'zip_description': u'TODO', 'disable': False, }
def test_uuid4(self): self.assertIsNotNone( re.match(r"([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})", utility.uuid4()) )
def update_fields(self, language, admin_data): """ update_fields imply create_fields @param language: @param admin_data: This function shall be used in two cases: 1) a new field has been added with the language 2) a new language has been provided admin_data expect this kind of data -LOCALIZED- [ { u'name': u'Short title', u'presentation_order': 1, u'hint': u'Describe your Tip with a short title', u'required': True, u'value': u'', u'key': u'b410bb94-00a7-4b9f-9499-f4fea086e4cc', u'preview': True, u'type': u'text' }, { u'name': u'Full description', ... } ] """ self.debug_status('before update') # this variable collect the updated fields from the # admin var, in order to keep track of the real existing keys existing_keys = [] for admin_order, field_desc in enumerate(admin_data): check_type = field_desc['type'] if not check_type in Fields.accepted_form_type: raise InvalidInputFormat("Fields validation deny '%s' in %s" % (check_type, field_desc['name']) ) if field_desc.has_key(u'key') and \ len(field_desc.get(u'key')) == len(unicode(uuid4())): key = field_desc.get(u'key') # print "key recognized and retrieved %s" % key else: # print "creating new key for %s" % field_desc key = unicode(uuid4()) existing_keys.append(key) self._fields[key] = dict(field_desc) if not self._localization.has_key(language): self._localization[language] = dict() self._localization[language][key] = dict() # init localization track self._localization[language][key].update({'name' : field_desc['name']}) self._localization[language][key].update({'hint' : field_desc['hint']}) del self._fields[key]['name'] del self._fields[key]['hint'] del self._fields[key]['key'] # This variable keep track of the key that has not been updated, # and then need to be removed. removed_keys = [] for k, v in self._fields.iteritems(): if k not in existing_keys: removed_keys.append(k) # loop over the internal dict and remove the not updated keys for key in removed_keys: for lang in self._localization: try: del self._localization[lang][key] except KeyError as keyerr: log.err("Handled inconsistency (field delete) lang (%s) %s" % (lang, keyerr)) try: del self._fields[key] except KeyError as keyerr: log.err("Handled inconsistency (field delete): %s" % keyerr) self.debug_status('after update')
def duplicate_questionnaire(session, tid, questionnaire_id, new_name): """ Transaction for duplicating an existing questionnaire :param session: An ORM session :param tid: A tnenat ID :param questionnaire_id A questionnaire ID :param new_name: The name to be assigned to the new questionnaire """ id_map = {} q = db_get_questionnaire(session, tid, questionnaire_id, None, False) # We need to change the primary key references and so this can be reimported # as a new questionnaire q['id'] = uuid4() # Each step has a UUID that needs to be replaced def fix_field_pass_1(field): new_child_id = uuid4() id_map[field['id']] = new_child_id field['id'] = new_child_id # Tweak the fiel in order to make a raw copy field['instance'] = 'instance' field['template_id'] = field['template_override_id'] = '' # Rewrite the option ID if it exists for option in field['options']: option_id = option.get('id', None) if option_id is not None: new_option_id = uuid4() id_map[option['id']] = new_option_id option['id'] = new_option_id # And now we need to keep going down the latter for attr in field['attrs'].values(): attr['id'] = uuid4() # Recursion! for child in field['children']: child['field_id'] = new_child_id fix_field_pass_1(child) def fix_field_pass_2(field): # Fix triggers references for trigger in field.get('triggered_by_options', []): trigger['field'] = id_map[trigger['field']] trigger['option'] = id_map[trigger['option']] # Recursion! for child in field['children']: fix_field_pass_2(child) # Step1: replacement of IDs for step in q['steps']: new_step_id = uuid4() id_map[step['id']] = new_step_id step['id'] = new_step_id # Each field has a UUID that needs to be replaced for field in step['children']: field['step_id'] = step['id'] fix_field_pass_1(field) # Step2: fix of fields triggers following IDs replacement for step in q['steps']: # Fix triggers references for trigger in step.get('triggered_by_options', []): trigger['field'] = id_map[trigger['field']] trigger['option'] = id_map[trigger['option']] for field in step['children']: fix_field_pass_2(field) q['name'] = new_name db_create_questionnaire(session, tid, q, None)
def test_uuid4(self): self.assertIsNotNone(re.match(r'([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})', utility.uuid4()))
from twisted.internet.defer import inlineCallbacks from globaleaks.tests import helpers from globaleaks.handlers import admin from globaleaks.utils.utility import uuid4 text_field = { u'name': u'Localized name 1', u'hint': u"Localized hint 1", u'presentation_order': 0, u'key': unicode(uuid4()), u'required': True, u'preview': True, u'type': u'text', u'value': u'' } class TestRosetta(helpers.TestHandler): _handler = admin.ContextInstance @inlineCallbacks def test_simple_update_fields(self): handler = self.request(role='admin') yield handler.get(self.dummyContext['id']) self.assertTrue(isinstance(self.responses[0], dict)) new_context_dict = dict(self.responses[0]) new_context_dict['fields'] = [ text_field ] handler = self.request(new_context_dict, role='admin') yield handler.put(new_context_dict['id'])
def db_create_user(session, tid, request, language): """ Transaction for creating a new user :param session: An ORM session :param tid: A tenant ID :param request: The request data :param language: The language of the request :return: The serialized descriptor of the created object """ request['tid'] = tid fill_localized_keys(request, models.User.localized_keys, language) if request['username']: user = session.query(models.User).filter( models.User.username == request['username'], models.User.tid == tid).one_or_none() if user is not None: raise errors.InputValidationError('Username already in use') user = models.User({ 'tid': tid, 'username': request['username'], 'role': request['role'], 'state': 'enabled', 'name': request['name'], 'description': request['description'], 'public_name': request['public_name'] if request['public_name'] else request['name'], 'language': language, 'password_change_needed': request['password_change_needed'], 'mail_address': request['mail_address'], 'can_edit_general_settings': request['can_edit_general_settings'] }) if not request['username']: user.username = user.id = uuid4() user.salt = GCE.generate_salt() # The various options related in manage PGP keys are used here. parse_pgp_options(user, request) session.add(user) session.flush() if request.get('send_account_activation_link', False): db_generate_password_reset_token(session, user) return user
def update_fields(self, language, admin_data): """ update_fields imply create_fields @param language: @param admin_data: This function shall be used in two cases: 1) a new field has been added with the language 2) a new language has been provided admin_data expect this kind of data -LOCALIZED- [ { u'name': u'Short title', u'presentation_order': 1, u'hint': u'Describe your Tip with a short title', u'required': True, u'value': u'', u'key': u'b410bb94-00a7-4b9f-9499-f4fea086e4cc', u'preview': True, u'type': u'text' }, { u'name': u'Full description', ... } ] """ self.debug_status('before update') # this variable collect the updated fields from the # admin var, in order to keep track of the real existing keys existing_keys = [] for admin_order, field_desc in enumerate(admin_data): check_type = field_desc['type'] if not check_type in Fields.accepted_form_type: raise InvalidInputFormat("Fields validation deny '%s' in %s" % (check_type, field_desc['name'])) if field_desc.has_key(u'key') and \ len(field_desc.get(u'key')) == len(unicode(uuid4())): key = field_desc.get(u'key') # print "key recognized and retrieved %s" % key else: # print "creating new key for %s" % field_desc key = unicode(uuid4()) existing_keys.append(key) self._fields[key] = dict(field_desc) if not self._localization.has_key(language): self._localization[language] = dict() self._localization[language][key] = dict() # init localization track self._localization[language][key].update( {'name': field_desc['name']}) self._localization[language][key].update( {'hint': field_desc['hint']}) del self._fields[key]['name'] del self._fields[key]['hint'] del self._fields[key]['key'] # This variable keep track of the key that has not been updated, # and then need to be removed. removed_keys = [] for k, v in self._fields.iteritems(): if k not in existing_keys: removed_keys.append(k) # loop over the internal dict and remove the not updated keys for key in removed_keys: for lang in self._localization: try: del self._localization[lang][key] except KeyError as keyerr: log.err( "Handled inconsistency (field delete) lang (%s) %s" % (lang, keyerr)) try: del self._fields[key] except KeyError as keyerr: log.err("Handled inconsistency (field delete): %s" % keyerr) self.debug_status('after update')
def __init__(self): self.dummyReceiverUser = { 'username': u'*****@*****.**', 'password': VALID_HASH1, 'salt': VALID_SALT1, 'role': u'receiver', 'state': u'enabled', 'last_login': datetime_null(), } self.dummyReceiver = { 'id': unicode(uuid4()), 'password': VALID_PASSWORD1, 'name': u'Ned Stark', 'description': u'King MockDummy Receiver', # Email can be different from the user, but at the creation time is used # the same address, therefore we keep the same of dummyReceiver.username 'mail_address': self.dummyReceiverUser['username'], 'can_delete_submission': True, 'postpone_superpower': False, 'receiver_level': 1, 'contexts' : [], 'tags': [ u'first', u'second', u'third' ], 'tip_notification': True, 'file_notification': True, 'comment_notification': True, 'message_notification': True, 'gpg_key_info': u'', 'gpg_key_fingerprint' : u'', 'gpg_key_status': models.Receiver._gpg_types[0], # disabled 'gpg_key_armor' : u'', 'gpg_enable_notification': False, 'gpg_key_remove': False, 'presentation_order': 0, } self.dummyContext = { 'id': unicode(uuid4()), # localized stuff 'name': u'Already localized name', 'description': u'Already localized desc', # fields, usually filled in content by fill_random_fields 'fields': default_context_fields(), 'selectable_receiver': False, 'select_all_receivers': True, 'tip_max_access': 10, # tip_timetolive is expressed in days 'tip_timetolive': 20, # submission_timetolive is expressed in hours 'submission_timetolive': 48, 'file_max_download' :1, 'escalation_threshold': 1, 'receivers' : [], 'tags': [], 'file_required': False, 'receiver_introduction': u'These are our receivers', 'fields_introduction': u'These are our fields', 'postpone_superpower': False, 'can_delete_submission': False, 'maximum_selectable_receivers': 0, 'require_file_description': False, 'delete_consensus_percentage': 0, 'require_pgp': False, 'show_small_cards': False, 'show_receivers': False, 'enable_private_messages': True, 'presentation_order': 0, } self.dummySubmission = { 'context_id': '', 'wb_fields': fill_random_fields(self.dummyContext), 'finalize': False, 'receivers': [], 'files': [], } self.dummyNode = { 'name': u"Please, set me: name/title", 'description': u"Pleæs€, set m€: d€scription", 'presentation': u'This is whæt æpp€ærs on top', 'footer': u'check it out https://www.youtube.com/franksentus ;)', 'subtitle': u'https://twitter.com/TheHackersNews/status/410457372042092544/photo/1', 'terms_and_conditions': u'', 'security_awareness_title': u'', 'security_awareness_text': u'', 'hidden_service': u"http://1234567890123456.onion", 'public_site': u"https://globaleaks.org", 'email': u"*****@*****.**", 'receipt_regexp': u'[0-9]{16}', 'stats_update_time': 2, # hours, 'languages_supported': [], # ignored 'languages_enabled': [ "it" , "en" ], 'default_language': 'en', 'password': '', 'old_password': '', 'salt': 'OMG!, the Rains of Castamere ;( ;(', 'salt_receipt': '<<the Lannisters send their regards>>', 'maximum_filesize': GLSetting.defaults.maximum_filesize, 'maximum_namesize': GLSetting.defaults.maximum_namesize, 'maximum_textsize': GLSetting.defaults.maximum_textsize, 'tor2web_admin': True, 'tor2web_submission': True, 'tor2web_receiver': True, 'tor2web_unauth': True, 'postpone_superpower': False, 'can_delete_submission': False, 'exception_email': GLSetting.defaults.exception_email, 'reset_css': False, 'reset_homepage': False, 'ahmia': False, 'anomaly_checks': False, 'allow_unencrypted': True, 'x_frame_options_mode': 'deny', 'x_frame_options_allow_from': '', 'configured': False, 'wizard_done': False, 'custom_homepage': False, 'disable_privacy_badge': False, 'disable_security_awareness_badge': False, 'disable_security_awareness_questions': False, } self.generic_template_keywords = [ '%NodeName%', '%HiddenService%', '%PublicSite%', '%ReceiverName%', '%ContextName%' ] self.tip_template_keywords = [ '%TipTorURL%', '%TipT2WURL%', '%EventTime%' ] self.comment_template_keywords = [ '%CommentSource%', '%EventTime%' ] self.file_template_keywords = [ '%FileName%', '%EventTime%', '%FileSize%', '%FileType%' ] self.dummyNotification = { 'server': u'mail.foobar.xxx', 'port': 12345, 'username': u'[email protected]', 'password': u'antani', 'security': u'SSL', 'source_name': u'UnitTest Helper Name', 'source_email': u'*****@*****.**', 'encrypted_tip_template': template_keys(self.tip_template_keywords, self.generic_template_keywords, "Tip"), 'plaintext_tip_template': template_keys(self.tip_template_keywords, self.generic_template_keywords, "Tip"), 'encrypted_tip_mail_title': u'xXx', 'plaintext_tip_mail_title': u'XxX', 'encrypted_file_template':template_keys(self.file_template_keywords, self.generic_template_keywords, "File"), 'plaintext_file_template':template_keys(self.file_template_keywords, self.generic_template_keywords, "File"), 'encrypted_file_mail_title': u'kkk', 'plaintext_file_mail_title': u'kkk', 'encrypted_comment_template': template_keys(self.comment_template_keywords, self.generic_template_keywords, "Comment"), 'plaintext_comment_template': template_keys(self.comment_template_keywords, self.generic_template_keywords, "Comment"), 'encrypted_comment_mail_title': u'yyy', 'plaintext_comment_mail_title': u'yyy', 'encrypted_message_template': u'%B EventTime% %TipUN%', 'plaintext_message_template': u'%B EventTime% %TipUN%', 'encrypted_message_mail_title': u'T %EventTime %TipUN', 'plaintext_message_mail_title': u'T %EventTime %TipUN', 'zip_description': u'TODO', 'disable': False, }
def migrate_InternalTip(self): print "%s InternalTip migration assistant" % self.std_fancy steps = [] steps.append(load_appdata()['fields'][0]) i = 1 for step in steps: step['number'] = i step['label'] = step['label']['en'] step['hint'] = step['hint']['en'] step['description'] = step['description']['en'] step['children'] = [] # wipe out default fields old_itips = self.store_old.find(self.get_right_model("InternalTip", 14)) context_model = self.get_right_model("Context", 14) for old_itip in old_itips: new_itip = self.get_right_model("InternalTip", 15)() try: wb_steps = copy.deepcopy(steps) wb_fields_copy = copy.deepcopy(old_itip.wb_fields) for wb_field in wb_fields_copy: wb_fields_copy[wb_field]["id"] = "" wb_fields_copy[wb_field]["step_id"] = "" wb_fields_copy[wb_field]["fieldgroup_id"] = "" wb_fields_copy[wb_field]["description"] = "" wb_fields_copy[wb_field]["hint"] = "" wb_fields_copy[wb_field]["multi_entry"] = False wb_fields_copy[wb_field]["stats_enabled"] = False wb_fields_copy[wb_field]["required"] = False wb_fields_copy[wb_field]["is_template"] = False wb_fields_copy[wb_field]["options"] = [] wb_fields_copy[wb_field]["y"] = wb_fields_copy[wb_field]['answer_order'] wb_fields_copy[wb_field]["x"] = 0 wb_fields_copy[wb_field]["preview"] = False wb_fields_copy[wb_field]["children"] = [] wb_fields_copy[wb_field]["options"] = [] del wb_fields_copy[wb_field]['answer_order'] c = self.store_old.find(context_model, context_model.id == old_itip.context_id).one() for f in c.unique_fields: if f == wb_field: wb_fields_copy[wb_field]['label'] = c.unique_fields[f]['name'] if c.unique_fields[f]['type'] in ['email', 'phone', 'url', 'number', 'text']: wb_fields_copy[wb_field]['type'] = 'inputbox' elif c.unique_fields[f]['type'] in ['radio', 'select']: wb_fields_copy[wb_field]['type'] = 'selectbox' elif c.unique_fields[f]['type'] in ['multiple', 'checkboxes']: wb_fields_copy[wb_field]['type'] = 'checkbox' else: wb_fields_copy[wb_field]['type'] = c.unique_fields[f]['type'] if wb_fields_copy[wb_field]['type'] in ['selectbox', 'checkbox'] and \ 'options' in c.unique_fields[f]: val = {} j = 1 for o in c.unique_fields[f]['options']: opt_dict = {} opt_dict['id'] = uuid4() opt_dict['attrs'] = {} opt_dict['attrs']['name'] = o['name'] opt_dict['value'] = '' wb_fields_copy[wb_field]['options'].append(opt_dict) if wb_fields_copy[wb_field]['type'] == 'checkbox': opt_name = o['name'] if opt_name in wb_fields_copy[wb_field]["value"] and \ wb_fields_copy[wb_field]["value"][opt_name]: opt_val = True else: opt_val = False val[opt_dict['id']] = { 'order': j, 'value': opt_val, 'name': o['name'] } j += 1 if wb_fields_copy[wb_field]['type'] == 'checkbox': wb_fields_copy[wb_field]["value"] = val # else: it's already initialized with copy for f in wb_fields_copy: wb_steps[0]['children'].append(wb_fields_copy[f]) for _, v in new_itip._storm_columns.iteritems(): if v.name == 'wb_steps': new_itip.wb_steps = wb_steps; continue setattr(new_itip, v.name, getattr(old_itip, v.name)) except Exception: continue self.store_new.add(new_itip) self.store_new.commit()