Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
        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,