Ejemplo n.º 1
0
  def execute(self, http_method, path, params=None, data=None, headers=None, allow_redirects=False, urlencode=True):
    """
    Submit an HTTP request.
    @param http_method: GET, POST, PUT, DELETE
    @param path: The path of the resource. Unsafe characters will be quoted.
    @param params: Key-value parameter data.
    @param data: The data to attach to the body of the request.
    @param headers: The headers to set for this request.
    @param allow_redirects: requests should automatically resolve redirects.
    @param urlencode: percent encode paths.

    @return: The result of urllib2.urlopen()
    """
    # Prepare URL and params
    if urlencode:
      path = urllib.quote(smart_str(path))
      params_encoded = {}
      if isinstance(params, dict):
        for k, val in params.iteritems():
          params_encoded[smart_str(k)] = smart_str(val)
        params = params_encoded
    url = self._make_url(path, params)

    ##REST logging
    command = "curl -X %s " % http_method
    if self.is_kerberos_auth:
      command += "--negotiate -u :"
    if headers:
      headers_string = ["{0}: {1}".format(k, v) for k, v in headers.items()]
      command += " -H ".join([""] + headers_string)
    if data and ((headers is None) or (headers.get("Content-Type", "") != "application/octet-stream")):
      command += "".join(" -d " + param for param in urllib.unquote_plus(data).split('&'))
    if DJANGO_DEBUG_MODE.get():
      self.logger.debug("REST invocation: %s '%s'" % (command, url))
    ######

    if http_method in ("GET", "DELETE"):
      if data is not None:
        self.logger.warn("GET and DELETE methods do not pass any data. Path '%s'" % path)
        data = None

    request_kwargs = {'allow_redirects': allow_redirects}
    if headers:
      request_kwargs['headers'] = headers
    if data:
      request_kwargs['data'] = data
    request_kwargs["verify"] = self._cert_validate

    try:
      resp = getattr(self._session, http_method.lower())(url, **request_kwargs)
      if resp.status_code >= 300:
        resp.raise_for_status()
        raise exceptions.HTTPError(response=resp)
      return resp
    except (exceptions.ConnectionError,
            exceptions.HTTPError,
            exceptions.RequestException,
            exceptions.URLRequired,
            exceptions.TooManyRedirects), ex:
      raise self._exc_class(ex)
Ejemplo n.º 2
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        """
    We also perform access logging in ``process_view()`` since we have the view function,
    which tells us the log level. The downside is that we don't have the status code,
    which isn't useful for status logging anyways.
    """
        request.ts = time.time()
        request.view_func = view_func
        access_log_level = getattr(view_func, 'access_log_level', None)

        # Skip loop for oidc
        if request.path in [
                '/oidc/authenticate/', '/oidc/callback/', '/oidc/logout/',
                '/hue/oidc_failed/'
        ]:
            return None

        if request.path.startswith(
                '/api/') or request.path == '/notebook/api/create_session':
            return None

        # Skip views not requiring login

        # If the view has "opted out" of login required, skip
        if hasattr(view_func, "login_notrequired"):
            log_page_hit(request,
                         view_func,
                         level=access_log_level or logging.DEBUG)
            return None

        # There are certain django views which are also opt-out, but
        # it would be evil to go add attributes to them
        if view_func in DJANGO_VIEW_AUTH_WHITELIST:
            log_page_hit(request,
                         view_func,
                         level=access_log_level or logging.DEBUG)
            return None

        # If user is logged in, check that he has permissions to access the app
        if request.user.is_active and request.user.is_authenticated:
            AppSpecificMiddleware.augment_request_with_app(request, view_func)

            # Until Django 1.3 which resolves returning the URL name, just do a match of the name of the view
            try:
                access_view = 'access_view:%s:%s' % (
                    request._desktop_app, resolve(request.path)[0].__name__)
            except Exception as e:
                access_log(request,
                           'error checking view perm: %s' % e,
                           level=access_log_level)
                access_view = ''

            app_accessed = request._desktop_app
            app_libs_whitelist = [
                "desktop", "home", "home2", "about", "hue", "editor",
                "notebook", "indexer", "404", "500", "403"
            ]
            if has_connectors():
                app_libs_whitelist.append('metadata')
                if DASHBOARD_ENABLED.get():
                    app_libs_whitelist.append('dashboard')
            # Accessing an app can access an underlying other app.
            # e.g. impala or spark uses code from beeswax and so accessing impala shows up as beeswax here.
            # Here we trust the URL to be the real app we need to check the perms.
            ui_app_accessed = get_app_name(request)
            if app_accessed != ui_app_accessed and ui_app_accessed not in (
                    'logs', 'accounts', 'login'):
                app_accessed = ui_app_accessed

            if app_accessed and \
                app_accessed not in app_libs_whitelist and \
                not (
                    is_admin(request.user) or
                    request.user.has_hue_permission(action="access", app=app_accessed) or
                    request.user.has_hue_permission(action=access_view, app=app_accessed)
                ) and \
                not (app_accessed == '__debug__' and DJANGO_DEBUG_MODE.get()):
                access_log(request,
                           'permission denied',
                           level=access_log_level)
                return PopupException(_(
                    "You do not have permission to access the %(app_name)s application."
                ) % {
                    'app_name': app_accessed.capitalize()
                },
                                      error_code=401).response(request)
            else:
                if not hasattr(request, 'view_func'):
                    log_page_hit(request, view_func, level=access_log_level)
                return None

        if AUTH.AUTO_LOGIN_ENABLED.get():
            # Auto-create the hue/hue user if not already present
            user = find_or_create_user(username='******', password='******')
            ensure_has_a_group(user)
            user = rewrite_user(user)

            user.is_active = True
            user.save()

            user = authenticate(request, username='******', password='******')
            if user is not None:
                login(request, user)
                return None

        logging.info("Redirecting to login page: %s", request.get_full_path())
        access_log(request, 'login redirection', level=access_log_level)
        no_idle_backends = ("libsaml.backend.SAML2Backend",
                            "desktop.auth.backend.SpnegoDjangoBackend",
                            "desktop.auth.backend.KnoxSpnegoDjangoBackend")
        if request.ajax and all(no_idle_backend not in AUTH.BACKEND.get()
                                for no_idle_backend in no_idle_backends):
            # Send back a magic header which causes Hue.Request to interpose itself
            # in the ajax request and make the user login before resubmitting the
            # request.
            response = HttpResponse("/* login required */",
                                    content_type="text/javascript")
            response[MIDDLEWARE_HEADER] = 'LOGIN_REQUIRED'
            return response
        else:
            if request.GET.get('is_embeddable'):
                return JsonResponse(
                    {
                        'url':
                        "%s?%s=%s" %
                        (settings.LOGIN_URL, REDIRECT_FIELD_NAME,
                         quote('/hue' + request.get_full_path().replace(
                             'is_embeddable=true', '').replace('&&', '&')))
                    }
                )  # Remove embeddable so redirect from & to login works. Login page is not embeddable
            else:
                return HttpResponseRedirect(
                    "%s?%s=%s" % (settings.LOGIN_URL, REDIRECT_FIELD_NAME,
                                  quote(request.get_full_path())))
Ejemplo n.º 3
0
    def execute(self,
                http_method,
                path,
                params=None,
                data=None,
                headers=None,
                allow_redirects=False,
                urlencode=True):
        """
    Submit an HTTP request.
    @param http_method: GET, POST, PUT, DELETE
    @param path: The path of the resource. Unsafe characters will be quoted.
    @param params: Key-value parameter data.
    @param data: The data to attach to the body of the request.
    @param headers: The headers to set for this request.
    @param allow_redirects: requests should automatically resolve redirects.
    @param urlencode: percent encode paths.

    @return: The result of urllib2.urlopen()
    """
        # Prepare URL and params
        if urlencode:
            path = urllib.quote(smart_str(path))
            params_encoded = {}
            if isinstance(params, dict):
                for k, val in params.iteritems():
                    params_encoded[smart_str(k)] = smart_str(val)
                params = params_encoded
        url = self._make_url(path, params)

        ##REST logging
        command = "curl -X %s " % http_method
        if self.is_kerberos_auth:
            command += "--negotiate -u :"
        if headers:
            headers_string = [
                "{0}: {1}".format(k, v) for k, v in headers.items()
            ]
            command += " -H ".join([""] + headers_string)
        if data and (
            (headers is None) or
            (headers.get("Content-Type", "") != "application/octet-stream")):
            command += "".join(
                " -d " + param
                for param in urllib.unquote_plus(data).split('&'))
        if DJANGO_DEBUG_MODE.get():
            self.logger.debug("REST invocation: %s '%s'" % (command, url))
        ######

        if http_method in ("GET", "DELETE"):
            if data is not None:
                self.logger.warn(
                    "GET and DELETE methods do not pass any data. Path '%s'" %
                    path)
                data = None

        request_kwargs = {'allow_redirects': allow_redirects}
        if headers:
            request_kwargs['headers'] = headers
        if data:
            request_kwargs['data'] = data
        request_kwargs["verify"] = self._cert_validate

        try:
            resp = getattr(self._session,
                           http_method.lower())(url, **request_kwargs)
            if resp.status_code >= 300:
                resp.raise_for_status()
                raise exceptions.HTTPError(response=resp)
            return resp
        except (exceptions.ConnectionError, exceptions.HTTPError,
                exceptions.RequestException, exceptions.URLRequired,
                exceptions.TooManyRedirects), ex:
            raise self._exc_class(ex)