def create_key(self): """ Create the AES Key to encrypt uploaded file. """ self.key = os.urandom(GLSetting.AES_key_size) self.key_id = xeger(GLSetting.AES_key_id_regexp) self.keypath = os.path.join(GLSetting.ramdisk_path, "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id)) while os.path.isfile(self.keypath): self.key_id = xeger(GLSetting.AES_key_id_regexp) self.keypath = os.path.join(GLSetting.ramdisk_path, "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id)) self.key_counter_nonce = os.urandom(GLSetting.AES_counter_nonce) self.initialize_cipher() saved_struct = { 'key' : self.key, 'key_counter_nonce' : self.key_counter_nonce } log.debug("Key initialization at %s" % self.keypath) with open(self.keypath, 'w') as kf: pickle.dump(saved_struct, kf) if not os.path.isfile(self.keypath): log.err("Unable to write keyfile %s" % self.keypath) raise Exception("Unable to write keyfile %s" % self.keypath)
def create_key(self): """ Create the AES Key to encrypt uploaded file. """ self.key = os.urandom(GLSetting.AES_key_size) self.key_id = xeger(GLSetting.AES_key_id_regexp) self.keypath = os.path.join( GLSetting.ramdisk_path, "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id)) while os.path.isfile(self.keypath): self.key_id = xeger(GLSetting.AES_key_id_regexp) self.keypath = os.path.join( GLSetting.ramdisk_path, "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id)) self.key_counter_nonce = os.urandom(GLSetting.AES_counter_nonce) self.initialize_cipher() saved_struct = { 'key': self.key, 'key_counter_nonce': self.key_counter_nonce } log.debug("Key initialization at %s" % self.keypath) with open(self.keypath, 'w') as kf: pickle.dump(saved_struct, kf) if not os.path.isfile(self.keypath): log.err("Unable to write keyfile %s" % self.keypath) raise Exception("Unable to write keyfile %s" % self.keypath)
def encrypt_file(self, key_fingerprint, plainpath, filestream, output_path): """ @param pgp_key_public: @param plainpath: @return: """ encrypt_obj = self.pgph.encrypt_file(filestream, str(key_fingerprint)) if not encrypt_obj.ok: raise errors.PGPKeyInvalid log.debug("Encrypting for key %s file %s (%d bytes)" % (key_fingerprint, plainpath, len(str(encrypt_obj)))) encrypted_path = os.path.join(os.path.abspath(output_path), "pgp_encrypted-%s" % xeger(r'[A-Za-z0-9]{16}')) try: with open(encrypted_path, "w+") as f: f.write(str(encrypt_obj)) return encrypted_path, len(str(encrypt_obj)) except Exception as excep: log.err("Error in writing PGP file output: %s (%s) bytes %d" % (excep.message, encrypted_path, len(str(encrypt_obj)) )) raise errors.InternalServerError("Error in writing [%s]" % excep.message)
def db_create_whistleblower_tip(store, internaltip): """ The plaintext receipt is returned only now, and then is stored hashed in the WBtip table """ wbtip = WhistleblowerTip() node = store.find(Node).one() receipt = unicode(rstr.xeger(GLSettings.receipt_regexp)) wbtip.receipt_hash = hash_password(receipt, node.receipt_salt) wbtip.access_counter = 0 wbtip.internaltip_id = internaltip.id store.add(wbtip) created_rtips = [] for receiver in internaltip.receivers: rtip_id = db_create_receivertip(store, receiver, internaltip) internaltip.new = False if len(created_rtips): log.debug("The finalized submissions had created %d ReceiverTip(s)" % len(created_rtips)) return receipt
def get_expirations(keylist): """ This function is not implemented in GPG object class because need to operate on the whole keys """ try: temp_gpgroot = os.path.join( GLSetting.gpgroot, "-expiration_check-%s" % xeger(r'[A-Za-z0-9]{8}')) os.makedirs(temp_gpgroot, mode=0700) gpexpire = GPG(gnupghome=temp_gpgroot, options=['--trust-model', 'always']) except Exception as excep: log.err("Unable to setup expiration check environment: %s" % excep) raise excep try: for key in keylist: gpexpire.import_keys(key) except Exception as excep: log.err("Error in GPG import_keys: %s" % excep) raise excep try: all_keys = gpexpire.list_keys() except Exception as excep: log.err("Error in GPG list_keys: %s" % excep) raise excep expirations = {} for ak in all_keys: expirations.update({ak['fingerprint']: ak['date']}) return expirations
def get_expirations(keylist): """ This function is not implemented in GPG object class because need to operate on the whole keys """ try: temp_gpgroot = os.path.join(GLSetting.gpgroot, "-expiration_check-%s" % xeger(r'[A-Za-z0-9]{8}')) os.makedirs(temp_gpgroot, mode=0700) gpexpire = GPG(gnupghome=temp_gpgroot, options=['--trust-model', 'always']) except Exception as excep: log.err("Unable to setup expiration check environment: %s" % excep) raise excep try: for key in keylist: gpexpire.import_keys(key) except Exception as excep: log.err("Error in GPG import_keys: %s" % excep) raise excep try: all_keys = gpexpire.list_keys() except Exception as excep: log.err("Error in GPG list_keys: %s" % excep) raise excep expirations = {} for ak in all_keys: expirations.update({ak['fingerprint']: ak['date']}) return expirations
def __init__(self, receiver_desc): """ every time is needed, a new keyring is created here. """ if receiver_desc.has_key('gpg_key_status') and \ receiver_desc['gpg_key_status'] != Receiver._gpg_types[1]: # Enabled log.err( "Requested GPG initialization for a receiver without GPG configured! %s" % receiver_desc['username']) raise Exception("Requested GPG init for user without GPG [%s]" % receiver_desc['username']) try: temp_gpgroot = os.path.join(GLSetting.gpgroot, "%s" % xeger(r'[A-Za-z0-9]{8}')) os.makedirs(temp_gpgroot, mode=0700) self.gpgh = GPG(gnupghome=temp_gpgroot, options=['--trust-model', 'always']) except Exception as excep: log.err("Unable to instance GPG object: %s" % excep) raise excep self.receiver_desc = receiver_desc log.debug("GPG object initialized for receiver %s" % receiver_desc['username'])
def __init__(self, user_id, user_role): self.user_role = user_role self.user_id = user_id tempobj.TempObj.__init__(self, GLSetting.sessions, rstr.xeger(r'[A-Za-z0-9]{42}'), GLSetting.defaults.lifetimes[user_role], reactor)
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_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 __init__(self, user_id, user_role, user_status): self.user_role = user_role self.user_id = user_id self.user_role = user_role self.user_status = user_status tempobj.TempObj.__init__(self, GLSetting.sessions, rstr.xeger(r'[A-Za-z0-9]{42}'), GLSetting.defaults.lifetimes[user_role], reactor)
def __init__(self, user_id, user_role, user_status): self.user_role = user_role self.user_id = user_id self.user_role = user_role self.user_status = user_status tempobj.TempObj.__init__(self, GLSettings.sessions, rstr.xeger(r'[A-Za-z0-9]{42}'), GLSettings.defaults.lifetimes[user_role], reactor_override)
def generate_example_receipt(regexp): """ @param regexp: @return: this function it's used to show to the Admin an example of the receipt_regexp configured, and if an error happen, it's works as validator. The exception is raised over and a default regexp is put """ return unicode(rstr.xeger(regexp))
def init_db(store, result, node_dict, appdata_dict): """ TODO refactor with languages the email_template, develop a dedicated function outside the node, and inquire f*****g YHWH about the callbacks existence/usage """ node = models.Node(node_dict) node.languages_enabled = GLSetting.defaults.languages_enabled node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) node.wizard_done = GLSetting.skip_wizard for k in appdata_dict['node']: setattr(node, k, appdata_dict['node'][k]) store.add(node) admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) admin_password = hash_password(u"globaleaks", admin_salt) admin_dict = { 'username': u'admin', 'password': admin_password, 'salt': admin_salt, 'role': u'admin', 'state': u'enabled', 'language': u"en", 'timezone': 0, 'password_change_needed': False, } admin = models.User(admin_dict) store.add(admin) notification = models.Notification() for k in appdata_dict['templates']: setattr(notification, k, appdata_dict['templates'][k]) store.add(notification)
def __init__(self): """ every time is needed, a new keyring is created here. """ try: temp_gpgroot = os.path.join(GLSetting.gpgroot, "%s" % xeger(r'[A-Za-z0-9]{8}')) os.makedirs(temp_gpgroot, mode=0700) self.gpgh = GPG(gnupghome=temp_gpgroot, options=['--trust-model', 'always']) self.gpgh.encoding = "UTF-8" except Exception as excep: log.err("Unable to instance GPG object: %s" % excep) raise excep
def __init__(self, token_kind, context_id): """ token_kind assumes currently only value 'submission. we plan to add other kinds like 'file'. """ if reactor_override: reactor = reactor_override else: reactor = None self.kind = token_kind # both 'validity' variables need to be expressed in seconds self.start_validity_secs = GLSettings.memory_copy.submission_minimum_delay self.end_validity_secs = GLSettings.memory_copy.submission_maximum_ttl # Remind: this is just for developers, because if a clean house # is a sign of a waste life, a Token object without shortcut # is a sign of a psycho life. (vecnish!) if GLSettings.devel_mode: self.start_validity_secs = 0 self.remaining_allowed_attempts = Token.MAXIMUM_ATTEMPTS_PER_TOKEN # creation_date of token assignment self.creation_date = datetime.utcnow() # in the future, difficulty can be trimmed on context basis too self.context_associated = context_id # to keep track of the file uploaded associated self.uploaded_files = [] self.token_id = rstr.xeger(r'[A-Za-z0-9]{42}') # initialization self.human_captcha = False self.graph_captcha = False self.proof_of_work = False TempObj.__init__(self, TokenList.token_dict, # token ID: self.token_id, # seconds of validity: self.start_validity_secs + self.end_validity_secs, reactor)
def __init__(self): """ every time is needed, a new keyring is created here. """ try: temp_pgproot = os.path.join(GLSettings.pgproot, "%s" % xeger(r'[A-Za-z0-9]{8}')) os.makedirs(temp_pgproot, mode=0700) self.pgph = GPG(gnupghome=temp_pgproot, options=['--trust-model', 'always']) self.pgph.encoding = "UTF-8" except OSError as ose: log.err("Critical, OS error in operating with GnuPG home: %s" % ose) raise except Exception as excep: log.err("Unable to instance PGP object: %s" % excep) raise
def init_db(store, result, node_dict, appdata_dict): """ """ node = models.Node(node_dict) node.languages_enabled = GLSettings.defaults.languages_enabled node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) node.wizard_done = GLSettings.skip_wizard for k in appdata_dict['node']: setattr(node, k, appdata_dict['node'][k]) store.add(node) admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) admin_password = hash_password(u"globaleaks", admin_salt) admin_dict = { 'username': u'admin', 'password': admin_password, 'salt': admin_salt, 'role': u'admin', 'state': u'enabled', 'mail_address': u'', 'language': u"en", 'timezone': 0, 'password_change_needed': False, } admin = models.User(admin_dict) store.add(admin) notification = models.Notification() for k in appdata_dict['templates']: setattr(notification, k, appdata_dict['templates'][k]) store.add(notification)
def encrypt_file(self, plainpath, filestream, output_path): """ @param gpg_key_armor: @param plainpath: @return: """ if not self.validate_key(self.receiver_desc['gpg_key_armor']): raise errors.GPGKeyInvalid encrypt_obj = self.gpgh.encrypt_file( filestream, str(self.receiver_desc['gpg_key_fingerprint'])) if not encrypt_obj.ok: # continue here if is not ok log.err("Falure in encrypting file %s %s (%s)" % (plainpath, self.receiver_desc['username'], self.receiver_desc['gpg_key_fingerprint'])) log.err(encrypt_obj.stderr) raise errors.GPGKeyInvalid log.debug("Encrypting for %s (%s) file %s (%d bytes)" % (self.receiver_desc['username'], self.receiver_desc['gpg_key_fingerprint'], plainpath, len(str(encrypt_obj)))) encrypted_path = os.path.join( os.path.abspath(output_path), "gpg_encrypted-%s" % xeger(r'[A-Za-z0-9]{8}')) if os.path.isfile(encrypted_path): log.err("Unexpected unpredictable unbelievable error! %s" % encrypted_path) raise errors.InternalServerError( "File conflict in GPG encrypted output") try: with open(encrypted_path, "w+") as f: f.write(str(encrypt_obj)) return encrypted_path, len(str(encrypt_obj)) except Exception as excep: log.err("Error in writing GPG file output: %s (%s) bytes %d" % (excep.message, encrypted_path, len(str(encrypt_obj)))) raise errors.InternalServerError("Error in writing [%s]" % excep.message)
def __init__(self, token_kind, uses=MAX_USES): """ token_kind assumes currently only value 'submission. we plan to add other kinds like 'file'. """ if reactor_override: reactor = reactor_override else: reactor = None self.kind = token_kind # both 'validity' variables need to be expressed in seconds self.start_validity_secs = GLSettings.memory_copy.submission_minimum_delay self.end_validity_secs = GLSettings.memory_copy.submission_maximum_ttl # Remind: this is just for developers, because if a clean house # is a sign of a waste life, a Token object without shortcut # is a sign of a psycho life. (vecnish!) if GLSettings.devel_mode: self.start_validity_secs = 0 self.remaining_uses = uses self.generate_token_challenge() # creation_date of token assignment self.creation_date = datetime.utcnow() # to keep track of the file uploaded associated self.uploaded_files = [] self.id = rstr.xeger(r'[A-Za-z0-9]{42}') TempObj.__init__( self, TokenList.token_dict, # token ID: self.id, # seconds of validity: self.start_validity_secs + self.end_validity_secs, reactor)
def generate_example_receipt(regexp): """ @param regexp: @return: this function it's used to show to the Admin an example of the receipt_regexp configured, and if an error happen, it's works as validator. """ Random.atfork() try: return_value_receipt = unicode(rstr.xeger(regexp)) except Exception as excep: log.err("Invalid receipt regexp: %s (%s)" % (regexp, excep) ) raise errors.InvalidReceiptRegexp return return_value_receipt
def db_create_whistleblower_tip(store, submission_desc): """ The plaintext receipt is returned only now, and then is stored hashed in the WBtip table """ wbtip = WhistleblowerTip() node = store.find(Node).one() return_value_receipt = unicode(rstr.xeger(node.receipt_regexp)) wbtip.receipt_hash = security.hash_password(return_value_receipt, node.receipt_salt) wbtip.access_counter = 0 wbtip.internaltip_id = submission_desc['id'] store.add(wbtip) return return_value_receipt
def db_create_whistleblower_tip(store, submission_desc): """ The plaintext receipt is returned only now, and then is stored hashed in the WBtip table """ wbtip = WhistleblowerTip() node = store.find(Node).one() receipt = unicode(rstr.xeger(GLSetting.receipt_regexp)) wbtip.receipt_hash = security.hash_password(receipt, node.receipt_salt) wbtip.access_counter = 0 wbtip.internaltip_id = submission_desc['id'] store.add(wbtip) return receipt
def __init__(self, token_kind, uses = MAX_USES): """ token_kind assumes currently only value 'submission. we plan to add other kinds like 'file'. """ if reactor_override: reactor = reactor_override else: reactor = None self.kind = token_kind # both 'validity' variables need to be expressed in seconds self.start_validity_secs = GLSettings.memory_copy.submission_minimum_delay self.end_validity_secs = GLSettings.memory_copy.submission_maximum_ttl # Remind: this is just for developers, because if a clean house # is a sign of a waste life, a Token object without shortcut # is a sign of a psycho life. (vecnish!) if GLSettings.devel_mode: self.start_validity_secs = 0 self.remaining_uses = uses self.generate_token_challenge() # creation_date of token assignment self.creation_date = datetime.utcnow() # to keep track of the file uploaded associated self.uploaded_files = [] self.id = rstr.xeger(r'[A-Za-z0-9]{42}') TempObj.__init__(self, TokenList.token_dict, # token ID: self.id, # seconds of validity: self.start_validity_secs + self.end_validity_secs, reactor)
def create_whistleblower_tip(store, submission_desc): """ The plaintext receipt is returned only now, and then is stored hashed in the WBtip table """ assert submission_desc is not None and submission_desc.has_key("id") wbtip = WhistleblowerTip() node = store.find(Node).one() return_value_receipt = unicode(rstr.xeger(node.receipt_regexp)) wbtip.receipt_hash = security.hash_password(return_value_receipt, node.receipt_salt) wbtip.access_counter = 0 wbtip.internaltip_id = submission_desc["id"] store.add(wbtip) return return_value_receipt
def __init__(self, receiver_desc): """ every time is needed, a new keyring is created here. """ if receiver_desc.has_key('gpg_key_status') and \ receiver_desc['gpg_key_status'] != Receiver._gpg_types[1]: # Enabled log.err("Requested GPG initialization for a receiver without GPG configured! %s" % receiver_desc['username']) raise Exception("Requested GPG init for user without GPG [%s]" % receiver_desc['username']) try: temp_gpgroot = os.path.join(GLSetting.gpgroot, "%s" % xeger(r'[A-Za-z0-9]{8}')) os.makedirs(temp_gpgroot, mode=0700) self.gpgh = GPG(gnupghome=temp_gpgroot, options=['--trust-model', 'always']) except Exception as excep: log.err("Unable to instance GPG object: %s" % excep) raise excep self.receiver_desc = receiver_desc log.debug("GPG object initialized for receiver %s" % receiver_desc['username'])
def encrypt_file(self, plainpath, filestream, output_path): """ @param gpg_key_armor: @param plainpath: @return: """ if not self.validate_key(self.receiver_desc['gpg_key_armor']): raise errors.GPGKeyInvalid encrypt_obj = self.gpgh.encrypt_file(filestream, str(self.receiver_desc['gpg_key_fingerprint'])) if not encrypt_obj.ok: # continue here if is not ok log.err("Falure in encrypting file %s %s (%s)" % ( plainpath, self.receiver_desc['username'], self.receiver_desc['gpg_key_fingerprint'])) log.err(encrypt_obj.stderr) raise errors.GPGKeyInvalid log.debug("Encrypting for %s (%s) file %s (%d bytes)" % (self.receiver_desc['username'], self.receiver_desc['gpg_key_fingerprint'], plainpath, len(str(encrypt_obj)))) encrypted_path = os.path.join(os.path.abspath(output_path), "gpg_encrypted-%s" % xeger(r'[A-Za-z0-9]{8}')) if os.path.isfile(encrypted_path): log.err("Unexpected unpredictable unbelievable error! %s" % encrypted_path) raise errors.InternalServerError("File conflict in GPG encrypted output") try: with open(encrypted_path, "w+") as f: f.write(str(encrypt_obj)) return encrypted_path, len(str(encrypt_obj)) except Exception as excep: log.err("Error in writing GPG file output: %s (%s) bytes %d" % (excep.message, encrypted_path, len(str(encrypt_obj)) )) raise errors.InternalServerError("Error in writing [%s]" % excep.message)
def generate_session(self, role, user_id): """ Args: role: can be either 'admin', 'wb' or 'receiver' user_id: will be in the case of the receiver the receiver.id in the case of an admin it will be set to 'admin', in the case of the 'wb' it will be the whistleblower id. """ self.session_id = rstr.xeger(r'[A-Za-z0-9]{42}') # This is the format to preserve sessions in memory # Key = session_id, values "last access" "id" "role" new_session = OD( refreshdate=utility.datetime_now(), id=self.session_id, role=role, user_id=user_id, expirydate=utility.get_future_epoch(seconds=GLSetting.defaults.lifetimes[role]) ) GLSetting.sessions[self.session_id] = new_session return self.session_id
def dump_file_fs(uploaded_file): """ @param files: a file @return: three variables: #0 a filepath linking the filename with the random filename saved in the disk #1 SHA256 checksum of the file #3 size in bytes of the files """ from Crypto.Random import atfork atfork() saved_name = rstr.xeger(r"[A-Za-z]{26}") filelocation = os.path.join(GLSetting.submission_path, saved_name) log.debug( "Start saving %d bytes from file [%s]" % (uploaded_file["body_len"], uploaded_file["filename"].encode("utf-8")) ) # checksum is computed here, because don't slow down the operation # enough to postpone in a scheduled job. # https://github.com/globaleaks/GlobaLeaks/issues/600 sha = SHA256.new() with open(filelocation, "w+") as fd: uploaded_file["body"].seek(0, 0) data = uploaded_file["body"].read() # 4kb total_length = 0 while data != "": total_length = total_length + len(data) sha.update(data) os.write(fd.fileno(), data) data = uploaded_file["body"].read(4096) # 4kb return (saved_name, sha.hexdigest(), total_length)
def create_whistleblower_tip(store, submission_desc): """ The plaintext receipt is returned only now, and then is stored hashed in the WBtip table """ from Crypto import Random Random.atfork() assert submission_desc is not None and submission_desc.has_key('id') wbtip = WhistleblowerTip() context = store.find(Context, Context.id == submission_desc['context_gus']).one() return_value_receipt = unicode( rstr.xeger(context.receipt_regexp) ) node = store.find(Node).one() wbtip.receipt_hash = security.hash_password(return_value_receipt, node.receipt_salt) wbtip.access_counter = 0 wbtip.internaltip_id = submission_desc['id'] store.add(wbtip) return return_value_receipt
def migrate_InternalFile(self): print "%s InternalFile migration assistant" % self.std_fancy old_objs = self.store_old.find(self.get_right_model( "InternalFile", 22)) for old_obj in old_objs: new_obj = self.get_right_model("InternalFile", 23)() for _, v in new_obj._storm_columns.iteritems(): if v.name == 'processing_attempts': new_obj.processing_attempts = 0 continue if v.name == 'file_path': new_obj.file_path = os.path.join( GLSettings.submission_path, "%s.aes" % xeger(r'[A-Za-z0-9]{16}')) continue setattr(new_obj, v.name, getattr(old_obj, v.name)) self.store_new.add(new_obj) self.store_new.commit()
def initialize_node(store, results, only_node, appdata): """ TODO refactor with languages the email_template, develop a dedicated function outside the node, and inquire f*****g YHWH about the callbacks existence/usage """ node = models.Node(only_node) log.debug("Inizializing ApplicationData") new_appdata = ApplicationData() new_appdata.fields = appdata['fields'] new_appdata.version = appdata['version'] store.add(new_appdata) for k in appdata['node']: setattr(node, k, appdata['node'][k]) node.languages_enabled = GLSetting.defaults.languages_enabled node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) node.wizard_done = GLSetting.skip_wizard node.creation_date = datetime_now() store.add(node) admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) admin_password = hash_password(u"globaleaks", admin_salt) admin_dict = { 'username': u'admin', 'password': admin_password, 'salt': admin_salt, 'role': u'admin', 'state': u'enabled', 'language': u"en", 'timezone': 0, 'password_change_needed': False, } admin = models.User(admin_dict) admin.last_login = datetime_null() admin.password_change_date = datetime_null() store.add(admin) notification = models.Notification() # our defaults for free, because we're like Gandhi of the mail accounts. notification.server = "mail.headstrong.de" notification.port = 587 # port 587/SMTP-TLS or 465/SMTPS notification.username = "******" notification.password = "******" notification.security = "TLS" notification.source_name = "Default GlobaLeaks sender" notification.source_email = notification.username # Those fields are sets as default in order to show to the Admin the various # 'variables' used in the template. for k in appdata['templates']: # Todo handle pgp_expiration_alert and pgp_expiration_notice already included in client/app/data/txt # and internationalized with right support on backend db. if k in appdata['templates']: setattr(notification, k, appdata['templates'][k]) # Todo handle pgp_expiration_alert and pgp_expiration_notice already included in client/app/data/txt # and internationalized with right support on backend db. store.add(notification)
def initialize_node(store, results, only_node, templates, appdata): """ TODO refactor with languages the email_template, develop a dedicated function outside the node, and inquire f*****g YHWH about the callbacks existence/usage """ node = models.Node(only_node) log.debug("Inizializing ApplicationData") new_appdata = ApplicationData() new_appdata.fields = appdata['fields'] new_appdata.version = appdata['version'] store.add(new_appdata) if 'node_presentation' in appdata: node.presentation = appdata['node_presentation'] if 'node_footer' in appdata: node.footer = appdata['node_footer'] if 'node_subtitle' in appdata: node.subtitle = appdata['node_subtitle'] node.languages_enabled = GLSetting.defaults.languages_enabled node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) node.wizard_done = GLSetting.skip_wizard node.creation_date = datetime_now() store.add(node) admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) admin_password = hash_password(u"globaleaks", admin_salt) admin_dict = { 'username': u'admin', 'password': admin_password, 'salt': admin_salt, 'role': u'admin', 'state': u'enabled', } admin = models.User(admin_dict) admin.last_login = datetime_null() store.add(admin) notification = models.Notification() # our defaults for free, because we're like Gandhi of the mail accounts. notification.server = "mail.headstrong.de" notification.port = 587 # port 587/SMTP-TLS or 465/SMTPS notification.username = "******" notification.password = "******" notification.security = "TLS" notification.source_name = "Default GlobaLeaks sender" notification.source_email = notification.username # Those fields are sets as default in order to show to the Admin the various # 'variables' used in the template. notification.encrypted_tip_template = { GLSetting.memory_copy.default_language: templates['encrypted_tip'] } notification.encrypted_tip_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new Tip (Encrypted)" } notification.plaintext_tip_template = { GLSetting.memory_copy.default_language: templates['plaintext_tip'] } notification.plaintext_tip_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new ClearText" } notification.encrypted_message_template = { GLSetting.memory_copy.default_language: templates['encrypted_message'] } notification.encrypted_message_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message (Encrypted)" } notification.plaintext_message_template = { GLSetting.memory_copy.default_language: templates['plaintext_message'] } notification.plaintext_message_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message" } notification.encrypted_file_template = { GLSetting.memory_copy.default_language: templates['encrypted_file'] } notification.encrypted_file_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached (Encrypted)" } notification.plaintext_file_template = { GLSetting.memory_copy.default_language: templates['plaintext_file'] } notification.plaintext_file_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached" } notification.encrypted_comment_template = { GLSetting.memory_copy.default_language: templates['encrypted_comment'] } notification.encrypted_comment_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment (Encrypted)" } notification.plaintext_comment_template = { GLSetting.memory_copy.default_language: templates['plaintext_comment'] } notification.plaintext_comment_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment" } notification.zip_description = { GLSetting.memory_copy.default_language: templates['zip_collection'] } store.add(notification)
def migrate_InternalFile(self): print "%s InternalFile migration assistant" % self.std_fancy old_objs = self.store_old.find(self.get_right_model("InternalFile", 22)) for old_obj in old_objs: new_obj = self.get_right_model("InternalFile", 23)() for _, v in new_obj._storm_columns.iteritems(): if v.name == 'processing_attempts': new_obj.processing_attempts = 0 continue if v.name == 'file_path': new_obj.file_path = os.path.join(GLSettings.submission_path, "%s.aes" % xeger(r'[A-Za-z0-9]{16}')) continue setattr(new_obj, v.name, getattr(old_obj, v.name)) self.store_new.add(new_obj) self.store_new.commit()
def initialize_node(store, results, only_node, email_templates): """ TODO refactor with languages the email_template, develop a dedicated function outside the node, and inquire f*****g YHWH about the callbacks existence/usage """ from Crypto import Random Random.atfork() node = models.Node(only_node) # by default, only english is the surely present language node.languages_enabled = GLSetting.defaults.languages_enabled node.receipt_salt = get_salt(rstr.xeger("[A-Za-z0-9]{56}")) node.creation_date = datetime_now() store.add(node) admin_salt = get_salt(rstr.xeger("[A-Za-z0-9]{56}")) admin_password = hash_password(u"globaleaks", admin_salt) admin_dict = { "username": u"admin", "password": admin_password, "salt": admin_salt, "role": u"admin", "state": u"enabled", "failed_login_count": 0, } admin = models.User(admin_dict) admin.last_login = datetime_null() store.add(admin) notification = models.Notification() # our defaults for free, because we're like Gandhi of the mail accounts. notification.server = "mail.headstrong.de" notification.port = 587 # port 587/SMTP-TLS or 465/SMTPS notification.username = "******" notification.password = "******" notification.security = "TLS" notification.source_name = "Default GlobaLeaks sender" notification.source_email = notification.username # Those fields are sets as default in order to show to the Admin the various 'variables' # used in the template. notification.tip_template = {GLSetting.memory_copy.default_language: email_templates["tip"]} notification.tip_mail_title = {GLSetting.memory_copy.default_language: "From %NodeName% a new Tip"} notification.file_template = {GLSetting.memory_copy.default_language: email_templates["file"]} notification.file_mail_title = { GLSetting.memory_copy.default_language: "From %NodeName% a new file appended to a tip" } notification.comment_template = {GLSetting.memory_copy.default_language: email_templates["comment"]} notification.comment_mail_title = {GLSetting.memory_copy.default_language: "From %NodeName% a new comment"} notification.activation_template = {GLSetting.memory_copy.default_language: "*Not Yet implemented*"} notification.activation_mail_title = {GLSetting.memory_copy.default_language: "**Not Yet implemented"} store.add(notification)
def db_create_receiver(store, request, language=GLSetting.memory_copy.default_language): """ Creates a new receiver. Returns: (dict) the configured receiver """ mo = structures.Rosetta() mo.acquire_request(language, request, Receiver) for attr in mo.get_localized_attrs(): request[attr] = mo.get_localized_dict(attr) mail_address = request['mail_address'] # Pretend that username is unique: homonymous = store.find(User, User.username == mail_address).count() if homonymous: log.err("Creation error: already present receiver with the requested username: %s" % mail_address) raise errors.ExpectedUniqueField('mail_address', mail_address) password = request.get('password') security.check_password_format(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': mail_address, 'password': receiver_password, 'salt': receiver_salt, 'role': u'receiver', 'state': u'enabled', } receiver_user = models.User(receiver_user_dict) receiver_user.last_login = datetime_null() store.add(receiver_user) receiver = Receiver(request) receiver.user = receiver_user receiver.mail_address = mail_address receiver.tags = request['tags'] # 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 = store.find(Context, Context.id == context_id).one() 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 operation(self): """ Goal of this function is to process/validate files, compute their checksums and apply the configured delivery method. """ try: # ==> Submission && Escalation info_created_tips = yield tip_creation() if info_created_tips: log.debug("Delivery job: created %d tips" % len(info_created_tips)) except Exception as excep: log.err("Exception in asyncronous delivery job: %s" % excep) sys.excepthook(*sys.exc_info()) # ==> Files && Files update, # InternalFile is set as 'locked' status # and would be unlocked at the end. # TODO xxx limit of file number per operation filemap = yield receiverfile_planning() # the function returns a dict of lists with dicts: # { # 'ifile_path' : [ # { 'receiver' : receiver_desc, 'path': file_path, # 'size' : file_size, 'status': XXX }, # { 'receiver' : receiver_desc, 'path': file_path, # 'size' : file_size, 'status': YYY }, ... ] # }, { }, ... # if not filemap: return # Here the files received are encrypted (if the receiver has PGP key) log.debug("Delivery task: Iterate over %d ReceiverFile(s)" % len(filemap.keys())) for ifile_path, receivermap in filemap.iteritems(): plain_path = os.path.join(GLSetting.submission_path, "%s.plain" % xeger(r'[A-Za-z0-9]{16}')) create_plaintextfile = encrypt_where_available(receivermap) for rfileinfo in receivermap: if not create_plaintextfile and rfileinfo[ 'status'] == u'reference': rfileinfo['path'] = plain_path try: yield receiverfile_create(ifile_path, rfileinfo['path'], rfileinfo['status'], rfileinfo['size'], rfileinfo['receiver']) except Exception as excep: log.err( "Unable to create ReceiverFile from %s for %s: %s" % (ifile_path, rfileinfo['receiver']['name'], excep)) continue if not create_plaintextfile: log.debug( ":( NOT all receivers support PGP and the system allows plaintext version of files: %s saved in plaintext file %s" % (ifile_path, plain_path)) try: with open(plain_path, "wb") as plain_f_is_sad_f, \ GLSecureFile(ifile_path) as encrypted_file: chunk_size = 4096 while True: chunk = encrypted_file.read(chunk_size) if len(chunk) == 0: break plain_f_is_sad_f.write(chunk) yield do_final_internalfile_update(ifile_path, u'ready', plain_path) except Exception as excep: log.err("Unable to create plaintext file %s: %s" % (plain_path, excep)) else: # create_plaintextfile log.debug( "All Receivers support PGP or the system denys plaintext version of files: marking internalfile as removed" ) yield do_final_internalfile_update(ifile_path, u'delivered') # Removed # the original AES file need always to be deleted log.debug("Deleting the submission AES encrypted file: %s" % ifile_path) try: os.remove(ifile_path) except OSError as ose: log.err("Unable to remove %s: %s" % (ifile_path, ose.message)) try: key_id = os.path.basename(ifile_path).split('.')[0] keypath = os.path.join( GLSetting.ramdisk_path, ("%s%s" % (GLSetting.AES_keyfile_prefix, key_id))) os.remove(keypath) except Exception as excep: log.err("Unable to remove keyfile associated with %s: %s" % (ifile_path, excep))
def init_db(store, result, node_dict, appdata_dict): """ TODO refactor with languages the email_template, develop a dedicated function outside the node, and inquire f*****g YHWH about the callbacks existence/usage """ node = models.Node(node_dict) for k in appdata_dict['node']: setattr(node, k, appdata_dict['node'][k]) node.languages_enabled = GLSetting.defaults.languages_enabled node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) node.wizard_done = GLSetting.skip_wizard node.creation_date = datetime_now() store.add(node) admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) admin_password = hash_password(u"globaleaks", admin_salt) admin_dict = { 'username': u'admin', 'password': admin_password, 'salt': admin_salt, 'role': u'admin', 'state': u'enabled', 'language': u"en", 'timezone': 0, 'password_change_needed': False, } admin = models.User(admin_dict) admin.last_login = datetime_null() admin.password_change_date = datetime_null() store.add(admin) notification = models.Notification() # our defaults for free, because we're like Gandhi of the mail accounts. notification.server = "mail.headstrong.de" notification.port = 587 # port 587/SMTP-TLS or 465/SMTPS notification.username = "******" notification.password = "******" notification.security = "TLS" notification.source_name = "Default GlobaLeaks sender" notification.source_email = notification.username # Those fields are sets as default in order to show to the Admin the various # 'variables' used in the template. for k in appdata_dict['templates']: setattr(notification, k, appdata_dict['templates'][k]) store.add(notification)
def operation(self): """ Goal of this function is to process/validate files, compute their checksums and apply the configured delivery method. """ try: # ==> Submission && Escalation info_created_tips = yield tip_creation() if info_created_tips: log.debug("Delivery job: created %d tips" % len(info_created_tips)) except Exception as excep: log.err("Exception in asyncronous delivery job: %s" % excep ) sys.excepthook(*sys.exc_info()) # ==> Files && Files update, # InternalFile is set as 'locked' status # and would be unlocked at the end. # TODO xxx limit of file number per operation filemap = yield receiverfile_planning() # the function returns a dict of lists with dicts: # { # 'ifile_path' : [ # { 'receiver' : receiver_desc, 'path': file_path, # 'size' : file_size, 'status': XXX }, # { 'receiver' : receiver_desc, 'path': file_path, # 'size' : file_size, 'status': YYY }, ... ] # }, { }, ... # if not filemap: return # Here the files received are encrypted (if the receiver has PGP key) log.debug("Delivery task: Iterate over %d ReceiverFile(s)" % len(filemap.keys()) ) for ifile_path, receivermap in filemap.iteritems(): plain_path = os.path.join(GLSetting.submission_path, "%s.plain" % xeger(r'[A-Za-z0-9]{16}') ) create_plaintextfile = encrypt_where_available(receivermap) for rfileinfo in receivermap: if not create_plaintextfile and rfileinfo['status'] == u'reference': rfileinfo['path'] = plain_path try: yield receiverfile_create(ifile_path, rfileinfo['path'], rfileinfo['status'], rfileinfo['size'], rfileinfo['receiver']) except Exception as excep: log.err("Unable to create ReceiverFile from %s for %s: %s" % (ifile_path, rfileinfo['receiver']['name'], excep)) continue if not create_plaintextfile: log.debug(":( NOT all receivers support PGP and the system allows plaintext version of files: %s saved in plaintext file %s" % (ifile_path, plain_path) ) try: with open(plain_path, "wb") as plain_f_is_sad_f, \ GLSecureFile(ifile_path) as encrypted_file: chunk_size = 4096 while True: chunk = encrypted_file.read(chunk_size) if len(chunk) == 0: break plain_f_is_sad_f.write(chunk) yield do_final_internalfile_update(ifile_path, u'ready', plain_path) except Exception as excep: log.err("Unable to create plaintext file %s: %s" % (plain_path, excep)) else: # create_plaintextfile log.debug("All Receivers support PGP or the system denys plaintext version of files: marking internalfile as removed") yield do_final_internalfile_update(ifile_path, u'delivered') # Removed # the original AES file need always to be deleted log.debug("Deleting the submission AES encrypted file: %s" % ifile_path) try: os.remove(ifile_path) except OSError as ose: log.err("Unable to remove %s: %s" % (ifile_path, ose.message)) try: key_id = os.path.basename(ifile_path).split('.')[0] keypath = os.path.join(GLSetting.ramdisk_path, ("%s%s" % (GLSetting.AES_keyfile_prefix, key_id))) os.remove(keypath) except Exception as excep: log.err("Unable to remove keyfile associated with %s: %s" % (ifile_path, excep))
def test_xeger(self): assert re.match(r'^foo[\d]{10}bar$', rstr.xeger('^foo[\d]{10}bar$'))
from globaleaks.jobs import statistics_sched, mailflush_sched from globaleaks.models import db_forge_obj, ReceiverTip, ReceiverFile, WhistleblowerTip, InternalTip from globaleaks.rest.apicache import GLApiCache from globaleaks.settings import GLSettings, transact, transact_ro from globaleaks.security import GLSecureTemporaryFile from globaleaks.third_party import rstr from globaleaks.utils import token from globaleaks.utils.structures import fill_localized_keys from globaleaks.utils.utility import datetime_null, log from . import TEST_DIR ## constants VALID_PASSWORD1 = u'justapasswordwithaletterandanumberandbiggerthan8chars' VALID_PASSWORD2 = u'justap455w0rdwithaletterandanumberandbiggerthan8chars' VALID_SALT1 = security.get_salt(rstr.xeger(r'[A-Za-z0-9]{56}')) VALID_SALT2 = security.get_salt(rstr.xeger(r'[A-Za-z0-9]{56}')) VALID_HASH1 = security.hash_password(VALID_PASSWORD1, VALID_SALT1) VALID_HASH2 = security.hash_password(VALID_PASSWORD2, VALID_SALT2) INVALID_PASSWORD = u'antani' FIXTURES_PATH = os.path.join(TEST_DIR, 'fixtures') with open(os.path.join(TEST_DIR, 'keys/valid_pgp_key1.txt')) as pgp_file: VALID_PGP_KEY1 = unicode(pgp_file.read()) with open(os.path.join(TEST_DIR, 'keys/valid_pgp_key2.txt')) as pgp_file: VALID_PGP_KEY2 = unicode(pgp_file.read()) with open(os.path.join(TEST_DIR, 'keys/expired_pgp_key.txt')) as pgp_file: EXPIRED_PGP_KEY = unicode(pgp_file.read())
def db_create_receiver(store, request, language=GLSetting.memory_copy.default_language): """ Creates a new receiver. Returns: (dict) the configured receiver """ mo = structures.Rosetta() mo.acquire_request(language, request, Receiver) for attr in mo.get_localized_attrs(): request[attr] = mo.get_localized_dict(attr) mail_address = request['mail_address'] # Pretend that username is unique: homonymous = store.find(User, User.username == mail_address).count() if homonymous: log.err( "Creation error: already present receiver with the requested username: %s" % mail_address) raise errors.ExpectedUniqueField('mail_address', mail_address) password = request.get('password') security.check_password_format(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': mail_address, 'password': receiver_password, 'salt': receiver_salt, 'role': u'receiver', 'state': u'enabled', } receiver_user = models.User(receiver_user_dict) receiver_user.last_login = datetime_null() store.add(receiver_user) receiver = Receiver(request) receiver.user = receiver_user receiver.mail_address = mail_address receiver.tags = request['tags'] # 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 = store.find(Context, Context.id == context_id).one() 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 initialize_node(store, results, only_node, templates, appdata): """ TODO refactor with languages the email_template, develop a dedicated function outside the node, and inquire f*****g YHWH about the callbacks existence/usage """ node = models.Node(only_node) log.debug("Inizializing ApplicationData") new_appdata = ApplicationData() new_appdata.fields = appdata['fields'] new_appdata.version = appdata['version'] store.add(new_appdata) if 'node_presentation' in appdata: node.presentation = appdata['node_presentation'] if 'node_footer' in appdata: node.footer = appdata['node_footer'] if 'node_subtitle' in appdata: node.subtitle = appdata['node_subtitle'] node.languages_enabled = GLSetting.defaults.languages_enabled node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) node.wizard_done = GLSetting.skip_wizard node.creation_date = datetime_now() store.add(node) admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}')) admin_password = hash_password(u"globaleaks", admin_salt) admin_dict = { 'username': u'admin', 'password': admin_password, 'salt': admin_salt, 'role': u'admin', 'state': u'enabled', } admin = models.User(admin_dict) admin.last_login = datetime_null() store.add(admin) notification = models.Notification() # our defaults for free, because we're like Gandhi of the mail accounts. notification.server = "mail.headstrong.de" notification.port = 587 # port 587/SMTP-TLS or 465/SMTPS notification.username = "******" notification.password = "******" notification.security = "TLS" notification.source_name = "Default GlobaLeaks sender" notification.source_email = notification.username # Those fields are sets as default in order to show to the Admin the various # 'variables' used in the template. notification.encrypted_tip_template = { GLSetting.memory_copy.default_language: templates['encrypted_tip'] } notification.encrypted_tip_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new Tip (Encrypted)" } notification.plaintext_tip_template= { GLSetting.memory_copy.default_language: templates['plaintext_tip'] } notification.plaintext_tip_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new ClearText" } notification.encrypted_message_template = { GLSetting.memory_copy.default_language: templates['encrypted_message'] } notification.encrypted_message_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message (Encrypted)" } notification.plaintext_message_template = { GLSetting.memory_copy.default_language: templates['plaintext_message'] } notification.plaintext_message_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message" } notification.encrypted_file_template = { GLSetting.memory_copy.default_language: templates['encrypted_file'] } notification.encrypted_file_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached (Encrypted)" } notification.plaintext_file_template = { GLSetting.memory_copy.default_language: templates['plaintext_file'] } notification.plaintext_file_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached" } notification.encrypted_comment_template = { GLSetting.memory_copy.default_language: templates['encrypted_comment'] } notification.encrypted_comment_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment (Encrypted)" } notification.plaintext_comment_template = { GLSetting.memory_copy.default_language: templates['plaintext_comment'] } notification.plaintext_comment_mail_title = { GLSetting.memory_copy.default_language: "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment" } notification.zip_description = { GLSetting.memory_copy.default_language: templates['zip_collection'] } store.add(notification)
def db_create_receiver(store, request, language=GLSetting.memory_copy.default_language): """ Creates a new receiver. Returns: (dict) the configured receiver """ fill_localized_keys(request, models.Receiver.localized_strings, language) mail_address = request['mail_address'] # Pretend that username is unique: homonymous = store.find(models.User, models.User.username == mail_address).count() if homonymous: log.err("Creation error: already present receiver with the requested username: %s" % mail_address) raise errors.ExpectedUniqueField('mail_address', mail_address) 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': mail_address, '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_needed = request['password_change_needed'] receiver_user.password_change_date = datetime_null() store.add(receiver_user) receiver = models.Receiver(request) receiver.user = receiver_user receiver.mail_address = mail_address # 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)