def validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects, require_user=True, filter_values=None, environ=None, ): """A wrapper used by most back end functionality - redirects to sign up if client_id is missing. """ logger = configuration.logger if environ is None: environ = os.environ creds_error = '' if not client_id: creds_error = "Invalid or missing user credentials" elif require_user and not is_user(client_id, configuration.mig_server_home): creds_error = "No such user (%s)" % client_id if creds_error and not requested_page().endswith('logout.py'): output_objects.append({'object_type': 'error_text', 'text' : creds_error }) # Redirect to sign-up cert page trying to guess relevant choices signup_url = os.path.join(configuration.migserver_https_sid_url, 'cgi-sid', 'signup.py') signup_query = '' if not client_id: output_objects.append( {'object_type': 'text', 'text': '''Apparently you do not already have access to %s, but you can sign up:''' % configuration.short_title }) output_objects.append({'object_type': 'link', 'text': signup_url, 'destination': signup_url + signup_query}) output_objects.append( {'object_type': 'text', 'text': '''If you already signed up and received a user certificate you probably just need to import it in your browser.'''}) else: output_objects.append( {'object_type': 'text', 'text': '''Apparently you already have suitable credentials and just need to sign up for a local %s account on:''' % \ configuration.short_title}) if extract_client_cert(configuration, environ) is None: # Force logout/expire session cookie here to support signup identity = extract_client_openid(configuration, environ, lookup_dn=False) if identity: logger.info("expire openid user %s" % identity) (success, _) = expire_oid_sessions(configuration, identity) else: logger.info("no openid user logged in") output_objects.append({'object_type': 'link', 'text': signup_url, 'destination': signup_url + signup_query}) return (False, output_objects) (status, retval) = validate_input(user_arguments_dict, defaults, output_objects, allow_rejects, filter_values) return (status, retval)
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) status = returnvalues.OK defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) do_logout = accepted['logout'][-1].lower() in ('true', '1') # sub-container inside default IU container output_objects.append({ 'object_type': 'html_form', 'text': ''' <div class="global-full-height row"> <div class="col-12 align-self-center"> ''' }) output_objects.append({'object_type': 'header', 'text': 'Logout'}) (oid_db, identity) = extract_client_openid(configuration, environ, lookup_dn=False) logger.info("%s from %s with identity %s" % (op_name, client_id, identity)) if client_id and client_id == identity: output_objects.append({ 'object_type': 'warning', 'text': """You're accessing %s with a user certificate so to completely logout you need to make sure it is protected by a password and then close the browser. Please refer to your browser and system documentation for details. """ % configuration.short_title }) return (output_objects, status) # OpenID requires logout on provider and in local mod-auth-openid database. # IMPORTANT: some browsers like Firefox may inadvertently renew the local # OpenID session while loading the resources for this page (in parallel). # User clicks logout at OpenID provider, which sends her back here to # finish the local logout. if do_logout: if configuration.site_enable_twofactor: real_user = client_id addr_filter = environ['REMOTE_ADDR'] # GDP logout is for project user so we strip project to force # repeat 2FA login on project logout / switch if configuration.site_enable_gdp: real_user = get_client_id_from_project_client_id( configuration, client_id) addr_filter = None if real_user and not expire_twofactor_session( configuration, real_user, environ, allow_missing=True, user_addr=addr_filter): logger.warning("expire twofactor session failed for %s" % client_id) output_objects.append({ 'object_type': 'html_form', 'text': """<p class='warningtext'> There was a potential problem with 2-factor session termination. Please contact the %s Admins if it happens repeatedly. </p>""" % configuration.short_title }) logger.info("expiring active sessions for %s in %s" % (identity, oid_db)) (success, _) = expire_oid_sessions(configuration, oid_db, identity) logger.info("verifying no active sessions left for %s" % identity) (found, remaining) = find_oid_sessions(configuration, oid_db, identity) if success and found and not remaining: if configuration.site_enable_gdp: reentry_page = "https://%s" % configuration.server_fqdn if configuration.user_mig_oid_provider and \ identity.startswith( configuration.user_mig_oid_provider): reentry_page = configuration.migserver_https_mig_oid_url elif configuration.user_ext_oid_provider and \ identity.startswith( configuration.user_ext_oid_provider): reentry_page = configuration.migserver_https_ext_oid_url project_logout(configuration, 'https', environ['REMOTE_ADDR'], client_id) html = ''' <a id='gdp_logout' href='%s'></a> <script type='text/javascript'> document.getElementById('gdp_logout').click(); </script>''' % reentry_page output_objects.append({ 'object_type': 'html_form', 'text': html }) else: output_objects.append({ 'object_type': 'text', 'text': """You are now logged out of %s locally - you may want to close your web browser to finish""" % configuration.short_title }) title_entry = find_entry(output_objects, 'title') title_entry['skipmenu'] = True else: logger.error("remaining active sessions for %s: %s" % (identity, remaining)) output_objects.append({ 'object_type': 'error_text', 'text': "Could not log you out of %s!" % configuration.short_title }) status = returnvalues.CLIENT_ERROR else: local_logout = '?logout=true' oid_logout = os.path.join(os.path.dirname(os.path.dirname(identity)), 'logout?return_to=%(SCRIPT_URI)s' % environ) oid_logout += local_logout output_objects.append({ 'object_type': 'text', 'text': """Are you sure you want to log out of %s?""" % configuration.short_title }) output_objects.append({'object_type': 'text', 'text': ""}) output_objects.append({ 'object_type': 'link', 'destination': oid_logout, 'class': 'genericbutton greenBtn', 'text': "Yes" }) output_objects.append({ 'object_type': 'link', 'destination': 'javascript:history.back();', 'class': 'genericbutton greenBtn', 'text': "No, go back" }) # sub-container end output_objects.append({ 'object_type': 'html_form', 'text': ''' </div> </div> ''' }) return (output_objects, status)
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) status = returnvalues.OK defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) do_logout = accepted['logout'][-1].lower() in ('true', '1') output_objects.append({'object_type': 'header', 'text' : 'Logout'}) identity = extract_client_openid(configuration, environ, lookup_dn=False) logger.info("%s from %s with identity %s" % (op_name, client_id, identity)) if client_id and client_id == identity: output_objects.append( {'object_type': 'warning', 'text': """You're accessing %s with a user certificate so to completely logout you need to make sure it is protected by a password and then close the browser. Please refer to your browser and system documentation for details. """ % configuration.short_title}) return (output_objects, status) # OpenID requires logout on provider and in local mod-auth-openid database. # IMPORTANT: some browsers like Firefox may inadvertently renew the local # OpenID session while loading the resources for this page (in parallel). # User clicks logout at OpenID provider, which sends her back here to # finish the local logout. if do_logout: logger.info("expiring active sessions for %s" % identity) (success, _) = expire_oid_sessions(configuration, identity) logger.info("verifying no active sessions left for %s" % identity) (found, remaining) = find_oid_sessions(configuration, identity) if success and found and not remaining: output_objects.append( {'object_type': 'text', 'text': """You are now logged out of %s locally - you may want to close your web browser to finish""" % \ configuration.short_title}) else: logger.error("remaining active sessions for %s: %s" % (identity, remaining)) output_objects.append({'object_type': 'error_text', 'text' : "Could not log you out of %s!" % \ configuration.short_title}) status = returnvalues.CLIENT_ERROR else: local_logout = '?logout=true' oid_logout = os.path.join(os.path.dirname(os.path.dirname(identity)), 'logout?return_to=%(SCRIPT_URI)s' % environ) oid_logout += local_logout output_objects.append( {'object_type': 'text', 'text': """You can log out from your OpenID identity provider and end the active %s session with the link below.""" % \ configuration.short_title}) # TODO: we could trigger this link automatically output_objects.append( {'object_type': 'link', 'destination': oid_logout, 'text': "Logout"}) return (output_objects, status)
def validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects, require_user=True, filter_values=None, environ=None, ): """A wrapper used by most back end functionality - redirects to sign up if client_id is missing. """ logger = configuration.logger if environ is None: environ = os.environ creds_error = '' if not client_id: creds_error = "Invalid or missing user credentials" elif require_user and not is_user(client_id, configuration.mig_server_home): creds_error = "No such user (%s)" % client_id if creds_error and not requested_page().endswith('logout.py'): output_objects.append({ 'object_type': 'error_text', 'text': creds_error }) if configuration.site_enable_gdp: main_url = configuration.migserver_http_url output_objects.append({ 'object_type': 'text', 'text': '''Apparently you do not have access to this page, please return to:''' }) output_objects.append({ 'object_type': 'link', 'text': main_url, 'destination': main_url }) else: # Redirect to sign-up cert page trying to guess relevant choices signup_url = os.path.join(configuration.migserver_https_sid_url, 'cgi-sid', 'signup.py') signup_query = '' if not client_id: output_objects.append({ 'object_type': 'text', 'text': '''Apparently you do not already have access to %s, but you can sign up:''' % configuration.short_title }) output_objects.append({'object_type': 'link', 'text': '%s sign up page' % \ configuration.short_title, 'destination': signup_url + signup_query}) output_objects.append({ 'object_type': 'text', 'text': '''If you already signed up and received a user certificate you probably just need to import it in your browser.''' }) else: output_objects.append({ 'object_type': 'text', 'text': '''Apparently you already have suitable credentials and just need to sign up for a local %s account on the''' % configuration.short_title }) base_url = extract_base_url(configuration, environ) if base_url == configuration.migserver_https_ext_cert_url and \ 'extcert' in configuration.site_login_methods: signup_query = '?show=extcert' elif base_url in (configuration.migserver_https_ext_oid_url, configuration.migserver_https_mig_oid_url): # Force logout/expire session cookie here to support signup (oid_db, identity) = extract_client_openid(configuration, environ, lookup_dn=False) if oid_db and identity: logger.info("openid expire user %s in %s" % (identity, oid_db)) (success, _) = expire_oid_sessions(configuration, oid_db, identity) if oid_db == auth_openid_ext_db and \ 'extoid' in configuration.site_signup_methods: signup_query = '?show=extoid' else: logger.error("unknown migoid client_id %s on %s" \ % (client_id, base_url)) else: logger.warning("unexpected client_id %s on %s" % \ (client_id, base_url)) output_objects.append({'object_type': 'link', 'text': '%s sign up page' % \ configuration.short_title, 'destination': signup_url + signup_query}) return (False, output_objects) (status, retval) = validate_input(user_arguments_dict, defaults, output_objects, allow_rejects, filter_values) return (status, retval)
msg += 'sign up problems ...' else: msg += 'stale sessions ...' output_objects.append({ 'object_type': 'html_form', 'text': '''<p class="spinner iconleftpad">%s</p>''' % msg }) # OpenID requires logout on provider and in local mod-auth-openid database. # IMPORTANT: some browsers like Firefox may inadvertently renew the local # OpenID session while loading the resources for this page (in parallel). logger.info('expiring active sessions for %s in %s' % (identity, oid_db)) (success, _) = expire_oid_sessions(configuration, oid_db, identity) logger.info('verifying no active sessions left for %s' % identity) (found, remaining) = find_oid_sessions(configuration, oid_db, identity) if success and found and not remaining: # Expire twofactor session expire_twofactor_session(configuration, client_id, environ, allow_missing=True) # Generate HTML and submit redirect form csrf_limit = get_csrf_limit(configuration, environ) csrf_token = make_csrf_token(configuration, 'post', op_name, client_id,