Beispiel #1
0
    def _GET(self, id=None):
        """
        Return entry.

        """
        if id is None:
            query = parse_dict_querystring(self.environ)
            size = int(query.get("size", DEFAULT_NUMBER_OF_ENTRIES))
            offset = int(query.get("offset", 0))
            
            # Read members from the collection. We get the requested number of
            # entries plus the next one.
            entries = self.em.get_entries(size+1, offset)
            if len(entries) == size+1:
                entries.pop()  # remove "next" entry
                next = "?size=%d&offset=%d" % (size, offset+size)
            else:
                next = None
            
            output = {"collection": entries, "next": next}
        else: 
            try:
                output = self.em.get_entry(id)
            except KeyError:
                raise httpexceptions.HTTPNotFound()  # 404

        app = self.format.responder(output, content_type='application/json')
        return app(self.environ, self.start)
Beispiel #2
0
    def identify(self, environ):
        if environ.has_key('rwpc.logout'):
            return

        uri = environ.get('REQUEST_URI', construct_url(environ))
        query = parse_dict_querystring(environ)

        cookies = get_cookies(environ) 
        cookie = cookies.get('auth_tkt') 


        if cookie is None or not cookie.value: 
            return None 
 
        remote_addr = '0.0.0.0' 

        identity = {}
         
        try: 
            timestamp, userid, tokens, user_data = auth_tkt.parse_ticket( 
                self.ticket_secret, cookie.value, remote_addr) 
        except auth_tkt.BadTicket as e: 
            return None 
        #userObj = model.Session.query(model.User).filter_by(id=userid).first()
        #if userObj is None:
        #    return None
        #identity['login'] = userObj.name
        identity['login'] = userid
        return identity
Beispiel #3
0
    def authenticate(self, environ, identity):
        log.info('In authenticate()')

        def set_error(msg):
            log.info(msg)
            err = 1
            environ['FAS_AUTH_ERROR'] = err
            # HTTPForbidden ?
            err_app = HTTPFound(err_goto + '?' + 'came_from=' +
                                quote_plus(came_from))
            environ['repoze.who.application'] = err_app

        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        try:
            auth_params = {
                'username': identity['login'],
                'password': identity['password']
            }
        except KeyError:
            try:
                auth_params = {'session_id': identity['session_id']}
            except:
                # On error we return None which means that auth failed
                set_error('Parameters for authenticating not found')
                return None

        try:
            user_data = self._retrieve_user_info(environ, auth_params)
        except AuthError as e:
            set_error('Authentication failed: %s' % exception_to_bytes(e))
            log.warning(e)
            return None
        except Exception as e:
            set_error('Unknown auth failure: %s' % exception_to_bytes(e))
            return None

        if user_data:
            try:
                del user_data[1]['password']
                environ['CSRF_AUTH_SESSION_ID'] = user_data[0]
                return user_data[1]['username']
            except ValueError:
                set_error('user information from fas not in expected format!')
                return None
            except Exception:
                pass
        set_error('An unknown error happened when trying to log you in.'
                  ' Please try again.')
        return None
Beispiel #4
0
    def challenge(self, environ, status, app_headers, forget_headers):
        logger = environ.get('repoze.who.logger','')
        logger.info("formplugin challenge")
        if app_headers:
            location = LOCATION(app_headers)
            if location:
                headers = list(app_headers) + list(forget_headers)
                return HTTPFound(headers = headers)

        query = parse_dict_querystring(environ)
        hidden = []
        for key, val in query.items():
            hidden.append(HIDDEN_PRE_LINE % ("_%s_" % key, val))

        logger.info("hidden: %s" % (hidden,))
        form = self.formbody or _DEFAULT_FORM
        form = form % "\n".join(hidden)

        if self.formcallable is not None:
            form = self.formcallable(environ)
        def auth_form(environ, start_response):
            content_length = CONTENT_LENGTH.tuples(str(len(form)))
            content_type = CONTENT_TYPE.tuples('text/html')
            headers = content_length + content_type + forget_headers
            start_response('200 OK', headers)
            return [form]

        return auth_form
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        if path_info == self.logout_handler_path:
            # we've been asked to perform a logout
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None

        elif path_info == self.login_handler_path:
            # we've been asked to perform a login
            form = parse_formvars(environ)
            form.update(query)
            try:
                max_age = form.get('max_age', None)
                credentials = {
                    'login':form['login'],
                    'password':form['password'],
                    'realm':form['realm'],
                    }
            except KeyError:
                credentials = None

            if credentials is not None:
                max_age = form.get('max_age', None)
                if max_age is not None:
                    credentials['max_age'] = max_age

            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPFound(referer)
            return credentials
Beispiel #6
0
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        # This will handle the logout request.
        if path_info == self._logout_url:
            # set in environ for self.challenge() to find later
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None
        elif path_info == self._login_url:
            form = parse_formvars(environ)
            form.update(query)
            try:
                credentials = {
                    'login': form['login'],
                    'password': form['password']
                }
            except KeyError:
                credentials = None

            def auth_resp(environ, start_response):
                import json
                resp = {"success": True}

                resp_str = json.dumps(resp)

                content_length = CONTENT_LENGTH.tuples(str(len(resp_str)))
                content_type = CONTENT_TYPE.tuples('application/json')
                headers = content_length + content_type
                start_response('200 OK', headers)
                return [resp_str]

            environ['repoze.who.application'] = auth_resp
            return credentials
Beispiel #7
0
    def identify(self, environ):
        query = parse_dict_querystring(environ)
        # If the extractor finds a special query string on any request,
        # it will attempt to find the values in the input body.
        if query.get(self.login_form_qs): 
            form = parse_formvars(environ)
            from StringIO import StringIO
            # XXX we need to replace wsgi.input because we've read it
            # this smells funny
            environ['wsgi.input'] = StringIO()
            form.update(query)
            try:
                login = form['login']
                password = form['password']
            except KeyError:
                return None
            del query[self.login_form_qs]
            environ['QUERY_STRING'] = urllib.urlencode(query)
            environ['repoze.who.application'] = HTTPFound(
                                                    construct_url(environ))
            credentials = {'login':login, 'password':password}
            max_age = form.get('max_age', None)
            if max_age is not None:
                credentials['max_age'] = max_age
            return credentials

        return None
Beispiel #8
0
    def challenge(self, environ, status, app_headers, forget_headers):
        logger = environ.get("repoze.who.logger", "")
        logger.info("formplugin challenge")
        if app_headers:
            location = LOCATION(app_headers)
            if location:
                headers = list(app_headers) + list(forget_headers)
                return HTTPFound(headers=headers)

        query = parse_dict_querystring(environ)
        hidden = []
        for key, val in query.items():
            hidden.append(HIDDEN_PRE_LINE % ("_%s_" % key, val))

        logger.info("hidden: %s", hidden)
        form = self.formbody or _DEFAULT_FORM
        form = form % "\n".join(hidden)

        if self.formcallable is not None:
            form = self.formcallable(environ)

        def auth_form(environ, start_response):
            content_length = CONTENT_LENGTH.tuples(str(len(form)))
            content_type = CONTENT_TYPE.tuples("text/html")
            headers = content_length + content_type + forget_headers
            start_response("200 OK", headers)
            return [form]

        return auth_form
Beispiel #9
0
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        if path_info == self.logout_handler_path:
            # we've been asked to perform a logout
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None

        elif path_info == self.login_handler_path:
            # we've been asked to perform a login
            form = parse_formvars(environ)
            form.update(query)
            try:
                max_age = form.get('max_age', None)
                credentials = {
                    'login': form['login'],
                    'password': form['password'],
                    'realm': form['realm'],
                }
            except KeyError:
                credentials = None

            if credentials is not None:
                max_age = form.get('max_age', None)
                if max_age is not None:
                    credentials['max_age'] = max_age

            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPFound(referer)
            return credentials
Beispiel #10
0
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        # we've been asked to perform a login
        if self.login_handler_match(path_info):
            body = environ['wsgi.input'].read()
            stream = environ['wsgi.input'] = StringIO(body)
            form = parse_formvars(environ)
            form.update(query)
            stream.seek(0)

            # extract username and password
            for key in self.username:
                if key in form:
                    login = form[key]; break
            else:
                return None

            for key in self.password:
                if key in form:
                    password = form[key]; break
            else:
                return None

            return {
                'login': login,
                'password': password,
                }
    def identify(self, environ):
        query = parse_dict_querystring(environ)
        # If the extractor finds a special query string on any request,
        # it will attempt to find the values in the input body.
        if query.get(self.login_form_qs):
            form = parse_formvars(environ)
            from StringIO import StringIO
            # XXX we need to replace wsgi.input because we've read it
            # this smells funny
            environ['wsgi.input'] = StringIO()
            form.update(query)
            try:
                login = form['login']
                password = form['password']
                realm = form['realm']
            except KeyError:
                return None
            del query[self.login_form_qs]
            environ['QUERY_STRING'] = urllib.urlencode(query)
            environ['repoze.who.application'] = HTTPFound(
                                                    construct_url(environ))
            credentials = {'login':login, 'password':password, 'realm':realm}
            max_age = form.get('max_age', None)
            if max_age is not None:
                credentials['max_age'] = max_age
            return credentials

        return None
Beispiel #12
0
    def identify(self, environ):
        query = parse_dict_querystring(environ)
        # If the extractor finds a special query string on any request,
        # it will attempt to find the values in the input body.
        if query.get(self.login_form_qs):
            form = parse_formvars(environ)
            from StringIO import StringIO
            # XXX we need to replace wsgi.input because we've read it
            # this smells funny
            environ['wsgi.input'] = StringIO()
            form.update(query)

            credentials = self._getCredentials(form)

            del query[self.login_form_qs]
            environ['QUERY_STRING'] = urllib.urlencode(query)
            environ['repoze.who.application'] = HTTPFound(
                                                    construct_url(environ))

            if 'login' not in credentials or 'password' not in credentials:
                return None

            return credentials

        return None
Beispiel #13
0
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        if path_info == self.logout_handler_path:
            # we've been asked to perform a logout
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPUnauthorized()

            # invalidate the session
            identity = environ.get('repoze.who.identity')
            if identity:
                self.forget(environ, identity)

            return None

        elif path_info == self.login_handler_path:
            # we've been asked to perform a login
            form = parse_formvars(environ)
            form.update(query)

            credentials = self._getCredentials(form)

            referer = environ.get('HTTP_REFERER', '/')
            environ['repoze.who.application'] = HTTPFound(referer)
            if 'login' not in credentials or 'password' not in credentials:
                return None
            return credentials
Beispiel #14
0
    def identify(self, environ):
        """
        Tries do the identification 
        """
        #logger = environ.get('repoze.who.logger', '')

        if "CONTENT_LENGTH" not in environ or not environ["CONTENT_LENGTH"]:
            logger.debug('[identify] get or empty post')
            return {}
        
        # if logger:
        #     logger.info("ENVIRON: %s" % environ)
        #     logger.info("self: %s" % (self.__dict__,))
        
        uri = environ.get('REQUEST_URI', construct_url(environ))
        
        logger.debug('[sp.identify] uri: %s' % (uri,))

        query = parse_dict_querystring(environ)
        logger.debug('[sp.identify] query: %s' % (query,))
        
        post = self._get_post(environ)

        try:
            logger.debug('[sp.identify] post keys: %s' % (post.keys(),))
        except (TypeError, IndexError):
            pass
            
        try:
            if not post.has_key("SAMLResponse"):
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can
                # find it
                environ["post.fieldstorage"] = post
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                #if self.debug:
                try:
                    session_info = self._eval_authn_response(environ,
                                                cgi_field_storage_to_dict(post))
                except Exception:
                    return None
        except TypeError, exc:
            # might be a ECP (=SOAP) response
            body = environ.get('s2repoze.body', None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception:
                    environ["post.fieldstorage"] = post
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}
Beispiel #15
0
    def authenticate(self, environ, identity):
        log.info('In authenticate()')

        def set_error(msg):
            log.info(msg)
            err = 1
            environ['FAS_AUTH_ERROR'] = err
            # HTTPForbidden ?
            err_app = HTTPFound(err_goto + '?' +
                                'came_from=' + quote_plus(came_from))
            environ['repoze.who.application'] = err_app

        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        try:
            auth_params = {'username': identity['login'],
                           'password': identity['password']}
        except KeyError:
            try:
                auth_params = {'session_id': identity['session_id']}
            except:
                # On error we return None which means that auth failed
                set_error('Parameters for authenticating not found')
                return None

        try:
            user_data = self._retrieve_user_info(environ, auth_params)
        except AuthError as e:
            set_error('Authentication failed: %s' % exception_to_bytes(e))
            log.warning(e)
            return None
        except Exception as e:
            set_error('Unknown auth failure: %s' % exception_to_bytes(e))
            return None

        if user_data:
            try:
                del user_data[1]['password']
                environ['CSRF_AUTH_SESSION_ID'] = user_data[0]
                return user_data[1]['username']
            except ValueError:
                set_error('user information from fas not in expected format!')
                return None
            except Exception:
                pass
        set_error('An unknown error happened when trying to log you in.'
                  ' Please try again.')
        return None
Beispiel #16
0
    def identify(self, environ):
        """
        Tries do the identification 
        """
        #logger = environ.get('repoze.who.logger', '')

        if "CONTENT_LENGTH" not in environ or not environ["CONTENT_LENGTH"]:
            logger.debug('[identify] get or empty post')
            return {}

        # if logger:
        #     logger.info("ENVIRON: %s" % environ)
        #     logger.info("self: %s" % (self.__dict__,))

        uri = environ.get('REQUEST_URI', construct_url(environ))

        logger.debug('[sp.identify] uri: %s' % (uri, ))

        query = parse_dict_querystring(environ)
        logger.debug('[sp.identify] query: %s' % (query, ))

        post = self._get_post(environ)

        try:
            logger.debug('[sp.identify] post keys: %s' % (post.keys(), ))
        except (TypeError, IndexError):
            pass

        try:
            if not post.has_key("SAMLResponse"):
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can
                # find it
                environ["post.fieldstorage"] = post
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                #if self.debug:
                try:
                    session_info = self._eval_authn_response(
                        environ, cgi_field_storage_to_dict(post))
                except Exception:
                    return None
        except TypeError, exc:
            # might be a ECP (=SOAP) response
            body = environ.get('s2repoze.body', None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception:
                    environ["post.fieldstorage"] = post
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}
def parse_dict_querystring_lower(environ):
    """Parses query string into dict with keys in lower case."""
    query = parse_dict_querystring(environ)
    # Convert WMS argument keys to lower case
    lowerlist = []
    for k,v in query.items():
        if k.lower() in WMS_ARGUMENTS:
            lowerlist.append(k)
    for k in lowerlist:
        v = query.pop(k)
        query[k.lower()] = v
    return query
 def parse_variables(self, environ):
     """
     Return the GET and POST variables in the request, as well as
     ``wsgiorg.routing_args`` arguments.
     
     :param environ: The WSGI environ.
     :return: The GET and POST variables and ``wsgiorg.routing_args``
         arguments.
     :rtype: dict
     
     This is a handy method for request-sensitive predicate checkers.
     
     It will return a dictionary for the POST and GET variables, as well as
     the `wsgiorg.routing_args 
     <http://www.wsgi.org/wsgi/Specifications/routing_args>`_'s 
     ``positional_args`` and ``named_args`` arguments, in the ``post``, 
     ``get``, ``positional_args`` and ``named_args`` items (respectively) of
     the returned dictionary.
     
     For example, if the user submits a form using the POST method to
     ``http://example.com/blog/hello-world/edit_post?wysiwyg_editor=Yes``,
     this method may return::
     
         {
         'post': {'new_post_contents': 'These are the new contents'},
         'get': {'wysiwyg_editor': 'Yes'},
         'named_args': {'post_slug': 'hello-world'},
         'positional_args': (),
         }
     
     But note that the ``named_args`` and ``positional_args`` items depend
     completely on how you configured the dispatcher.
     
     .. versionadded:: 1.0.4
     
     """
     get_vars = parse_dict_querystring(environ) or {}
     try:
         post_vars = parse_formvars(environ, False) or {}
     except KeyError:
         post_vars = {}
     routing_args = environ.get('wsgiorg.routing_args', ([], {}))
     positional_args = routing_args[0] or ()
     named_args = routing_args[1] or {}
     variables = {
         'post': post_vars,
         'get': get_vars,
         'positional_args': positional_args,
         'named_args': named_args
     }
     return variables
Beispiel #19
0
 def parse_variables(self, environ):
     """
     Return the GET and POST variables in the request, as well as
     ``wsgiorg.routing_args`` arguments.
     
     :param environ: The WSGI environ.
     :return: The GET and POST variables and ``wsgiorg.routing_args``
         arguments.
     :rtype: dict
     
     This is a handy method for request-sensitive predicate checkers.
     
     It will return a dictionary for the POST and GET variables, as well as
     the `wsgiorg.routing_args 
     <http://www.wsgi.org/wsgi/Specifications/routing_args>`_'s 
     ``positional_args`` and ``named_args`` arguments, in the ``post``, 
     ``get``, ``positional_args`` and ``named_args`` items (respectively) of
     the returned dictionary.
     
     For example, if the user submits a form using the POST method to
     ``http://example.com/blog/hello-world/edit_post?wysiwyg_editor=Yes``,
     this method may return::
     
         {
         'post': {'new_post_contents': 'These are the new contents'},
         'get': {'wysiwyg_editor': 'Yes'},
         'named_args': {'post_slug': 'hello-world'},
         'positional_args': (),
         }
     
     But note that the ``named_args`` and ``positional_args`` items depend
     completely on how you configured the dispatcher.
     
     .. versionadded:: 1.0.4
     
     """
     get_vars = parse_dict_querystring(environ) or {}
     try:
         post_vars = parse_formvars(environ, False) or {}
     except KeyError:
         post_vars = {}
     routing_args = environ.get('wsgiorg.routing_args', ([], {}))
     positional_args = routing_args[0] or ()
     named_args = routing_args[1] or {}
     variables = {
         'post': post_vars,
         'get': get_vars,
         'positional_args': positional_args,
         'named_args': named_args}
     return variables
Beispiel #20
0
    def _get_logins(self, environ, force_typecast=False):
        """
        Return the login counter from the query string in the ``environ``.

        If it's not possible to convert it into an integer and
        ``force_typecast`` is ``True``, it will be set to zero (int(0)).
        Otherwise, it will be ``None`` or an string.

        """
        variables = parse_dict_querystring(environ)
        failed_logins = variables.get(self.login_counter_name)
        if force_typecast:
            try:
                failed_logins = int(failed_logins)
            except (ValueError, TypeError):
                failed_logins = 0
        return failed_logins
    def _get_logins(self, environ, force_typecast=False):
        """
        Return the login counter from the query string in the ``environ``.

        If it's not possible to convert it into an integer and
        ``force_typecast`` is ``True``, it will be set to zero (int(0)).
        Otherwise, it will be ``None`` or an string.

        """
        variables = parse_dict_querystring(environ)
        failed_logins = variables.get(self.login_counter_name)
        if force_typecast:
            try:
                failed_logins = int(failed_logins)
            except (ValueError, TypeError):
                failed_logins = 0
        return failed_logins
    def identify(self, environ):
        """ Identify the user according to the current environment.

        An incoming request will be processed as follows, from top to
        bottom:

        #. If a logout is in progress, return immediately.
        #. If the URI matches a *logout* regex path, then log the user out.

           #. The user will be forgotten via the ``rememberer`` specified
              by ``rememberer_name``, and
           #. A redirection will log the user out from CAS.

        #. If the URI matches a *skip* regex path, then skip identification
        #. If the query string contains a CAS ticket, then validate it
           against the server and return the result.
        """
        #If logout is in process, abort identification
        if environ.has_key('rwpc.logout'):
            return

        uri = environ.get('REQUEST_URI', construct_url(environ))
        query = parse_dict_querystring(environ)

        #Logout for a path that matches the configuration
        for path in self.path_logout:
            if path.match(uri):
                # Trigger a challenge and tell challenge this is a
                # logout, passing the service URL to CAS
                log.warn('Logout called')
                environ['rwpc.logout'] = \
                        self._serviceURL(environ, urllib.urlencode(query))
                return

        #Skip any path that matches the configuration
        for path in self.path_toskip:
            if path.match(uri):
                log.warn('Skipping path: {}'.format(uri))
                return

        #Check the CAS validation ticket
        ticket = query.pop('ticket', None)
        if ticket:
            log.warn("Retrieving credentials: validating against CAS")
            credentials = self._validate(ticket, environ, query)
            return credentials
    def identify(self, environ):
        """ Identify the user according to the current environment.

        An incoming request will be processed as follows, from top to
        bottom:

        #. If a logout is in progress, return immediately.
        #. If the URI matches a *logout* regex path, then log the user out.

           #. The user will be forgotten via the ``rememberer`` specified
              by ``rememberer_name``, and
           #. A redirection will log the user out from CAS.

        #. If the URI matches a *skip* regex path, then skip identification
        #. If the query string contains a CAS ticket, then validate it
           against the server and return the result.
        """
        #If logout is in process, abort identification
        if environ.has_key('rwpc.logout'):
            return

        uri = environ.get('REQUEST_URI', construct_url(environ))
        query = parse_dict_querystring(environ)

        #Logout for a path that matches the configuration
        for path in self.path_logout:
            if path.match(uri):
                # Trigger a challenge and tell challenge this is a
                # logout, passing the service URL to CAS
                log.debug('Logout called')
                environ['rwpc.logout'] = \
                        self._serviceURL(environ, urllib.urlencode(query))
                return

        #Skip any path that matches the configuration
        for path in self.path_toskip:
            if path.match(uri):
                log.debug('Skipping path: {}'.format(uri))
                return

        #Check the CAS validation ticket
        ticket = query.pop('ticket', None)
        if ticket:
            log.debug("Retrieving credentials: validating against CAS")
            credentials = self._validate(ticket, environ, query)
            return credentials
    def identify(self, environ):
# WARNING : does not completely check the uri => should use construct_url
        #path_info = environ['PATH_INFO']
        #path_script = environ['SCRIPT_NAME']
        #uri  =  path_script + path_info
        uri = environ.get('REQUEST_URI',construct_url(environ))

        query = parse_dict_querystring(environ)
# This cgi parameter is set if this is a callback from the CAS server after 
# having perform a logout
        if query.get('bhp',None):
# we could get rid of this parameter..
            return None

# path_logout for every app. 
# 1/ A first redirection will disconnect from the CAS 
#    (passing in service=intended_url_callback_
# 2/ The URL will finally perform normally
        for regex in self.path_logout:
           if re.match(regex, uri) != None:
               if __MYDEBUG__ : print "LOGOUT #### "
               # we've been asked to perform a logout

# use all except : POST
# trigger the challenge and tells the challenge this is a logout
               query['bhp'] = 'go'
               environ['rwpc.logout'] = \
                    self._serviceURL(environ,urllib.urlencode(query))
               
               return None

# skipping, whatever it is (loggin, validating ticket etc.)
# except for logout (see above)
        for regex in self.path_toskip:
            if re.match(regex, uri) != None:
                if __MYDEBUG__ : print "########### SKIPPING"
                return None

# one use ticket, try to validate
        t = query.pop('ticket',None)
        if t:
            if __MYDEBUG__ : print "Retrieving credentials : calling cas, calidate"
            credentials = self._validate(t,environ,query)
            return credentials
Beispiel #25
0
    def search(self, filters):
        query = parse_dict_querystring(self.environ)
        size = int(query.get("size", DEFAULT_NUMBER_OF_ENTRIES))
        offset = int(query.get("offset", 0))

        filters = urllib.unquote(filters)
        filters = simplejson.loads(filters)
        entries = self.em.search(filters, re.IGNORECASE, size, offset)

        if len(entries) == size+1:
            entries.pop()  # remove "next" entry
            next = "?size=%d&offset=%d" % (size, offset+size)
        else:
            next = None
            
        output = {"collection": entries, "next": next}

        app = self.format.responder(output, content_type='application/json')
        return app(self.environ, self.start)
Beispiel #26
0
    def authenticate(self, environ, identity):
        log.info('In authenticate()')

        def set_error(msg):
            log.info(msg)
            err = 1
            environ['FAS_AUTH_ERROR'] = err
            # HTTPForbidden ?
            err_app = HTTPFound(err_goto + '?' + 'came_from=' +
                                quote_plus(came_from))
            environ['repoze.who.application'] = err_app

        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        try:
            auth_params = {
                'username': identity['login'],
                'password': identity['password']
            }
        except KeyError:
            try:
                auth_params = {'session_id': identity['session_id']}
            except:
                # On error we return None which means that auth failed
                set_error('Parameters for authenticating not found')
                return None

        try:
            user_data = self._retrieve_user_info(environ, auth_params)
        except AuthError, e:
            set_error('Authentication failed: %s' % exception_to_bytes(e))
            log.warning(e)
            return None
    def authenticate(self, environ, identity):
        log.info(b_('In authenticate()'))

        def set_error(msg):
            log.info(msg)
            err = 1
            environ['FAS_AUTH_ERROR'] = err
            # HTTPForbidden ?
            err_app = HTTPFound(err_goto + '?' +
                                'came_from=' + quote_plus(came_from))
            environ['repoze.who.application'] = err_app


        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        try:
            auth_params = {'username': identity['login'],
                    'password': identity['password']}
        except KeyError:
            try:
                auth_params = {'session_id': identity['session_id']}
            except:
                # On error we return None which means that auth failed
                set_error(b_('Parameters for authenticating not found'))
                return None

        try:
            user_data = self._retrieve_user_info(environ, auth_params)
        except AuthError, e:
            set_error(b_('Authentication failed: %s') % exception_to_bytes(e))
            log.warning(e)
            return None
Beispiel #28
0
    def _get_colorbar(self, environ):
        w, h = 90, 300
        query = parse_dict_querystring(environ)
        dpi = float(environ.get('pydap.responses.wms.dpi', 80))
        figsize = w / dpi, h / dpi
        cmap = query.get('cmap', environ.get('pydap.responses.wms.cmap',
                                             'jet'))

        def serialize(dataset):
            fix_map_attributes(dataset)
            fig = Figure(figsize=figsize, dpi=dpi)
            fig.figurePatch.set_alpha(0.0)
            ax = fig.add_axes([0.05, 0.05, 0.45, 0.85])
            ax.axesPatch.set_alpha(0.5)

            # Plot requested grids.
            layers = [
                layer for layer in query.get('LAYERS', '').split(',') if layer
            ] or [var.id for var in walk(dataset, GridType)]
            layer = layers[0]
            names = [dataset] + layer.split('.')
            grid = reduce(operator.getitem, names)

            actual_range = self._get_actual_range(grid)
            norm = Normalize(vmin=actual_range[0], vmax=actual_range[1])
            cb = ColorbarBase(ax,
                              cmap=get_cmap(cmap),
                              norm=norm,
                              orientation='vertical')
            for tick in cb.ax.get_yticklabels():
                tick.set_fontsize(14)
                tick.set_color('white')
                #tick.set_fontweight('bold')

            # Save to buffer.
            canvas = FigureCanvas(fig)
            output = StringIO()
            canvas.print_png(output)
            if hasattr(dataset, 'close'): dataset.close()
            return [output.getvalue()]

        return serialize
Beispiel #29
0
    def evaluate(self, environ, credentials):
        if not 'repoze.what.oauth' in environ:
            environ['repoze.what.oauth'] = {}
        what_env = environ['repoze.what.oauth']
        if environ['REQUEST_METHOD'] == 'GET':
            # Look for a token using the given oauth_token key
            params = parse_dict_querystring(environ)
            token_key = params.get('oauth_token')
            if not token_key:
                # Token key not given
                self.unmet()

            token = self.manager.get_request_token(token_key)
            if not token:
                # Token not found
                self.unmet()
            # Put the token to environ for later use in the actions
            what_env['token'] = token
        elif environ['REQUEST_METHOD'] == 'POST':
            # Just construct a callback maker and put it into environ
            what_env['make_callback'] = self._make_callback()
Beispiel #30
0
    def authenticate(self, environ, identity):
        log.info('Authenticate')
        try:
            login = identity['login']
            password = identity['password']
        except KeyError:
            return None

        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        user_data = ""
        try:
            fas = FasClient(self.url)
            user_data = fas.login(login, password)
        except AuthError, e:
            log.info('Authentication failed, setting error')
            log.warning(e)
            err = 1
            environ['FAS_AUTH_ERROR'] = err

            err_app = HTTPFound(
                err_goto + '?' +
                'came_from=' + quote_plus(came_from) +
                '&ec=' + login_error.USERNAME_PASSWORD_ERROR.code)

            environ['repoze.who.application'] = err_app

            return None
Beispiel #31
0
    def identify(self, environ):
        logger = environ.get("repoze.who.logger", "")
        logger.info("formplugin identify")
        # logger and logger.info("environ keys: %s", environ.keys())
        query = parse_dict_querystring(environ)
        # If the extractor finds a special query string on any request,
        # it will attempt to find the values in the input body.
        if query.get(self.login_form_qs):
            form = parse_formvars(environ)
            from StringIO import StringIO

            # we need to replace wsgi.input because we've read it
            # this smells funny
            environ["wsgi.input"] = StringIO()
            form.update(query)
            qinfo = {}
            for key, val in form.items():
                if key.startswith("_") and key.endswith("_"):
                    qinfo[key[1:-1]] = val
            if qinfo:
                environ["s2repoze.qinfo"] = qinfo
            try:
                login = form["login"]
                password = form["password"]
            except KeyError:
                return None
            del query[self.login_form_qs]
            query.update(qinfo)
            environ["QUERY_STRING"] = urllib.urlencode(query)
            environ["repoze.who.application"] = HTTPFound(
                construct_url(environ))
            credentials = {"login": login, "password": password}
            max_age = form.get("max_age", None)
            if max_age is not None:
                credentials["max_age"] = max_age
            return credentials

        return None
Beispiel #32
0
    def __call__(self, environ, start_response):
        # Create a Beaker cache dependent on the query string, since
        # most (all?) pre-computed values will depend on the specific
        # dataset. We strip all WMS related arguments since they don't
        # affect the dataset.
        query = parse_dict_querystring(environ)
        try:
            dap_query = [
                '%s=%s' % (k, query[k]) for k in query
                if k.lower() not in WMS_ARGUMENTS
            ]
            dap_query = [pair.rstrip('=') for pair in dap_query]
            dap_query.sort()  # sort for uniqueness
            dap_query = '&'.join(dap_query)
            location = construct_url(environ,
                                     with_query_string=True,
                                     querystring=dap_query)
            self.cache = environ['beaker.cache'].get_cache(
                'pydap.responses.wms+' + location)
        except KeyError:
            self.cache = None

        # Handle GetMap and GetCapabilities requests
        type_ = query.get('REQUEST', 'GetMap')
        if type_ == 'GetCapabilities':
            self.serialize = self._get_capabilities(environ)
            self.headers.append(('Content-type', 'text/xml'))
            self.headers.append(('Access-Control-Allow-Origin', '*'))
        elif type_ == 'GetMap':
            self.serialize = self._get_map(environ)
            self.headers.append(('Content-type', 'image/png'))
        elif type_ == 'GetColorbar':
            self.serialize = self._get_colorbar(environ)
            self.headers.append(('Content-type', 'image/png'))
        else:
            raise HTTPBadRequest('Invalid REQUEST "%s"' % type_)

        return BaseResponse.__call__(self, environ, start_response)
Beispiel #33
0
    def authenticate(self, environ, identity):
        log.info('Authenticate')
        try:
            login = identity['login']
            password = identity['password']
        except KeyError:
            return None

        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        user_data = ""
        try:
            fas = FasClient(self.url)
            user_data = fas.login(login, password)
        except AuthError, e:
            log.info('Authentication failed, setting error')
            log.warning(e)
            err = 1
            environ['FAS_AUTH_ERROR'] = err

            err_app = HTTPFound(err_goto + '?' + 'came_from=' +
                                quote_plus(came_from) + '&ec=' +
                                login_error.USERNAME_PASSWORD_ERROR.code)

            environ['repoze.who.application'] = err_app

            return None
Beispiel #34
0
    def identify(self, environ):
        '''
        identifier hook to get the user/password/realm from the form and
        return the identifier + credentials

        remark: in contradiction to the parent.identity method, we set the 
                referer always to be root '/'

        :param environment: the request data as environment

        :return credentials: dict with login, password and realm if not None
        '''
        referer = environ.get('HTTP_REFERER', '/')
        credentials = self.parent.identify(environ)

        if credentials is not None:
            # in case we have no '@' in login
            # we extende the login to contain the realm if there is a valid one
            query = parse_dict_querystring(environ)
            form = parse_formvars(environ)
            form.update(query)

            if not "@" in credentials['login']:
                # get the realm from the form data
                

                if 'realm' in form and form['realm']:
                    credentials['login'] = "******" % (credentials['login'],
                                                      form['realm'])

            otp = base64.b32encode(form.get('otp', ''))
            passw = base64.b32encode(form['password'])
            password = "******" % (otp, passw)
            credentials['password'] = password

            environ['repoze.who.application'] = HTTPFound(referer)
        return credentials
Beispiel #35
0
    def identify(self, environ):
        logger = environ.get('repoze.who.logger','')
        logger.info("formplugin identify")
        #logger and logger.info("environ keys: %s" % environ.keys())
        query = parse_dict_querystring(environ)
        # If the extractor finds a special query string on any request,
        # it will attempt to find the values in the input body.
        if query.get(self.login_form_qs):
            form = parse_formvars(environ)
            from StringIO import StringIO
            # we need to replace wsgi.input because we've read it
            # this smells funny
            environ['wsgi.input'] = StringIO()
            form.update(query)
            qinfo = {}
            for key, val in form.items():
                if key.startswith("_") and key.endswith("_"):
                    qinfo[key[1:-1]] = val
            if qinfo:
                environ["s2repoze.qinfo"] = qinfo
            try:
                login = form['login']
                password = form['password']
            except KeyError:
                return None
            del query[self.login_form_qs]
            query.update(qinfo)
            environ['QUERY_STRING'] = urllib.urlencode(query)
            environ['repoze.who.application'] = HTTPFound(
                                                    construct_url(environ))
            credentials = {'login':login, 'password':password}
            max_age = form.get('max_age', None)
            if max_age is not None:
                credentials['max_age'] = max_age
            return credentials

        return None
Beispiel #36
0
    def _get_colorbar(self, environ):
        w, h = 90, 300
        query = parse_dict_querystring(environ)
        dpi = float(environ.get('pydap.responses.wms.dpi', 80))
        figsize = w/dpi, h/dpi
        cmap = query.get('cmap', environ.get('pydap.responses.wms.cmap', 'jet'))

        def serialize(dataset):
            fix_map_attributes(dataset)
            fig = Figure(figsize=figsize, dpi=dpi)
            fig.figurePatch.set_alpha(0.0)
            ax = fig.add_axes([0.05, 0.05, 0.45, 0.85])
            ax.axesPatch.set_alpha(0.5)

            # Plot requested grids.
            layers = [layer for layer in query.get('LAYERS', '').split(',')
                    if layer] or [var.id for var in walk(dataset, GridType)]
            layer = layers[0]
            names = [dataset] + layer.split('.')
            grid = reduce(operator.getitem, names)

            actual_range = self._get_actual_range(grid)
            norm = Normalize(vmin=actual_range[0], vmax=actual_range[1])
            cb = ColorbarBase(ax, cmap=get_cmap(cmap), norm=norm,
                    orientation='vertical')
            for tick in cb.ax.get_yticklabels():
                tick.set_fontsize(14)
                tick.set_color('white')
                #tick.set_fontweight('bold')

            # Save to buffer.
            canvas = FigureCanvas(fig)
            output = StringIO() 
            canvas.print_png(output)
            if hasattr(dataset, 'close'): dataset.close()
            return [ output.getvalue() ]
        return serialize
Beispiel #37
0
    def authenticate(self, environ, identity):
        log.info(_('In authenticate()'))
        try:
            login = identity['login']
            password = identity['password']
        except KeyError:
            return None

        err_goto = '/login'
        default_came_from = '/'
        if 'SCRIPT_NAME' in environ:
            sn = environ['SCRIPT_NAME']
            err_goto = sn + err_goto
            default_came_from = sn + default_came_from

        query = parse_dict_querystring(environ)
        form = parse_formvars(environ)
        form.update(query)
        came_from = form.get('came_from', default_came_from)

        user_data = ''
        try:
            user_data = self.fas.get_user_info({'username': login,
                'password': password})
        except AuthError, e:
            log.info(_('Authentication failed, setting error'))
            log.warning(e)
            err = 1
            environ['FAS_AUTH_ERROR'] = err

            err_app = HTTPFound(err_goto + '?' +
                                'came_from=' + quote_plus(came_from))

            environ['repoze.who.application'] = err_app

            return None
Beispiel #38
0
    def identify(self, environ):
        '''
        identifier hook to get the user/password/realm from the form and
        return the identifier + credentials

        remark: in contradiction to the parent.identity method, we set the 
                referer always to be root '/'

        :param environment: the request data as environment

        :return credentials: dict with login, password and realm if not None
        '''
        referer = environ.get('HTTP_REFERER', '/')
        credentials = self.parent.identify(environ)

        if credentials is not None:
            # in case we have no '@' in login
            # we extende the login to contain the realm if there is a valid one
            query = parse_dict_querystring(environ)
            form = parse_formvars(environ)
            form.update(query)

            if not "@" in credentials['login']:
                # get the realm from the form data

                if 'realm' in form and form['realm']:
                    credentials['login'] = "******" % (credentials['login'],
                                                      form['realm'])

            otp = base64.b32encode(form.get('otp', ''))
            passw = base64.b32encode(form['password'])
            password = "******" % (otp, passw)
            credentials['password'] = password

            environ['repoze.who.application'] = HTTPFound(referer)
        return credentials
Beispiel #39
0
    def identify(self, environ):
        path_info = environ['PATH_INFO']
        query = parse_dict_querystring(environ)

        # This will handle the logout request.
        if path_info == self._logout_url:
            # set in environ for self.challenge() to find later
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None
        elif path_info == self._login_url:
            form = parse_formvars(environ)
            form.update(query)
            try:
                credentials = {
                    'login': form['login'],
                    'password': form['password']
                }
            except KeyError:
                credentials = None

            def auth_resp(environ, start_response):
                import json
                resp = {
                    "success": True
                }

                resp_str = json.dumps(resp)

                content_length = CONTENT_LENGTH.tuples(str(len(resp_str)))
                content_type = CONTENT_TYPE.tuples('application/json')
                headers = content_length + content_type
                start_response('200 OK', headers)
                return [resp_str]

            environ['repoze.who.application'] = auth_resp
            return credentials
Beispiel #40
0
    def __call__(self, environ, start_response):
        # Create a Beaker cache dependent on the query string, since
        # most (all?) pre-computed values will depend on the specific
        # dataset. We strip all WMS related arguments since they don't
        # affect the dataset.
        query = parse_dict_querystring(environ)
        try:
            dap_query = ['%s=%s' % (k, query[k]) for k in query
                    if k.lower() not in WMS_ARGUMENTS]
            dap_query = [pair.rstrip('=') for pair in dap_query]
            dap_query.sort()  # sort for uniqueness
            dap_query = '&'.join(dap_query)
            location = construct_url(environ,
                    with_query_string=True,
                    querystring=dap_query)
            self.cache = environ['beaker.cache'].get_cache(
                    'pydap.responses.wms+' + location)
        except KeyError:
            self.cache = None

        # Handle GetMap and GetCapabilities requests
        type_ = query.get('REQUEST', 'GetMap')
        if type_ == 'GetCapabilities':
            self.serialize = self._get_capabilities(environ)
            self.headers.append( ('Content-type', 'text/xml') )
            self.headers.append( ('Access-Control-Allow-Origin', '*') )
        elif type_ == 'GetMap':
            self.serialize = self._get_map(environ)
            self.headers.append( ('Content-type', 'image/png') )
        elif type_ == 'GetColorbar':
            self.serialize = self._get_colorbar(environ)
            self.headers.append( ('Content-type', 'image/png') )
        else:
            raise HTTPBadRequest('Invalid REQUEST "%s"' % type_)

        return BaseResponse.__call__(self, environ, start_response)
Beispiel #41
0
    def identify(self, environ):
        """
        Override the parent's identifier to introduce a login counter
        (possibly along with a post-login page) and load the login counter into
        the ``environ``.
        
        """

        path_info = environ['PATH_INFO']
        script_name = environ.get('SCRIPT_NAME') or '/'
        query = parse_dict_querystring(environ)

        if path_info == self.login_handler_path:
            ## We are on the URL where repoze.who processes authentication. ##
            # Let's append the login counter to the query string of the
            # "came_from" URL. It will be used by the challenge below if
            # authorization is denied for this request.
            form = parse_formvars(environ)
            form.update(query)
            try:
                credentials = {
                    'login': form['login'].lower(),
                    'password': form['password']
                }
            except KeyError:
                credentials = None
            referer = environ.get('HTTP_REFERER', script_name)
            destination = form.get('came_from', referer)

            if self.post_login_url:
                # There's a post-login page, so we have to replace the
                # destination with it.
                destination = self._get_full_path(self.post_login_url, environ)
                if 'came_from' in query:
                    # There's a referrer URL defined, so we have to pass it to
                    # the post-login page as a GET variable.
                    destination = self._insert_qs_variable(
                        destination, 'came_from', query['came_from'])
            failed_logins = self._get_logins(environ, True)
            new_dest = self._set_logins_in_url(destination, failed_logins)
            environ['repoze.who.application'] = HTTPFound(new_dest)
            return credentials

        elif path_info == self.logout_handler_path:
            ##    We are on the URL where repoze.who logs the user out.    ##
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', script_name)
            came_from = form.get('came_from', referer)
            # set in environ for self.challenge() to find later
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None

        elif path_info == self.login_form_url or self._get_logins(environ):
            ##  We are on the URL that displays the from OR any other page  ##
            ##   where the login counter is included in the query string.   ##
            # So let's load the counter into the environ and then hide it from
            # the query string (it will cause problems in frameworks like TG2,
            # where this unexpected variable would be passed to the controller)
            environ['repoze.who.logins'] = self._get_logins(environ, True)
            # Hiding the GET variable in the environ:
            if self.login_counter_name in query:
                del query[self.login_counter_name]
                environ['QUERY_STRING'] = urlencode(query, doseq=True)
Beispiel #42
0
    def identify(self, environ):
        """
        Tries to do the identification
        """
        #logger = environ.get('repoze.who.logger', '')

        query = parse_dict_querystring(environ)
        if ("CONTENT_LENGTH" not in environ or not environ["CONTENT_LENGTH"]) and \
                        "SAMLResponse" not in query and "SAMLRequest" not in query:
            logger.debug('[identify] get or empty post')
            return None
        
        # if logger:
        #     logger.info("ENVIRON: %s" % environ)
        #     logger.info("self: %s" % (self.__dict__,))
        
        uri = environ.get('REQUEST_URI', construct_url(environ))
        
        logger.debug('[sp.identify] uri: %s' % (uri,))

        query = parse_dict_querystring(environ)
        logger.debug('[sp.identify] query: %s' % (query,))

        if "SAMLResponse" in query or "SAMLRequest" in query:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            if post.list is None:
                post.list = []
            binding = BINDING_HTTP_POST

        try:
            logger.debug('[sp.identify] post keys: %s' % (post.keys(),))
        except (TypeError, IndexError):
            pass
            
        try:
            path_info = environ['PATH_INFO']
            logout = False
            if path_info in self.logout_endpoints:
                logout = True

            if logout and "SAMLRequest" in post:
                print("logout request received")
                try:
                    response = self.saml_client.handle_logout_request(
                        post["SAMLRequest"],
                        self.saml_client.users.subjects()[0], binding)
                    environ['samlsp.pending'] = self._handle_logout(response)
                    return {}
                except:
                    import traceback
                    traceback.print_exc()
            elif "SAMLResponse" not in post:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can
                # find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                environ['wsgi.input'] = StringIO(environ['s2repoze.body'])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                #if self.debug:
                try:
                    if logout:
                        response = self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"], binding)
                        if response:
                            action = self.saml_client.handle_logout_response(
                                response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                #logout complete
                                request = HTTPSeeOther(headers=[
                                    ('Location', "/")])
                            if request:
                                environ['samlsp.pending'] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, cgi_field_storage_to_dict(post),
                            binding=binding)
                except Exception, err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError, exc:
            # might be a ECP (=SOAP) response
            body = environ.get('s2repoze.body', None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception, err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
Beispiel #43
0
    def identify(self, environ):
        """
        Tries to do the identification
        """
        #logger = environ.get('repoze.who.logger', '')

        query = parse_dict_querystring(environ)
        if ("CONTENT_LENGTH" not in environ or not environ[
            "CONTENT_LENGTH"]) and \
                        "SAMLResponse" not in query and "SAMLRequest" not in \
                query:
            logger.debug('[identify] get or empty post')
            return None

        # if logger:
        #     logger.info("ENVIRON: %s" % environ)
        #     logger.info("self: %s" % (self.__dict__,))

        uri = environ.get('REQUEST_URI', construct_url(environ))

        logger.debug('[sp.identify] uri: %s' % (uri,))

        query = parse_dict_querystring(environ)
        logger.debug('[sp.identify] query: %s' % (query,))

        if "SAMLResponse" in query or "SAMLRequest" in query:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            binding = BINDING_HTTP_POST

        try:
            logger.debug('[sp.identify] post keys: %s' % (post.keys(),))
        except (TypeError, IndexError):
            pass

        try:
            path_info = environ['PATH_INFO']
            logout = False
            if path_info in self.logout_endpoints:
                logout = True

            if logout and "SAMLRequest" in post:
                print("logout request received")
                try:
                    response = self.saml_client.handle_logout_request(
                        post["SAMLRequest"][0],
                        self.saml_client.users.subjects()[0], binding)
                    environ['samlsp.pending'] = self._handle_logout(response)
                    return {}
                except:
                    import traceback

                    traceback.print_exc()
            elif "SAMLResponse" not in post:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can
                # find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                environ['wsgi.input'] = StringIO(environ['s2repoze.body'])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                #if self.debug:
                try:
                    if logout:
                        response = \
                            self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"][0], binding)
                        if response:
                            action = self.saml_client.handle_logout_response(
                                response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                #logout complete
                                request = HTTPSeeOther(headers=[
                                    ('Location', "/")])
                            if request:
                                environ['samlsp.pending'] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, post,
                            binding=binding)
                except Exception, err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError, exc:
            # might be a ECP (=SOAP) response
            body = environ.get('s2repoze.body', None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception, err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
Beispiel #44
0
    def identify(self, environ):
        """
        Override the parent's identifier to introduce a login counter
        (possibly along with a post-login page) and load the login counter into
        the ``environ``.
        
        """
        
        path_info = environ['PATH_INFO']
        script_name = environ.get('SCRIPT_NAME') or '/'
        query = parse_dict_querystring(environ)
        
        if path_info == self.login_handler_path:
            ## We are on the URL where repoze.who processes authentication. ##
            # Let's append the login counter to the query string of the
            # "came_from" URL. It will be used by the challenge below if
            # authorization is denied for this request.
            form = parse_formvars(environ)
            form.update(query)
            try:
                credentials = {
                    'login': form['login'].lower(),
                    'password': form['password']
                    }
            except KeyError:
                credentials = None
            referer = environ.get('HTTP_REFERER', script_name)
            destination = form.get('came_from', referer)
            
            if self.post_login_url:
                # There's a post-login page, so we have to replace the
                # destination with it.
                destination = self._get_full_path(self.post_login_url,
                                                  environ)
                if 'came_from' in query:
                    # There's a referrer URL defined, so we have to pass it to
                    # the post-login page as a GET variable.
                    destination = self._insert_qs_variable(destination,
                                                           'came_from',
                                                           query['came_from'])
            failed_logins = self._get_logins(environ, True)
            new_dest = self._set_logins_in_url(destination, failed_logins)
            environ['repoze.who.application'] = HTTPFound(new_dest)
            return credentials

        elif path_info == self.logout_handler_path:
            ##    We are on the URL where repoze.who logs the user out.    ##
            form = parse_formvars(environ)
            form.update(query)
            referer = environ.get('HTTP_REFERER', script_name)
            came_from = form.get('came_from', referer)
            # set in environ for self.challenge() to find later
            environ['repoze.who.application'] = HTTPUnauthorized()
            return None
            
        elif path_info == self.login_form_url or self._get_logins(environ):
            ##  We are on the URL that displays the from OR any other page  ##
            ##   where the login counter is included in the query string.   ##
            # So let's load the counter into the environ and then hide it from
            # the query string (it will cause problems in frameworks like TG2,
            # where this unexpected variable would be passed to the controller)
            environ['repoze.who.logins'] = self._get_logins(environ, True)
            # Hiding the GET variable in the environ:
            if self.login_counter_name in query:
                del query[self.login_counter_name]
                environ['QUERY_STRING'] = urlencode(query, doseq=True)
 def _GET(self):
     return parse_dict_querystring(self.environ)
Beispiel #46
0
    def identify(self, environ):
        """
        Tries to do the identification
        """
        # logger = environ.get('repoze.who.logger', '')

        session_info = None

        uri = environ.get("REQUEST_URI", construct_url(environ))
        query = parse_dict_querystring(environ)

        logger.debug("[sp.identify] uri: %s", uri)
        logger.debug("[sp.identify] query: %s", query)

        is_request = "SAMLRequest" in query
        is_response = "SAMLResponse" in query
        has_content_length = environ.get("CONTENT_LENGTH")

        if not has_content_length and not is_request and not is_response:
            logger.debug("[identify] get or empty post")
            return None

        if is_request or is_response:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            binding = BINDING_HTTP_POST

        try:
            logger.debug("[sp.identify] post keys: %s", post.keys())
        except (TypeError, IndexError):
            pass

        try:
            path = getpath(environ)
            logout = False
            if path in self.logout_endpoints:
                logout = True

            if logout and is_request:
                print("logout request received")
                if binding == BINDING_HTTP_REDIRECT:
                    saml_request = post["SAMLRequest"]
                else:
                    saml_request = post["SAMLRequest"][0]
                try:
                    response = self.saml_client.handle_logout_request(
                        saml_request,
                        self.saml_client.users.subjects()[0], binding)
                    environ["samlsp.pending"] = self._handle_logout(response)
                    return {}
                except:
                    import traceback

                    traceback.print_exc()
            elif not is_response:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                # only of s2repoze.body is present
                if "s2repoze.body" in environ:
                    environ["wsgi.input"] = StringIO(environ["s2repoze.body"])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                try:
                    if logout:
                        response = self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"][0], binding)
                        if response:
                            action = self.saml_client.handle_logout_response(
                                response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                request = HTTPSeeOther(headers=[("Location",
                                                                 "/")])
                            if request:
                                environ["samlsp.pending"] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, post, binding=binding)
                except Exception as err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError as exc:
            # might be a ECP (=SOAP) response
            body = environ.get("s2repoze.body", None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception as err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}

        if session_info:
            environ["s2repoze.sessioninfo"] = session_info
            identity_info = self._construct_identity(session_info)
        else:
            identity_info = None

        return identity_info
 def _GET(self):
     return parse_dict_querystring(self.environ)
Beispiel #48
0
    def _get_map(self, environ):
        # Calculate appropriate figure size.
        query = parse_dict_querystring(environ)
        dpi = float(environ.get('pydap.responses.wms.dpi', 80))
        w = float(query.get('WIDTH', 256))
        h = float(query.get('HEIGHT', 256))
        time = query.get('TIME')
        figsize = w / dpi, h / dpi
        bbox = [
            float(v) for v in query.get('BBOX', '-180,-90,180,90').split(',')
        ]
        cmap = query.get('cmap', environ.get('pydap.responses.wms.cmap',
                                             'jet'))

        def serialize(dataset):
            fix_map_attributes(dataset)
            fig = Figure(figsize=figsize, dpi=dpi)
            ax = fig.add_axes([0.0, 0.0, 1.0, 1.0])

            # Set transparent background; found through http://sparkplot.org/browser/sparkplot.py.
            if asbool(query.get('TRANSPARENT', 'true')):
                fig.figurePatch.set_alpha(0.0)
                ax.axesPatch.set_alpha(0.0)

            # Plot requested grids (or all if none requested).
            layers = [
                layer for layer in query.get('LAYERS', '').split(',') if layer
            ] or [var.id for var in walk(dataset, GridType)]
            for layer in layers:
                names = [dataset] + layer.split('.')
                grid = reduce(operator.getitem, names)
                if is_valid(grid, dataset):
                    self._plot_grid(dataset, grid, time, bbox, (w, h), ax,
                                    cmap)

            # Save to buffer.
            ax.axis([bbox[0], bbox[2], bbox[1], bbox[3]])
            ax.axis('off')
            canvas = FigureCanvas(fig)
            output = StringIO()
            # Optionally convert to paletted png
            paletted = asbool(
                environ.get('pydap.responses.wms.paletted', 'false'))
            if paletted:
                # Read image
                buf, size = canvas.print_to_buffer()
                im = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
                # Find number of colors
                colors = im.getcolors(256)
                # Only convert if the number of colors is less than 256
                if colors is not None:
                    ncolors = len(colors)
                    # Get alpha band
                    alpha = im.split()[-1]
                    # Convert to paletted image
                    im = im.convert("RGB")
                    im = im.convert("P",
                                    palette=Image.ADAPTIVE,
                                    colors=ncolors)
                    # Set all pixel values below ncolors to 1 and the rest to 0
                    mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)
                    # Paste the color of index ncolors and use alpha as a mask
                    im.paste(ncolors, mask)
                    # Truncate palette to actual size to save space
                    im.palette.palette = im.palette.palette[:3 * (ncolors + 1)]
                    im.save(output,
                            'png',
                            optimize=False,
                            transparency=ncolors)
                else:
                    canvas.print_png(output)
            else:
                canvas.print_png(output)
            if hasattr(dataset, 'close'): dataset.close()
            return [output.getvalue()]

        return serialize
Beispiel #49
0
    def identify(self, environ):
        """
        Tries to do the identification
        """
        #logger = environ.get('repoze.who.logger', '')

        query = parse_dict_querystring(environ)
        if ("CONTENT_LENGTH" not in environ or not environ[
            "CONTENT_LENGTH"]) and \
                        "SAMLResponse" not in query and "SAMLRequest" not in \
                query:
            logger.debug('[identify] get or empty post')
            return None

        # if logger:
        #     logger.info("ENVIRON: %s", environ)
        #     logger.info("self: %s", self.__dict__)

        uri = environ.get('REQUEST_URI', construct_url(environ)).split('?')[0]

        handled_urls = (self.conf.endpoint('assertion_consumer_service') +
                        self.conf.endpoint('single_logout_service'))
        logger.debug("Handled URLs: %s" % (handled_urls))
        logger.debug('[sp.identify] uri: %s', uri)
        for item in handled_urls:
            if item.find(uri) >= 0:
                break
        else:
            logger.debug('[sp.identify] uri passed: %s', uri)
            return

        logger.debug('[sp.identify] uri: %s', uri)
        logger.debug('[sp.identify] query: %s', query)

        if "SAMLResponse" in query or "SAMLRequest" in query:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            binding = BINDING_HTTP_POST

        try:
            logger.debug('[sp.identify] post keys: %s', post.keys())
        except (TypeError, IndexError):
            pass

        try:
            path = getpath(environ)
            logout = False
            if path in self.logout_endpoints:
                logout = True

            if logout and "SAMLRequest" in post:
                print("logout request received")
                if binding == BINDING_HTTP_REDIRECT:
                    saml_request = post["SAMLRequest"]
                else:
                    saml_request = post["SAMLRequest"][0]
                try:
                    response = self.saml_client.handle_logout_request(
                        saml_request,
                        self.saml_client.users.subjects()[0], binding)
                    environ['samlsp.pending'] = self._handle_logout(response)
                    return {}
                except:
                    import traceback

                    traceback.print_exc()
            elif "SAMLResponse" not in post:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can
                # find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                # only of s2repoze.body is present
                if 's2repoze.body' in environ:
                    environ['wsgi.input'] = StringIO(environ['s2repoze.body'])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                #if self.debug:
                try:
                    if logout:
                        response = \
                            self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"][0], binding)
                        if response:
                            action = self.saml_client.handle_logout_response(
                                response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                #logout complete
                                request = HTTPSeeOther(headers=[('Location',
                                                                 "/")])
                            if request:
                                environ['samlsp.pending'] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, post, binding=binding)
                except Exception as err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError as exc:
            # might be a ECP (=SOAP) response
            body = environ.get('s2repoze.body', None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception as err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}

        try:
            environ["s2repoze.sessioninfo"] = session_info
            return self._construct_identity(session_info)
        except UnboundLocalError:
            return None
Beispiel #50
0
    def _get_map(self, environ):
        # Calculate appropriate figure size.
        query = parse_dict_querystring(environ)
        dpi = float(environ.get('pydap.responses.wms.dpi', 80))
        w = float(query.get('WIDTH', 256))
        h = float(query.get('HEIGHT', 256))
        time = query.get('TIME')
        figsize = w/dpi, h/dpi
        bbox = [float(v) for v in query.get('BBOX', '-180,-90,180,90').split(',')]
        cmap = query.get('cmap', environ.get('pydap.responses.wms.cmap', 'jet'))

        def serialize(dataset):
            fix_map_attributes(dataset)
            fig = Figure(figsize=figsize, dpi=dpi)
            ax = fig.add_axes([0.0, 0.0, 1.0, 1.0])

            # Set transparent background; found through http://sparkplot.org/browser/sparkplot.py.
            if asbool(query.get('TRANSPARENT', 'true')):
                fig.figurePatch.set_alpha(0.0)
                ax.axesPatch.set_alpha(0.0)
            
            # Plot requested grids (or all if none requested).
            layers = [layer for layer in query.get('LAYERS', '').split(',')
                    if layer] or [var.id for var in walk(dataset, GridType)]
            for layer in layers:
                names = [dataset] + layer.split('.')
                grid = reduce(operator.getitem, names)
                if is_valid(grid, dataset):
                    self._plot_grid(dataset, grid, time, bbox, (w, h), ax, cmap)

            # Save to buffer.
            ax.axis( [bbox[0], bbox[2], bbox[1], bbox[3]] )
            ax.axis('off')
            canvas = FigureCanvas(fig)
            output = StringIO() 
            # Optionally convert to paletted png
            paletted = asbool(environ.get('pydap.responses.wms.paletted', 'false'))
            if paletted:
                # Read image
                buf, size = canvas.print_to_buffer()
                im = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
                # Find number of colors
                colors = im.getcolors(256)
                # Only convert if the number of colors is less than 256
                if colors is not None:
                    ncolors = len(colors)
                    # Get alpha band
                    alpha = im.split()[-1]
                    # Convert to paletted image
                    im = im.convert("RGB")
                    im = im.convert("P", palette=Image.ADAPTIVE, colors=ncolors)
                    # Set all pixel values below ncolors to 1 and the rest to 0
                    mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
                    # Paste the color of index ncolors and use alpha as a mask
                    im.paste(ncolors, mask)
                    # Truncate palette to actual size to save space
                    im.palette.palette = im.palette.palette[:3*(ncolors+1)]
                    im.save(output, 'png', optimize=False, transparency=ncolors)
                else:
                    canvas.print_png(output)
            else:
                canvas.print_png(output)
            if hasattr(dataset, 'close'): dataset.close()
            return [ output.getvalue() ]
        return serialize
Beispiel #51
0
    def identify(self, environ):
        """
        Tries to do the identification
        """
        # logger = environ.get('repoze.who.logger', '')

        session_info = None

        uri = environ.get("REQUEST_URI", construct_url(environ))
        query = parse_dict_querystring(environ)

        logger.debug("[sp.identify] uri: %s", uri)
        logger.debug("[sp.identify] query: %s", query)

        is_request = "SAMLRequest" in query
        is_response = "SAMLResponse" in query
        has_content_length = "CONTENT_LENGTH" in environ or environ["CONTENT_LENGTH"]

        if not has_content_length and not is_request and not is_response:
            logger.debug("[identify] get or empty post")
            return None

        if is_request or is_response:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            binding = BINDING_HTTP_POST

        try:
            logger.debug("[sp.identify] post keys: %s", post.keys())
        except (TypeError, IndexError):
            pass

        try:
            path = getpath(environ)
            logout = False
            if path in self.logout_endpoints:
                logout = True

            if logout and is_request:
                print("logout request received")
                if binding == BINDING_HTTP_REDIRECT:
                    saml_request = post["SAMLRequest"]
                else:
                    saml_request = post["SAMLRequest"][0]
                try:
                    response = self.saml_client.handle_logout_request(
                        saml_request, self.saml_client.users.subjects()[0], binding
                    )
                    environ["samlsp.pending"] = self._handle_logout(response)
                    return {}
                except:
                    import traceback

                    traceback.print_exc()
            elif not is_response:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                # only of s2repoze.body is present
                if "s2repoze.body" in environ:
                    environ["wsgi.input"] = StringIO(environ["s2repoze.body"])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                try:
                    if logout:
                        response = self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"][0], binding
                        )
                        if response:
                            action = self.saml_client.handle_logout_response(response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                request = HTTPSeeOther(headers=[("Location", "/")])
                            if request:
                                environ["samlsp.pending"] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, post, binding=binding
                        )
                except Exception as err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError as exc:
            # might be a ECP (=SOAP) response
            body = environ.get("s2repoze.body", None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception as err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}

        if session_info:
            environ["s2repoze.sessioninfo"] = session_info
            identity_info = self._construct_identity(session_info)
        else:
            identity_info = None

        return identity_info