def db_gen_user_keys(session, tid, user, password): """ Transaction generating and saving user keys :param session: An ORM session :param tid: A tenant ID :param user: A user object :param password: A user's password :return: A private key generated for the user """ enc_key = GCE.derive_key(password.encode(), user.salt) crypto_prv_key, user.crypto_pub_key = GCE.generate_keypair() user.crypto_bkp_key, user.crypto_rec_key = GCE.generate_recovery_key( crypto_prv_key) user.crypto_prv_key = Base64Encoder.encode( GCE.symmetric_encrypt(enc_key, crypto_prv_key)) # Create an escrow backup for the root tenant tid_1_escrow = config.ConfigFactory(session, 1).get_val('crypto_escrow_pub_key') if tid_1_escrow: user.crypto_escrow_bkp1_key = Base64Encoder.encode( GCE.asymmetric_encrypt(tid_1_escrow, crypto_prv_key)) # Create an escrow backup for the actual tenant tid_n_escrow = config.ConfigFactory(session, tid).get_val('crypto_escrow_pub_key') if tid_n_escrow: user.crypto_escrow_bkp2_key = Base64Encoder.encode( GCE.asymmetric_encrypt(tid_n_escrow, crypto_prv_key)) return crypto_prv_key
def signup(session, state, tid, request, language): node = config.ConfigFactory(session, 1, 'node') if not node.get_val(u'enable_signup'): raise errors.ForbiddenOperation request['activation_token'] = generateRandomKey(32) request['language'] = language signup = models.Signup(request) session.add(signup) ret = { 'signup': serialize_signup(signup), 'activation_url': 'https://%s/#/activation?token=%s' % (node.get_val(u'rootdomain'), signup.activation_token), 'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=7)) } template_vars = copy.deepcopy(ret) template_vars.update({ 'type': 'signup', 'node': db_admin_serialize_node(session, 1, language), 'notification': db_get_notification(session, 1, language), }) state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars) return ret
def signup_activation(session, state, tid, token, language): node = config.ConfigFactory(session, 1, 'node') if not node.get_val(u'enable_signup'): raise errors.ForbiddenOperation signup = session.query(models.Signup).filter( models.Signup.activation_token == token).one_or_none() if signup is None: return {} if not session.query( models.Config).filter(models.Config.tid == signup.tid).count(): tenant = session.query( models.Tenant).filter(models.Tenant.id == signup.tid).one() mode = node.get_val('mode') db_initialize_tenant(session, tenant, mode) password_admin = generateRandomKey(16) password_recipient = generateRandomKey(16) node_name = signup.organization_name if signup.organization_name else signup.subdomain wizard = { 'node_language': signup.language, 'node_name': node_name, 'admin_name': signup.name + ' ' + signup.surname, 'admin_password': password_admin, 'admin_mail_address': signup.email, 'receiver_name': signup.name + ' ' + signup.surname, 'receiver_password': password_recipient, 'receiver_mail_address': signup.email, 'profile': 'default', 'enable_developers_exception_notification': True } db_wizard(session, state, signup.tid, wizard, False, language) ids = [ r[0] for r in session.query(models.User.id).filter( models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == signup.tid) ] template_vars = { 'type': 'activation', 'node': db_admin_serialize_node(session, 1, language), 'notification': db_get_notification(session, 1, language), 'signup': serialize_signup(signup), 'password_admin': password_admin, 'password_recipient': password_recipient } state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars) db_refresh_memory_variables(session, [1])
def transaction(session): # Rename 'name' variable with the effect of: # - simuulating missing variable # - simulating the presence of a variable not anymore defined session.query(models.Config).filter(models.Config.tid == 1, models.Config.var_name==u'name').one().var_name=u'removed' # Delete a variable that requires initialization via a constructor session.query(models.Config).filter(models.Config.tid == 1, models.Config.var_name==u'receipt_salt').delete() config.ConfigFactory(session, 1).update_defaults()
def signup_activation(session, state, tid, token, language): node = config.ConfigFactory(session, 1, 'node') if not node.get_val(u'enable_signup'): raise errors.ForbiddenOperation signup = session.query(models.Signup).filter(models.Signup.activation_token == token).one_or_none() if signup is None: return {} if signup.tid is None: signup.tid = db_create_tenant(session, {'label': signup.subdomain, 'subdomain': signup.subdomain}).id wizard = { 'node_name': signup.subdomain, 'admin_name': signup.name + ' ' + signup.surname, 'admin_password': '', 'admin_mail_address': signup.email, 'receiver_name': signup.name + ' ' + signup.surname, 'receiver_mail_address': signup.email, 'profile': 'default', 'enable_developers_exception_notification': True } db_wizard(session, state, signup.tid, wizard, False, language) template_vars = { 'type': 'activation', 'node': db_admin_serialize_node(session, 1, language), 'notification': db_get_notification(session, 1, language), 'signup': serialize_signup(signup), 'activation_url': '', 'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=7)) } state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars) if session.query(models.Tenant).filter(models.Tenant.id == signup.tid).one_or_none() is not None: admin = session.query(models.User).filter(models.User.tid == signup.tid, models.User.role == u'admin').one() admin.password_change_needed = False recipient = session.query(models.User).filter(models.User.tid == signup.tid, models.User.role == u'receiver').one() recipient.password_change_needed = False return { 'platform_url': 'https://%s.%s' % (signup.subdomain, node.get_val(u'rootdomain')), 'login_url': 'https://%s.%s/#/login' % (signup.subdomain, node.get_val(u'rootdomain')), 'admin_login_url': 'https://%s.%s/#/login?token=%s' % (signup.subdomain, node.get_val(u'rootdomain'), admin.auth_token), 'recipient_login_url': 'https://%s.%s/#/login?token=%s' % (signup.subdomain, node.get_val(u'rootdomain'), recipient.auth_token), 'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=7)) } else: return {}
def signup(session, state, tid, request, language): node = config.ConfigFactory(session, 1, 'node') if not node.get_val(u'enable_signup'): raise errors.ForbiddenOperation request['activation_token'] = generateRandomKey(32) request['language'] = language tenant_id = db_preallocate_tenant(session, { 'label': request['subdomain'], 'subdomain': request['subdomain'] }).id signup = models.Signup(request) signup.tid = tenant_id session.add(signup) # We need to send two emails # # The first one is sent to the platform owner with the activation email. # # The second goes to the instance administrators notifying them that a new # platform has been added. signup_dict = serialize_signup(signup) # Email 1 - Activation Link template_vars = { 'type': 'signup', 'node': db_admin_serialize_node(session, 1, language), 'notification': db_get_notification(session, 1, language), 'signup': signup_dict } state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars) # Email 2 - Admin Notification for user_desc in db_get_admin_users(session, 1): template_vars = { 'type': 'admin_signup_alert', 'signup': serialize_signup(signup), 'node': db_admin_serialize_node(session, 1, user_desc['language']), 'notification': db_get_notification(session, 1, user_desc['language']), 'user': user_desc, 'signup': signup_dict } state.format_and_send_mail(session, 1, user_desc, template_vars)
def perform_data_update(db_file): """ Update the database including up-to-date application data :param db_file: The database file path """ now = datetime_now() appdata = load_appdata() session = get_session(make_db_uri(db_file), foreign_keys=False) enabled_languages = [ lang.name for lang in session.query(models.EnabledLanguage) ] removed_languages = list( set(enabled_languages) - set(LANGUAGES_SUPPORTED_CODES)) if removed_languages: removed_languages.sort() removed_languages = ', '.join(removed_languages) raise Exception( "FATAL: cannot complete the upgrade because the support for some of the enabled languages is currently incomplete (%s)\n" % removed_languages) try: if config.ConfigFactory(session, 1).get_val('version') != __version__: session.query(models.Config).filter_by(var_name = 'version') \ .update({'value': __version__, 'update_date': now}) session.query(models.Config).filter_by(var_name = 'latest_version') \ .update({'value': __version__, 'update_date': now}) session.query(models.Config).filter_by(var_name = 'version_db') \ .update({'value': DATABASE_VERSION, 'update_date': now}) for tid in [t[0] for t in session.query(models.Tenant.id)]: config.update_defaults(session, tid, appdata) db_load_defaults(session) session.commit() except: session.rollback() raise finally: session.close()
def perform_data_update(db_file): """ Update the database including up-to-date application data :param db_file: The database file path """ session = get_session(make_db_uri(db_file), foreign_keys=False) enabled_languages = [ lang.name for lang in session.query(models.EnabledLanguage) ] removed_languages = list( set(enabled_languages) - set(LANGUAGES_SUPPORTED_CODES)) if removed_languages: removed_languages.sort() removed_languages = ', '.join(removed_languages) raise Exception( "FATAL: cannot complete the upgrade because the support for some of the enabled languages is currently incomplete (%s)\n" "Read about how to handle this condition at: https://github.com/globaleaks/GlobaLeaks/wiki/Upgrade-Guide#lang-drop" % removed_languages) try: cfg = config.ConfigFactory(session, 1) stored_ver = cfg.get_val('version') if stored_ver != __version__: # The below commands can change the current store based on the what is # currently stored in the DB. for tid in [t[0] for t in session.query(models.Tenant.id)]: appdata = load_appdata() config.update_defaults(session, tid, appdata) db_load_defaults(session) cfg.set_val('version', __version__) cfg.set_val('latest_version', __version__) cfg.set_val('version_db', DATABASE_VERSION) session.commit() except: session.rollback() raise finally: session.close()
def get_salt(session, tid): return config.ConfigFactory(session, tid, 'node').get_val(u'receipt_salt')
def enable_signup(session): config.ConfigFactory(session, 1, 'node').set_val(u'enable_signup', True)
def db_wizard(session, state, tid, request, client_using_tor, language): node = config.ConfigFactory(session, tid, 'node') if node.get_val(u'wizard_done'): log.err("DANGER: Wizard already initialized!", tid=tid) raise errors.ForbiddenOperation db_update_enabled_languages(session, tid, [language], language) tenant = models.db_get(session, models.Tenant, models.Tenant.id == tid) tenant.label = request['node_name'] node.set_val(u'name', request['node_name']) node.set_val(u'default_language', language) node.set_val(u'wizard_done', True) node.set_val(u'enable_developers_exception_notification', request['enable_developers_exception_notification']) # Guess Tor configuration from thee media used on first configuration and # if the user is using Tor preserve node anonymity and perform outgoing connections via Tor node.set_val(u'reachable_via_web', not client_using_tor) node.set_val(u'allow_unencrypted', not client_using_tor) node.set_val(u'anonymize_outgoing_connections', client_using_tor) node.set_val(u'disable_encryption_warnings', not client_using_tor) node_l10n = config.NodeL10NFactory(session, tid) node_l10n.set_val(u'header_title_homepage', language, request['node_name']) profiles.load_profile(session, tid, request['profile']) receiver_desc = models.User().dict(language) receiver_desc['name'] = request['receiver_name'] receiver_desc['username'] = u'recipient' receiver_desc['name'] = request['receiver_name'] receiver_desc['mail_address'] = request['receiver_mail_address'] receiver_desc['language'] = language receiver_desc['role'] = u'receiver' receiver_desc['deletable'] = True receiver_desc['pgp_key_remove'] = False _, receiver = db_create_receiver_user(session, state, tid, receiver_desc, language) context_desc = models.Context().dict(language) context_desc['name'] = u'Default' context_desc['receivers'] = [receiver.id] db_create_context(session, state, tid, context_desc, language) admin_desc = models.User().dict(language) admin_desc['name'] = request['admin_name'] admin_desc['username'] = u'admin' admin_desc['password'] = request['admin_password'] admin_desc['name'] = request['admin_name'] admin_desc['mail_address'] = request['admin_mail_address'] admin_desc['language'] = language admin_desc['role'] = u'admin' admin_desc['deletable'] = False admin_desc['pgp_key_remove'] = False admin_desc['password_change_needed'] = False db_create_user(session, state, tid, admin_desc, language) db_refresh_memory_variables(session, [tid])
def db_wizard(session, tid, hostname, request): """ Transaction for the handling of wizard request :param session: An ORM session :param tid: A tenant ID :param request: A user request """ language = request['node_language'] node = config.ConfigFactory(session, tid) if tid == 1: root_tenant_node = node encryption = True else: root_tenant_node = node encryption = root_tenant_node.get_val('encryption') if node.get_val('wizard_done'): log.err("DANGER: Wizard already initialized!", tid=tid) raise errors.ForbiddenOperation db_update_enabled_languages(session, tid, [language], language) node.set_val('encryption', encryption) node.set_val('name', request['node_name']) node.set_val('default_language', language) node.set_val('wizard_done', True) node.set_val('enable_developers_exception_notification', request['enable_developers_exception_notification']) node.set_val('hostname', hostname) node_l10n = config.ConfigL10NFactory(session, tid) node_l10n.set_val('header_title_homepage', language, request['node_name']) profiles.load_profile(session, tid, request['profile']) if encryption: crypto_escrow_prv_key, crypto_escrow_pub_key = GCE.generate_keypair() node.set_val('crypto_escrow_pub_key', crypto_escrow_pub_key) admin_desc = models.User().dict(language) admin_desc['username'] = request['admin_username'] admin_desc['name'] = request['admin_name'] admin_desc['password'] = request['admin_password'] admin_desc['name'] = request['admin_name'] admin_desc['mail_address'] = request['admin_mail_address'] admin_desc['language'] = language admin_desc['role'] = 'admin' admin_desc['pgp_key_remove'] = False admin_user = db_create_user(session, tid, admin_desc, language) admin_user.password = GCE.hash_password(request['admin_password'], admin_user.salt) admin_user.password_change_needed = False admin_user.password_change_date = datetime_now() if encryption: db_gen_user_keys(session, tid, admin_user, request['admin_password']) admin_user.crypto_escrow_prv_key = Base64Encoder.encode( GCE.asymmetric_encrypt(admin_user.crypto_pub_key, crypto_escrow_prv_key)) receiver_user = None if not request['skip_recipient_account_creation']: receiver_desc = models.User().dict(language) receiver_desc['username'] = request['receiver_username'] receiver_desc['name'] = request['receiver_name'] receiver_desc['password'] = request['receiver_password'] receiver_desc['mail_address'] = request['receiver_mail_address'] receiver_desc['language'] = language receiver_desc['role'] = 'receiver' receiver_desc['pgp_key_remove'] = False receiver_desc['send_account_activation_link'] = receiver_desc[ 'password'] == '' receiver_user = db_create_user(session, tid, receiver_desc, language) if receiver_desc['password']: receiver_user.password = GCE.hash_password( receiver_desc['password'], receiver_user.salt) if encryption: db_gen_user_keys(session, tid, receiver_user, receiver_desc['password']) context_desc = models.Context().dict(language) context_desc['name'] = 'Default' context_desc['status'] = 'enabled' context_desc['receivers'] = [receiver_user.id] if receiver_user else [] context = db_create_context(session, tid, context_desc, language) # Root tenants initialization terminates here if tid == 1: db_refresh_memory_variables(session, [tid]) return # Secondary tenants initialization starts here tenant = models.db_get(session, models.Tenant, models.Tenant.id == tid) tenant.label = request['node_name'] mode = node.get_val('mode') if mode not in ['default', 'demo']: node.set_val( 'hostname', tenant.subdomain + '.' + root_tenant_node.get_val('rootdomain')) for varname in [ 'reachable_via_web', 'enable_receipt_hint', 'disable_privacy_badge', 'simplified_login', 'can_delete_submission', 'can_postpone_expiration', 'anonymize_outgoing_connections', 'frame_ancestors', 'password_change_period', 'default_questionnaire', 'enable_password_reset' ]: node.set_val(varname, root_tenant_node.get_val(varname)) context.questionnaire_id = root_tenant_node.get_val( 'default_questionnaire') # Set data retention policy to 18 months context.tip_timetolive = 540 # Delete the admin user request['admin_password'] = '' session.delete(admin_user) if receiver_user is not None: # Enable the recipient user to configure platform general settings receiver_user.can_edit_general_settings = True # Set the recipient name equal to the node name receiver_user.name = receiver_user.public_name = request[ 'node_name'] # Apply the specific fixes related to whistleblowing.it projects if mode == 'whistleblowing.it': node.set_val('simplified_login', True) node.set_val('tor', False) db_refresh_memory_variables(session, [tid])
def db_wizard(session, tid, request, client_using_tor, language): language = request['node_language'] node = config.ConfigFactory(session, tid) if tid != 1: root_tenant_node = config.ConfigFactory(session, 1) else: root_tenant_node = node if node.get_val(u'wizard_done'): log.err("DANGER: Wizard already initialized!", tid=tid) raise errors.ForbiddenOperation db_update_enabled_languages(session, tid, [language], language) node.set_val(u'name', request['node_name']) node.set_val(u'default_language', language) node.set_val(u'wizard_done', True) node.set_val(u'enable_developers_exception_notification', request['enable_developers_exception_notification']) # Guess Tor configuration from thee media used on first configuration and # if the user is using Tor preserve node anonymity and perform outgoing connections via Tor node.set_val(u'reachable_via_web', not client_using_tor) node.set_val(u'allow_unencrypted', not client_using_tor) node.set_val(u'anonymize_outgoing_connections', client_using_tor) node_l10n = config.ConfigL10NFactory(session, tid) node_l10n.set_val(u'header_title_homepage', language, request['node_name']) profiles.load_profile(session, tid, request['profile']) admin_desc = models.User().dict(language) admin_desc['name'] = request['admin_name'] admin_desc['username'] = u'admin' admin_desc['password'] = request['admin_password'] admin_desc['name'] = request['admin_name'] admin_desc['mail_address'] = request['admin_mail_address'] admin_desc['language'] = language admin_desc['role'] = u'admin' admin_desc['deletable'] = False admin_desc['pgp_key_remove'] = False admin_user = db_create_user(session, tid, admin_desc, language) admin_user.password_change_needed = False admin_user.password_change_date = datetime_now() receiver_desc = models.User().dict(language) receiver_desc['name'] = request['receiver_name'] receiver_desc['username'] = u'recipient' receiver_desc['password'] = request['receiver_password'] receiver_desc['name'] = request['receiver_name'] receiver_desc['mail_address'] = request['receiver_mail_address'] receiver_desc['language'] = language receiver_desc['role'] = u'receiver' receiver_desc['deletable'] = True receiver_desc['pgp_key_remove'] = False receiver_user = db_create_user(session, tid, receiver_desc, language) context_desc = models.Context().dict(language) context_desc['status'] = 1 context_desc['name'] = u'Default' context_desc['receivers'] = [receiver_user.id] context = db_create_context(session, tid, context_desc, language) # Root tenants initialization terminates here if tid == 1: db_refresh_memory_variables(session, [tid]) return # Secondary tenants initialization starts here tenant = models.db_get(session, models.Tenant, models.Tenant.id == tid) tenant.label = request['node_name'] mode = node.get_val(u'mode') if mode != u'default': node.set_val( u'hostname', tenant.subdomain + '.' + root_tenant_node.get_val(u'rootdomain')) for varname in [ 'reachable_via_web', 'disable_key_code_hint', 'disable_privacy_badge', 'disable_donation_panel', 'simplified_login', 'can_delete_submission', 'can_postpone_expiration', 'enable_user_pgp_key_upload', 'allow_unencrypted', 'anonymize_outgoing_connections', 'allow_iframes_inclusion', 'password_change_period', 'default_questionnaire' ]: node.set_val(varname, root_tenant_node.get_val(varname)) context.questionnaire_id = root_tenant_node.get_val( u'default_questionnaire') # Apply the general settings to apply on all mode != default if mode != u'default': # Enable the recipient user to configure platform general settings receiver_user.can_edit_general_settings = True # Set data retention policy to 18 months context.tip_timetolive = 540 # Apply the specific fixes related to whistleblowing.it projects if mode == u'whistleblowing.it': node.set_val(u'simplified_login', True) node.set_val(u'tor', False) # Enable recipients to load files to the whistleblower context.enable_rc_to_wb_files = True # Set the recipient name equal to the node name receiver_user.name = request['node_name'] # Delete the admin user session.delete(admin_user) db_refresh_memory_variables(session, [tid])
def signup(session, state, tid, request, language): node = config.ConfigFactory(session, 1, 'node') if not node.get_val(u'enable_signup'): raise errors.ForbiddenOperation request['activation_token'] = generateRandomKey(32) request['language'] = language signup = models.Signup(request) session.add(signup) session.flush() ret = { 'signup': serialize_signup(signup), 'activation_url': 'https://%s/#/activation?token=%s' % (node.get_val(u'rootdomain'), signup.activation_token), 'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=30)) } # We need to send two emails # # The first one is sent to the platform owner with the activation email. # # The second goes to the instance administrators notifying them that a new # platform has been added. # Email 1 - Activation Link template_vars = copy.deepcopy(ret) template_vars.update({ 'type': 'signup', 'node': db_admin_serialize_node(session, 1, language), 'notification': db_get_notification(session, 1, language), }) state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars) # Email 2 - Admin Notification for user_desc in db_get_admin_users(session, 1): template_vars = copy.deepcopy(ret) template_vars.update({ 'type': 'admin_signup_alert', 'signup': serialize_signup(signup), 'node': db_admin_serialize_node(session, 1, user_desc['language']), 'notification': db_get_notification(session, 1, user_desc['language']), 'user': user_desc }) state.format_and_send_mail(session, 1, user_desc, template_vars) return ret
def signup_activation(session, state, tid, token, language): node = config.ConfigFactory(session, 1, 'node') if not node.get_val(u'enable_signup'): raise errors.ForbiddenOperation signup = session.query(models.Signup).filter( models.Signup.activation_token == token).one_or_none() if signup is None: return {} if not session.query( models.Config).filter(models.Config.tid == signup.tid).count(): db_initialize_tenant(session, signup.tid) create_admin = not node.get_val(u'signup_no_admin_user') if create_admin: signup.password_admin = generateRandomKey(16) signup.password_recipient = generateRandomKey(16) wizard = { 'node_language': signup.language, 'node_name': signup.subdomain, 'admin_name': signup.name + ' ' + signup.surname, 'admin_password': signup.password_admin, 'admin_mail_address': signup.email, 'receiver_name': signup.name + ' ' + signup.surname, 'receiver_password': signup.password_recipient, 'receiver_mail_address': signup.email, 'profile': 'default', 'enable_developers_exception_notification': True } db_wizard(session, state, signup.tid, wizard, create_admin, False, language) ids = [ r[0] for r in session.query(models.User.id).filter( models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == signup.tid) ] session.query(models.User).filter(models.User.id.in_(ids)).update( {'password_change_needed': False}, synchronize_session='fetch') template_vars = { 'type': 'activation', 'node': db_admin_serialize_node(session, 1, language), 'notification': db_get_notification(session, 1, language), 'signup': serialize_signup(signup), 'activation_url': '', 'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=30)) } state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars) if session.query(models.Tenant).filter( models.Tenant.id == signup.tid).one_or_none() is not None: admin = session.query(models.User).filter( models.User.role == u'admin', models.User.username == u'admin', models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == signup.tid).one_or_none() recipient = session.query(models.User).filter( models.User.role == u'receiver', models.User.username == u'recipient', models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == signup.tid).one_or_none() ret_dict = { 'platform_url': 'https://%s.%s' % (signup.subdomain, node.get_val(u'rootdomain')), 'login_url': 'https://%s.%s/#/login' % (signup.subdomain, node.get_val(u'rootdomain')), 'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=7)) } if admin is not None: ret_dict['login_url_admin'] = 'https://%s.%s/#/login?token=%s' % ( signup.subdomain, node.get_val(u'rootdomain'), admin.auth_token) ret_dict['password_admin'] = signup.password_admin if recipient is not None: ret_dict[ 'login_url_recipient'] = 'https://%s.%s/#/login?token=%s' % ( signup.subdomain, node.get_val(u'rootdomain'), recipient.auth_token) ret_dict['password_recipient'] = signup.password_recipient return ret_dict return {}