Esempio n. 1
0
def autocommit(func):
    """
    Decorates func such that Django transactions are managed to autocommitt.

    Django's autocommit decorator begins and commits a transaction on every
    statement, but will not properly rollback such a failed transaction unless
    it marked as dirty (something tried to modify the database).  This is
    because Django is optimized for a web request cycle and throws away the
    connection at the end of each request.

    """
    def _autocommit(*args, **kw):
        try:
            transaction.enter_transaction_management()
            transaction.managed(False)
            try:
                result = func(*args, **kw)
            except:
                transaction.rollback_unless_managed()
                raise
            else:
                transaction.commit_unless_managed()
                return result
        finally:
            transaction.leave_transaction_management()
    return wraps(func)(_autocommit)
Esempio n. 2
0
def json_response(view):
    def wrapper(request, *args, **kwargs):
        data = view(request, *args, **kwargs)

        response = HttpResponse(simplejson.dumps(data, cls = DjangoJSONEncoder))
        return response
    return wraps(view)(wrapper)
def fetch_by_chunks_of(func, items_limit, ids_argument='ids'):
    """
    Class method decorator for fetching ammount of items bigger than allowed at once.
    Decorator receive parameters:
      * `items_limit`. Max limit of allowned items to fetch at once
      * `ids_argument` string, name of argument, that store list of ids.
    Usage:

        @fetch_by_chunks_of(1000)
        def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self, *args, **kwargs):

        if len(args) > 0:
            raise ValueError("It's prohibited to use non-key arguments for method decorated with @fetch_all, method is %s.%s(), args=%s" % (self.__class__.__name__, func.__name__, args))

        ids = kwargs[ids_argument]
        if ids:
            kwargs_sliced = dict(kwargs)
            for chunk in list_chunks_iterator(ids, items_limit):
                kwargs_sliced[ids_argument] = chunk
                instances = func(self, **kwargs_sliced)

            return renew_if_not_equal(self.model, instances, ids)
        else:
            return func(self, **kwargs)

    return wraps(func)(wrapper)
Esempio n. 4
0
def check_editor_access_permission(view_func):

  def decorate(request, *args, **kwargs):
    if not request.user.is_superuser and request.user.has_hue_permission(action="disable_editor_access", app="oozie"):
      raise PopupException(_('Missing permission to access the Oozie Editor'), error_code=401)
    return view_func(request, *args, **kwargs)
  return wraps(view_func)(decorate)
def fetch_only_expired(func, timeout_days, expiration_fieldname='fetched', ids_argument='ids'):
    """
    Class method decorator for fetching only expired items. Add parameter `only_expired=False` for decored method.
    If `only_expired` is True, method substitute argument `ids_argument` with new value, that consist only expired ids.
    Decorator receive parameters:
      * `timeout_days` int, number of day, after that instance is suppose to be expired.
      * `expiration_fieldname` string, name of datetime field, that indicate time of instance last fetching
      * `ids_argument` string, name of argument, that store list of ids.
    Usage:

        @fetch_only_expired(timeout_days=3)
        def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self, only_expired=False, *args, **kwargs):

        if len(args) > 0:
            raise ValueError("It's prohibited to use non-key arguments for method decorated with @fetch_all, method is %s.%s(), args=%s" % (self.__class__.__name__, func.__name__, args))

        if only_expired:
            ids = kwargs[ids_argument]
            expired_at = datetime.now() - timedelta(timeout_days)
            ids_non_expired = self.model.objects.filter(**{'%s__gte' % expiration_fieldname: expired_at, 'pk__in': ids}).values_list('pk', flat=True)
            kwargs[ids_argument] = list(set(ids).difference(set(ids_non_expired)))

            instances = None
            if len(kwargs[ids_argument]):
                instances = func(self, **kwargs)
            return renew_if_not_equal(self.model, instances, ids)

        return func(self, **kwargs)

    return wraps(func)(wrapper)
Esempio n. 6
0
 def _is_enabled(view):
     def _decorator(request, *args, **kwargs):
         if setting:
             return view(request, *args, **kwargs)
         else:
             return redirect(next)
     return wraps(view)(_decorator)
Esempio n. 7
0
    def renderer(func):
        def wrapper(request, *args, **kw):
            template_name = False
            output = func(request, *args, **kw)
            if isinstance(output, (list, tuple)):
                template_name = output[1]
                context = output[0]
            elif isinstance(output, dict):
                context = output
                template_name = template

            if template_name and context:
                # manage cookies in dict output
                cookies = []
                if '_cookies' in context:
                    cookies = context.pop('_cookies')

                response = render_to_response(template_name, context, RequestContext(request))
                for cookie in cookies:
                    # https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponse.set_cookie
                    response.set_cookie(
                        key = cookie['key'],
                        value = cookie.get('value'),
                        max_age = cookie.get('max_age'),
                        expires = cookie.get('expires'),
                        path = cookie.get('path', '/'),
                        domain = cookie.get('domain') or getattr(settings, 'SESSION_COOKIE_DOMAIN', None),
                        secure = cookie.get('secure'),
                        httponly = cookie.get('httponly', False)
                    )
                return response
            else:
                return output

        return wraps(func)(wrapper)
Esempio n. 8
0
  def inner(view_func):
    def decorate(request, *args, **kwargs):
      doc_id = uuid = doc2 = None

      try:
        if request.REQUEST.get('workflow'):
          workflow_id = request.REQUEST.get('workflow')
          if workflow_id.isdigit():
            doc_id = workflow_id
          else:
            uuid = workflow_id
        elif request.GET.get('uuid'):
          uuid = request.GET.get('uuid')
        elif request.GET.get('coordinator'):
          doc_id = request.GET.get('coordinator')
        elif request.GET.get('bundle'):
          doc_id = request.GET.get('bundle')
        elif 'doc_id' in kwargs:
          doc_id = kwargs['doc_id']

        if doc_id is not None:
          doc2 = Document2.objects.get(id=doc_id)
        elif uuid is not None:
          doc2 = Document2.objects.get_by_uuid(user=request.user, uuid=uuid)

        if doc2:
          doc2.doc.get().can_read_or_exception(request.user)
      except Document2.DoesNotExist:
        raise PopupException(_('Job with %(key)s=%(value)s does not exist') %
                             {'key': 'id' if doc_id else 'uuid', 'value': doc_id or uuid})

      return view_func(request, *args, **kwargs)
    return wraps(view_func)(decorate)
Esempio n. 9
0
    def __call__(ctx, f):
        """ Here we wrap the view method f and return the wrapped method """

        def wrapper(request, *args, **kwargs):
            """ Wrapper calls the view function, processes the result and returns HttpResponse """

            # call the view function itself...
            context = f(request, *args, **kwargs)

            # if we happen to have a Response, return it
            if isinstance(context, HttpResponse):
                return context

            # get template from view dict. Can be overridden from the **kwargs
            template = 'template' in context and context['template'] or None
            template = kwargs.get('template', template)
            logger.debug("Rendering template: %s" % template)

            # allows us to return the dict as json  (NB: BlitzGateway objects don't serialize)
            if template is None or template == 'json':
                json_data = simplejson.dumps(context)
                return HttpResponse(json_data, mimetype='application/javascript')
            else:
                # allow additional processing of context dict
                ctx.prepare_context(request, context, *args, **kwargs)
                t = template_loader.get_template(template)
                c = RequestContext(request, context)
                return HttpResponse(t.render(c))
        return wraps(f)(wrapper)
Esempio n. 10
0
 def decorator(func):
     def inner(request):
         for key in key_list:
             if key not in request.POST:
                 return HttpResponseForbidden()
         return func(request)
     return wraps(func, assigned = available_attrs(func))(inner)
Esempio n. 11
0
def user_in_project(view):
    """
    Checks if user exists in project and returns 403 if not
    """
    def wrapper(request, *args, **kwargs):

        try:
            # if user is a superuser, it has access to all projects
            if not request.user.is_superuser:
                #project = request.user.project_set.get(id=kwargs['project_id'])
                membership = Membership.objects.get(user=request.user, project__id=kwargs['project_id'])
                roles = Role.objects.all()
                for role in roles:
                    request.user.groups.remove(role.group)
                if membership.role.group:
                    request.user.groups.add(membership.role.group)

        except ObjectDoesNotExist:
            resp = render_to_response('403.html', context_instance=RequestContext(request))
            resp.status_code = 403
            return resp

        return view(request, *args, **kwargs)

    return wraps(view)(wrapper)
Esempio n. 12
0
    def decorator(func):
        def inner(request, *args, **kwargs):
            if request.method not in methods:
                logger.warning(
                    'Method Not Allowed (%s): %s' % (
                        request.method, request.path),
                    extra={
                        'status_code': 405,
                        'request': request
                    }
                )
                return HttpResponseNotAllowed(methods)

            coerce_put_post(request)

            language = requested_language(request)
            if language is not None and language != request.LANGUAGE_CODE:
                activate_language(language)

            authorized = check_api_key_authentication(request)
            if not authorized:
                authorized = request.user.is_authenticated()
            if login_required and not authorized:
                return HttpResponse(status=401)

            return func(request, *args, **kwargs)
        return wraps(func, assigned=available_attrs(func))(inner)
Esempio n. 13
0
def use_locale(func):
    """
    Decorator for tasks with respect to site's current language.
    e.g.:
        @task
        @use_locale
        def my_task(**kwargs):
            pass

    """
    def wrapper(*args, **kwargs):
        try:
            lang = settings.LANGUAGE_CODE
        except AttributeError:
            lang = None
        language = kwargs.pop('language', lang)
        prev_language = translation.get_language()
        if language:
            translation.activate(language)
        try:
            return func(*args, **kwargs)
        finally:
            translation.activate(prev_language)

    wrapper.__doc__ = func.__doc__
    wrapper.__name__ = func.__name__
    wrapper.__module__ = func.__module__
    return wraps(func)(wrapper)
Esempio n. 14
0
def respects_language(func):
    '''
    Decorator for tasks with respect to site's current language.
    You can use this decorator in tasks.py together with default @task decorator
    Be sure that task method have kwargs argument:

        @task
        @respects_language
        def my_task(any_optional_arguments, **kwargs):
            pass

    You can call this task this way:

        from django.utils import translation
        tasks.my_task.delay(any_optional_arguments, language=translation.get_language())
    '''
    def wrapper(*args, **kwargs):
        language = kwargs.pop('language', None)
        prev_language = translation.get_language()
        language and translation.activate(language)
        try:
            return func(*args, **kwargs)
        finally:
            translation.activate(prev_language)

    wrapper.__doc__ = func.__doc__
    wrapper.__name__ = func.__name__
    wrapper.__module__ = func.__module__
    return wraps(func)(wrapper)
Esempio n. 15
0
def enforce_lockout(function):
    """Wraps the provided ``function`` (django.contrib.auth.authenticate) to
    enforce lockout if the max attempts is exceeded.
    """

    def wrapper(*args, **kwargs):
        # Get request details from thread local
        request = getattr(thread_namespace, 'lockoutrequest', None)
        
        if request is None:
            # The call to authenticate must not have come via an HttpRequest, so
            # lockout is not enforced.
            return function(*args, **kwargs)

        params = []
        ip = request.META.get('HTTP_X_FORWARDED_FOR', None)
        if ip:
            # X_FORWARDED_FOR returns client1, proxy1, proxy2,...
            ip = ip.split(', ')[0]
        else:
            ip = request.META.get('REMOTE_ADDR', '')
        params.append(ip)
        if settings.USE_USER_AGENT:
            useragent = request.META.get('HTTP_USER_AGENT', '')
            params.append(useragent)

        if settings.WITH_USERNAME:
            try:
                username = kwargs.get('username') or args[0]
                params.append(username)
            except IndexError:
                pass
                #raise ValueError("No username in parameters, but LOCKOUT_WITH_USERNAME specified")
        
        key = generate_base_key(*params)
        attempts = cache.get(key) or 0
        
        if attempts >= settings.MAX_ATTEMPTS:
            raise LockedOut()
        
        result = function(*args, **kwargs)
        
        if result is None:
            try:
                attempts = cache.incr(key)
            except ValueError:
                # No such key, so set it
                cache.set(key, 1, settings.ENFORCEMENT_WINDOW)
            
            # If attempts is max allowed, set a new key with that
            # value so that the lockout time will be based on the most
            # recent login attempt.
            if attempts >= settings.MAX_ATTEMPTS:
                cache.set(key, attempts, settings.LOCKOUT_TIME)
        
        return result
    
    return wraps(function)(wrapper)

########################################################################
Esempio n. 16
0
def fetch_all(func, max_count):
    """
    Class method decorator for fetching all items. Add parameter `all=False` for decored method.
    If `all` is True, method runs as many times as it returns any results.
    Decorator receive 2 parameters:
      * integer `max_count` - max number of items method able to return
    Usage:

    @fetch_all(max_count=200)
    def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self, all=False, return_instances=None, *args, **kwargs):
        if all:
            if return_instances is None:
                return_instances = []
            kwargs['count'] = max_count
            instances = func(self, *args, **kwargs)
            instances_count = len(instances)
            return_instances += instances

            if instances_count > 1:
                # TODO: make protection somehow from endless loop
                kwargs['max_id'] = instances[instances_count-1].id
                return wrapper(self, all=True, return_instances=return_instances, *args, **kwargs)
            else:
                return self.model.objects.filter(id__in=[instance.id for instance in return_instances])
        else:
            return func(self, *args, **kwargs)

    return wraps(func)(wrapper)
Esempio n. 17
0
def reduce_data_amount(func):
    """
    Class method decorator for handling FacebookGraphAPIError:
        Please reduce the amount of data you're asking for, then retry your request.
    Usage:

        @reduce_data_amount
        @fetch_all(....)
        def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self, *args, **kwargs):
        try:
            instances = func(self, *args, **kwargs)
        except FacebookError as e:
            if e.message == "Please reduce the amount of data you're asking for, then retry your request" \
                and 'limit' in kwargs:
                    kwargs['limit'] = kwargs['limit'] / 2
                    log.debug('Reduced amount of asking data in twice. args=%s, kwargs=%s' % (args, kwargs))
                    return wrapper(self, *args, **kwargs)
            else:
                raise

        return instances

    return wraps(func)(wrapper)
Esempio n. 18
0
 def decorator(func):
     def inner(request):
         if not request.user.is_staff:
             if 'SID' not in request.POST or not Session.objects.get(pk=request.POST['SID']):
                 return HttpResponseForbidden()
         return func(request)
     return wraps(func, assigned=available_attrs(func))(inner)
Esempio n. 19
0
def commit_on_success(func):
    """Decorates func such that the current Django transaction is committed on
    successful return.

    If func raises an exception, the current transaction is rolled back.

    Why don't we use django.db.transaction.commit_on_success()? Because it does
    not commit or rollback unless Django actually tried to change something in
    the database. It was designed with short-lived web request cycles in mind.
    This gives us two problems:

    1. If the transaction consisted of read-only operations, the connection
       will stay idle inside a transaction, and that's bad.

    2. If a database error occurred inside a transaction, the connection would
       be useless until the transaction is rolled back.  Any further attempts
       to use the same connection will result in more errors, and a long-lived
       process will keep spewing error messages.

    """
    def _commit_on_success(*args, **kwargs):
        try:
            transaction.enter_transaction_management()
            transaction.managed(True)
            try:
                result = func(*args, **kwargs)
            except:
                transaction.rollback()
                raise
            else:
                transaction.commit()
            return result
        finally:
            transaction.leave_transaction_management()
    return wraps(func)(_commit_on_success)
Esempio n. 20
0
  def inner(view_func):
    def decorate(request, *args, **kwargs):
      doc_id = {}

      try:
        if request.GET.get('workflow') or request.POST.get('workflow'):
          workflow_id = request.GET.get('workflow') or request.POST.get('workflow')
          if workflow_id.isdigit():
            doc_id['id'] = workflow_id
          else:
            doc_id['uuid'] = workflow_id
        elif request.GET.get('uuid'):
          doc_id['uuid'] = request.GET.get('uuid')
        elif request.GET.get('coordinator'):
          doc_id['id'] = request.GET.get('coordinator')
        elif request.GET.get('bundle'):
          doc_id['id'] = request.GET.get('bundle')
        elif 'doc_id' in kwargs:
          doc_id['id'] = kwargs['doc_id']

        if doc_id:
          doc2 = Document2.objects.get(**doc_id)
          doc2.doc.get().can_read_or_exception(request.user)
      except Document2.DoesNotExist:
        raise PopupException(_('Job %(id)s does not exist') % {'id': doc_id})

      return view_func(request, *args, **kwargs)
    return wraps(view_func)(decorate)
Esempio n. 21
0
 def decorator(view_func):
     def _wrapped_view(self, request, *args, **kwargs):
         if test_func(request.user):
             return view_func(self, request, *args, **kwargs)
         path = urlquote(request.get_full_path())
         tup = login_url, redirect_field_name, path
         return HttpResponseRedirect('%s?%s=%s' % tup)
     return wraps(view_func)(_wrapped_view)
Esempio n. 22
0
def get_article_from_id(view):
    """
    Retrieves a specific article, passing it to the view directly
    """
    def wrapper(request, id, *args, **kwargs):
        article = get_object_or_404(Article, id=int(id))
        return view(request, article=article, *args, **kwargs)
    return wraps(view)(wrapper)
Esempio n. 23
0
def ensure_company_membership(func):
    def inner_func(request, *args, **kwargs):
        user = request.user
        company = request.company
        if not user.is_staff and user.id not in company.administrators and user.id not in company.members:
            raise Http404
        return func(request, *args, **kwargs)
    return wraps(func)(inner_func)
Esempio n. 24
0
 def decorator(func):
     def inner(request, *args, **kwargs):
         status = elasticSearchFunctions.check_server_status()
         if status == 'OK':
             return func(request, *args, **kwargs)
         else:
             return render(request, 'elasticsearch_error.html', {'status': status})
     return wraps(func)(inner)
Esempio n. 25
0
  def inner(view_func):
    def decorate(request, *args, **kwargs):
      dataset = kwargs.get('dataset')
      if dataset is not None and not (authorize_get and request.method == 'GET'):
        Job.objects.can_edit_or_exception(request, dataset.coordinator)

      return view_func(request, *args, **kwargs)
    return wraps(view_func)(decorate)
Esempio n. 26
0
 def _decorator(view_func):
     def _wrapped_view(request, *args, **kwargs):
         site = AmpCmsSite.objects.get_by_request(request)
         module_name = kwargs.get(C.URL_KEY_MODULE)
         page_name = kwargs.get(C.URL_KEY_PAGE)
         if not site.private:
             try:
                 module, page = get_public_module_and_page(site, module_name, page_name, request.user)
             except:
                 # Redirect to the public home page
                 return HttpResponseRedirect(public_url)
             else:
                 if page is None and (module.redirect_url or module.redirect_module):
                     if module.redirect_url:
                         log.debug('Successfully loaded module. Redirecting to %s' % module.redirect_url)
                         return HttpResponsePermanentRedirect(module.redirect_url)
                     elif module.redirect_module is not None:
                         if request.is_secure():
                             redirect_url = 'https://%s%s?%s' % (module.redirect_module.site.domain,
                                                                 module.redirect_module.get_absolute_url(),
                                                                 request.GET.urlencode())
                         else:
                             redirect_url = 'http://%s%s?%s' % (module.redirect_module.site.domain,
                                                                module.redirect_module.get_absolute_url(),
                                                                request.GET.urlencode())
                         log.debug('Successfully loaded module. Redirecting to %s' % redirect_url)
                         return HttpResponsePermanentRedirect(redirect_url)
                 else:
                     log.debug('Successfully loaded module and page: User %s viewing %s and %s' 
                               % (request.user.username, module.name, page.name))
             if page.private and not request.user.is_authenticated():
                 log.debug('Site is private and no user is logged in. Redirecting to login.')
                 return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, urlquote(request.get_full_path())))
         elif request.user.is_authenticated():
             # Attempt to load module and page
             try:
                 module, page = get_private_module_and_page(site, module_name, page_name, request.user)
             except PageDoesNotExist:
                 return HttpResponseRedirect(permission_denied_url)
             except NoPermissions:
                 return HttpResponseRedirect(settings.AMPCMS_ACCOUNT_NO_PERMISSIONS_URL)
             else:
                 log.debug('Successfully loaded module and page: User %s viewing page %s.%s' 
                           % (request.user.username, module.name, page.name))
         else:
             return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, urlquote(request.get_full_path())))
         
         kwargs.update({
             C.EXTRA_KWARGS_SITE : site,
             C.EXTRA_KWARGS_MODULE : module,
             C.EXTRA_KWARGS_PAGE : page
         })
         if not site.private or request.user.has_acl(module, page):
             return view_func(request, *args, **kwargs)
         else:
             log.warning('User ACL rejected for %s viewing %s.%s' % (request.user, module.name, page.name))
             return HttpResponseRedirect(permission_denied_url)
     return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view)
Esempio n. 27
0
def title_check(view):
    def new_view(request, title, *args, **kwargs):
        newtitle = title.replace(' ', '_')
        if newtitle != title:
            return redirect(request.path.replace(title, newtitle),
                            permanent=True)
        else:
            return view(request, title, *args, **kwargs)
    return wraps(view)(new_view)
Esempio n. 28
0
 def decorator(view_func):
     def _wrapped_view(request, *args, **kwargs):
         if test_func(request.user):
             return view_func(request, *args, **kwargs)
         path = urlquote(request.get_full_path())
         tup = login_url, redirect_field_name, path
         messages.warning(request, u"You must be logged in to perform this action.")
         return HttpResponseRedirect('%s?%s=%s' % tup)
     return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view)
Esempio n. 29
0
 def decorator(func):
     def inner(request, *args, **kwargs):
         if request.POST.has_key(key):
             return func(request, *args, **kwargs)
         else:
             context = context_creator and context_creator(request, *args, **kwargs) \
                 or RequestContext(request)
             return render_to_response(template_name, context)
     return wraps(func)(inner)
Esempio n. 30
0
def allow_admin_only(view_func):
  def decorate(request, *args, **kwargs):

    if not request.user.is_superuser:
      message = _("Permission denied. You are not an Administrator.")
      raise PopupException(message)

    return view_func(request, *args, **kwargs)
  return wraps(view_func)(decorate)
def opt_generator(func):
    """
    Class method or function decorator makes able to call generator methods as usual methods.
    Usage:

        @method_decorator(opt_generator)
        def some_method(self, ...):
            ...
            for count in some_another_method():
                yield (count, total)

    It's possible to call this method 2 different ways:

        * instance.some_method() - it will return nothing
        * for count, total in instance.some_method(as_generator=True):
            print count, total
    """
    def wrapper(*args, **kwargs):
        as_generator = kwargs.pop('as_generator', False)
        result = func(*args, **kwargs)
        return result if as_generator else list(result)

    return wraps(func)(wrapper)
Esempio n. 32
0
    def decorator(view_func):
        def _wrapped_view(view, request, *args, **kwargs):
            obj = None

            if hasattr(view, 'get_queryset'):
                pk = kwargs.get('pk')
                model = view.get_queryset().model
                if model and pk is not None:
                    obj = get_object_or_404(model, pk=pk)

            if obj is not None:
                try:
                    with cache.lock('%s-%s' % (obj.__class__.__name__, obj.pk),
                                    timeout=timeout,
                                    sleep=sleep,
                                    blocking_timeout=blocking_timeout):
                        return view_func(view, request, *args, **kwargs)
                except LockError:
                    raise Conflict('Resource is locked')
            else:
                return view_func(view, request, *args, **kwargs)

        return wraps(view_func)(_wrapped_view)
Esempio n. 33
0
    def inner(view_func):
        def decorate(request, *args, **kwargs):
            doc_id = None

            job = json.loads(request.POST.get('workflow', '{}'))
            if not job:
                job = json.loads(request.POST.get('coordinator', '{}'))
            elif not job:
                job = json.loads(request.POST.get('bundle', '{}'))

            if job and job.get('id'):
                doc_id = job.get('id')

                try:
                    doc2 = Document2.objects.get(id=job['id'])
                    doc2.doc.get().can_write_or_exception(request.user)
                except Document.DoesNotExist:
                    raise PopupException(
                        _('Job %(id)s does not exist') % {'id': doc_id})

            return view_func(request, *args, **kwargs)

        return wraps(view_func)(decorate)
Esempio n. 34
0
def check_job_access_permission(view_func):
    """
  Decorator ensuring that the user has access to the workflow or coordinator.

  Arg: 'workflow' or 'coordinator' id.
  Return: the workflow of coordinator or raise an exception

  Notice: its gets an id in input and returns the full object in output (not an id).
  """
    def decorate(request, *args, **kwargs):
        if 'workflow' in kwargs:
            job_type = 'workflow'
        else:
            job_type = 'coordinator'

        job = kwargs.get(job_type)
        if job is not None:
            job = Job.objects.is_accessible_or_exception(request, job)
        kwargs[job_type] = job

        return view_func(request, *args, **kwargs)

    return wraps(view_func)(decorate)
Esempio n. 35
0
def secure_required(view_func):
    """
    Decorator to switch an url from http to https.

    If a view is accessed through http and this decorator is applied to that
    view, than it will return a permanent redirect to the secure (https)
    version of the same view.

    The decorator also must check that ``ACCOUNTS_USE_HTTPS`` is enabled. If
    disabled, it should not redirect to https because the project doesn't
    support it.

    """
    def _wrapped_view(request, *args, **kwargs):
        if not request.is_secure():
            if accounts_settings.ACCOUNTS_USE_HTTPS:
                request_url = request.build_absolute_uri(
                    request.get_full_path())
                secure_url = request_url.replace('http://', 'https://')
                return HttpResponsePermanentRedirect(secure_url)
        return view_func(request, *args, **kwargs)

    return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view)
Esempio n. 36
0
    def inner(view_func):
        def decorate(request, *args, **kwargs):
            notebook_id = request.GET.get('notebook',
                                          request.GET.get('editor'))
            if not notebook_id:
                notebook_id = json.loads(request.POST.get('notebook',
                                                          '{}')).get('id')

            try:
                if notebook_id:
                    if str(notebook_id).isdigit():
                        document = Document2.objects.get(id=notebook_id)
                        document.can_read_or_exception(request.user)
                    else:
                        Document2.objects.get_by_uuid(user=request.user,
                                                      uuid=notebook_id)
            except Document2.DoesNotExist:
                raise PopupException(
                    _('Document %(id)s does not exist') % {'id': notebook_id})

            return view_func(request, *args, **kwargs)

        return wraps(view_func)(decorate)
Esempio n. 37
0
def edit_project_allowed(func):
    """
    Wraps a view with a signature such as
    view(request, slug, project_slug=None...)
    to -> view(request, team, project=None...),
    authorization credentials for viewing have been checked 
    for the user on that request.
    """
    def wrapper( self, team_slug, project_pk=None, *args, **kwargs):
        team = get_object_or_404(Team, slug=team_slug)
        project = None
        user = kwargs.pop("user")
        if project_pk is not None:
            project = get_object_or_404(Project, team=team, pk=project_pk)
        
        if not can_edit_project(user, team, project):
            return raise_forbidden_project(request)
        kwargs.update({
            "user": user,
            })

        return func( team, project, *args, **kwargs)
    return wraps(func)(wrapper)
Esempio n. 38
0
    def inner(view_func):
        def decorate(request, *args, **kwargs):
            doc_id = uuid = doc2 = None

            try:
                if request.REQUEST.get('workflow'):
                    workflow_id = request.REQUEST.get('workflow')
                    if workflow_id.isdigit():
                        doc_id = workflow_id
                    else:
                        uuid = workflow_id
                elif request.GET.get('uuid'):
                    uuid = request.GET.get('uuid')
                elif request.GET.get('coordinator'):
                    doc_id = request.GET.get('coordinator')
                elif request.GET.get('bundle'):
                    doc_id = request.GET.get('bundle')
                elif 'doc_id' in kwargs:
                    doc_id = kwargs['doc_id']

                if doc_id is not None:
                    doc2 = Document2.objects.get(id=doc_id)
                elif uuid is not None:
                    doc2 = Document2.objects.get_by_uuid(uuid)

                if doc2:
                    doc2.doc.get().can_read_or_exception(request.user)
            except Document2.DoesNotExist:
                raise PopupException(
                    _('Job with %(key)s=%(value)s does not exist') % {
                        'key': 'id' if doc_id else 'uuid',
                        'value': doc_id or uuid
                    })

            return view_func(request, *args, **kwargs)

        return wraps(view_func)(decorate)
Esempio n. 39
0
def check_job_permission(view_func):
    """
  Ensure that the user has access to the job.
  Assumes that the wrapped function takes a 'jobid' param named 'job'.
  """
    def decorate(request, *args, **kwargs):
        jobid = kwargs['job']
        try:
            job = get_job(request, job_id=jobid)
        except ApplicationNotRunning as e:
            LOG.warn(
                'Job %s has not yet been accepted by the RM, will poll for status.'
                % jobid)
            return job_not_assigned(request, jobid, request.path)

        if not SHARE_JOBS.get() and not is_admin(request.user) \
            and job.user != request.user.username and not can_view_job(request.user.username, job):
            raise PopupException(
                _("You don't have permission to access job %(id)s.") %
                {'id': jobid})
        kwargs['job'] = job
        return view_func(request, *args, **kwargs)

    return wraps(view_func)(decorate)
Esempio n. 40
0
def memoize(func,
            cache,
            num_args,
            offset=0,
            convert_args_func=None,
            update_cache_if_empty=True):
    """
    It's like django.utils.functional.memoize but with an extra offset parameter

    Only the first num_args are considered when creating the key, but starting
    from offset.
    """
    def wrapper(*args):
        mem_args = args[offset:num_args]
        if convert_args_func is not None:
            mem_args = convert_args_func(mem_args)
        if mem_args in cache:
            return cache[mem_args]
        result = func(*args)
        if update_cache_if_empty or result:
            cache[mem_args] = result
        return result

    return wraps(func)(wrapper)
Esempio n. 41
0
def check_privileges(view_func):
    def decorate(*args, **kwargs):

        if OPTIMIZER.APPLY_SENTRY_PERMISSIONS.get():
            checker = get_checker(user=args[0].user)
            action = 'SELECT'
            objects = []

            if kwargs.get('db_tables'):
                for db_table in kwargs['db_tables']:
                    objects.append({
                        'server': get_hive_sentry_provider(),
                        'db': _get_table_name(db_table)['database'],
                        'table': _get_table_name(db_table)['table']
                    })
            else:
                objects = [{'server': get_hive_sentry_provider()}]
                if kwargs.get('database_name'):
                    objects[0]['db'] = kwargs['database_name']
                if kwargs.get('table_name'):
                    objects[0]['table'] = kwargs['table_name']

            filtered = list(checker.filter_objects(objects, action))
            if len(filtered) != len(objects):
                raise MissingSentryPrivilegeException({
                    'pre_filtering':
                    objects,
                    'post_filtering':
                    filtered,
                    'diff':
                    len(objects) - len(filtered)
                })

        return view_func(*args, **kwargs)

    return wraps(view_func)(decorate)
Esempio n. 42
0
    def decorator(view_func):
        def _wrapped_view(view, request, *args, **kwargs):
            pk = kwargs.get('pk')
            obj = None

            model = view.get_queryset().model
            if model and pk is not None:
                obj = get_object_or_404(model, pk=pk)

            has_permissions = False
            if accept_global_perms:
                has_permissions = all(
                    request.user.has_perm(perm) for perm in perms)

            if not has_permissions:
                has_permissions = all(
                    request.user.has_perm(perm, obj) for perm in perms)

            if not has_permissions:
                raise exceptions.PermissionDenied

            return view_func(view, request, *args, **kwargs)

        return wraps(view_func)(_wrapped_view)
Esempio n. 43
0
def rm_ha(funct):
    """
  Support RM HA by trying other RM API.
  """
    def decorate(api, *args, **kwargs):
        try:
            return funct(api, *args, **kwargs)
        except Exception as ex:
            ex_message = str(ex)
            if 'Connection refused' in ex_message or 'Connection aborted' in ex_message or 'standby RM' in ex_message:
                LOG.info(
                    'Resource Manager not available, trying another RM: %s.' %
                    ex)
                rm_ha = get_next_ha_yarncluster(current_user=api.user)
                if rm_ha is not None:
                    if rm_ha[1].url == api.resource_manager_api.url:
                        raise ex
                    LOG.info('Retrying with Resource Manager: %s.' %
                             rm_ha[1].url)
                    config, api.resource_manager_api = rm_ha
                    return funct(api, *args, **kwargs)
            raise ex

    return wraps(funct)(decorate)
Esempio n. 44
0
    def decorator(controller):
        def wrapper(*args, **kwargs):
            from tethys_quotas.models import ResourceQuota
            from tethys_apps.utilities import get_active_app

            request = None
            for index, arg in enumerate(args):
                if isinstance(arg, HttpRequest):
                    request = arg
                    break

            if request is None:
                raise ValueError(
                    'No request given. The app_workspace decorator only works on controllers.'
                )

            try:
                codename = 'app_workspace_quota'
                rq = ResourceQuota.objects.get(codename=codename)

            except ResourceQuota.DoesNotExist:
                log.warning(
                    'ResourceQuota with codename {} does not exist.'.format(
                        codename))

            # Get the active app
            app = get_active_app(request, get_class=True)

            if not passes_quota(app, codename):
                raise PermissionDenied(rq.help)

            the_workspace = _get_app_workspace(app)

            return controller(*args, the_workspace, **kwargs)

        return wraps(controller)(wrapper)
Esempio n. 45
0
def fetch_all(func, max_count):
    """
    Class method decorator for fetching all items. Add parameter `all=False` for decored method.
    If `all` is True, method runs as many times as it returns any results.
    Decorator receive 2 parameters:
      * integer `max_count` - max number of items method able to return
    Usage:

    @fetch_all(max_count=200)
    def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self, all=False, return_instances=None, *args, **kwargs):
        if all:
            if not return_instances:
                return_instances = []
            kwargs['count'] = max_count
            instances = func(self, *args, **kwargs)
            instances_count = len(instances)
            return_instances += instances

            if instances_count > 1:
                # TODO: make protection somehow from endless loop
                kwargs['max_id'] = instances[instances_count - 1].id
                return wrapper(self,
                               all=True,
                               return_instances=return_instances,
                               *args,
                               **kwargs)
            else:
                return self.model.objects.filter(
                    id__in=[instance.id for instance in return_instances])
        else:
            return func(self, *args, **kwargs)

    return wraps(func)(wrapper)
Esempio n. 46
0
def pend_form(view):
    def wrapper(request,
                form_class,
                template_name,
                form_hash=None,
                *args,
                **kwargs):
        if request.method == 'POST':
            form = form_class(request.POST)
            if 'pend' in request.POST:
                form_hash = form.pend()
                return http.HttpRedirect(form_hash)
            else:
                if form.is_valid():
                    return view(request, form=form, *args, **kwargs)
                else:
                    if form_hash:
                        form = form_class.resume(form_hash)
                    else:
                        form = form_class()
                return render_to_response(template_name, {'form': form},
                                          RequestContext(request))

    return wraps(view)(wrapper)
Esempio n. 47
0
        except JobExpired, e:
            raise PopupException(
                _('Job %s has expired.') % jobid,
                detail=_('Cannot be found on the History Server.'))
        except Exception, e:
            raise PopupException(_('Could not find job %s.') % jobid, detail=e)

        if not SHARE_JOBS.get() and not request.user.is_superuser \
            and job.user != request.user.username and not can_view_job(request.user.username, job):
            raise PopupException(
                _("You don't have permission to access job %(id)s.") %
                {'id': jobid})
        kwargs['job'] = job
        return view_func(request, *args, **kwargs)

    return wraps(view_func)(decorate)


def job_not_assigned(request, jobid, path):
    if request.GET.get('format') == 'json':
        result = {'status': -1, 'message': ''}

        try:
            get_api(request.user, request.jt).get_job(jobid=jobid)
            result['status'] = 0
        except ApplicationNotRunning, e:
            result['status'] = 1
        except Exception, e:
            result['message'] = _('Error polling job %s: %s') % (jobid, e)

        return JsonResponse(result, encoder=JSONEncoderForHTML)
Esempio n. 48
0
def fetch_all(func, return_all=None, always_all=False, pagination='anchor'):
    """
    Class method decorator for fetching all items. Add parameter `all=False` for decored method.
    If `all` is True, method runs as many times as it returns any results.
    Decorator receive parameters:
      * callback method `return_all`. It's called with the same parameters
        as decored method after all itmes are fetched.
      * `always_all` bool - return all instances in any case of argument `all`
        of decorated method
    Usage:

        @fetch_all(return_all=lambda self,instance,*a,**k: instance.items.all())
        def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self, all=False, instances_all=None, *args, **kwargs):

        if len(args) > 0:
            raise ValueError(
                "It's prohibited to use non-key arguments for method decorated with @fetch_all, method is %s.%s(), args=%s"
                % (self.__class__.__name__, func.__name__, args))

        instances = func(self, **kwargs)
        if len(instances) == 2 and isinstance(instances, tuple):
            instances, response = instances

        if always_all or all:
            if isinstance(instances, QuerySet):
                if not instances_all:
                    instances_all = QuerySet().none()
                instances_count = instances.count()
                if instances_count:
                    instances_all |= instances
            elif isinstance(instances, list):
                if not instances_all:
                    instances_all = []
                instances_count = len(instances)
                instances_all += instances
            else:
                raise ValueError(
                    "Wrong type of response from func %s. It should be QuerySet or list, not a %s"
                    % (func, type(instances)))

            # recursive pagination
            if instances_count and (
                    'has_more' in response and response['has_more']
                    or 'has_more' not in response and pagination in response):
                kwargs[pagination] = response.get(pagination)
                return wrapper(self,
                               all=all,
                               instances_all=instances_all,
                               **kwargs)

            if return_all:
                kwargs['instances'] = instances_all
                return return_all(self, **kwargs)
            else:
                return instances_all
        else:
            return instances

    return wraps(func)(wrapper)
Esempio n. 49
0
    def decorator(controller_func):
        def _wrapped_controller(*args, **kwargs):
            # With OR check, we assume the permission test passes upfront
            # Find request (varies position if class method is wrapped)
            # e.g.: func(request, *args, **kwargs) vs. method(self, request, *args, **kwargs)
            request_args_index = None
            the_self = None

            for index, arg in enumerate(args):
                if isinstance(arg, HttpRequest):
                    request_args_index = index

            # Args are everything after the request object
            if request_args_index is not None:
                request = args[request_args_index]
            else:
                raise ValueError("No HttpRequest object provided.")

            if request_args_index > 0:
                the_self = args[0]

            args = args[request_args_index + 1:]

            # OR Loop
            if use_or:
                pass_permission_test = False
                for perm in perms:
                    # If any one of the permission evaluates to True, the test passes
                    if has_permission(request, perm):
                        pass_permission_test = True
                        break

            # AND Loop
            else:
                # Assume pass test
                pass_permission_test = True

                for perm in perms:
                    # If any one of the permissions evaluates to False, the test fails
                    if not has_permission(request, perm):
                        pass_permission_test = False
                        break

            if not pass_permission_test:
                if not raise_exception:
                    # If user is authenticated...
                    if request.user.is_authenticated:
                        # User feedback
                        messages.add_message(request, messages.WARNING,
                                             message)

                        # Default redirect URL
                        redirect_url = reverse('app_library')

                        # If there is a referer (i.e.: we followed a link to get here)
                        if 'HTTP_REFERER' in request.META:
                            # Try to redirect to the referer URL
                            referer = request.META['HTTP_REFERER']
                            parsed_referer = urlparse(referer)

                            # But avoid an infinite redirect loop (if referer is self somehow)
                            if parsed_referer.path != request.path:
                                # e.g. hostname:port
                                request_host_parts = request.get_host().split(
                                    ':')

                                # Only attempt redirect if host names are the same
                                if len(
                                        request_host_parts
                                ) > 0 and parsed_referer.hostname == request_host_parts[
                                        0]:
                                    redirect_url = parsed_referer.path

                        # Redirect to apps library with message
                        return redirect(redirect_url)

                    # If not authenticated...
                    else:
                        # User feedback
                        messages.add_message(
                            request, messages.INFO,
                            "You must be logged in to access this feature.")

                        # Redirect to login page
                        return redirect(
                            reverse('accounts:login') + '?next=' +
                            request.path)

                else:
                    # Return Error 404: Not Found in production to prevent directory enumeration
                    if not getattr(settings, 'DEBUG', False):
                        return tethys_portal_error.handler_404(request)
                    return tethys_portal_error.handler_403(request)

            # Call the controller
            if the_self is not None:
                response = controller_func(the_self, request, *args, **kwargs)
            else:
                response = controller_func(request, *args, **kwargs)

            return response

        return wraps(controller_func)(_wrapped_controller)
Esempio n. 50
0
    def wrap_many_related_descriptor(descriptor_cls):
        """Wraps the ``descriptor_cls``'s __get__ method to return a modified
        manager whose all() method will return the cached related objects, if
        populated. Additionally, add an uncache method to clear the all()
        cache, and pathes add, remove, and clear to call uncached_all before
        adding, removing, or clearing.
        """

        if descriptor_cls in (ManyRelatedObjectsDescriptor,
                              ForeignRelatedObjectsDescriptor):

            def get_attr_name(descriptor):
                return descriptor.related.get_accessor_name()

        elif descriptor_cls == ReverseManyRelatedObjectsDescriptor:

            def get_attr_name(descriptor):
                return descriptor.field.name
        else:
            raise ValueError("invalid descriptor class: %s" %
                             descriptor_cls.__name__)

        original__get__ = descriptor_cls.__get__

        def __get__(self, instance, *args, **kwargs):

            if instance is None:
                return original__get__(self, instance, *args, **kwargs)

            manager = original__get__(self, instance, *args, **kwargs)

            attr_name = get_attr_name(self)
            cached_attr_name = "%s%s" % (
                cachetree_settings.CACHETREE_MANY_RELATED_PREFIX, attr_name)

            original_all = manager.__class__.all

            def all_(*args, **kwargs):
                try:
                    return getattr(instance, cached_attr_name)
                except AttributeError:
                    return original_all(*args, **kwargs)

            manager.__class__.all = wraps(original_all)(all_)

            def uncache(*args, **kwargs):
                """Uncaches the manager's all method, if it's cached."""
                try:
                    delattr(instance, cached_attr_name)
                except AttributeError:
                    pass

            manager.__class__.uncache = uncache

            # The add, remove, and clear methods should uncache the manager's
            # all(), since they change the related objects.
            if hasattr(manager, "add"):
                original_add = manager.add

                def add(*args, **kwargs):
                    manager.uncache()
                    return original_add(*args, **kwargs)

                manager.add = wraps(original_add)(add)

            if hasattr(manager, "remove"):
                original_remove = manager.remove

                def remove(*args, **kwargs):
                    manager.uncache()
                    return original_remove(*args, **kwargs)

                manager.remove = wraps(original_remove)(remove)

            if hasattr(manager, "clear"):
                original_clear = manager.clear

                def clear(*args, **kwargs):
                    manager.uncache()
                    return original_clear(*args, **kwargs)

                manager.clear = wraps(original_clear)(clear)

            return manager

        descriptor_cls.__get__ = wraps(original__get__)(__get__)
Esempio n. 51
0
    def decorate(api, *args, **kwargs):
        try:
            return funct(api, *args, **kwargs)
        except Exception, ex:
            if 'Could not connect to' in str(ex):
                LOG.info('JobTracker not available, trying JT plugin HA: %s.' %
                         ex)
                jt_ha = get_next_ha_mrcluster()
                if jt_ha is not None:
                    if jt_ha[1].host == api.jt.host:
                        raise ex
                    config, api.jt = jt_ha
                    return funct(api, *args, **kwargs)
            raise ex

    return wraps(funct)(decorate)


def rm_ha(funct):
    """
  Support RM HA by trying other RM API.
  """
    def decorate(api, *args, **kwargs):
        try:
            return funct(api, *args, **kwargs)
        except Exception, ex:
            ex_message = str(ex)
            if 'Connection refused' in ex_message or 'standby RM' in ex_message:
                LOG.info(
                    'Resource Manager not available, trying another RM: %s.' %
                    ex)
Esempio n. 52
0
def log_errors(function):
    """Decorator that catches and logs error in the wrapped
    function.
    """
    def wrapper(*args, **kwargs):
        try:
            return function(*args, **kwargs)
        except Exception, e:
            logger.error(
                "Error in {0}.{1}: {2}".format(
                    function.__module__, function.__name__,e),
                exc_info=e,
            )
            
    return wraps(function)(wrapper)

########################################################################

def monitor(function):
    """Decorator that performs monitoring before calling the wrapped
    function.
    """
    from monitor import ServiceMonitor
    def wrapper(*args, **kwargs):
        ServiceMonitor.monitor()
        return function(*args, **kwargs)
    return wraps(function)(wrapper)

########################################################################
Esempio n. 53
0
    urlnode = django_url_tag(parser, urltoken)
    return LocaleURLNode(bits[1], urlnode)


class LocaleURLNode(Node):
    def __init__(self, locale, urlnode):
        self.locale = locale
        self.urlnode = urlnode

    def render(self, context):
        locale = resolve_variable(self.locale, context)
        if utils.supported_language(locale) is None:
            raise ValueError("locale not in settings.LANGUAGES: %s" % locale)
        path = self.urlnode.render(context)
        if self.urlnode.asvar:
            self.urlnode.render(context)
            context[self.urlnode.asvar] = chlocale(context[self.urlnode.asvar],
                                                   locale)
            return ''
        else:
            return chlocale(path, locale)


def locale_url_wrapper(parser, token):
    return locale_url(parser, token, django_url_tag=defaulttags.url)


locale_url_wrapper = wraps(locale_url)(locale_url_wrapper)

register.tag('locale_url', locale_url_wrapper)
Esempio n. 54
0
    def decorator(view):
        def wrapper(request, *args, **kwargs):
            response = view(request, *args, **kwargs)
            response['Content-Type'] = c_type

        return wraps(view)(wrapper)
Esempio n. 55
0
class login_required(object):
    """
    OMERO.web specific extension of the Django login_required() decorator,
    https://docs.djangoproject.com/en/dev/topics/auth/, which is responsible
    for ensuring a valid L{omero.gateway.BlitzGateway} connection. Is
    configurable by various options.
    """
    def __init__(self,
                 useragent='OMERO.web',
                 isAdmin=False,
                 isGroupOwner=False,
                 doConnectionCleanup=True,
                 omero_group='-1',
                 allowPublic=None):
        """
        Initialises the decorator.
        """
        self.useragent = useragent
        self.isAdmin = isAdmin
        self.isGroupOwner = isGroupOwner
        self.doConnectionCleanup = doConnectionCleanup
        self.omero_group = omero_group
        self.allowPublic = allowPublic

    def get_login_url(self):
        """The URL that should be redirected to if not logged in."""
        return reverse(settings.LOGIN_VIEW)

    login_url = property(get_login_url)

    def get_share_connection(self, request, conn, share_id):
        try:
            conn.SERVICE_OPTS.setOmeroShare(share_id)
            share = conn.getShare(share_id)
            return conn
        except:
            logger.error('Error activating share.', exc_info=True)
            return None

    def prepare_share_connection(self, request, conn, share_id):
        """Prepares the share connection if we have a valid share ID."""
        # we always need to clear any dirty 'omero.share' values from previous calls
        conn.SERVICE_OPTS.setOmeroShare()
        if share_id is None:
            return None
        share = conn.getShare(share_id)
        try:
            if share.getOwner().id != conn.getUserId():
                return self.get_share_connection(request, conn, share_id)
        except:
            logger.error('Error retrieving share connection.', exc_info=True)
            return None

    def on_not_logged_in(self, request, url, error=None):
        """Called whenever the user is not logged in."""
        if request.is_ajax():
            logger.debug('Request is Ajax, returning HTTP 403.')
            return HttpResponseForbidden()
        args = {'url': url}
        logger.debug('Request is not Ajax, redirecting to %s' % self.login_url)
        return HttpResponseRedirect('%s?%s' %
                                    (self.login_url, urlencode(args)))

    def on_logged_in(self, request, conn):
        """
        Called whenever the users is successfully logged in.
        Sets the 'omero.group' option if specified in the constructor
        """
        if self.omero_group is not None:
            conn.SERVICE_OPTS.setOmeroGroup(self.omero_group)

    def on_share_connection_prepared(self, request, conn_share):
        """Called whenever a share connection is successfully prepared."""
        pass

    def verify_is_admin(self, conn):
        """
        If we have been requested to by the isAdmin flag, verify the user
        is an admin and raise an exception if they are not.
        """
        if self.isAdmin and not conn.isAdmin():
            raise Http404

    def verify_is_group_owner(self, conn, gid):
        """
        If we have been requested to by the isGroupOwner flag, verify the user
        is the owner of the provided group. If no group is provided the user's
        active session group ownership will be verified.
        """
        if not self.isGroupOwner:
            return
        if gid is not None:
            if not conn.isLeader(gid):
                raise Http404
        else:
            if not conn.isLeader():
                raise Http404

    def is_valid_public_url(self, server_id, request):
        """
        Verifies that the URL for the resource being requested falls within
        the scope of the OMERO.webpublic URL filter.
        """
        if settings.PUBLIC_ENABLED:
            if not hasattr(settings, 'PUBLIC_USER'):
                logger.warn('OMERO.webpublic enabled but public user ' \
                            '(omero.web.public.user) not set, disabling ' \
                            'OMERO.webpublic.')
                settings.PUBLIC_ENABLED = False
                return False
            if not hasattr(settings, 'PUBLIC_PASSWORD'):
                logger.warn('OMERO.webpublic enabled but public user ' \
                            'password (omero.web.public.password) not set, ' \
                            'disabling OMERO.webpublic.')
                settings.PUBLIC_ENABLED = False
                return False
            if self.allowPublic is None:
                return settings.PUBLIC_URL_FILTER.search(
                    request.path) is not None
            return self.allowPublic
        return False

    def get_public_user_connector(self):
        """
        Returns the current cached OMERO.webpublic connector or None if
        nothing has been cached.
        """
        if not settings.PUBLIC_CACHE_ENABLED:
            return
        return cache.get(settings.PUBLIC_CACHE_KEY)

    def set_public_user_connector(self, connector):
        """Sets the current cached OMERO.webpublic connector."""
        if not settings.PUBLIC_CACHE_ENABLED \
                or connector.omero_session_key is None:
            return
        logger.debug('Setting OMERO.webpublic connector: %r' % connector)
        cache.set(settings.PUBLIC_CACHE_KEY, connector,
                  settings.PUBLIC_CACHE_TIMEOUT)

    def get_connection(self, server_id, request):
        """
        Prepares a Blitz connection wrapper (from L{omero.gateway}) for
        use with a view function.
        """
        connection = self.get_authenticated_connection(server_id, request)
        is_valid_public_url = self.is_valid_public_url(server_id, request)
        logger.debug('Is valid public URL? %s' % is_valid_public_url)
        if connection is None and is_valid_public_url:
            # If OMERO.webpublic is enabled, pick up a username and
            # password from configuration and use those credentials to
            # create a connection.
            logger.debug('OMERO.webpublic enabled, attempting to login ' \
                         'with configuration supplied credentials.')
            if server_id is None:
                server_id = settings.PUBLIC_SERVER_ID
            username = settings.PUBLIC_USER
            password = settings.PUBLIC_PASSWORD
            is_secure = request.REQUEST.get('ssl', False)
            logger.debug('Is SSL? %s' % is_secure)
            # Try and use a cached OMERO.webpublic user session key.
            public_user_connector = self.get_public_user_connector()
            if public_user_connector is not None:
                logger.debug('Attempting to use cached OMERO.webpublic ' \
                             'connector: %r' % public_user_connector)
                connection = public_user_connector.join_connection(
                    self.useragent)
                if connection is not None:
                    request.session['connector'] = public_user_connector
                    logger.debug('Attempt to use cached OMERO.web public ' \
                                 'session key successful!')
                    return connection
                logger.debug('Attempt to use cached OMERO.web public ' \
                             'session key failed.')
            # We don't have a cached OMERO.webpublic user session key,
            # create a new connection based on the credentials we've been
            # given.
            connector = Connector(server_id, is_secure)
            connection = connector.create_connection(self.useragent,
                                                     username,
                                                     password,
                                                     is_public=True)
            request.session['connector'] = connector
            self.set_public_user_connector(connector)
        elif connection is not None:
            is_anonymous = connection.isAnonymous()
            logger.debug('Is anonymous? %s' % is_anonymous)
            if is_anonymous and not is_valid_public_url:
                return None
        return connection

    def get_authenticated_connection(self, server_id, request):
        """
        Prepares an authenticated Blitz connection wrapper (from
        L{omero.gateway}) for use with a view function.
        """
        # TODO: Handle previous try_super logic; is it still needed?

        session = request.session
        request = request.REQUEST
        is_secure = request.get('ssl', False)
        logger.debug('Is SSL? %s' % is_secure)
        connector = session.get('connector', None)
        logger.debug('Connector: %s' % connector)

        if server_id is None:
            # If no server id is passed, the db entry will not be used and
            # instead we'll depend on the request.session and request.REQUEST
            # values
            if connector is not None:
                server_id = connector.server_id
            else:
                try:
                    server_id = request['server']
                except:
                    logger.debug('No Server ID available.')
                    return None

        # If we have an OMERO session key in our request variables attempt
        # to make a connection based on those credentials.
        try:
            omero_session_key = request['bsession']
            connector = Connector(server_id, is_secure)
        except KeyError:
            # We do not have an OMERO session key in the current request.
            pass
        else:
            # We have an OMERO session key in the current request use it
            # to try join an existing connection / OMERO session.
            logger.debug('Have OMERO session key %s, attempting to join...' % \
                    omero_session_key)
            connector.user_id = None
            connector.omero_session_key = omero_session_key
            connection = connector.join_connection(self.useragent)
            session['connector'] = connector
            return connection

        # An OMERO session is not available, we're either trying to service
        # a request to a login page or an anonymous request.
        username = None
        password = None
        try:
            username = request['username']
            password = request['password']
        except KeyError:
            if connector is None:
                logger.debug('No username or password in request, exiting.')
                # We do not have an OMERO session or a username and password
                # in the current request and we do not have a valid connector.
                # Raise an error (return None).
                return None

        if username is not None and password is not None:
            # We have a username and password in the current request, or
            # OMERO.webpublic is enabled and has provided us with a username
            # and password via configureation. Use them to try and create a
            # new connection / OMERO session.
            logger.debug('Creating connection with username and password...')
            connector = Connector(server_id, is_secure)
            connection = connector.create_connection(self.useragent, username,
                                                     password)
            session['connector'] = connector
            return connection

        logger.debug('Django session connector: %r' % connector)
        if connector is not None:
            # We have a connector, attempt to use it to join an existing
            # connection / OMERO session.
            connection = connector.join_connection(self.useragent)
            if connection is not None:
                logger.debug('Connector valid, session successfully joined.')
                return connection
            # Fall through, we the session we've been asked to join may
            # be invalid and we may have other credentials as request
            # variables.
            logger.debug('Connector is no longer valid, destroying...')
            del session['connector']
            return None

        session['connector'] = connector
        return connection

    def __call__(ctx, f):
        """
        Tries to prepare a logged in connection, then calls function and
        returns the result.
        """
        def wrapped(request, *args, **kwargs):
            url = request.REQUEST.get('url')
            if url is None or len(url) == 0:
                url = request.get_full_path()

            doConnectionCleanup = False

            conn = kwargs.get('conn', None)
            error = None
            server_id = kwargs.get('server_id', None)
            # Short circuit connection retrieval when a connection was
            # provided to us via 'conn'. This is useful when in testing
            # mode or when stacking view functions/methods.
            if conn is None:
                doConnectionCleanup = ctx.doConnectionCleanup
                logger.debug('Connection not provided, attempting to get one.')
                try:
                    conn = ctx.get_connection(server_id, request)
                except Exception, x:
                    logger.error('Error retrieving connection.', exc_info=True)
                    error = str(x)
                else:
                    # various configuration & checks only performed on new 'conn'
                    if conn is None:
                        return ctx.on_not_logged_in(request, url, error)
                    else:
                        ctx.on_logged_in(request, conn)
                    ctx.verify_is_admin(conn)
                    ctx.verify_is_group_owner(conn, kwargs.get('gid'))

                    share_id = kwargs.get('share_id')
                    conn_share = ctx.prepare_share_connection(
                        request, conn, share_id)
                    if conn_share is not None:
                        ctx.on_share_connection_prepared(request, conn_share)
                        kwargs['conn'] = conn_share
                    else:
                        kwargs['conn'] = conn

                    #kwargs['error'] = request.REQUEST.get('error')
                    kwargs['url'] = url

            retval = f(request, *args, **kwargs)
            try:
                logger.debug('Doing connection cleanup? %s' % \
                        doConnectionCleanup)
                if doConnectionCleanup:
                    if conn is not None and conn.c is not None:
                        for v in conn._proxies.values():
                            v.close()
                        conn.c.closeSession()
            except:
                logger.warn('Failed to clean up connection.', exc_info=True)
            return retval

        return wraps(f)(wrapped)
Esempio n. 56
0
element is a dictionary of kwargs to be passed to the filter function
along with the markup to parse.

For instance, if MARKITUP_PREVIEW_FILTER is set to::

    ('markdown.markdown', {'safe_mode': True})

then calling ``filter_func(text)`` is equivalent to::

    from markdown import markdown
    markdown(text, safe_mode=True)

Though the implementation differs, the format of the
MARKITUP_PREVIEW_FILTER setting is inspired by James Bennett's
django-template-utils_.

.. _django-template-utils: http://code.google.com/p/django-template-utils/

"""
from django.utils.functional import curry, wraps

from markitup.settings import MARKITUP_PREVIEW_FILTER

if MARKITUP_PREVIEW_FILTER is None:
    filter_func = lambda text: text
else:
    filter_path, filter_kwargs = MARKITUP_PREVIEW_FILTER
    module, funcname = filter_path.rsplit('.', 1)
    func = getattr(__import__(module, {}, {}, [funcname]), funcname)
    filter_func = wraps(func)(curry(func, **filter_kwargs))
def fetch_all(func,
              return_all=None,
              always_all=False,
              paging_next_arg_name=None):
    """
    Class method decorator for fetching all items. Add parameter `all=False` for decored method.
    If `all` is True, method runs as many times as it returns any results.
    Decorator receive parameters:
      * callback method `return_all`. It's called with the same parameters
        as decored method after all itmes are fetched.
      * `always_all` bool - return all instances in any case of argument `all`
        of decorated method
    Usage:

        @fetch_all(return_all=lambda self,instance,*a,**k: instance.items.all())
        def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self, *args, **kwargs):

        all = kwargs.pop('all', False) or always_all
        instances_all = kwargs.pop('instances_all', None)

        response = None
        instances = func(self, *args, **kwargs)
        if len(instances) == 2 and isinstance(instances, tuple):
            instances, response = instances

        if all:
            if isinstance(instances, QuerySet):
                if instances_all is None:
                    instances_all = QuerySet().none()
                instances_all |= instances
            elif isinstance(instances, list):
                if instances_all is None:
                    instances_all = []
                instances_all += instances
            else:
                raise ValueError(
                    "Wrong type of response from func %s. It should be QuerySet or list, not a %s"
                    % (func, type(instances)))

            # resursive pagination
            paging_next = paging_cursors = None
            if response:
                try:
                    paging_next = response['paging']['next']
                except KeyError:
                    pass
                try:
                    paging_cursors = response['paging']['cursors']
                except KeyError:
                    pass

            if paging_next_arg_name and paging_next and paging_next_arg_name in paging_next \
                    or paging_next_arg_name and paging_cursors and paging_next_arg_name in paging_cursors:
                paging_next_arg_value = None
                # at first look in cursors
                if paging_cursors:
                    paging_next_arg_value = paging_cursors.get(
                        paging_next_arg_name, None)
                if paging_next_arg_value is None:
                    # at second look parse from paging_next
                    m = re.findall('%s=([^&]+)' % paging_next_arg_name,
                                   paging_next)
                    if len(m):
                        paging_next_arg_value = m[0]
                    # __paging_token=enc_AeylNUQG2Z3DpcZgvUECXW1BHDhsvO8chTp-mQY341mQex3MIce-VnU_PztAiKnskGDcNT61dsycEgphUi9kVy9KYJV2QutwpbPZ0p32OsSQlw
                    m = re.findall('%s=([^&]+)' % '__paging_token',
                                   paging_next)
                    if len(m):
                        kwargs['__paging_token'] = m[0]
                if paging_next_arg_value is None:
                    raise ValueError(
                        "Wrong response pagination value: %s, paging_next_arg_name=%s"
                        % (paging_next, paging_next_arg_name))
                # only if argument is changed
                if kwargs.get(paging_next_arg_name) != paging_next_arg_value:
                    kwargs[paging_next_arg_name] = paging_next_arg_value
                    return wrapper(self,
                                   all=all,
                                   instances_all=instances_all,
                                   *args,
                                   **kwargs)

            if return_all:
                kwargs['instances'] = instances_all
                return return_all(self, *args, **kwargs)
            else:
                return instances_all
        else:
            return instances

    return wraps(func)(wrapper)
def fetch_all(func,
              return_all=None,
              kwargs_offset='offset',
              kwargs_count='count',
              default_count=None):
    """
    Class method decorator for fetching all items. Add parameter `all=False` for decored method.
    If `all` is True, method runs as many times as it returns any results.
    Decorator receive 2 parameters:
      * callback method `return_all`. It's called with the same parameters
        as decored method after all itmes are fetched.
      * `kwargs_offset` - name of offset parameter among kwargs
    Usage:

        @fetch_all(return_all=lambda self,instance,*a,**k: instance.items.all())
        def fetch_something(self, ..., *kwargs):
        ....
    """
    def wrapper(self,
                all=False,
                instances_all=None,
                extra_calls=0,
                *args,
                **kwargs):
        if all:

            instances = func(self, *args, **kwargs)

            if isinstance(instances, QuerySet):
                if not instances_all:
                    instances_all = QuerySet().none()
                instances_all |= instances
                instances_count = instances.count()
            elif isinstance(instances, list):
                if not instances_all:
                    instances_all = []
                instances_all += instances
                instances_count = len(instances)
            else:
                raise ValueError(
                    "Wrong type of response from func %s. It should be QuerySet or list, not a %s"
                    % (func, type(instances)))


#            print kwargs.get(kwargs_offset, 0), instances_count, extra_calls
            if instances_count > 0 and (not default_count
                                        or instances_count == kwargs.get(
                                            kwargs_count, default_count)):
                # TODO: make protection somehow from endless loop in case
                # where `kwargs_offset` argument is not make any sense for `func`
                kwargs[kwargs_offset] = kwargs.get(kwargs_offset,
                                                   0) + instances_count
                return wrapper(self,
                               all=all,
                               instances_all=instances_all,
                               *args,
                               **kwargs)
            # попытка решить проблему получения репостов поста https://vk.com/wall-36948301_23383?w=shares%2Fwall-36948301_23383
            elif extra_calls < 3:
                kwargs[kwargs_offset] = kwargs.get(kwargs_offset, 0) + 1
                extra_calls += 1
                return wrapper(self,
                               all=all,
                               instances_all=instances_all,
                               extra_calls=extra_calls,
                               *args,
                               **kwargs)

            if return_all:
                return return_all(self, *args, **kwargs)
            else:
                return instances_all
        else:
            return func(self, *args, **kwargs)

    return wraps(func)(wrapper)
Esempio n. 59
0
from django.utils.functional import wraps

from chapter4.logging.models import Entry

def logged(view):
    """
    Logs any errors that occurred during the view
    in a special model design for app-specific errors
    """
    def wrapper(request, *args, **kwargs):
        try:
            return view(request, *args, **kwargs)
        except Exception, e:
            # Log the entry using the application’s Entry model
            Entry.objects.create(path=request.path, type='View exception',
                                 description=str(e))

            # Re-raise it so standard error handling still applies
            raise
    return wraps(view)(wrapper)

Esempio n. 60
0
    def decorator(controller_func):
        def _wrapped_controller(request, *args, **kwargs):
            # With OR check, we assume the permission test passes upfront

            # Check permission
            pass_permission_test = True

            # OR Loop
            if use_or:
                pass_permission_test = False
                for perm in perms:
                    # If any one of the permission evaluates to True, the test passes
                    if has_permission(request, perm):
                        pass_permission_test = True
                        break

            # AND Loop
            else:
                # Assume pass test
                pass_permission_test = True

                for perm in perms:
                    # If any one of the permissions evaluates to False, the test fails
                    if not has_permission(request, perm):
                        pass_permission_test = False
                        break

            if not pass_permission_test:
                if not raise_exception:
                    # If user is authenticated...
                    if request.user.is_authenticated():
                        # User feedback
                        messages.add_message(request, messages.WARNING,
                                             message)

                        # Default redirect URL
                        redirect_url = reverse('app_library')

                        # If there is a referer (i.e.: we followed a link to get here)
                        if 'HTTP_REFERER' in request.META:
                            # Try to redirect to the referer URL
                            referer = request.META['HTTP_REFERER']
                            parsed_referer = urlparse(referer)

                            # But avoid an infinite redirect loop (if referer is self somehow)
                            if parsed_referer.path != request.path:
                                # e.g. hostname:port
                                request_host_parts = request.get_host().split(
                                    ':')

                                # Only attempt redirect if host names are the same
                                if len(
                                        request_host_parts
                                ) > 0 and parsed_referer.hostname == request_host_parts[
                                        0]:
                                    redirect_url = parsed_referer.path

                        # Redirect to apps library with message
                        return redirect(redirect_url)

                    # If not authenticated...
                    else:
                        # User feedback
                        messages.add_message(
                            request, messages.INFO,
                            "You must be logged in to access this feature.")

                        # Redirect to login page
                        return redirect(
                            reverse('accounts:login') + '?next=' +
                            request.path)

                else:
                    return tethys_portal_error.handler_403(request)

            return controller_func(request, *args, **kwargs)

        return wraps(controller_func)(_wrapped_controller)