def _get_extra_permissions(opts, ctype):
    new_perms = []

    for field in GROUP_FIELDS:
        try:
            opts.get_field(field)
        except FieldDoesNotExist:
            pass
        else:
            for action in GROUP_ACTIONS:
                action = 'group_' + action
                new_perms.append((
                    get_permission_codename(action, opts),
                    'Can %s %s' % (action, opts.verbose_name_raw)
                ))

            # Only need one match to create the perm
            break

    for field in OWNER_FIELDS:
        try:
            opts.get_field(field)
        except FieldDoesNotExist:
            pass
        else:
            for action in OWNER_ACTIONS:
                action = 'owner_' + action
                new_perms.append((
                    get_permission_codename(action, opts),
                    'Can %s %s' % (action, opts.verbose_name_raw)
                ))
            # Only need one match to create the perm
            break

    return new_perms
Exemple #2
0
 def get_object_list(self, request):
     """ The Project queryset is filtered depending on the user accessing the API
         All users get Project.objects.published()
         If the user is authenticated via an API key additional projects are added similarly to the access in the
         admin:
             Superusers get access to ALL projects
             Users with "change_project" perm (currently Akvo staff users) also get access to ALL projects
             Users with "rsr_limited_change_project" perm get access to all projects linked to their organisation
             regardless of publishing status
     """
     object_list = super(ProjectResource, self).get_object_list(request)
     # The whole point of ConditionalApiKeyAuthentication is to allow some access even for unauthorised requests,
     # but here we need to figure out if the request contains a name/key pair and if so allow access to unpublished
     # projects. So we call ApiKeyAuthentication.is_authenticated() (using super() which returns True if there is an
     # identified user holding an api key, AND is_authenticated() also sets request.user to the User object which we
     # need to be able to call request.user.has_perm() correctly.
     if super(ConditionalApiKeyAuthentication, self.Meta.authentication).is_authenticated(request) is True:
         opts = Project._meta
         if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
             return object_list
         elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
             object_list = object_list.published() | object_list.of_partner(
                 request.user.userprofile.organisation
             )
             return object_list.distinct()
     return object_list.published()
Exemple #3
0
    def __init__(self, *args, **kwargs):
        super(TreeEditor, self).__init__(*args, **kwargs)

        self.list_display = list(self.list_display)

        if "indented_short_title" not in self.list_display:
            if self.list_display[0] == "action_checkbox":
                self.list_display[1] = "indented_short_title"
            else:
                self.list_display[0] = "indented_short_title"
        self.list_display_links = ("indented_short_title",)

        opts = self.model._meta
        self.change_list_template = [
            "admin/feincms/%s/%s/tree_editor.html"
            % (opts.app_label, opts.object_name.lower()),
            "admin/feincms/%s/tree_editor.html" % opts.app_label,
            "admin/feincms/tree_editor.html",
        ]
        self.object_change_permission = (
            opts.app_label + "." + get_permission_codename("change", opts)
        )
        self.object_add_permission = (
            opts.app_label + "." + get_permission_codename("add", opts)
        )
        self.object_delete_permission = (
            opts.app_label + "." + get_permission_codename("delete", opts)
        )
Exemple #4
0
    def __init__(self, *args, **kwargs):
        super(TreeEditor, self).__init__(*args, **kwargs)

        self.list_display = list(self.list_display)

        if 'indented_short_title' not in self.list_display:
            if self.list_display[0] == 'action_checkbox':
                self.list_display[1] = 'indented_short_title'
            else:
                self.list_display[0] = 'indented_short_title'
        self.list_display_links = ('indented_short_title',)

        opts = self.model._meta
        self.change_list_template = [
            'admin/feincms/%s/%s/tree_editor.html' % (
                opts.app_label, opts.object_name.lower()),
            'admin/feincms/%s/tree_editor.html' % opts.app_label,
            'admin/feincms/tree_editor.html',
        ]
        self.object_change_permission =\
            opts.app_label + '.' + get_permission_codename('change', opts)
        self.object_add_permission =\
            opts.app_label + '.' + get_permission_codename('add', opts)
        self.object_delete_permission =\
            opts.app_label + '.' + get_permission_codename('delete', opts)
    def test_post_delete_view__post__success(self, _, __, delete_post_mock):
        thread_data = THREADS_LIST_RESPONSE['response'][0]
        post_data = POSTS_LIST_RESPONSE['response'][0]
        thread_object = thread_factory(thread_data)
        post_object = post_factory(post_data)
        post_object.thread = thread_object
        deleteuser = User.objects.create_user(
            username='******',
            password='******',
            is_staff=True
        )
        deleteuser.user_permissions.add(
            get_perm(
                Thread,
                get_permission_codename('delete', Thread._meta)
            )
        )
        deleteuser.user_permissions.add(
            get_perm(
                Post,
                get_permission_codename('delete', Post._meta)
            )
        )
        self.client.force_login(deleteuser)
        delete_url = reverse('{admin_site_name}:{app_label}_{model_name}_delete'.format(
            admin_site_name=admin.site.name,
            app_label=Post._meta.app_label,
            model_name=Post._meta.model_name
        ), args=[post_data['id']])
        delete_dict = {'post': 'yes'}

        response = self.client.post(delete_url, delete_dict)

        self.assertEqual(response.status_code, 302)
        delete_post_mock.assert_called_once_with(post_object.id)
Exemple #6
0
 def permissions_for_user(self, user, obj):
     opts = self.opts
     app_label = opts.app_label
     return {
         'can_edit': user.has_perm("%s.%s" % (
             app_label, get_permission_codename('change', self.opts))),
         'can_delete': user.has_perm("%s.%s" % (
             app_label, get_permission_codename('delete', self.opts))),
     }
Exemple #7
0
 def get_queryset(self, request):
     qs = super(OrganisationAdmin, self).get_queryset(request)
     opts = self.opts
     if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
         return qs
     elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
         organisation = request.user.userprofile.organisation
         return qs.filter(pk=organisation.id)
     else:
         raise PermissionDenied
Exemple #8
0
 def has_change_permission(self, request, user=None):
     """
     Return True if user in :param:request has change permission
     :param request: The request http
     :return: bool. True if user has change permission
     """
     opts = self._meta
     if not user:
         user = request.user
     if user.is_superuser:
         return True
     return ((user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)) and self.smooth_perm_change_all)
             or (user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)) and self.has_generic_permission(request, "change")))
Exemple #9
0
 def get_queryset(self, request):
     """
     Return a queryset possibly filtered depending on current user's group(s)
     """
     qs = super(UserProfileAdmin, self).get_queryset(request)
     opts = self.opts
     if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
         return qs
     elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
         organisation = request.user.userprofile.organisation
         return qs.filter(organisation=organisation)
     else:
         raise PermissionDenied
 def get_readonly_fields(self, request, obj=None):
     fields_list = []
     if obj:
         view_permission = obj._meta.app_label + '.' + get_permission_codename('view', obj.__class__._meta)
         add_permission = obj._meta.app_label + '.' + get_permission_codename('add', obj.__class__._meta)
         if request.user.has_perm(view_permission) and not request.user.has_perm(add_permission):
             return list(set(
                 [field.name for field in self.opts.local_fields] +
                 [field.name for field in self.opts.local_many_to_many] +
                 fields_list
             ))
         else:
             return list(set(list(self.readonly_fields) + fields_list))
     else:
         return self.readonly_fields
Exemple #11
0
    def format_callback(obj):
        has_admin = obj.__class__ in admin_site._registry
        opts = obj._meta

        no_edit_link = '%s: %s' % (capfirst(opts.verbose_name),
                                   force_text(obj))

        if has_admin:
            try:
                admin_url = reverse('%s:%s_%s_change'
                                    % (admin_site.name,
                                       opts.app_label,
                                       opts.model_name),
                                    None, (quote(obj._get_pk_val()),))
            except NoReverseMatch:
                # Change url doesn't exist -- don't display link to edit
                return no_edit_link

            p = '%s.%s' % (opts.app_label,
                           get_permission_codename('delete', opts))
            if not user.has_perm(p):
                perms_needed.add(opts.verbose_name)
            # Display a link to the admin page.
            return format_html('{}: <a href="{}">{}</a>',
                               capfirst(opts.verbose_name),
                               admin_url,
                               obj)
        else:
            # Don't display link to edit, because it either has no
            # admin or is edited inline.
            return no_edit_link
Exemple #12
0
    def format_callback(obj):
        has_admin = obj.__class__ in admin_site._registry
        opts = obj._meta

        if has_admin:
            admin_url = reverse('%s:%s_%s_change'
                                % (admin_site.name,
                                   opts.app_label,
                                   opts.object_name.lower()),
                                None, (quote(obj._get_pk_val()),))
            p = '%s.%s' % (opts.app_label,
                           get_permission_codename('delete', opts))
            if not user.has_perm(p):
                perms_needed.add(opts.verbose_name)
            # Display a link to the admin page.
            return mark_safe(u'<span class="label label-info">%s:</span> <a href="%s">%s</a>' %
                             (escape(capfirst(opts.verbose_name)),
                              admin_url,
                              escape(obj)))
        else:
            # Don't display link to edit, because it either has no
            # admin or is edited inline.
            return mark_safe(u'<span class="label label-info">%s:</span> %s' %
                             (escape(capfirst(opts.verbose_name)),
                              escape(obj)))
Exemple #13
0
def save_permissions(data, obj):
    models = (
        (Page, 'page'),
        (PageUser, 'pageuser'),
        (PageUserGroup, 'pageuser'),
        (PagePermission, 'pagepermission'),
    )

    if not obj.pk:
        # save obj, otherwise we can't assign permissions to him
        obj.save()

    permission_accessor = get_permission_accessor(obj)

    for model, name in models:
        content_type = ContentType.objects.get_for_model(model)
        for key in ('add', 'change', 'delete'):
            # add permission `key` for model `model`
            codename = get_permission_codename(key, model._meta)
            permission = Permission.objects.get(content_type=content_type, codename=codename)
            field = 'can_%s_%s' % (key, name)

            if data.get(field):
                permission_accessor.add(permission)
            elif field in data:
                permission_accessor.remove(permission)
def customized_editor(user, settings):
    "Customize the setting editor based on the current user and setting list"
    base_fields = OrderedDict()
    verbose_names = {}
    apps = {}
    for setting in settings:
        perm = '%s.%s' % (
            Setting._meta.app_label,
            get_permission_codename('change', Setting._meta)
        )
        if user.has_perm(perm):
            # Add the field to the customized field list
            storage = get_setting_storage(*setting.key)
            kwargs = {
                'label': setting.description,
                'help_text': setting.help_text,
                # Provide current setting values for initializing the form
                'initial': setting.to_editor(storage.value),
                'required': setting.required,
                'widget': setting.widget,
            }
            if setting.choices:
                field = forms.ChoiceField(choices=setting.choices, **kwargs)
            else:
                field = setting.field(**kwargs)
            key = '%s__%s__%s' % setting.key
            apps[key] = setting.app
            base_fields[key] = field
            verbose_names[key] = setting.verbose_name
    attrs = {'base_fields': base_fields, 'verbose_names': verbose_names, 'apps': apps}
    return type('SettingsEditor', (SettingsEditor,), attrs)
    def test_add_permission(self):
        """With add permission, an inline can be added even if parent has only view perms"""
        self.user.user_permissions.add(
            get_perm(StackedItem, get_permission_codename('add', StackedItem._meta)))

        self.load_admin(self.group)

        has_save = self.selenium.execute_script('return !!$("[name=_save]").length')
        self.assertTrue(has_save)

        if self.has_grappelli:
            readonly_xpath = '//div[@class="grp-readonly" and text()="B 0"]'
        else:
            readonly_xpath = '//p[text()="B 0"]'

        self.wait_until_xpath(readonly_xpath)

        add_buttons = self.selenium.find_elements_by_css_selector(
            '#section_set-1-item_set-group .djn-add-handler.djn-model-two_deep-stackeditem')

        self.assertNotEqual(len(add_buttons), 0)

        add_buttons[0].click()

        with self.visible_selector('#id_section_set-1-item_set-1-name') as el:
            el.clear()
            el.send_keys('B 1')

        self.save_form()

        items = StackedItem.objects.filter(section=self.section_b)
        self.assertEqual(items.count(), 2)
        self.assertEqual(items[1].name, 'B 1')
Exemple #16
0
 def get_queryset(self, request):
     """
     Return a queryset possibly filtered depending on current user's group(s)
     """
     qs = super(ProjectAdmin, self).get_queryset(request)
     opts = self.opts
     if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
         return qs
     elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
         user_profile = request.user.userprofile
         projects = user_profile.organisation.all_projects()
         # Access to Partner users may be limited by Support partner "ownership"
         allowed_projects = [project.pk for project in projects if user_profile.allow_edit(project)]
         return qs.filter(pk__in=allowed_projects)
     else:
         raise PermissionDenied
Exemple #17
0
 def get_readonly_fields(self, request, obj=None):
     # parter_types is read only unless you have change permission for organisations
     if not request.user.has_perm(self.opts.app_label + '.' + get_permission_codename('change', self.opts)):
         self.readonly_fields = ('partner_types', 'created_at', 'last_modified_at',)
     else:
         self.readonly_fields = ('created_at', 'last_modified_at',)
     return super(OrganisationAdmin, self).get_readonly_fields(request, obj=obj)
Exemple #18
0
 def get_actions(self, request):
     """ Remove delete admin action for "non certified" users"""
     actions = super(UserProfileAdmin, self).get_actions(request)
     opts = self.opts
     if not request.user.has_perm(opts.app_label + '.' + get_permission_codename('delete', opts)):
         del actions['delete_selected']
     return actions
Exemple #19
0
def get_permission_choices():
    """
        Rather than creating permissions in the datastore which is incredibly slow (and relational)
        we just use the permission codenames, stored in a ListField.
    """

    global PERMISSIONS_LIST

    if PERMISSIONS_LIST:
        return PERMISSIONS_LIST

    from django.conf import settings

    AUTO_PERMISSIONS = getattr(settings, "AUTOGENERATED_PERMISSIONS", ('add', 'change', 'delete'))

    result = getattr(settings, "MANUAL_PERMISSIONS", [])

    for app in get_apps():
        for model in get_models(app):
            for action in AUTO_PERMISSIONS:
                opts = model._meta
                result.append((get_permission_codename(action, opts), 'Can %s %s' % (action, opts.verbose_name_raw)))

    PERMISSIONS_LIST = sorted(result)
    return PERMISSIONS_LIST
Exemple #20
0
        def format_callback(obj):

            p = '%s.%s' % (
                obj._meta.app_label,
                get_permission_codename('delete', obj._meta)
            )

            if not self.request.user.has_perm(p):
                perms_needed.add(obj._meta.verbose_name)

            registered = obj.__class__ in self.request.djangobmf_site.modules

            # only show bmf modules
            if not registered:
                return None

            if hasattr(obj, '_bmfmeta') and obj._bmfmeta.only_related:
                return format_html(
                    '{0}: {1}',
                    obj._meta.verbose_name,
                    obj
                )
            else:
                return format_html(
                    '{0}: <a href="{1}">{2}</a>',
                    obj._meta.verbose_name,
                    obj.bmfmodule_detail(),
                    obj
                )
Exemple #21
0
def show_content_type_selection_widget(context, region):
    """
    {% show_content_type_selection_widget region %}
    """
    if "request" in context:
        user = context["request"].user
    elif "user" in context:
        user = context["user"]
    else:
        user = None

    grouped = {}
    ungrouped = []

    if user:
        for ct in region._content_types:
            # Skip cts that we shouldn't be adding anyway
            opts = ct._meta
            perm = opts.app_label + "." + get_permission_codename("add", opts)
            if not user.has_perm(perm):
                continue

            ct_info = (ct.__name__.lower(), ct._meta.verbose_name)
            if hasattr(ct, "optgroup"):
                if ct.optgroup in grouped:
                    grouped[ct.optgroup].append(ct_info)
                else:
                    grouped[ct.optgroup] = [ct_info]
            else:
                ungrouped.append(ct_info)

    return {"grouped": grouped, "ungrouped": ungrouped}
Exemple #22
0
    def get_results(self, request):
        mptt_opts = self.model._mptt_meta
        if self.model_admin.filter_include_ancestors:
            clauses = [Q(**{
                mptt_opts.tree_id_attr: tree_id,
                mptt_opts.left_attr + '__lte': lft,
                mptt_opts.right_attr + '__gte': rght,
            }) for lft, rght, tree_id in \
                self.query_set.values_list(mptt_opts.left_attr, mptt_opts.right_attr, mptt_opts.tree_id_attr)]
            if clauses:
                self.query_set = self.model._default_manager.filter(reduce(lambda p, q: p|q, clauses))

        super(ChangeList, self).get_results(request)

        opts = self.model_admin.opts
        try:
            label = opts.app_label + '.' + opts.get_change_permission()
        except AttributeError:
            from django.contrib.auth import get_permission_codename
            label = '%s.%s' % (opts.app_label, get_permission_codename('change', opts))
        for item in self.result_list:
            if self.model_admin.enable_object_permissions:
                item.feincms_editable = self.model_admin.has_change_permission(request, item)
            else:
                item.feincms_editable = True
    def has_add_permission(self, request):
        """Return True if the user has the permission to add a model."""
        if not request.user.is_authenticated():
            return False

        opts = self.get_queryset().model._meta
        codename = get_permission_codename('add', opts)
        return request.user.has_perm("%s.%s" % (opts.app_label, codename))
 def get_permission_codename(cls, entity_kind):
     perm = cls.get_entity_kind_permission(entity_kind)
     opts = cls._meta
     appname = opts.app_label.lower()
     if opts.proxy:
         proxied = opts.proxy_for_model._meta
         appname = proxied.app_label.lower()
     return '%s.%s' % (appname, auth.get_permission_codename(perm, opts))
Exemple #25
0
 def can_add_content(self, request, content_type):
     perm = ".".join(
         (
             content_type._meta.app_label,
             get_permission_codename("add", content_type._meta),
         )
     )
     return request.user.has_perm(perm)
Exemple #26
0
def get_delete_permission(opts):
    try:
        from django.contrib.auth import get_permission_codename  # flake8: noqa
        return '%s.%s' % (opts.app_label,
                          get_permission_codename('delete', opts))
    except ImportError:
        return '%s.%s' % (opts.app_label,
                          opts.get_delete_permission())
Exemple #27
0
    def has_add_permission(self, request):
        """Default add permission check for a detail and list views.

        May not be called if views have own implementation.
        """
        opts = self.model._meta
        codename = get_permission_codename('add', opts)
        return request.user.has_perm('{}.{}'.format(opts.app_label, codename))
 def has_delete_permission(self, user):
     """
     For typical models, whether or not a user can delete an object depends
     on their permissions on that model
     """
     return user.has_perm("%s.%s" % (
         self.opts.app_label, get_permission_codename('delete', self.opts)
     ))
 def has_view_permission(self, request, obj=None):
     """
     Returns True if the given request has permission to view an object.
     Can be overridden by the user in subclasses.
     """
     opts = self.opts
     codename = get_permission_codename('view', opts)
     return request.user.has_perm("%s.%s" % (opts.app_label, codename))
Exemple #30
0
    def _get_permission(self):
        if hasattr(self, '_permission'):
            return self._permission

        self._permission = (self.model._meta.app_label,
                            get_permission_codename(self._get_type(),
                                                    self.model._meta))
        return self._permission
Exemple #31
0
    def has_view_permission(self, obj=None):
        view_codename = get_permission_codename('view', self.opts)
        change_codename = get_permission_codename('change', self.opts)

        return ('view' not in self.remove_permissions) and (self.user.has_perm('%s.%s' % (self.app_label, view_codename)) or \
            self.user.has_perm('%s.%s' % (self.app_label, change_codename)))
Exemple #32
0
def importWorkbook(request):
    """
    This method reads a spreadsheet in Office Open XML format (typically with
    the extension .xlsx or .ods).
    Each entity has a tab in the spreadsheet, and the first row contains
    the fields names.
    """
    # Build a list of all contenttypes
    all_models = [(ct.model_class(), ct.pk)
                  for ct in ContentType.objects.all() if ct.model_class()]
    try:
        # Find all models in the workbook
        for filename, file in request.FILES.items():
            yield "<strong>" + force_text(
                _("Processing file")) + " " + filename + "</strong><br>"
            if filename.endswith(".xls"):
                yield _(
                    "Files in the old .XLS excel format can't be read.<br>Please convert them to the new .XLSX format."
                )
                continue
            elif (file.content_type !=
                  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                  ):
                yield _("Unsupported file format.")
                continue
            wb = load_workbook(filename=file, read_only=True, data_only=True)
            models = []
            for ws_name in wb.sheetnames:
                # Find the model
                model = None
                contenttype_id = None
                for m, ct in all_models:
                    if matchesModelName(ws_name, m):
                        model = m
                        contenttype_id = ct
                        break
                if not model or model in EXCLUDE_FROM_BULK_OPERATIONS:
                    yield '<div class="alert alert-warning">' + force_text(
                        _("Ignoring data in worksheet: %s") %
                        ws_name) + "</div>"
                elif not request.user.has_perm("%s.%s" % (
                        model._meta.app_label,
                        get_permission_codename("add", model._meta),
                )):
                    # Check permissions
                    yield '<div class="alert alert-danger">' + force_text(
                        _("You don't permissions to add: %s") %
                        ws_name) + "</div>"
                else:
                    deps = set([model])
                    GridReport.dependent_models(model, deps)
                    models.append((ws_name, model, contenttype_id, deps))

            # Sort the list of models, based on dependencies between models
            models = GridReport.sort_models(models)

            # Process all rows in each worksheet
            for ws_name, model, contenttype_id, dependencies in models:
                with transaction.atomic(using=request.database):
                    yield "<strong>" + force_text(
                        _("Processing data in worksheet: %s") %
                        ws_name) + "</strong><br>"
                    yield (
                        '<div class="table-responsive">'
                        '<table class="table table-condensed" style="white-space: nowrap;"><tbody>'
                    )
                    numerrors = 0
                    numwarnings = 0
                    firsterror = True
                    ws = wb[ws_name]
                    for error in parseExcelWorksheet(
                            model,
                            ws,
                            user=request.user,
                            database=request.database,
                            ping=True,
                    ):
                        if error[0] == logging.DEBUG:
                            # Yield some result so we can detect disconnect clients and interrupt the upload
                            yield " "
                            continue
                        if firsterror and error[0] in (logging.ERROR,
                                                       logging.WARNING):
                            yield '<tr><th class="sr-only">%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s%s%s</th></tr>' % (
                                capfirst(_("worksheet")),
                                capfirst(_("row")),
                                capfirst(_("field")),
                                capfirst(_("value")),
                                capfirst(_("error")),
                                " / ",
                                capfirst(_("warning")),
                            )
                            firsterror = False
                        if error[0] == logging.ERROR:
                            yield '<tr><td class="sr-only">%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s: %s</td></tr>' % (
                                ws_name,
                                error[1] if error[1] else "",
                                error[2] if error[2] else "",
                                error[3] if error[3] else "",
                                capfirst(_("error")),
                                error[4],
                            )
                            numerrors += 1
                        elif error[1] == logging.WARNING:
                            yield '<tr><td class="sr-only">%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s: %s</td></tr>' % (
                                ws_name,
                                error[1] if error[1] else "",
                                error[2] if error[2] else "",
                                error[3] if error[3] else "",
                                capfirst(_("warning")),
                                error[4],
                            )
                            numwarnings += 1
                        else:
                            yield '<tr class=%s><td class="sr-only">%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' % (
                                "danger" if numerrors > 0 else "success",
                                ws_name,
                                error[1] if error[1] else "",
                                error[2] if error[2] else "",
                                error[3] if error[3] else "",
                                error[4],
                            )
                    yield "</tbody></table></div>"
            yield "<div><strong>%s</strong><br><br></div>" % _("Done")
    except GeneratorExit:
        logger.warning("Connection Aborted")
    except Exception as e:
        yield "Import aborted: %s" % e
        logger.error("Exception importing workbook: %s" % e)
Exemple #33
0
def exportWorkbook(request):
    # Create a workbook
    wb = Workbook(write_only=True)

    # Create a named style for the header row
    headerstyle = NamedStyle(name="headerstyle")
    headerstyle.fill = PatternFill(fill_type="solid", fgColor="70c4f4")
    wb.add_named_style(headerstyle)
    readlonlyheaderstyle = NamedStyle(name="readlonlyheaderstyle")
    readlonlyheaderstyle.fill = PatternFill(fill_type="solid",
                                            fgColor="d0ebfb")
    wb.add_named_style(readlonlyheaderstyle)

    # Loop over all selected entity types
    exportConfig = {"anonymous": request.POST.get("anonymous", False)}
    ok = False
    for entity_name in request.POST.getlist("entities"):
        try:
            # Initialize
            (app_label, model_label) = entity_name.split(".")
            model = apps.get_model(app_label, model_label)
            # Verify access rights
            permname = get_permission_codename("change", model._meta)
            if not request.user.has_perm("%s.%s" % (app_label, permname)):
                continue

            # Never export some special administrative models
            if model in EXCLUDE_FROM_BULK_OPERATIONS:
                continue

            # Create sheet
            ok = True
            ws = wb.create_sheet(title=force_text(model._meta.verbose_name))

            # Build a list of fields and properties
            fields = []
            modelfields = []
            header = []
            source = False
            lastmodified = False
            owner = False
            comment = None
            try:
                # The admin model of the class can define some fields to exclude from the export
                exclude = data_site._registry[model].exclude
            except Exception:
                exclude = None
            for i in model._meta.fields:
                if i.name in ["lft", "rght", "lvl"]:
                    continue  # Skip some fields of HierarchyModel
                elif i.name == "source":
                    source = i  # Put the source field at the end
                elif i.name == "lastmodified":
                    lastmodified = i  # Put the last-modified field at the very end
                elif not (exclude and i.name in exclude):
                    fields.append(i.column)
                    modelfields.append(i)
                    cell = WriteOnlyCell(ws,
                                         value=force_text(
                                             i.verbose_name).title())
                    if i.editable:
                        cell.style = "headerstyle"
                        if isinstance(i, ForeignKey):
                            cell.comment = CellComment(
                                force_text(
                                    _("Values in this field must exist in the %s table"
                                      ) % force_text(i.remote_field.model.
                                                     _meta.verbose_name)),
                                "Author",
                            )
                        elif i.choices:
                            cell.comment = CellComment(
                                force_text(
                                    _("Accepted values are: %s") %
                                    ", ".join([c[0] for c in i.choices])),
                                "Author",
                            )
                    else:
                        cell.style = "readlonlyheaderstyle"
                        if not comment:
                            comment = CellComment(
                                force_text(_("Read only")),
                                "Author",
                                height=20,
                                width=80,
                            )
                        cell.comment = comment
                    header.append(cell)
                    if i.name == "owner":
                        owner = True
            if hasattr(model, "propertyFields"):
                if callable(model.propertyFields):
                    props = model.propertyFields(request)
                else:
                    props = model.propertyFields
                for i in props:
                    if i.export:
                        fields.append(i.name)
                        cell = WriteOnlyCell(ws,
                                             value=force_text(
                                                 i.verbose_name).title())
                        if i.editable:
                            cell.style = "headerstyle"
                            if isinstance(i, ForeignKey):
                                cell.comment = CellComment(
                                    force_text(
                                        _("Values in this field must exist in the %s table"
                                          ) % force_text(i.remote_field.model.
                                                         _meta.verbose_name)),
                                    "Author",
                                )
                        elif i.choices:
                            cell.comment = CellComment(
                                force_text(
                                    _("Accepted values are: %s") %
                                    ", ".join([c[0] for c in i.choices])),
                                "Author",
                            )
                        else:
                            cell.style = "readlonlyheaderstyle"
                            if not comment:
                                comment = CellComment(
                                    force_text(_("Read only")),
                                    "Author",
                                    height=20,
                                    width=80,
                                )
                            cell.comment = comment
                        header.append(cell)
                        modelfields.append(i)
            if source:
                fields.append("source")
                cell = WriteOnlyCell(ws, value=force_text(_("source")).title())
                cell.style = "headerstyle"
                header.append(cell)
                modelfields.append(source)
            if lastmodified:
                fields.append("lastmodified")
                cell = WriteOnlyCell(ws,
                                     value=force_text(
                                         _("last modified")).title())
                cell.style = "readlonlyheaderstyle"
                if not comment:
                    comment = CellComment(force_text(_("Read only")),
                                          "Author",
                                          height=20,
                                          width=80)
                cell.comment = comment
                header.append(cell)
                modelfields.append(lastmodified)

            # Write a formatted header row
            ws.append(header)

            # Add an auto-filter to the table
            ws.auto_filter.ref = "A1:%s1048576" % get_column_letter(
                len(header))

            # Use the default manager
            if issubclass(model, HierarchyModel):
                model.rebuildHierarchy(database=request.database)
                query = (model.objects.all().using(request.database).order_by(
                    "lvl", "pk"))
            elif owner:
                # First export records with empty owner field
                query = (model.objects.all().using(request.database).order_by(
                    "-owner", "pk"))
            else:
                query = model.objects.all().using(
                    request.database).order_by("pk")

            # Special annotation of the export query
            if hasattr(model, "export_objects"):
                query = model.export_objects(query, request)

            # Loop over all records
            for rec in query.values_list(*fields):
                cells = []
                fld = 0
                for f in rec:
                    cells.append(
                        _getCellValue(f,
                                      field=modelfields[fld],
                                      exportConfig=exportConfig))
                    fld += 1
                ws.append(cells)
        except Exception:
            pass  # Silently ignore the error and move on to the next entity.

    # Not a single entity to export
    if not ok:
        raise Exception(_("Nothing to export"))

    # Write the excel from memory to a string and then to a HTTP response
    output = BytesIO()
    wb.save(output)
    response = HttpResponse(
        content_type=
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        content=output.getvalue(),
    )
    response["Content-Disposition"] = 'attachment; filename="frepple.xlsx"'
    response["Cache-Control"] = "no-cache, no-store"
    return response
Exemple #34
0
 def has_add_permission(self, request, parent, created_obj_cls):
     codename = get_permission_codename('add', created_obj_cls._meta)
     return request.user.has_perm(
         '%s.%s' % (created_obj_cls._meta.app_label, codename))
Exemple #35
0
 def has_add_content_permission(self, request, model):
     """Checks whether the given user can edit the given content model."""
     opts = model._meta
     return request.user.has_perm("{0}.{1}".format(opts.app_label, get_permission_codename('add', opts)))
Exemple #36
0
    def has_delete_permission(self):
        if self.opts.auto_created:
            return self.has_change_permission()

        codename = get_permission_codename('delete', self.opts)
        return self.user.has_perm("%s.%s" % (self.opts.app_label, codename))
"""
A custom AdminSite for AdminViewPermissionsTest.test_login_has_permission().
"""
from django.contrib import admin
from django.contrib.auth import get_permission_codename
from django.contrib.auth.forms import AuthenticationForm

from . import admin as base_admin, models

PERMISSION_NAME = 'admin_views.%s' % get_permission_codename(
    'change', models.Article._meta)


class PermissionAdminAuthenticationForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        from django import forms
        if not user.is_active or not (user.is_staff
                                      or user.has_perm(PERMISSION_NAME)):
            raise forms.ValidationError('permission denied')


class HasPermissionAdmin(admin.AdminSite):
    login_form = PermissionAdminAuthenticationForm

    def has_permission(self, request):
        return (request.user.is_active
                and (request.user.is_staff
                     or request.user.has_perm(PERMISSION_NAME)))


site = HasPermissionAdmin(name="has_permission_admin")
Exemple #38
0
def get_permission_name(action, model):
    return "%s_%s" % (model._meta.app_label,
                      get_permission_codename(action, model._meta))
Exemple #39
0
    def handle(self, **options):
        # Pick up the options
        self.database = options['database']
        if self.database not in settings.DATABASES:
            raise CommandError("No database settings known for '%s'" %
                               self.database)
        if options['user']:
            try:
                self.user = User.objects.all().using(
                    self.database).get(username=options['user'])
            except:
                raise CommandError("User '%s' not found" % options['user'])
        else:
            try:
                self.user = User.objects.all().using(
                    self.database).filter(is_superuser=True)[0]
            except:
                self.user = None

        now = datetime.now()

        task = None
        self.logfile = None
        errors = 0
        try:
            # Initialize the task
            if options['task']:
                try:
                    task = Task.objects.all().using(
                        self.database).get(pk=options['task'])
                except:
                    raise CommandError("Task identifier not found")
                if task.started or task.finished or task.status != "Waiting" or task.name != 'import from folder':
                    raise CommandError("Invalid task identifier")
                task.status = '0%'
                task.started = now
            else:
                task = Task(name='import from folder',
                            submitted=now,
                            started=now,
                            status='0%',
                            user=self.user)
            task.save(using=self.database)

            # Choose the right self.delimiter and language
            self.delimiter = get_format('DECIMAL_SEPARATOR',
                                        settings.LANGUAGE_CODE,
                                        True) == ',' and ';' or ','
            translation.activate(settings.LANGUAGE_CODE)

            # Execute
            if os.path.isdir(
                    settings.DATABASES[self.database]['FILEUPLOADFOLDER']):

                # Open the logfile
                self.logfile = open(
                    os.path.join(
                        settings.DATABASES[self.database]['FILEUPLOADFOLDER'],
                        'importfromfolder.log'), "a")
                print("%s Started import from folder\n" % datetime.now(),
                      file=self.logfile,
                      flush=True)

                all_models = [(ct.model_class(), ct.pk)
                              for ct in ContentType.objects.all()
                              if ct.model_class()]
                models = []
                for ifile in os.listdir(
                        settings.DATABASES[self.database]['FILEUPLOADFOLDER']):
                    if not ifile.lower().endswith(
                            '.csv') and not ifile.lower().endswith('.csv.gz'):
                        continue
                    filename0 = ifile.split('.')[0]

                    model = None
                    contenttype_id = None
                    for m, ct in all_models:
                        if filename0.lower() in (
                                m._meta.model_name.lower(),
                                m._meta.verbose_name.lower(),
                                m._meta.verbose_name_plural.lower()):
                            model = m
                            contenttype_id = ct
                            print("%s Matched a model to file: %s" %
                                  (datetime.now(), ifile),
                                  file=self.logfile,
                                  flush=True)
                            break

                    if not model or model in EXCLUDE_FROM_BULK_OPERATIONS:
                        print("%s Ignoring data in file: %s" %
                              (datetime.now(), ifile),
                              file=self.logfile,
                              flush=True)
                    elif self.user and not self.user.has_perm(
                            '%s.%s' %
                        (model._meta.app_label,
                         get_permission_codename('add', model._meta))):
                        # Check permissions
                        print("%s You don't have permissions to add: %s" %
                              (datetime.now(), ifile),
                              file=self.logfile,
                              flush=True)
                    else:
                        deps = set([model])
                        GridReport.dependent_models(model, deps)

                        models.append((ifile, model, contenttype_id, deps))

                # Sort the list of models, based on dependencies between models
                models = GridReport.sort_models(models)

                i = 0
                cnt = len(models)
                for ifile, model, contenttype_id, dependencies in models:
                    task.status = str(int(10 + i / cnt * 80)) + '%'
                    task.message = 'Processing data file %s' % ifile
                    task.save(using=self.database)
                    i += 1
                    filetoparse = os.path.join(
                        os.path.abspath(settings.DATABASES[self.database]
                                        ['FILEUPLOADFOLDER']), ifile)
                    print("%s Started processing data in file: %s" %
                          (datetime.now(), ifile),
                          file=self.logfile,
                          flush=True)
                    errors += self.parseCSVloadfromfolder(model, filetoparse)

            else:
                errors += 1
                cnt = 0
                print("%s Failed, folder does not exist" % datetime.now(),
                      file=self.logfile,
                      flush=True)

            # Task update
            if errors:
                task.status = 'Failed'
                if not cnt:
                    task.message = "Destination folder does not exist"
                else:
                    task.message = "Uploaded %s data files with %s errors" % (
                        cnt, errors)
            else:
                task.status = 'Done'
                task.message = "Uploaded %s data files" % cnt
            task.finished = datetime.now()

        except KeyboardInterrupt:
            if task:
                task.status = 'Cancelled'
                task.message = 'Cancelled'
            if self.logfile:
                print('%s Cancelled\n' % datetime.now(),
                      file=self.logfile,
                      flush=True)

        except Exception as e:
            print("%s Failed" % datetime.now(), file=self.logfile, flush=True)
            if task:
                task.status = 'Failed'
                task.message = '%s' % e
            raise e

        finally:
            if task:
                if not errors:
                    task.status = '100%'
                else:
                    task.status = 'Failed'
            task.finished = datetime.now()
            task.save(using=self.database)
            if self.logfile:
                print('%s End of import from folder\n' % datetime.now(),
                      file=self.logfile,
                      flush=True)
                self.logfile.close()
Exemple #40
0
def get_admin_menu_item_context(request, page, filtered=False, language=None):
    """
    Used for rendering the page tree, inserts into context everything what
    we need for single item
    """
    has_add_page_permission = page.has_add_permission(request)
    has_move_page_permission = page.has_move_page_permission(request)

    site = Site.objects.get_current()
    lang = get_language_from_request(request)
    #slug = page.get_slug(language=lang, fallback=True) # why was this here ??
    metadata = ""
    if get_cms_setting('PERMISSION'):
        # jstree metadata generator
        md = []

        #if not has_add_page_permission:
        if not has_move_page_permission:
            md.append(('valid_children', False))
            md.append(('draggable', False))
        if md:
            # just turn it into simple javascript object
            metadata = "{" + ", ".join(
                map(
                    lambda e: "%s: %s" %
                    (e[0], isinstance(e[1], bool) and str(e[1]) or e[1].lower(
                    )), md)) + "}"

    has_add_on_same_level_permission = False
    opts = Page._meta
    if get_cms_setting('PERMISSION'):
        if hasattr(request.user, '_global_add_perm_cache'):
            global_add_perm = request.user._global_add_perm_cache
        else:
            global_add_perm = GlobalPagePermission.objects.user_has_add_permission(
                request.user, page.site_id).exists()
            request.user._global_add_perm_cache = global_add_perm
        if request.user.has_perm(
                opts.app_label + '.' +
                get_permission_codename('add', opts)) and global_add_perm:
            has_add_on_same_level_permission = True
    from cms.utils import permissions
    if not has_add_on_same_level_permission and page.parent_id:
        has_add_on_same_level_permission = permissions.has_generic_permission(
            page.parent_id, request.user, "add", page.site_id)
        #has_add_on_same_level_permission = has_add_page_on_same_level_permission(request, page)
    context = {
        'page': page,
        'site': site,
        'lang': lang,
        'filtered': filtered,
        'metadata': metadata,
        'preview_language': language,
        'has_change_permission': page.has_change_permission(request),
        'has_publish_permission': page.has_publish_permission(request),
        'has_delete_permission': page.has_delete_permission(request),
        'has_move_page_permission': has_move_page_permission,
        'has_add_page_permission': has_add_page_permission,
        'has_add_on_same_level_permission': has_add_on_same_level_permission,
        'CMS_PERMISSION': get_cms_setting('PERMISSION'),
    }
    return context
Exemple #41
0
 def has_add_permission(self):
     codename = get_permission_codename('add', self.opts)
     return ('add' not in self.remove_permissions) and self.user.has_perm(
         '%s.%s' % (self.app_label, codename))
Exemple #42
0
    def handle(self, **options):
        # Pick up the options
        now = datetime.now()
        self.database = options["database"]
        if self.database not in settings.DATABASES:
            raise CommandError("No database settings known for '%s'" %
                               self.database)
        if options["user"]:
            try:
                self.user = (User.objects.all().using(
                    self.database).get(username=options["user"]))
            except Exception:
                raise CommandError("User '%s' not found" % options["user"])
        else:
            self.user = None
        timestamp = now.strftime("%Y%m%d%H%M%S")
        if self.database == DEFAULT_DB_ALIAS:
            logfile = "importworkbook-%s.log" % timestamp
        else:
            logfile = "importworkbook_%s-%s.log" % (self.database, timestamp)

        task = None
        try:
            setattr(_thread_locals, "database", self.database)
            # Initialize the task
            if options["task"]:
                try:
                    task = (Task.objects.all().using(
                        self.database).get(pk=options["task"]))
                except Exception:
                    raise CommandError("Task identifier not found")
                if (task.started or task.finished or task.status != "Waiting"
                        or task.name
                        not in ("frepple_importworkbook", "importworkbook")):
                    raise CommandError("Invalid task identifier")
                task.status = "0%"
                task.started = now
            else:
                task = Task(
                    name="importworkbook",
                    submitted=now,
                    started=now,
                    status="0%",
                    user=self.user,
                )
            task.arguments = " ".join(options["file"])
            task.save(using=self.database)

            all_models = [(ct.model_class(), ct.pk)
                          for ct in ContentType.objects.all()
                          if ct.model_class()]
            try:
                with transaction.atomic(using=self.database):
                    # Find all models in the workbook
                    if "filename" not in locals():
                        filename = options["file"]
                    for file in filename:
                        wb = load_workbook(filename=file,
                                           read_only=True,
                                           data_only=True)
                        models = []
                        for ws_name in wb.sheetnames:
                            # Find the model
                            model = None
                            contenttype_id = None
                            for m, ct in all_models:
                                if matchesModelName(ws_name, m):
                                    model = m
                                    contenttype_id = ct
                                    break
                            if not model or model in EXCLUDE_FROM_BULK_OPERATIONS:
                                print(
                                    force_text(
                                        _("Ignoring data in worksheet: %s") %
                                        ws_name))
                                # yield '<div class="alert alert-warning">' + force_text(_("Ignoring data in worksheet: %s") % ws_name) + '</div>'
                            elif not self.user.has_perm("%s.%s" % (
                                    model._meta.app_label,
                                    get_permission_codename(
                                        "add", model._meta),
                            )):
                                # Check permissions
                                print(
                                    force_text(
                                        _("You don't permissions to add: %s") %
                                        ws_name))
                                # yield '<div class="alert alert-danger">' + force_text(_("You don't permissions to add: %s") % ws_name) + '</div>'
                            else:
                                deps = set([model])
                                GridReport.dependent_models(model, deps)
                                models.append(
                                    (ws_name, model, contenttype_id, deps))

                        # Sort the list of models, based on dependencies between models
                        models = GridReport.sort_models(models)

                        # Process all rows in each worksheet
                        for ws_name, model, contenttype_id, dependencies in models:
                            print(
                                force_text(
                                    _("Processing data in worksheet: %s") %
                                    ws_name))
                            # yield '<strong>' + force_text(_("Processing data in worksheet: %s") % ws_name) + '</strong><br>'
                            # yield ('<div class="table-responsive">'
                            # '<table class="table table-condensed" style="white-space: nowrap;"><tbody>')
                            numerrors = 0
                            numwarnings = 0
                            firsterror = True
                            ws = wb[ws_name]
                            for error in parseExcelWorksheet(
                                    model,
                                    ws,
                                    user=self.user,
                                    database=self.database,
                                    ping=True,
                            ):
                                if error[0] == logging.DEBUG:
                                    # Yield some result so we can detect disconnect clients and interrupt the upload
                                    # yield ' '
                                    continue
                                if firsterror and error[0] in (
                                        logging.ERROR,
                                        logging.WARNING,
                                ):
                                    print("%s %s %s %s %s%s%s" % (
                                        capfirst(_("worksheet")),
                                        capfirst(_("row")),
                                        capfirst(_("field")),
                                        capfirst(_("value")),
                                        capfirst(_("error")),
                                        " / ",
                                        capfirst(_("warning")),
                                    ))
                                    # yield '<tr><th class="sr-only">%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s%s%s</th></tr>' % (
                                    #   capfirst(_("worksheet")), capfirst(_("row")),
                                    #   capfirst(_("field")), capfirst(_("value")),
                                    #   capfirst(_("error")), " / ", capfirst(_("warning"))
                                    #   )
                                    firsterror = False
                                if error[0] == logging.ERROR:
                                    print("%s %s %s %s %s: %s" % (
                                        ws_name,
                                        error[1] if error[1] else "",
                                        error[2] if error[2] else "",
                                        error[3] if error[3] else "",
                                        capfirst(_("error")),
                                        error[4],
                                    ))
                                    # yield '<tr><td class="sr-only">%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s: %s</td></tr>' % (
                                    #   ws_name,
                                    #   error[1] if error[1] else '',
                                    #   error[2] if error[2] else '',
                                    #   error[3] if error[3] else '',
                                    #   capfirst(_('error')),
                                    #   error[4]
                                    #   )
                                    numerrors += 1
                                elif error[1] == logging.WARNING:
                                    print("%s %s %s %s %s: %s" % (
                                        ws_name,
                                        error[1] if error[1] else "",
                                        error[2] if error[2] else "",
                                        error[3] if error[3] else "",
                                        capfirst(_("warning")),
                                        error[4],
                                    ))
                                    # yield '<tr><td class="sr-only">%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s: %s</td></tr>' % (
                                    #   ws_name,
                                    #   error[1] if error[1] else '',
                                    #   error[2] if error[2] else '',
                                    #   error[3] if error[3] else '',
                                    #   capfirst(_('warning')),
                                    #   error[4]
                                    #   )
                                    numwarnings += 1
                                else:
                                    print("%s %s %s %s %s %s" % (
                                        "danger"
                                        if numerrors > 0 else "success",
                                        ws_name,
                                        error[1] if error[1] else "",
                                        error[2] if error[2] else "",
                                        error[3] if error[3] else "",
                                        error[4],
                                    ))
                            #     yield '<tr class=%s><td class="sr-only">%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' % (
                            #       "danger" if numerrors > 0 else 'success',
                            #       ws_name,
                            #       error[1] if error[1] else '',
                            #       error[2] if error[2] else '',
                            #       error[3] if error[3] else '',
                            #       error[4]
                            #       )
                            # yield '</tbody></table></div>'
                        print("%s" % _("Done"))
                        # yield '<div><strong>%s</strong></div>' % _("Done")
            except GeneratorExit:
                logger.warning("Connection Aborted")
        except Exception as e:
            if task:
                task.status = "Failed"
                task.message = "%s" % e
                task.finished = datetime.now()
            raise e

        finally:
            setattr(_thread_locals, "database", None)
            if task:
                task.save(using=self.database)

        # Task update
        task.status = "Done"
        task.finished = datetime.now()
        task.processid = None
        task.save(using=self.database, update_fields=["status", "finished"])

        return _("Done")
 def _give_permission(self, user, model, permission_type, save=True):
     codename = get_permission_codename(permission_type, model._meta)
     user.user_permissions.add(Permission.objects.get(codename=codename))
Exemple #44
0
 def can_add(self, user):
   return self.model and user.has_perm("%s.%s" % (self.model._meta.app_label, get_permission_codename('add', self.model._meta)))
Exemple #45
0
def has_permission(opts, user, perm):
    codename = get_permission_codename(perm, opts)
    return user.has_perm("%s.%s" % (opts.app_label, codename))
Exemple #46
0
 def has_view_permission(self, request, obj=None):
     opts = self.opts
     codename = get_permission_codename('view', opts)
     return request.user.has_perm("%s.%s" % (opts.app_label, codename))
Exemple #47
0
def create_view_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs):  # noqa
    """
    Create 'view' permissions for all models.

    ``django.contrib.auth`` only creates add, change and delete permissions.
    Since we want to support read-only views, we need to add our own
    permission.

    Copied from ``https://github.com/django/django/blob/1.9.6/django/contrib/auth/management/__init__.py#L60``.

    """
    if not app_config.models_module:
        return

    try:
        Permission = apps.get_model('auth', 'Permission')
    except LookupError:
        return

    if not router.allow_migrate_model(using, Permission):
        return

    from django.contrib.contenttypes.models import ContentType

    # This will hold the permissions we're looking for as
    # (content_type, (codename, name))
    searched_perms = list()
    # The codenames and ctypes that should exist.
    ctypes = set()
    for klass in app_config.get_models():
        # Force looking up the content types in the current database
        # before creating foreign keys to them.
        ctype = ContentType.objects.db_manager(using).get_for_model(klass)

        ctypes.add(ctype)
        perm = (get_permission_codename('view', klass._meta), 'Can view %s' % (klass._meta.verbose_name_raw))
        searched_perms.append((ctype, perm))

    # Find all the Permissions that have a content_type for a model we're
    # looking for.  We don't need to check for codenames since we already have
    # a list of the ones we're going to create.
    all_perms = set(Permission.objects.using(using).filter(
        content_type__in=ctypes,
    ).values_list(
        "content_type", "codename"
    ))

    perms = [
        Permission(codename=codename, name=name, content_type=ct)
        for ct, (codename, name) in searched_perms
        if (ct.pk, codename) not in all_perms
    ]
    # Validate the permissions before bulk_creation to avoid cryptic
    # database error when the verbose_name is longer than 50 characters
    permission_name_max_length = Permission._meta.get_field('name').max_length
    verbose_name_max_length = permission_name_max_length - 11  # len('Can change ') prefix
    for perm in perms:
        if len(perm.name) > permission_name_max_length:
            raise ValidationError(
                "The verbose_name of %s.%s is longer than %s characters" % (
                    perm.content_type.app_label,
                    perm.content_type.model,
                    verbose_name_max_length,
                )
            )
    Permission.objects.using(using).bulk_create(perms)
    if verbosity >= 2:
        for perm in perms:
            print("Adding permission '%s'" % perm)
Exemple #48
0
 def has_add_content_permission(request, model):
     '''Checks whether the given user can edit the given content model.'''
     opts = model._meta
     return request.user.has_perm('{0}.{1}'.format(opts.app_label, get_permission_codename('add', opts)))
Exemple #49
0
 def has_perm(o):
     codename = get_permission_codename('delete', o._meta)
     return request.user.has_perm('%s.%s' %
                                  (o._meta.app_label, codename))
Exemple #50
0
def permission_name(opts, name):
    codename = get_permission_codename(name, opts)
    permission = f"{opts.app_label}.{codename}"
    return permission
Exemple #51
0
 def has_change_permission(self, request, obj_or_class):
     codename = get_permission_codename('change', obj_or_class._meta)
     return request.user.has_perm('%s.%s' %
                                  (obj_or_class._meta.app_label, codename))
Exemple #52
0
 def has_delete_permission(self, request, obj=None):
     opts = self.opts
     codename = get_permission_codename('delete', opts)
     return request.user.has_perm('%s.%s' % (opts.app_label, codename), obj)
Exemple #53
0
 def has_decline_permission(self, request):
     """Does the user have permission to Cancel ?"""
     opts = self.opts
     codename = get_permission_codename('decline', opts)
     return request.user.has_perm('%s %s' % (opts.app_label, codename))
Exemple #54
0
 def has_permission(self, user, action, model):
     opts = model._meta
     codename = get_permission_codename(action, opts)
     return user.has_perm('.'.join((opts.app_label, codename)))
Exemple #55
0
 def has_accepted_permission(self, request):
     """Does the user have permission to accept ?"""
     opts = self.opts
     codename = get_permission_codename('accepted', opts)
     return request.user.has_perm('%s %s' % (opts.app_label, codename))
Exemple #56
0
    def handle(self, **options):
        # Pick up the options
        now = datetime.now()
        self.database = options['database']
        if self.database not in settings.DATABASES:
            raise CommandError("No database settings known for '%s'" %
                               self.database)
        if options['user']:
            try:
                self.user = User.objects.all().using(
                    self.database).get(username=options['user'])
            except:
                raise CommandError("User '%s' not found" % options['user'])
        else:
            self.user = None
        timestamp = now.strftime("%Y%m%d%H%M%S")
        if self.database == DEFAULT_DB_ALIAS:
            logfile = 'importfromfolder-%s.log' % timestamp
        else:
            logfile = 'importfromfolder_%s-%s.log' % (self.database, timestamp)

        try:
            handler = logging.FileHandler(os.path.join(settings.FREPPLE_LOGDIR,
                                                       logfile),
                                          encoding='utf-8')
            # handler.setFormatter(logging.Formatter(settings.LOGGING['formatters']['simple']['format']))
            logger.addHandler(handler)
            logger.propagate = False
        except Exception as e:
            print("%s Failed to open logfile %s: %s" %
                  (datetime.now(), logfile, e))

        task = None
        errors = [0, 0]
        returnederrors = [0, 0]
        try:
            setattr(_thread_locals, 'database', self.database)
            # Initialize the task
            if options['task']:
                try:
                    task = Task.objects.all().using(
                        self.database).get(pk=options['task'])
                except:
                    raise CommandError("Task identifier not found")
                if task.started or task.finished or task.status != "Waiting" or task.name not in (
                        'frepple_importfromfolder', 'importfromfolder'):
                    raise CommandError("Invalid task identifier")
                task.status = '0%'
                task.started = now
                task.logfile = logfile
            else:
                task = Task(name='importfromfolder',
                            submitted=now,
                            started=now,
                            status='0%',
                            user=self.user,
                            logfile=logfile)
            task.save(using=self.database)

            # Choose the right self.delimiter and language
            self.delimiter = get_format('DECIMAL_SEPARATOR',
                                        settings.LANGUAGE_CODE,
                                        True) == ',' and ';' or ','
            translation.activate(settings.LANGUAGE_CODE)

            # Execute
            if 'FILEUPLOADFOLDER' in settings.DATABASES[self.database] \
              and os.path.isdir(settings.DATABASES[self.database]['FILEUPLOADFOLDER']):

                # Open the logfile
                logger.info("%s Started importfromfolder\n" %
                            datetime.now().replace(microsecond=0))

                all_models = [(ct.model_class(), ct.pk)
                              for ct in ContentType.objects.all()
                              if ct.model_class()]
                models = []
                for ifile in os.listdir(
                        settings.DATABASES[self.database]['FILEUPLOADFOLDER']):
                    if not ifile.lower().endswith(
                        ('.csv', '.csv.gz', '.xlsx')):
                        continue
                    filename0 = ifile.split('.')[0]

                    model = None
                    contenttype_id = None
                    for m, ct in all_models:
                        # Try with translated model names
                        if filename0.lower() in (
                                m._meta.model_name.lower(),
                                m._meta.verbose_name.lower(),
                                m._meta.verbose_name_plural.lower()):
                            model = m
                            contenttype_id = ct
                            logger.info(
                                "%s Matched a model to file: %s" %
                                (datetime.now().replace(microsecond=0), ifile))
                            break
                        # Try with English model names
                        with translation.override('en'):
                            if filename0.lower() in (
                                    m._meta.model_name.lower(),
                                    m._meta.verbose_name.lower(),
                                    m._meta.verbose_name_plural.lower()):
                                model = m
                                contenttype_id = ct
                                logger.info(
                                    "%s Matched a model to file: %s" %
                                    (datetime.now().replace(microsecond=0),
                                     ifile))
                                break

                    if not model or model in EXCLUDE_FROM_BULK_OPERATIONS:
                        logger.info(
                            "%s Ignoring data in file: %s" %
                            (datetime.now().replace(microsecond=0), ifile))
                    elif self.user and not self.user.has_perm(
                            '%s.%s' %
                        (model._meta.app_label,
                         get_permission_codename('add', model._meta))):
                        # Check permissions
                        logger.info(
                            "%s You don't have permissions to add: %s" %
                            (datetime.now().replace(microsecond=0), ifile))
                    else:
                        deps = set([model])
                        GridReport.dependent_models(model, deps)

                        models.append((ifile, model, contenttype_id, deps))

                # Sort the list of models, based on dependencies between models
                models = GridReport.sort_models(models)

                i = 0
                cnt = len(models)
                for ifile, model, contenttype_id, dependencies in models:
                    task.status = str(int(10 + i / cnt * 80)) + '%'
                    task.message = 'Processing data file %s' % ifile
                    task.save(using=self.database)
                    i += 1
                    filetoparse = os.path.join(
                        os.path.abspath(settings.DATABASES[self.database]
                                        ['FILEUPLOADFOLDER']), ifile)
                    if ifile.lower().endswith('.xlsx'):
                        logger.info(
                            "%s Started processing data in Excel file: %s" %
                            (datetime.now().replace(microsecond=0), ifile))
                        returnederrors = self.loadExcelfile(model, filetoparse)
                        errors[0] += returnederrors[0]
                        errors[1] += returnederrors[1]
                        logger.info(
                            "%s Finished processing data in file: %s" %
                            (datetime.now().replace(microsecond=0), ifile))
                    else:
                        logger.info(
                            "%s Started processing data in CSV file: %s" %
                            (datetime.now().replace(microsecond=0), ifile))
                        returnederrors = self.loadCSVfile(model, filetoparse)
                        errors[0] += returnederrors[0]
                        errors[1] += returnederrors[1]
                        logger.info(
                            "%s Finished processing data in CSV file: %s" %
                            (datetime.now().replace(microsecond=0), ifile))
            else:
                errors[0] += 1
                cnt = 0
                logger.error("%s Failed, folder does not exist" %
                             datetime.now().replace(microsecond=0))

            # Task update
            if errors[0] > 0:
                task.status = 'Failed'
                if not cnt:
                    task.message = "Destination folder does not exist"
                else:
                    task.message = "Uploaded %s data files with %s errors and %s warnings" % (
                        cnt, errors[0], errors[1])
            else:
                task.status = 'Done'
                task.message = "Uploaded %s data files with %s warnings" % (
                    cnt, errors[1])
            task.finished = datetime.now()

        except KeyboardInterrupt:
            if task:
                task.status = 'Cancelled'
                task.message = 'Cancelled'
            logger.info('%s Cancelled\n' %
                        datetime.now().replace(microsecond=0))

        except Exception as e:
            logger.error("%s Failed" % datetime.now().replace(microsecond=0))
            if task:
                task.status = 'Failed'
                task.message = '%s' % e
            raise e

        finally:
            setattr(_thread_locals, 'database', None)
            if task:
                if errors[0] == 0:
                    task.status = 'Done'
                else:
                    task.status = 'Failed'
            task.finished = datetime.now()
            task.save(using=self.database)
            logger.info('%s End of importfromfolder\n' %
                        datetime.now().replace(microsecond=0))
Exemple #57
0
 def _has_transfer_permission(self, request, obj=None):
     change_permission = Persona._meta.app_label + '.' + get_permission_codename(
         'transfer', Persona._meta)
     return request.user.has_perm(change_permission)
Exemple #58
0
 def has_active_permission(self, request):
     opts = self.opts
     codename = get_permission_codename('active', opts)
     return request.user.has_perm('%s.%s' % (opts.app_label, codename))
Exemple #59
0
 def has_delete_permission(self, obj=None):
     codename = get_permission_codename('delete', self.opts)
     return ('delete'
             not in self.remove_permissions) and self.user.has_perm(
                 '%s.%s' % (self.app_label, codename))
 def get_perm_codename(self, action):
     return get_permission_codename(action, self.opts)