def test_bad_bulk_action_settings_log_correctly(self, mock_logger):
     with override_settings(ARISTOTLE_SETTINGS=dict(
             settings.ARISTOTLE_SETTINGS, BULK_ACTIONS={}),
                            ARISTOTLE_SETTINGS_STRICT_MODE=True):
         with self.assertRaisesRegexp(ImproperlyConfigured,
                                      error_messages['bulk_action_failed']):
             fetch_aristotle_settings()
 def test_downloader_settings_log_correctly(self, mock_logger):
     with override_settings(ARISTOTLE_SETTINGS=dict(
             settings.ARISTOTLE_SETTINGS, DOWNLOADERS=[1]),
                            ARISTOTLE_SETTINGS_STRICT_MODE=True):
         with self.assertRaisesRegexp(ImproperlyConfigured,
                                      error_messages['downloaders_failed']):
             fetch_aristotle_settings()
 def test_content_extensions_settings_log_correctly(self, mock_logger):
     with override_settings(ARISTOTLE_SETTINGS=dict(
             settings.ARISTOTLE_SETTINGS, CONTENT_EXTENSIONS=[1]),
                            ARISTOTLE_SETTINGS_STRICT_MODE=True):
         with self.assertRaisesRegexp(
                 ImproperlyConfigured,
                 error_messages['content_extensions_failed']):
             fetch_aristotle_settings()
def user_can_query_user_list(user):
    user_visbility = fetch_aristotle_settings().get('USER_VISIBILITY', 'owner')
    return (
        user.has_perm("aristotle_mdr.is_registry_administrator") or
        ('workgroup_manager' in user_visbility and user.profile.is_workgroup_manager()) or
        ('registation_authority_manager' in user_visbility and user.profile.is_registrar)
    )
Example #5
0
def user_can_query_user_list(user):
    user_visbility = fetch_aristotle_settings().get('USER_VISIBILITY', 'owner')
    return (user.has_perm("aristotle_mdr.is_registry_administrator")
            or ('workgroup_manager' in user_visbility
                and user.profile.is_workgroup_manager())
            or ('registation_authority_manager' in user_visbility
                and user.profile.is_registrar))
    def relational_attributes(self):
        rels = {
            "indicator_sets": {
                "all":
                _("Indicator Sets that include this Indicator"),
                "qs":
                IndicatorSet.objects.filter(indicatorinclusion__indicator=self)
            },
        }

        if "aristotle_dse" in fetch_aristotle_settings().get(
                'CONTENT_EXTENSIONS'):
            from aristotle_dse.models import DataSetSpecification, Dataset

            numdefn_datasets = IndicatorNumeratorDefinition.objects.filter(
                indicator_id=self.id).values('data_set_id')
            dendefn_datasets = IndicatorDenominatorDefinition.objects.filter(
                indicator_id=self.id).values('data_set_id')
            dissagedefn_datasets = IndicatorDisaggregationDefinition.objects.filter(
                indicator_id=self.id).values('data_set_id')
            datasets = Dataset.objects.filter(id__in=Subquery(
                numdefn_datasets.union(dendefn_datasets).union(
                    dissagedefn_datasets)))

            rels.update({
                "data_sources": {
                    "all": _("Data Sets that are used in this Indicator"),
                    "qs": datasets
                },
            })
        return rels
 def test_content_extensions_settings_log_correctly(self, mock_logger):
     with override_settings(
         ARISTOTLE_SETTINGS=dict(settings.ARISTOTLE_SETTINGS, CONTENT_EXTENSIONS=[1]),
         ARISTOTLE_SETTINGS_STRICT_MODE=True
     ):
         with self.assertRaisesRegexp(ImproperlyConfigured, error_messages['content_extensions_failed']):
             my_settings = fetch_aristotle_settings()
 def test_downloader_settings_log_correctly(self, mock_logger):
     with override_settings(
         ARISTOTLE_SETTINGS=dict(settings.ARISTOTLE_SETTINGS, DOWNLOADERS=[1]),
         ARISTOTLE_SETTINGS_STRICT_MODE=True
     ):
         with self.assertRaisesRegexp(ImproperlyConfigured, error_messages['downloaders_failed']):
             my_settings = fetch_aristotle_settings()
Example #9
0
    def get_download_items(self, cluster_relations=None, de_relations=None):
        from django.db.models import Q

        if not cluster_relations:
            cluster_relations = self.get_all_clusters()
        dss_ids = self.get_unique_ids(cluster_relations)

        if not de_relations:
            de_relations = self.get_de_relations(dss_ids)
        de_ids = self.get_unique_ids(de_relations)

        items = [
            type(self).objects.filter(Q(id__in=dss_ids)
                                      & ~Q(id=self.id)).distinct(),
            aristotle.models.DataElement.objects.filter(
                id__in=de_ids).distinct(),
            aristotle.models.DataElementConcept.objects.filter(
                dataelement__in=de_ids).distinct(),
            aristotle.models.ObjectClass.objects.filter(
                dataelementconcept__dataelement__in=de_ids).distinct(),
            aristotle.models.Property.objects.filter(
                dataelementconcept__dataelement__in=de_ids).distinct(),
            aristotle.models.ValueDomain.objects.filter(
                dataelement__in=de_ids).distinct(),
        ]

        if 'aristotle_mdr_backwards' in fetch_aristotle_settings().get(
                'CONTENT_EXTENSIONS', []):
            from aristotle_mdr.contrib.aristotle_backwards.models import ClassificationScheme
            items.append(
                ClassificationScheme.objects.filter(
                    valueDomains__dataelement__in=de_ids).distinct(), )

        return items
Example #10
0
 def __new__(cls, *args, **kwargs):
     kwargs['request'] = request
     kwargs['name_suggest_fields'] = self.name_suggest_fields
     if self.name_suggest_fields:
         SEPARATORS = fetch_aristotle_settings().get('SEPARATORS', {})
         kwargs['separator'] = SEPARATORS[self.model.__name__]
     return conceptForm(*args, **kwargs)
def create_list(request):
    if not request.user.is_authenticated:
        return redirect(reverse('friendly_login') + '?next=%s' % request.path)

    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])
    aristotle_apps += ["aristotle_mdr"]
    out = {}

    wizards = []
    for wiz in getattr(settings, 'ARISTOTLE_SETTINGS', {}).get('METADATA_CREATION_WIZARDS', []):
        w = wiz.copy()
        _w = {
            'model': apps.get_app_config(wiz['app_label']).get_model(wiz['model']),
            'class': import_string(wiz['class']),
        }
        w.update(_w)
        wizards.append(w)

    return render(
        request, "aristotle_mdr/create/create_list.html",
        {
            'models': get_app_config_list(),
            'wizards': wizards
        }
    )
    def has_perm(self, user_obj, perm, obj=None):

        if not user_obj.is_active:
            return False
        if user_obj.is_superuser:
            return True

        app_label, perm_name = perm.split('.', 1)
        extensions = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])

        if app_label == "aristotle_mdr" and hasattr(perms, perm_name):
            return getattr(perms, perm_name)(user_obj, obj)

        if app_label in extensions + ["aristotle_mdr"]:
            # This is required so that a user can correctly delete the 'concept' parent class in the admin site.
            if perm_name == "delete_concept_from_admin":
                return obj is None or perms.user_can_edit(user_obj, obj)

            # This is a rough catch all, and is designed to indicate a user could
            # delete an item type, but not a specific item.
            elif (perm_name.startswith('delete_')
                  or perm_name.startswith('create_')
                  or perm_name.startswith('add_')):
                if obj is None:
                    return perms.user_is_editor(user_obj)
                else:
                    return perms.user_can_edit(user_obj, obj)

        return super(AristotleBackend, self).has_perm(user_obj, perm, obj)
def admin_tools(request):
    if not request.user.is_superuser:
        raise PermissionDenied

    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])
    aristotle_apps += ["aristotle_mdr"]

    from django.contrib.contenttypes.models import ContentType
    models = ContentType.objects.filter(app_label__in=aristotle_apps).all()
    model_stats = {}

    for m in models:
        if m.model_class() and issubclass(
                m.model_class(), MDR._concept) and not m.model.startswith("_"):
            # Only output subclasses of 11179 concept
            app_models = model_stats.get(m.app_label, {
                'app': None,
                'models': []
            })
            if app_models['app'] is None:
                app_models['app'] = getattr(apps.get_app_config(m.app_label),
                                            'verbose_name')
            app_models['models'].append(
                (m.model_class(), get_cached_object_count(m),
                 reverse("admin:%s_%s_changelist" % (m.app_label, m.model))))
            model_stats[m.app_label] = app_models

    page = render(request, "aristotle_mdr/user/userAdminTools.html", {
        "item": request.user,
        "models": model_stats
    })
    return page
def extensions(request):
    content=[]
    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])

    if aristotle_apps:
        for app_label in aristotle_apps:
            app=apps.get_app_config(app_label)
            try:
                app.about_url = reverse('%s:about' % app_label)
            except:
                pass  # if there is no about URL, thats ok.
            content.append(app)

    content = list(set(content))
    aristotle_downloads = fetch_aristotle_downloaders()
    downloads=[]
    if aristotle_downloads:
        for download in aristotle_downloads:
            downloads.append(download())

    return render(
        request,
        "aristotle_mdr/static/extensions.html",
        {'content_extensions': content, 'download_extensions': downloads, }
    )
def extensions(request):
    content=[]
    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])

    if aristotle_apps:
        for app_label in aristotle_apps:
            app=apps.get_app_config(app_label)
            try:
                app.about_url = reverse('%s:about' % app_label)
            except:
                pass  # if there is no about URL, thats ok.
            content.append(app)

    content = list(set(content))
    aristotle_downloads = fetch_aristotle_downloaders()
    downloads=[]
    if aristotle_downloads:
        for download in aristotle_downloads:
            downloads.append(download())

    return render(
        request,
        "aristotle_mdr/static/extensions.html",
        {'content_extensions': content, 'download_extensions': downloads, }
    )
Example #16
0
    def get_context_data(self, *args, **kwargs):
        context = super(BrowseApps, self).get_context_data(*args, **kwargs)

        aristotle_apps = fetch_aristotle_settings().get(
            'CONTENT_EXTENSIONS', [])
        aristotle_apps += ["aristotle_mdr"]
        out = {}

        for m in get_concepts_for_apps(aristotle_apps):
            # Only output subclasses of 11179 concept
            app_models = out.get(m.app_label, {'app': None, 'models': []})
            if app_models['app'] is None:
                app_models['app'] = getattr(
                    apps.get_app_config(m.app_label),
                    'verbose_name',
                    _(
                        "No name"
                    )  # Where no name is configured in the app_config, set a dummy so we don't keep trying
                )

            app_models['models'].append(m)
            out[m.app_label] = app_models

        context['apps'] = OrderedDict(
            sorted(out.items(), key=lambda app: app[1]['app']))
        return context
def extensions(request):
    content = []
    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])

    if aristotle_apps:
        for app_label in aristotle_apps:
            app = apps.get_app_config(app_label)
            try:
                app.about_url = reverse('%s:about' % app_label)
            except:
                pass  # if there is no about URL, thats ok.
            content.append(app)

    content = list(set(content))
    aristotle_downloads = getattr(settings, 'ARISTOTLE_DOWNLOADS', [])
    downloads = dict()
    if aristotle_downloads:
        for download in aristotle_downloads:
            app_label = download[3]
            app_details = downloads.get(app_label, {
                'app': apps.get_app_config(app_label),
                'downloads': []
            })
            try:
                app_details['about_url'] = reverse('%s:about' % app_label)
            except:
                pass  # if there is no about URL, thats ok.
            app_details['downloads'].append(download)
            downloads[app_label] = app_details

    return render(request, "aristotle_mdr/static/extensions.html", {
        'content_extensions': content,
        'download_extensions': downloads,
    })
    def test_help_pages_load(self):
        call_command('load_aristotle_help')
        regular_help = models.HelpPage.objects.all()
        concept_help = models.ConceptHelp.objects.all()

        response = self.client.get(reverse('aristotle_help:help_base'))
        self.assertEqual(response.status_code, 200)
        response = self.client.get(reverse('aristotle_help:help_concepts'))
        self.assertEqual(response.status_code, 200)

        for app_label in fetch_aristotle_settings()['CONTENT_EXTENSIONS']:
            response = self.client.get(reverse('aristotle_help:concept_app_help', args=[app_label]))
            self.assertEqual(response.status_code, 200)

        for obj in concept_help:
            response = self.client.get(reverse('aristotle_help:concept_help', args=[obj.app_label, obj.concept_type]))
            self.assertEqual(response.status_code, 200)

        for obj in concept_help:
            response = self.client.get(reverse('aristotle_help:concept_help', args=[obj.app_label, obj.concept_type]))
            self.assertEqual(response.status_code, 200)

        for obj in regular_help:
            response = self.client.get(reverse('aristotle_help:help_page', args=[obj.slug]))
            self.assertEqual(response.status_code, 200)
Example #19
0
    def test_help_pages_load(self):
        call_command('load_aristotle_help')
        regular_help = models.HelpPage.objects.all()
        concept_help = models.ConceptHelp.objects.all()

        response = self.client.get(reverse('aristotle_help:help_base'))
        self.assertEqual(response.status_code, 200)
        response = self.client.get(reverse('aristotle_help:help_concepts'))
        self.assertEqual(response.status_code, 200)

        for app_label in fetch_aristotle_settings()['CONTENT_EXTENSIONS']:
            response = self.client.get(
                reverse('aristotle_help:concept_app_help', args=[app_label]))
            self.assertEqual(response.status_code, 200)

        for obj in concept_help:
            # TODO: implement better behavior for this
            if obj.app_label not in ('aristotle_dse', 'aristotle_glossary',
                                     'comet'):
                response = self.client.get(
                    reverse('aristotle_help:concept_help',
                            args=[obj.app_label, obj.concept_type]))
                self.assertEqual(response.status_code, 200)

        for obj in regular_help:
            response = self.client.get(
                reverse('aristotle_help:help_page', args=[obj.slug]))
            self.assertEqual(response.status_code, 200)
def get_bulk_actions():
    import re
    config = fetch_aristotle_settings()
    if not hasattr(get_bulk_actions,
                   'actions') or not get_bulk_actions.actions:
        actions = {}
        for action_name, form in config.get('BULK_ACTIONS', {}).items():
            if not re.search('^[a-zA-Z0-9\_\.]+$', form):  # pragma: no cover
                # Invalid download_type
                raise registry_exceptions.BadBulkActionModuleName(
                    "Bulk action isn't a valid Python module name.")

            from django.utils.module_loading import import_string
            # module, form = form.rsplit('.', 1)
            # f = exec('from %s import %s as f' % (module, form))
            f = import_string(form)
            # We need to make this a dictionary, not a class as otherwise
            # the template engine tries to instantiate it.
            frm = {'form': f}
            for prop in ['classes', 'can_use', 'text']:
                frm[prop] = getattr(f, prop, None)
            actions[action_name] = frm
        # Save to method to prevent having to reimport everytime
        get_bulk_actions.actions = actions
    return get_bulk_actions.actions
 def test_bad_bulk_action_settings_log_correctly(self, mock_logger):
     with override_settings(
         ARISTOTLE_SETTINGS=dict(settings.ARISTOTLE_SETTINGS, BULK_ACTIONS={}),
         ARISTOTLE_SETTINGS_STRICT_MODE=True
     ):
         with self.assertRaisesRegexp(ImproperlyConfigured, error_messages['bulk_action_failed']):
             my_settings = fetch_aristotle_settings()
Example #22
0
 def has_module_perms(self, user_obj, app_label):
     """
     Returns True if the requested app is an aristotle extension.
     Actual permissions to edit/change content are covered in aristotle_mdr.admin
     Otherwise, it returns as per Django permissions
     """
     extensions = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])
     if app_label in extensions + ["aristotle_mdr"]:
         return perms.user_is_authenticated_and_active(user_obj)
     return super().has_module_perms(user_obj, app_label)
    def get_form_initial(self, step):
        initial = super().get_form_initial(step)
        if step is None:  # pragma: no cover
            step = self.steps.current
        if step == "make_oc":
            initial.update(self.get_field_defaults('oc'))
        elif step == "make_p":
            initial.update(self.get_field_defaults('pr'))
        elif step in ['find_dec_results',
                      'make_dec']:  # Account for DE and DEC wizards
            made_oc = self.get_cleaned_data_for_step('make_oc')
            if self.get_object_class():
                oc_name = self.get_object_class().name
                oc_desc = self.get_object_class().definition
            elif made_oc:
                oc_name = made_oc.get('name', _("No object class name found"))
                oc_desc = made_oc.get('definition',
                                      _("No object class definition found"))
            else:
                oc_name = _("No object class name found")
                oc_desc = _("No object class definition found")
            oc_desc = make_it_clean(oc_desc)
            if oc_desc:
                # lower case the first letter as this will be the latter part of a sentence
                oc_desc = oc_desc[0].lower() + oc_desc[1:]

            made_pr = self.get_cleaned_data_for_step('make_p')
            if self.get_property():
                pr_name = self.get_property().name
                pr_desc = self.get_property().definition
            elif made_pr:
                pr_name = made_pr.get('name', _("No property name found"))
                pr_desc = made_pr.get('definition',
                                      _("No property definition found"))
            else:
                pr_name = _("No property name found")
                pr_desc = _("No property definition found")
            pr_desc = make_it_clean(pr_desc)
            if pr_desc and pr_desc[-1] == ".":
                # remove the tailing period as we are going to try to make a sentence
                pr_desc = pr_desc[:-1]

            SEPARATORS = fetch_aristotle_settings().get('SEPARATORS', {})
            initial.update({
                'name':
                u"{oc}{separator}{pr}".format(
                    oc=oc_name,
                    separator=SEPARATORS["DataElementConcept"],
                    pr=pr_name,
                ),
                'definition':
                _(u"<p>{pr} of {oc}</p> - This was an autogenerated definition."
                  ).format(oc=oc_desc, pr=pr_desc)
            })
        return initial
 def has_module_perms(self, user_obj, app_label):
     """
     Returns True if the requested app is an aristotle extension.
     Actual permissions to edit/change content are covered in aristotle_mdr.admin
     Otherwise, it returns as per Django permissions
     """
     if not user_obj.is_active:
         return False
     extensions = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])
     if app_label in extensions + ["aristotle_mdr"]:
         return perms.user_is_editor(user_obj)
     return super().has_module_perms(user_obj, app_label)
    def get_form_initial(self, step):
        initial = super().get_form_initial(step)
        if step is None:  # pragma: no cover
            step = self.steps.current
        if step == "make_vd":
            initial.update(self.get_field_defaults('vd'))
        elif step == 'find_de_results':
            made_vd = self.get_cleaned_data_for_step('make_vd')
            if self.get_value_domain():
                vd_name = self.get_value_domain().name
                vd_desc = self.get_value_domain().definition
            elif made_vd:
                vd_name = made_vd.get('name', _("No value domain name found"))
                vd_desc = made_vd.get('definition',
                                      _("No value domain definition found"))
            else:
                vd_name = _("No value domain name found")
                vd_desc = _("No value domain definition found")
            vd_desc = make_it_clean(vd_desc)
            if vd_desc:
                # lower case the first letter as this will be the latter part of a sentence
                vd_desc = vd_desc[0].lower() + vd_desc[1:]

            made_dec = self.get_cleaned_data_for_step('make_dec')
            if self.get_data_element_concept():
                dec_name = self.get_data_element_concept().name
                dec_desc = self.get_data_element_concept().definition
            elif made_dec:
                dec_name = made_dec.get('name', _("No property name found"))
                dec_desc = made_dec.get('definition',
                                        _("No property definition found"))
            else:
                dec_name = _("No property name found")
                dec_desc = _("No property definition found")
            dec_desc = make_it_clean(dec_desc)

            if dec_desc and dec_desc[-1] == ".":
                # remove the trailing period as we are going to try to make a sentence
                dec_desc = dec_desc[:-1]

            SEPARATORS = fetch_aristotle_settings().get('SEPARATORS', {})

            initial.update({
                'name':
                u"{dec}{separator}{vd}".format(
                    dec=dec_name,
                    separator=SEPARATORS["DataElement"],
                    vd=vd_name),
                'definition':
                _(u"<p>{dec}, recorded as {vd}</p> - This was an autogenerated definition."
                  ).format(dec=dec_desc, vd=vd_desc)
            })
        return initial
def user_can_add_or_remove_workgroup(user, workgroup):
    workgroup_change_access = fetch_aristotle_settings().get('WORKGROUP_CHANGES', [])

    if user.is_superuser:
        return True
    if 'admin' in workgroup_change_access and user.has_perm("aristotle_mdr.is_registry_administrator"):
        return True
    if 'manager' in workgroup_change_access and user in workgroup.managers.all():
        return True
    if 'submitter' in workgroup_change_access and user in workgroup.submitters.all():
        return True
    return False
    def get_base_download_context(self) -> Dict[str, Any]:

        aristotle_settings = fetch_aristotle_settings()

        context = {
            'infobox_identifier_name': aristotle_settings.get('INFOBOX_IDENTIFIER_NAME', _("Item ID")),
            'user': self.user,
            'options': self.options,
            'config': aristotle_settings,
            'export_date': now(),
        }
        context['CURRENT_CLIENT_BASE'] = getattr(settings, 'CURRENT_CLIENT_BASE', None)
        return context
Example #28
0
def get_comet_indicator_relational_attributes(model_instance):
    """
    The purpose of this function is to retrieve the relational attributes
    from the Comet Indicator Registry, particularly from the
    IndicatorDataElementBase model.
    :param model_instance: The related model.
    :return: Dictionary containing relational attributes from the Comet extension.
    """
    rels = {}
    if "comet" in fetch_aristotle_settings().get('CONTENT_EXTENSIONS'):
        from comet.models import Indicator, IndicatorDataElementBase

        as_numerator_kwargs = {}
        as_denominator_kwargs = {}
        as_disaggregator_kwargs = {}

        for model_field in IndicatorDataElementBase._meta.get_fields():
            if model_field.is_relation and model_field.many_to_one:
                if model_field.related_model == model_instance._meta.model:
                    as_numerator_kwargs = {
                        'indicatornumeratordefinition__{}'.format(model_field.name):
                        model_instance,
                    }
                    as_denominator_kwargs = {
                        'indicatordenominatordefinition__{}'.format(model_field.name):
                        model_instance,
                    }
                    as_disaggregator_kwargs = {
                        'indicatordisaggregationdefinition__{}'.format(model_field.name):
                        model_instance,
                    }

        rels.update({
            "as_numerator": {
                "all": _("As a numerator in an Indicator"),
                "qs":
                Indicator.objects.filter(**as_numerator_kwargs).distinct()
            },
            "as_denominator": {
                "all": _("As a denominator in an Indicator"),
                "qs":
                Indicator.objects.filter(**as_denominator_kwargs).distinct()
            },
            "as_disaggregator": {
                "all":
                _("As a disaggregation in an Indicator"),
                "qs":
                Indicator.objects.filter(**as_disaggregator_kwargs).distinct()
            },
        })
    return rels
def user_can_add_or_remove_workgroup(user, workgroup):
    workgroup_change_access = fetch_aristotle_settings().get('WORKGROUP_CHANGES', [])

    if user.is_anonymous:
        return False

    if user.is_superuser:
        return True
    if 'admin' in workgroup_change_access and user.has_perm("aristotle_mdr.is_registry_administrator"):
        return True
    if 'manager' in workgroup_change_access and user in workgroup.managers.all():
        return True
    if 'submitter' in workgroup_change_access and user in workgroup.submitters.all():
        return True
    return False
def user_can_move_any_workgroup(user):
    """Checks if a user can move an item from any of their workgroups"""
    workgroup_change_access = fetch_aristotle_settings().get(
        'WORKGROUP_CHANGES', [])

    if user.is_superuser:
        return True
    if 'admin' in workgroup_change_access and user.is_staff:
        return True
    if 'manager' in workgroup_change_access and user.profile.is_workgroup_manager(
    ):
        return True
    if 'submitter' in workgroup_change_access and user.submitter_in.exists():
        return True

    return False
    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)

        if self.request.user.is_anonymous:
            context['isFavourite'] = False
        else:
            context['isFavourite'] = self.request.user.profile.is_favourite(self.item)

        aristotle_settings = fetch_aristotle_settings()

        links_from, links_to = self.get_links()

        context.update({
            'last_edit': Version.objects.get_for_object(self.item).first(),
            # Only display viewable slots
            'slots': Slot.objects.get_item_allowed(self.item, self.user),
            'item': self.item,
            'statuses': self.item.current_statuses,
            'discussions': self.item.relatedDiscussions.all(),
            'activetab': 'item',
            'has_links': links_from or links_to,
            'links_from': links_from,
            'links_to': links_to,
            'custom_values': self.get_custom_values(),
            'submitting_organizations': self.item.submitting_organizations,
            'responsible_organizations': self.item.responsible_organizations,
            'infobox_identifier_name': aristotle_settings['INFOBOX_IDENTIFIER_NAME']
        })

        # Add a list of viewable concept ids for fast visibility checks in
        # templates
        # Since its lazy we can do this every time :)
        lazy_viewable_ids = SimpleLazyObject(
            lambda: list(MDR._concept.objects.visible(self.user).values_list('id', flat=True))
        )
        context['viewable_ids'] = lazy_viewable_ids

        # Permissions (so they are looked up once)
        context.update({
            'can_edit': user_can_edit(self.user, self.item),
            'can_publish': user_can_publish_object(self.user, self.item),
            'can_supersede': user_can_supersede(self.user, self.item),
            'can_add_status': user_can_add_status(self.user, self.item)
        })

        return context
    def get(self, request, format=None):
        """
        Gives basic details about the registry
        """
        
        settings = fetch_aristotle_settings()

        about = {
            'name': settings['SITE_NAME'],
            'description': settings['SITE_DESCRIPTION'],
            'version': "1.6",
            'installed_apps': [],
            'aristotle_mdr' : {
                'version': import_string("aristotle_mdr.__version__"),
            }
        }
        return Response(about)
def user_can_move_any_workgroup(user):
    """Checks if a user can move an item from any of their workgroups"""
    workgroup_change_access = fetch_aristotle_settings().get('WORKGROUP_CHANGES', [])

    if user.is_anonymous:
        return False

    if user.is_superuser:
        return True
    if 'admin' in workgroup_change_access and user.is_staff:
        return True
    if 'manager' in workgroup_change_access and user.profile.is_workgroup_manager():
        return True
    if 'submitter' in workgroup_change_access and user.submitter_in.exists():
        return True

    return False
    def prepare_tokens(self):
        try:
            query = self.cleaned_data.get('q')
        except:
            return {}
        opts = connections[DEFAULT_ALIAS].get_unified_index().fields.keys()
        kwargs = {}
        query_text = []
        token_models = []
        for word in query.split(" "):
            if ":" in word:
                opt, arg = word.split(":", 1)
                if opt in opts:
                    kwargs[str(opt)] = arg
                elif opt == "type":
                    # we'll allow these through and assume they meant content type
                    from django.conf import settings
                    aristotle_apps = fetch_aristotle_settings().get(
                        'CONTENT_EXTENSIONS', [])
                    aristotle_apps += ["aristotle_mdr"]

                    from django.contrib.contenttypes.models import ContentType
                    arg = arg.lower().replace('_', '').replace('-', '')
                    mods = ContentType.objects.filter(
                        app_label__in=aristotle_apps).all()
                    for i in mods:
                        if hasattr(i.model_class(), 'get_verbose_name'):
                            model_short_code = "".join(
                                map(
                                    first_letter,
                                    i.model_class()._meta.verbose_name.split(
                                        " "))).lower()
                            if arg == model_short_code:
                                token_models.append(i.model_class())
                        if arg == i.model:
                            token_models.append(i.model_class())

            else:
                query_text.append(word)
        self.token_models = token_models
        self.query_text = " ".join(query_text)
        self.kwargs = kwargs
        return kwargs
    def check_is_public(self, when=timezone.now()):
        """
            A concept is public if any registration authority
            has advanced it to a public state in that RA.
        """
        statuses = self.statuses.all()
        statuses = self.current_statuses(qs=statuses, when=when)
        pub_state = True in [
            s.state >= s.registrationAuthority.public_state for s in statuses
        ]

        q = Q()
        extra = False
        extra_q = fetch_aristotle_settings().get('EXTRA_CONCEPT_QUERYSETS', {}).get('public', None)
        if extra_q:
            for func in extra_q:
                q |= import_string(func)()
            extra = self.__class__.objects.filter(pk=self.pk).filter(q).exists()
        return pub_state or extra
def get_bulk_actions():
    import re
    config = fetch_aristotle_settings()

    actions = {}
    for action_name in config.get('BULK_ACTIONS', []):
        if not re.search(r'^[a-zA-Z0-9\_\.]+$', action_name):  # pragma: no cover
            # Invalid download_type
            raise registry_exceptions.BadBulkActionModuleName("Bulk action isn't a valid Python module name.")

        from django.utils.module_loading import import_string

        f = import_string(action_name)
        # We need to make this a dictionary, not a class as otherwise
        # the template engine tries to instantiate it.
        frm = {'form': f}
        for prop in ['classes', 'can_use', 'text']:
            frm[prop] = getattr(f, prop, None)
        actions[action_name] = frm
    return actions
Example #37
0
def get_bulk_actions():
    import re
    config = fetch_aristotle_settings()

    actions = {}
    for action_name in config.get('BULK_ACTIONS', []):
        if not re.search('^[a-zA-Z0-9\_\.]+$', action_name):  # pragma: no cover
            # Invalid download_type
            raise registry_exceptions.BadBulkActionModuleName("Bulk action isn't a valid Python module name.")

        from django.utils.module_loading import import_string

        f = import_string(action_name)
        # We need to make this a dictionary, not a class as otherwise
        # the template engine tries to instantiate it.
        frm = {'form': f}
        for prop in ['classes', 'can_use', 'text']:
            frm[prop] = getattr(f, prop, None)
        actions[action_name] = frm
    return actions
Example #38
0
    def visible(self, user):
        """
        Returns a queryset that returns all items that the given user has
        permission to view.

        It is **chainable** with other querysets. For example, both of these
        will work and return the same list::

            ObjectClass.objects.filter(name__contains="Person").visible()
            ObjectClass.objects.visible().filter(name__contains="Person")
        """
        from aristotle_mdr.models import REVIEW_STATES
        if user.is_superuser:
            return self.all()
        if user.is_anonymous():
            return self.public()
        q = Q(_is_public=True)

        if user.is_active:
            # User can see everything they've made.
            q |= Q(submitter=user)
            if user.profile.workgroups:
                # User can see everything in their workgroups.
                q |= Q(workgroup__in=user.profile.workgroups)
                # q |= Q(workgroup__user__profile=user)
            if user.profile.is_registrar:
                # Registars can see items they have been asked to review
                q |= Q(
                    Q(review_requests__registration_authority__registrars__profile__user
                      =user)
                    & ~Q(review_requests__status=REVIEW_STATES.cancelled))
                # Registars can see items that have been registered in their registration authority
                q |= Q(
                    Q(statuses__registrationAuthority__registrars__profile__user
                      =user))
        extra_q = fetch_aristotle_settings().get('EXTRA_CONCEPT_QUERYSETS',
                                                 {}).get('visible', None)
        if extra_q:
            for func in extra_q:
                q |= import_string(func)(user)
        return self.filter(q)
    def visible(self, user):
        """
        Returns a queryset that returns all items that the given user has
        permission to view.

        It is **chainable** with other querysets. For example, both of these
        will work and return the same list::

            ObjectClass.objects.filter(name__contains="Person").visible()
            ObjectClass.objects.visible().filter(name__contains="Person")
        """
        if user is None or user.is_anonymous():
            return self.public()
        if user.is_superuser:
            return self.all()
        q = Q(_is_public=True)

        if user.is_active:
            # User can see everything they've made.
            q |= Q(submitter=user)
            if user.profile.workgroups:
                # User can see everything in their workgroups.
                q |= Q(workgroup__in=user.profile.workgroups)
                # q |= Q(workgroup__user__profile=user)
            if user.profile.is_registrar:
                # Registars can see items they have been asked to review
                q |= Q(
                    Q(rr_review_requests__registration_authority__registrars__profile__user=user) &
                    ~Q(review_requests__status=REVIEW_STATES.revoked)
                )
                # Registars can see items that have been registered in their registration authority
                q |= Q(
                    Q(statuses__registrationAuthority__registrars__profile__user=user)
                )
        extra_q = fetch_aristotle_settings().get('EXTRA_CONCEPT_QUERYSETS', {}).get('visible', None)
        if extra_q:
            for func in extra_q:
                q |= import_string(func)(user)
        return self.filter(q)
def extensions(request):
    content = []
    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])

    if aristotle_apps:
        for app_label in aristotle_apps:
            app = apps.get_app_config(app_label)
            try:
                app.about_url = reverse('%s:about' % app_label)
            except:
                pass  # If there is no "about" URL, that's ok.
            content.append(app)

    content = list(set(content))
    aristotle_downloaders = fetch_aristotle_downloaders()
    download_extensions = [dldr.get_class_info() for dldr in aristotle_downloaders]

    return render(
        request,
        "aristotle_mdr/static/extensions.html",
        {'content_extensions': content, 'download_extensions': download_extensions}
    )
Example #41
0
def create_list(request):
    if request.user.is_anonymous():
        return redirect(reverse('friendly_login') + '?next=%s' % request.path)
    if not perms.user_is_editor(request.user):
        raise PermissionDenied

    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])
    aristotle_apps += ["aristotle_mdr"]
    out = {}

    wizards = []
    for wiz in getattr(settings, 'ARISTOTLE_SETTINGS',
                       {}).get('METADATA_CREATION_WIZARDS', []):
        w = wiz.copy()
        _w = {
            'model':
            apps.get_app_config(wiz['app_label']).get_model(wiz['model']),
            'class': import_string(wiz['class']),
        }
        w.update(_w)
        wizards.append(w)

    for m in get_concepts_for_apps(aristotle_apps):
        # Only output subclasses of 11179 concept
        app_models = out.get(m.app_label, {'app': None, 'models': []})
        if app_models['app'] is None:
            try:
                app_models['app'] = getattr(apps.get_app_config(m.app_label),
                                            'verbose_name')
            except:
                app_models[
                    'app'] = "No name"  # Where no name is configured in the app_config, set a dummy so we don't keep trying
        app_models['models'].append((m, m.model_class()))
        out[m.app_label] = app_models

    return render(request, "aristotle_mdr/create/create_list.html", {
        'models': sorted(out.values(), key=lambda x: x['app']),
        'wizards': wizards
    })
def create_list(request):
    if request.user.is_anonymous():
        return redirect(reverse('friendly_login') + '?next=%s' % request.path)
    if not perms.user_is_editor(request.user):
        raise PermissionDenied

    aristotle_apps = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])
    aristotle_apps += ["aristotle_mdr"]
    out = {}

    wizards = []
    for wiz in getattr(settings, 'ARISTOTLE_SETTINGS', {}).get('METADATA_CREATION_WIZARDS', []):
        w = wiz.copy()
        _w = {
            'model': apps.get_app_config(wiz['app_label']).get_model(wiz['model']),
            'class': import_string(wiz['class']),
        }
        w.update(_w)
        wizards.append(w)

    for m in get_concepts_for_apps(aristotle_apps):
        # Only output subclasses of 11179 concept
        app_models = out.get(m.app_label, {'app': None, 'models': []})
        if app_models['app'] is None:
            try:
                app_models['app'] = getattr(apps.get_app_config(m.app_label), 'verbose_name')
            except:
                app_models['app'] = "No name"  # Where no name is configured in the app_config, set a dummy so we don't keep trying
        app_models['models'].append((m, m.model_class()))
        out[m.app_label] = app_models

    return render(
        request, "aristotle_mdr/create/create_list.html",
        {
            'models': sorted(out.values(), key=lambda x: x['app']),
            'wizards': wizards
        }
    )
    def has_perm(self, user_obj, perm, obj=None):

        if not user_obj.is_active:
            return False
        if user_obj.is_superuser:
            return True

        app_label, perm_name = perm.split('.', 1)
        extensions = fetch_aristotle_settings().get('CONTENT_EXTENSIONS', [])

        if app_label == "aristotle_mdr" and hasattr(perms, perm_name):
            return getattr(perms, perm_name)(user_obj, obj)

        from django.apps import apps
        from aristotle_mdr.models import _concept

        perm_parts = perm_name.split("_")
        if len(perm_parts) == 2:
            model = apps.get_model(app_label, perm_parts[1])
        elif obj is not None:
            model = type(obj)
        else:
            model = int

        if app_label in extensions + ["aristotle_mdr"] and issubclass(model, _concept):
            # This is required so that a user can correctly delete the 'concept' parent class in the admin site.

            # This is a rough catch all, and is designed to indicate a user could
            # delete an item type, but not a specific item.
            if (
                perm_name.startswith('delete_') or
                perm_name.startswith('create_') or
                perm_name.startswith('add_')
            ):
                if obj is None:
                    return perms.user_is_editor(user_obj)
                else:
                    return perms.user_can_edit(user_obj, obj)

        if app_label in extensions + ["aristotle_mdr"]:
            if perm_name == "delete_concept_from_admin":
                return obj is None or perms.user_can_edit(user_obj, obj)

        if perm == "aristotle_mdr.can_create_metadata":
            return perms.user_is_editor(user_obj)

        if perm == "aristotle_mdr.view_workgroup":
            return perms.user_in_workgroup(user_obj, obj)
        if perm == "aristotle_mdr.can_leave_workgroup":
            return perms.user_in_workgroup(user_obj, obj)
        if perm == "aristotle_mdr.change_workgroup_memberships":
            return perms.user_is_workgroup_manager(user_obj, obj)
        if perm == "aristotle_mdr.change_workgroup":
            return perms.user_is_workgroup_manager(user_obj, obj)
        if perm == "aristotle_mdr.can_archive_workgroup":
            return perms.user_is_workgroup_manager(user_obj, obj)

        if perm == "aristotle_mdr.can_view_discussions_in_workgroup":
            return perms.user_in_workgroup(user_obj, obj)
        if perm == "aristotle_mdr.can_post_discussion_in_workgroup":
            return perms.user_in_workgroup(user_obj, obj)
        if perm == "aristotle_mdr.can_view_discussion_post":
            return perms.user_in_workgroup(user_obj, obj.workgroup)

        if perm == "aristotle_mdr.view_registrationauthority_details":
            return (
                perms.user_is_registation_authority_manager(user_obj, obj) or
                perms.user_is_registrar(user_obj, obj)
            )
        if perm == "aristotle_mdr.change_registrationauthority":
            return perms.user_is_registation_authority_manager(user_obj, obj)
        if perm == "aristotle_mdr.change_registrationauthority_memberships":
            return perms.user_is_registation_authority_manager(user_obj, obj)

        from aristotle_mdr.contrib.links import perms as link_perms
        if perm == "aristotle_mdr_links.add_link":
            return link_perms.user_can_make_link(user_obj)

        return super().has_perm(user_obj, perm, obj)