user_dict = distinguished_name_to_user(user_id) elif not configuration.site_enable_gdp: print('Please enter the details for the user to be removed:') user_dict['full_name'] = raw_input('Full Name: ').title() user_dict['organization'] = raw_input('Organization: ') user_dict['state'] = raw_input('State: ') user_dict['country'] = raw_input('2-letter Country Code: ') user_dict['email'] = raw_input('Email: ') else: print("Error: Missing one or more of the arguments: " \ + "[FULL_NAME] [ORGANIZATION] [STATE] [COUNTRY] " \ + "[EMAIL]") sys.exit(1) if 'distinguished_name' not in user_dict: fill_distinguished_name(user_dict) fill_user(user_dict) # Now all user fields are set and we can begin deleting the user if verbose: print('Removing DB entry and dirs for user: %s' % user_dict) try: delete_user(user_dict, conf_path, db_path, force, verbose) except Exception as err: print(err) sys.exit(1) print('Deleted %s from user database and from file system'\ % user_dict['distinguished_name'])
def main(client_id, user_arguments_dict, environ=None): """Main function used by front end""" if environ is None: environ = os.environ (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False, op_menu=False) logger = configuration.logger logger.info('%s: args: %s' % (op_name, user_arguments_dict)) prefilter_map = {} output_objects.append({'object_type': 'header', 'text': 'Automatic %s sign up' % configuration.short_title}) (auth_type, auth_flavor) = detect_client_auth(configuration, environ) identity = extract_client_id(configuration, environ, lookup_dn=False) if client_id and auth_type == AUTH_CERTIFICATE: if auth_flavor == AUTH_MIG_CERT: base_url = configuration.migserver_https_mig_cert_url elif auth_flavor == AUTH_EXT_CERT: base_url = configuration.migserver_https_ext_cert_url else: logger.warning('no matching sign up auth flavor %s' % auth_flavor) output_objects.append({'object_type': 'error_text', 'text': '%s sign up not supported' % auth_flavor}) return (output_objects, returnvalues.SYSTEM_ERROR) elif identity and auth_type == AUTH_OPENID_V2: if auth_flavor == AUTH_MIG_OID: base_url = configuration.migserver_https_mig_oid_url elif auth_flavor == AUTH_EXT_OID: base_url = configuration.migserver_https_ext_oid_url else: logger.warning('no matching sign up auth flavor %s' % auth_flavor) output_objects.append({'object_type': 'error_text', 'text': '%s sign up not supported' % auth_flavor}) return (output_objects, returnvalues.SYSTEM_ERROR) for name in ('openid.sreg.cn', 'openid.sreg.fullname', 'openid.sreg.full_name'): prefilter_map[name] = filter_commonname elif identity and auth_type == AUTH_OPENID_CONNECT: if auth_flavor == AUTH_MIG_OIDC: base_url = configuration.migserver_https_mig_oidc_url elif auth_flavor == AUTH_EXT_OIDC: base_url = configuration.migserver_https_ext_oidc_url else: logger.warning('no matching sign up auth flavor %s' % auth_flavor) output_objects.append({'object_type': 'error_text', 'text': '%s sign up not supported' % auth_flavor}) return (output_objects, returnvalues.SYSTEM_ERROR) oidc_keys = signature(AUTH_OPENID_CONNECT)[1].keys() # NOTE: again we lowercase to avoid case sensitivity in validation for key in environ: low_key = key.replace('OIDC_CLAIM_', 'oidc.claim.').lower() if low_key in oidc_keys: user_arguments_dict[low_key] = [environ[key]] else: logger.error('autocreate without ID rejected for %s' % client_id) output_objects.append({'object_type': 'error_text', 'text': 'Missing user credentials'}) return (output_objects, returnvalues.CLIENT_ERROR) defaults = signature(auth_type)[1] (validate_status, accepted) = validate_input(user_arguments_dict, defaults, output_objects, allow_rejects=False, prefilter_map=prefilter_map) if not validate_status: logger.warning('%s from %s got invalid input: %s' % (op_name, client_id, accepted)) return (accepted, returnvalues.CLIENT_ERROR) logger.debug('Accepted arguments: %s' % accepted) # logger.debug('with environ: %s' % environ) admin_email = configuration.admin_email smtp_server = configuration.smtp_server (openid_names, oid_extras) = ([], {}) tmp_id = 'tmp%s' % time.time() logger.info('Received autocreate from %s with ID %s' % (client_id, tmp_id)) # Extract raw values if auth_type == AUTH_CERTIFICATE: uniq_id = accepted['cert_id'][-1].strip() raw_name = accepted['cert_name'][-1].strip() country = accepted['country'][-1].strip() state = accepted['state'][-1].strip() org = accepted['org'][-1].strip() org_unit = '' # NOTE: leave role and association alone here role = '' association = '' locality = '' timezone = '' email = accepted['email'][-1].strip() elif auth_type == AUTH_OPENID_V2: uniq_id = accepted['openid.sreg.nickname'][-1].strip() \ or accepted['openid.sreg.short_id'][-1].strip() raw_name = accepted['openid.sreg.fullname'][-1].strip() \ or accepted['openid.sreg.full_name'][-1].strip() country = accepted['openid.sreg.country'][-1].strip() state = accepted['openid.sreg.state'][-1].strip() org = accepted['openid.sreg.o'][-1].strip() \ or accepted['openid.sreg.organization'][-1].strip() org_unit = accepted['openid.sreg.ou'][-1].strip() \ or accepted['openid.sreg.organizational_unit'][-1].strip() # We may receive multiple roles and associations role = ','.join([i for i in accepted['openid.sreg.role'] if i]) association = ','.join([i for i in accepted['openid.sreg.association'] if i]) locality = accepted['openid.sreg.locality'][-1].strip() timezone = accepted['openid.sreg.timezone'][-1].strip() # We may encounter results without an email, fall back to uniq_id then email = accepted['openid.sreg.email'][-1].strip() or uniq_id elif auth_type == AUTH_OPENID_CONNECT: uniq_id = accepted['oidc.claim.upn'][-1].strip() \ or accepted['oidc.claim.sub'][-1].strip() raw_name = accepted['oidc.claim.fullname'][-1].strip() country = accepted['oidc.claim.country'][-1].strip() state = accepted['oidc.claim.state'][-1].strip() org = accepted['oidc.claim.o'][-1].strip() \ or accepted['oidc.claim.organization'][-1].strip() org_unit = accepted['oidc.claim.ou'][-1].strip() \ or accepted['oidc.claim.organizational_unit'][-1].strip() # We may receive multiple roles and associations role = ','.join([i for i in accepted['oidc.claim.role'] if i]) association = ','.join([i for i in accepted['oidc.claim.association'] if i]) locality = accepted['oidc.claim.locality'][-1].strip() timezone = accepted['oidc.claim.timezone'][-1].strip() # We may encounter results without an email, fall back to uniq_id then email = accepted['oidc.claim.email'][-1].strip() or uniq_id # TODO: switch to canonical_user fra mig.shared.base instead? # Fix case of values: # force name to capitalized form (henrik karlsen -> Henrik Karlsen) # please note that we get utf8 coded bytes here and title() treats such # chars as word termination. Temporarily force to unicode. try: full_name = force_utf8(force_unicode(raw_name).title()) except Exception: logger.warning('could not use unicode form to capitalize full name' ) full_name = raw_name.title() country = country.upper() state = state.upper() email = email.lower() accept_terms = (accepted['accept_terms'][-1].strip().lower() in ('1', 'o', 'y', 't', 'on', 'yes', 'true')) if auth_type in (AUTH_OPENID_V2, AUTH_OPENID_CONNECT): # KU OpenID sign up does not deliver accept_terms so we implicitly # let it imply acceptance for now accept_terms = True # Remap some oid attributes if on KIT format with faculty in # organization and institute in organizational_unit. We can add them # as different fields as long as we make sure the x509 fields are # preserved. # Additionally in the special case with unknown institute (ou=ukendt) # we force organization to KU to align with cert policies. # We do that to allow autocreate updating existing cert users. if org_unit not in ('', 'NA'): org_unit = org_unit.upper() oid_extras['faculty'] = org oid_extras['institute'] = org_unit org = org_unit.upper() org_unit = 'NA' if org == 'UKENDT': org = 'KU' logger.info('unknown affilition, set organization to %s' % org) # Stay on virtual host - extra useful while we test dual OpenID base_url = environ.get('REQUEST_URI', base_url).split('?')[0] backend = 'home.py' if configuration.site_enable_gdp: backend = 'gdpman.py' elif configuration.site_autolaunch_page: backend = os.path.basename(configuration.site_autolaunch_page) elif configuration.site_landing_page: backend = os.path.basename(configuration.site_landing_page) base_url = base_url.replace('autocreate.py', backend) raw_login = '' if auth_type == AUTH_OPENID_V2: # OpenID 2.0 provides user ID on URL format - only add plain ID for oid_provider in configuration.user_openid_providers: openid_prefix = oid_provider.rstrip('/') + '/' if identity.startswith(openid_prefix): raw_login = identity.replace(openid_prefix, '') break elif auth_type == AUTH_OPENID_CONNECT: raw_login = identity if raw_login and not raw_login in openid_names: openid_names.append(raw_login) if email and not email in openid_names: openid_names.append(email) # TODO: Add additional ext oid/oidc provider ID aliases here? # we should have the proxy file read... proxy_content = accepted['proxy_upload'][-1] # keep comment to a single line comment = accepted['comment'][-1].replace('\n', ' ') # single quotes break command line format - remove comment = comment.replace("'", ' ') # TODO: improve and enforce full authsig from extoid/extoidc provider authsig_list = accepted.get('authsig', []) # if len(authsig_list) != 1: # logger.warning('%s from %s got invalid authsig: %s' % # (op_name, client_id, authsig_list)) user_dict = { 'short_id': uniq_id, 'full_name': full_name, 'organization': org, 'organizational_unit': org_unit, 'locality': locality, 'state': state, 'country': country, 'email': email, 'role': role, 'association': association, 'timezone': timezone, 'password': '', 'comment': 'Signed up through autocreate with %s' % auth_type, 'openid_names': openid_names, } user_dict.update(oid_extras) # We must receive some ID from the provider otherwise we probably hit the # already logged in situation and must autologout first if not uniq_id and not email: if auth_type == AUTH_OPENID_V2 and identity and \ accepted.get('openid.sreg.required', ''): logger.warning('autocreate forcing autologut for %s' % client_id) output_objects.append({'object_type': 'html_form', 'text': '''<p class="spinner iconleftpad"> Auto log out first to avoid sign up problems ... </p>'''}) req_url = environ['SCRIPT_URI'] html = \ """ <a id='autologout' href='%s'></a> <script type='text/javascript'> document.getElementById('autologout').click(); </script>""" \ % openid_autologout_url(configuration, identity, client_id, req_url, user_arguments_dict) output_objects.append({'object_type': 'html_form', 'text': html}) else: logger.warning('%s autocreate without ID refused for %s' % (auth_type, client_id)) return (output_objects, returnvalues.CLIENT_ERROR) # NOTE: Unfortunately external OpenID 2.0 redirect does not enforce POST # Extract helper environments from Apache to verify request authenticity redirector = environ.get('HTTP_REFERER', '') extoid_prefix = configuration.user_ext_oid_provider.replace('id/', '') # TODO: extend redirector check to match the full signup request? # may not work with recent browser policy changes to limit referrer # details on cross site requests. # NOTE: redirector check breaks for FF default policy so disabled again! if auth_flavor == AUTH_EXT_OID and redirector and \ not redirector.startswith(extoid_prefix) and \ not redirector.startswith(configuration.migserver_https_sid_url) \ and not redirector.startswith(configuration.migserver_http_url) \ and not redirector.startswith(get_site_base_url(configuration)): logger.error('stray %s autocreate rejected for %r (ref: %r)' % (auth_flavor, client_id, redirector)) output_objects.append({'object_type': 'error_text', 'text': '''Only accepting authentic requests through %s OpenID 2.0''' % configuration.user_ext_oid_title}) return (output_objects, returnvalues.CLIENT_ERROR) elif auth_flavor != AUTH_EXT_OID and not safe_handler( configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): logger.error('unsafe %s autocreate rejected for %s' % (auth_flavor, client_id)) output_objects.append({'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates'''}) return (output_objects, returnvalues.CLIENT_ERROR) if auth_flavor == AUTH_EXT_CERT: ext_login_title = "%s certificate" % configuration.user_ext_cert_title personal_page_url = configuration.migserver_https_ext_cert_url # TODO: consider limiting expire to real cert expire if before default? user_dict['expire'] = default_account_expire(configuration, AUTH_CERTIFICATE) try: distinguished_name_to_user(uniq_id) user_dict['distinguished_name'] = uniq_id except: logger.error('%s autocreate with bad DN refused for %s' % (auth_flavor, client_id)) output_objects.append({'object_type': 'error_text', 'text': '''Illegal Distinguished name: Please note that the distinguished name must be a valid certificate DN with multiple "key=val" fields separated by "/". '''}) return (output_objects, returnvalues.CLIENT_ERROR) elif auth_flavor == AUTH_EXT_OID: ext_login_title = "%s login" % configuration.user_ext_oid_title personal_page_url = configuration.migserver_https_ext_oid_url user_dict['expire'] = default_account_expire(configuration, AUTH_OPENID_V2) fill_distinguished_name(user_dict) uniq_id = user_dict['distinguished_name'] elif auth_flavor == AUTH_EXT_OIDC: ext_login_title = "%s login" % configuration.user_ext_oid_title personal_page_url = configuration.migserver_https_ext_oidc_url user_dict['expire'] = default_account_expire(configuration, AUTH_OPENID_CONNECT) fill_distinguished_name(user_dict) uniq_id = user_dict['distinguished_name'] else: # Reject the migX sign up methods through this handler logger.error('%s autocreate not supported for %s - only ext auth' % (auth_flavor, client_id)) output_objects.append({'object_type': 'error_text', 'text': ''' Unsuported %s sign up method - you should sign up through the official sign up wrappers or go through the dedicated web form for %s.''' % (auth_type, auth_flavor)}) return (output_objects, returnvalues.CLIENT_ERROR) # IMPORTANT: do NOT let a user create with ID different from client_id if auth_type == AUTH_CERTIFICATE and client_id != uniq_id: logger.error('refusing autocreate invalid user for %s: %s' % (client_id, user_dict)) output_objects.append({'object_type': 'error_text', 'text': '''Only accepting create matching supplied ID!'''}) return (output_objects, returnvalues.CLIENT_ERROR) if not accept_terms: output_objects.append({'object_type': 'error_text', 'text': 'You must accept the terms of use in sign up!'}) output_objects.append( {'object_type': 'link', 'destination': 'javascript:history.back();', 'class': 'genericbutton', 'text': "Try again"}) return (output_objects, returnvalues.CLIENT_ERROR) # Save auth access method user_dict['auth'] = user_dict.get('auth', None) if not user_dict['auth']: user_dict['auth'] = [] elif isinstance(user_dict['auth'], basestring): user_dict['auth'] = [user_dict['auth']] user_dict['auth'].append(auth_flavor) fill_helper = {'short_title': configuration.short_title, 'base_url': base_url, 'admin_email': admin_email, 'ext_login_title': ext_login_title, 'front_page_url': get_site_base_url(configuration), 'personal_page_url': personal_page_url} fill_helper.update(user_dict) # If server allows automatic addition of users with a CA validated cert # we create the user immediately and skip mail if auth_type == AUTH_CERTIFICATE and configuration.auto_add_cert_user \ or auth_type == AUTH_OPENID_V2 and \ configuration.auto_add_oid_user \ or auth_type == AUTH_OPENID_CONNECT and \ configuration.auto_add_oid_user: fill_user(user_dict) logger.info('create user: %s' % user_dict) # Now all user fields are set and we can begin adding the user db_path = os.path.join(configuration.mig_server_home, user_db_filename) try: create_user(user_dict, configuration.config_file, db_path, ask_renew=False, default_renew=True) if configuration.site_enable_griddk \ and accepted['proxy_upload'] != ['']: # save the file, display expiration date proxy_out = handle_proxy(proxy_content, uniq_id, configuration) output_objects.extend(proxy_out) except Exception as err: logger.error('create failed for %s: %s' % (uniq_id, err)) output_objects.append({'object_type': 'error_text', 'text': ''' Could not create the user account for you: Please report this problem to the site administrators (%(admin_email)s).''' % fill_helper}) return (output_objects, returnvalues.SYSTEM_ERROR) logger.info('created user account for %s' % uniq_id) email_header = 'Welcome to %s' % configuration.short_title email_msg = """Hi and welcome to %(short_title)s! Your account sign up succeeded and you can now log in to your account using your %(ext_login_title)s from %(front_page_url)s There you'll also find further information about making the most of %(short_title)s, including a user guide and answers to Frequently Asked Questions, plus site status and support information. You're welcome to contact us with questions or comments using the contact details there and in the footer of your personal %(short_title)s pages. Please note that by signing up and using %(short_title)s you also formally accept the site Terms of Use, which you'll always find in the current form at %(front_page_url)s/terms.html All the best, The %(short_title)s Admins """ % fill_helper logger.info('Send email: to: %s, header: %s, msg: %s, smtp_server: %s' % (email, email_header, email_msg, smtp_server)) if not send_email(email, email_header, email_msg, logger, configuration): output_objects.append({ 'object_type': 'error_text', 'text': """An error occured trying to send your account welcome email. Please inform the site admins (%s) manually and include the session ID: %s""" % (admin_email, tmp_id)}) return (output_objects, returnvalues.SYSTEM_ERROR) logger.info('sent welcome email for %s to %s' % (uniq_id, email)) output_objects.append({'object_type': 'html_form', 'text': """ <p>Creating your %(short_title)s user account and sending welcome email ... </p> <p class='spinner iconleftpad'> redirecting to your <a href='%(personal_page_url)s'> personal pages </a> in a moment. </p> <script type='text/javascript'> setTimeout(function() {location.href='%(personal_page_url)s';}, 3000); </script> """ % fill_helper}) return (output_objects, returnvalues.OK) else: logger.warning('autocreate disabled and refused for %s' % client_id) output_objects.append({ 'object_type': 'error_text', 'text': """Automatic user creation disabled on this site. Please contact the site admins (%(admin_email)s) if you think it should be enabled. """ % fill_helper}) return (output_objects, returnvalues.ERROR)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) output_objects.append({ 'object_type': 'header', 'text': '%s external certificate sign up' % configuration.short_title }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert(user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, require_user=False) if not validate_status: logger.warning('%s invalid input: %s' % (op_name, accepted)) return (accepted, returnvalues.CLIENT_ERROR) admin_email = configuration.admin_email smtp_server = configuration.smtp_server user_pending = os.path.abspath(configuration.user_pending) cert_id = accepted['cert_id'][-1].strip() # TODO: switch to canonical_user fra mig.shared.base instead? # force name to capitalized form (henrik karlsen -> Henrik Karlsen) # please note that we get utf8 coded bytes here and title() treats such # chars as word termination. Temporarily force to unicode. raw_name = accepted['cert_name'][-1].strip() try: cert_name = force_utf8(force_unicode(raw_name).title()) except Exception: cert_name = raw_name.title() country = accepted['country'][-1].strip().upper() state = accepted['state'][-1].strip().upper() org = accepted['org'][-1].strip() # lower case email address email = accepted['email'][-1].strip().lower() # keep comment to a single line comment = accepted['comment'][-1].replace('\n', ' ') # single quotes break command line format - remove comment = comment.replace("'", ' ') accept_terms = (accepted['accept_terms'][-1].strip().lower() in ('1', 'o', 'y', 't', 'on', 'yes', 'true')) if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not accept_terms: output_objects.append({ 'object_type': 'error_text', 'text': 'You must accept the terms of use in sign up!' }) output_objects.append({ 'object_type': 'link', 'destination': 'javascript:history.back();', 'class': 'genericbutton', 'text': "Try again" }) return (output_objects, returnvalues.CLIENT_ERROR) is_diku_email = False is_diku_org = False if email.find('@diku.dk') != -1: is_diku_email = True if 'DIKU' == org.upper(): # Consistent upper casing org = org.upper() is_diku_org = True if is_diku_org != is_diku_email: output_objects.append({ 'object_type': 'error_text', 'text': '''Illegal email and organization combination: Please read and follow the instructions in red on the request page! If you are a DIKU student with only a @*.ku.dk address please just use KU as organization. As long as you state that you want the certificate for DIKU purposes in the comment field, you will be given access to the necessary resources anyway. ''' }) return (output_objects, returnvalues.CLIENT_ERROR) try: distinguished_name_to_user(cert_id) except: output_objects.append({ 'object_type': 'error_text', 'text': '''Illegal Distinguished name: Please note that the distinguished name must be a valid certificate DN with multiple "key=val" fields separated by "/". ''' }) return (output_objects, returnvalues.CLIENT_ERROR) user_dict = { 'distinguished_name': cert_id, 'full_name': cert_name, 'organization': org, 'state': state, 'country': country, 'email': email, 'password': '', 'comment': '%s: %s' % ('Existing certificate', comment), 'expire': default_account_expire(configuration, 'cert'), 'openid_names': [], 'auth': ['extcert'], } fill_distinguished_name(user_dict) user_id = user_dict['distinguished_name'] if configuration.user_openid_providers and configuration.user_openid_alias: user_dict['openid_names'] += \ [user_dict[configuration.user_openid_alias]] logger.info('got extcert request: %s' % user_dict) # If server allows automatic addition of users with a CA validated cert # we create the user immediately and skip mail if configuration.auto_add_cert_user: fill_user(user_dict) # Now all user fields are set and we can begin adding the user db_path = os.path.join(configuration.mig_server_home, user_db_filename) try: create_user(user_dict, configuration.config_file, db_path, ask_renew=False) except Exception as err: logger.error('Failed to create user with existing cert %s: %s' % (cert_id, err)) output_objects.append({ 'object_type': 'error_text', 'text': '''Could not create the user account for you: Please report this problem to the site administrators (%s).''' % admin_email }) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({ 'object_type': 'text', 'text': '''Created the user account for you: Please use the navigation menu to the left to proceed using it. ''' }) return (output_objects, returnvalues.OK) # Without auto add we end here and go through the mail-to-admins procedure req_path = None try: (os_fd, req_path) = tempfile.mkstemp(dir=user_pending) os.write(os_fd, dumps(user_dict)) os.close(os_fd) except Exception as err: logger.error('Failed to write existing certificate request to %s: %s' % (req_path, err)) output_objects.append({ 'object_type': 'error_text', 'text': """Request could not be sent to site administrators. Please contact them manually on %s if this error persists.""" % admin_email }) return (output_objects, returnvalues.SYSTEM_ERROR) logger.info('Wrote existing certificate sign up request to %s' % req_path) tmp_id = req_path.replace(user_pending, '') user_dict['tmp_id'] = tmp_id mig_user = os.environ.get('USER', 'mig') helper_commands = user_manage_commands(configuration, mig_user, req_path, user_id, user_dict, 'cert') user_dict.update(helper_commands) user_dict['site'] = configuration.short_title user_dict['vgrid_label'] = configuration.site_vgrid_label user_dict['vgridman_links'] = generate_https_urls( configuration, '%(auto_base)s/%(auto_bin)s/vgridman.py', {}) email_header = '%s sign up request for %s' % \ (configuration.short_title, cert_id) email_msg = \ """ Received an existing certificate sign up request with certificate data * Distinguished Name: %(distinguished_name)s * Full Name: %(full_name)s * Organization: %(organization)s * State: %(state)s * Country: %(country)s * Email: %(email)s * Comment: %(comment)s * Expire: %(expire)s Command to create user on %(site)s server: %(command_user_create)s Finally add the user %(distinguished_name)s to any relevant %(vgrid_label)ss using one of the management links: %(vgridman_links)s --- Command to reject user account request on %(site)s server: %(command_user_reject)s Command to suspend user on %(site)s server: %(command_user_suspend)s Command to delete user again on %(site)s server: %(command_user_delete)s --- """ % user_dict logger.info('Sending email: to: %s, header: %s, msg: %s, smtp_server: %s' % (admin_email, email_header, email_msg, smtp_server)) if not send_email(admin_email, email_header, email_msg, logger, configuration): output_objects.append({ 'object_type': 'error_text', 'text': """An error occured trying to send the email requesting the sign up with an existing certificate. Please email the site administrators (%s) manually and include the session ID: %s""" % (admin_email, tmp_id) }) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({ 'object_type': 'text', 'text': """Request sent to site administrators: Your request for a %s user account with your existing certificate will be verified and handled as soon as possible, so please be patient. In case of inquiries about this request, please email the site administrators (%s) and include the session ID: %s""" % (configuration.short_title, admin_email, tmp_id) }) return (output_objects, returnvalues.OK)