summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2022-01-20 17:10:43 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2022-12-12 12:20:59 +0100
commit31ef78cec0cd2ba3ccc91c4bafd89831e73abe20 (patch)
tree9a8365bef9f59a9348d719dcb3cb4e055e4ccce1
parent06b13fe771fd67ab655f0c81bbae51add767deb2 (diff)
downloadIshtar-31ef78cec0cd2ba3ccc91c4bafd89831e73abe20.tar.bz2
Ishtar-31ef78cec0cd2ba3ccc91c4bafd89831e73abe20.zip
External sources - limit access in admin, limit by profile
-rw-r--r--ishtar_common/admin.py3
-rw-r--r--ishtar_common/context_processors.py30
-rw-r--r--ishtar_common/forms_common.py66
-rw-r--r--ishtar_common/migrations/0219_auto_20220120_1552.py33
-rw-r--r--ishtar_common/models.py6
-rw-r--r--ishtar_common/models_rest.py13
6 files changed, 123 insertions, 28 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index b7de250c6..2dee828fc 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -1353,7 +1353,7 @@ admin_site.register(models.ProfileTypeSummary, ProfileTypeSummaryAdmin)
class IshtarUserAdmin(admin.ModelAdmin):
model = models.IshtarUser
- search_fields = ("user_ptr", "person")
+ search_fields = ("user_ptr__username", "person__raw_name")
admin_site.register(models.IshtarUser, IshtarUserAdmin)
@@ -2327,6 +2327,7 @@ class ApiExternalSourceAdmin(admin.ModelAdmin):
generate_match_document,
update_association_from_match_document,
]
+ autocomplete_fields = ["users"]
list_display = ("name", "url", "key")
diff --git a/ishtar_common/context_processors.py b/ishtar_common/context_processors.py
index 7e96bddbd..e1754e935 100644
--- a/ishtar_common/context_processors.py
+++ b/ishtar_common/context_processors.py
@@ -48,18 +48,6 @@ def get_base_context(request):
menu.init()
request.session['MENU'] = menu
""" # menu is now in cache - put it back in session later?
- if "EXTERNAL_SOURCES" not in request.session:
- q = ApiExternalSource.objects
- # TODO: check permissions
- request.session["EXTERNAL_SOURCES"] = {}
- if q.count():
- for source in q.all():
- request.session["EXTERNAL_SOURCES"][f"{source.id}||{source.name}"] = [
- f"{app_label}-{model_name}"
- for app_label, model_name in ApiKeyMatch.objects.values_list(
- "search_model__app_label", "search_model__model"
- ).distinct()
- ]
current_action = None
if "CURRENT_ACTION" in request.session:
@@ -83,6 +71,24 @@ def get_base_context(request):
menu.init()
if hasattr(request.user, "ishtaruser") and request.user.ishtaruser:
+ if (
+ request.user.ishtaruser.current_profile
+ and "EXTERNAL_SOURCES" not in request.session
+ ):
+ q = ApiExternalSource.objects.filter(
+ profiles=request.user.ishtaruser.current_profile
+ )
+ request.session["EXTERNAL_SOURCES"] = {}
+ if q.count():
+ for source in q.all():
+ request.session["EXTERNAL_SOURCES"][
+ f"{source.id}||{source.name}"
+ ] = [
+ f"{app_label}-{model_name}"
+ for app_label, model_name in ApiKeyMatch.objects.values_list(
+ "search_model__app_label", "search_model__model"
+ ).distinct()
+ ]
if request.user.ishtaruser.has_right("administrator", session=request.session):
dct["ADMIN"] = True
if (
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py
index 70727b243..0cdb70a36 100644
--- a/ishtar_common/forms_common.py
+++ b/ishtar_common/forms_common.py
@@ -44,7 +44,7 @@ from django.utils.text import slugify
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _, pgettext
-from . import models
+from . import models, models_rest
from . import widgets
from bootstrap_datepicker.widgets import DatePicker
from ishtar_common.templatetags.link_to_window import simple_link_to_window
@@ -705,7 +705,7 @@ class QAPersonFormMulti(QAForm):
associated_models = {
"qa_title": models.TitleType,
"qa_attached_to": models.Organization,
- "qa_person_types": models.PersonType
+ "qa_person_types": models.PersonType,
}
MULTI = True
@@ -726,7 +726,7 @@ class QAPersonFormMulti(QAForm):
TYPES = [
FieldType("qa_title", models.TitleType),
- FieldType('qa_person_types', models.PersonType, is_multiple=True),
+ FieldType("qa_person_types", models.PersonType, is_multiple=True),
]
def _get_qa_attached_to(self, value):
@@ -1159,7 +1159,7 @@ class ProfilePersonForm(forms.Form):
auto_pin = forms.BooleanField(
label=_("Pin automatically items on creation and modification"), required=False
)
- display_pin_menu = forms.BooleanField(label=_("Show pin menu"), required=False)
+ # display_pin_menu = forms.BooleanField(label=_("Show pin menu"), required=False)
duplicate_profile = forms.BooleanField(
label=_("Duplicate this profile"), required=False
@@ -1184,11 +1184,46 @@ class ProfilePersonForm(forms.Form):
initial["name"] = current_profile.name or current_profile.profile_type
initial["profile_type"] = current_profile.profile_type.pk
initial["auto_pin"] = current_profile.auto_pin
- initial["display_pin_menu"] = current_profile.display_pin_menu
+ # initial["display_pin_menu"] = current_profile.display_pin_menu
kwargs["initial"] = initial
super(ProfilePersonForm, self).__init__(*args, **kwargs)
self.fields["current_profile"].choices = choices
+ current_external_sources = (
+ [src.pk for src in current_profile.external_sources.all()]
+ if current_profile
+ else []
+ )
+ extra_fields = []
+ q = models_rest.ApiExternalSource.objects.filter(users=self.user.ishtaruser)
+ for src in q.all():
+ initial = True if src.pk in current_external_sources else False
+ extra_fields.append(
+ (
+ f"external_source_{src.pk}",
+ forms.BooleanField(
+ label=_(f"External source - {src.name}"),
+ required=False,
+ initial=initial,
+ ),
+ )
+ )
+
+ self.fields[f"external_source_{src.pk}"] = forms.BooleanField(
+ label=_(f"External source - {src.name}"),
+ required=False,
+ initial=initial,
+ )
+ if extra_fields:
+ # reorder fields
+ fields = OrderedDict()
+ for key in self.fields.keys():
+ if key == "duplicate_profile":
+ for extra_key, extra_field in extra_fields:
+ fields[extra_key] = extra_fields
+ fields[key] = self.fields[key]
+ self.fields = fields
+
if (
not current_profile
or not self.user.ishtaruser.person.profiles.filter(
@@ -1264,9 +1299,16 @@ class ProfilePersonForm(forms.Form):
profile.current = True
profile.name = name
profile.auto_pin = self.cleaned_data["auto_pin"]
- profile.display_pin_menu = self.cleaned_data["display_pin_menu"]
+ # profile.display_pin_menu = self.cleaned_data["display_pin_menu"]
profile.save()
+ profile.external_sources.clear()
+ q = models_rest.ApiExternalSource.objects.filter(users=self.user.ishtaruser)
+ for src in q.all():
+ if self.cleaned_data.get(f"external_source_{src.pk}", False):
+ profile.external_sources.add(src)
clean_session_cache(session)
+ if "EXTERNAL_SOURCES" in session:
+ session.pop("EXTERNAL_SOURCES")
class TownForm(forms.Form):
@@ -2096,15 +2138,9 @@ class QADocumentFormMulti(QAForm):
qa_creation_date = forms.DateField(
label=_("Creation date"), widget=DatePicker, required=False
)
- qa_format_type = forms.ChoiceField(
- label=_("Format"), choices=[], required=False
- )
- qa_support_type = forms.ChoiceField(
- label=_("Medium"), choices=[], required=False
- )
- qa_scale = forms.CharField(
- label=_("Scale"), max_length=30, required=False
- )
+ qa_format_type = forms.ChoiceField(label=_("Format"), choices=[], required=False)
+ qa_support_type = forms.ChoiceField(label=_("Medium"), choices=[], required=False)
+ qa_scale = forms.CharField(label=_("Scale"), max_length=30, required=False)
TYPES = [
FieldType("qa_source_type", models.SourceType),
diff --git a/ishtar_common/migrations/0219_auto_20220120_1552.py b/ishtar_common/migrations/0219_auto_20220120_1552.py
new file mode 100644
index 000000000..58d5930a9
--- /dev/null
+++ b/ishtar_common/migrations/0219_auto_20220120_1552.py
@@ -0,0 +1,33 @@
+# Generated by Django 2.2.24 on 2022-01-20 15:52
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0218_apisheetfilter'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='apiexternalsource',
+ options={'ordering': ('name',), 'verbose_name': 'API - Search - External source', 'verbose_name_plural': 'API - Search - External sources'},
+ ),
+ migrations.AddField(
+ model_name='apiexternalsource',
+ name='users',
+ field=models.ManyToManyField(blank=True, to='ishtar_common.IshtarUser'),
+ ),
+ migrations.AddField(
+ model_name='userprofile',
+ name='external_sources',
+ field=models.ManyToManyField(blank=True, related_name='profiles', to='ishtar_common.ApiExternalSource'),
+ ),
+ migrations.AlterField(
+ model_name='apisheetfilter',
+ name='api_search_model',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sheet_filters', to='ishtar_common.ApiSearchModel'),
+ ),
+ ]
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 8f916538c..a03b90434 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -3008,6 +3008,9 @@ class UserProfile(models.Model):
areas = models.ManyToManyField(
"Area", verbose_name=_("Areas"), blank=True, related_name="profiles"
)
+ external_sources = models.ManyToManyField(
+ "ApiExternalSource", blank=True, related_name="profiles"
+ )
current = models.BooleanField(_("Current profile"), default=False)
show_field_number = models.BooleanField(_("Show field number"), default=False)
auto_pin = models.BooleanField(_("Automatically pin"), default=False)
@@ -3046,6 +3049,7 @@ class UserProfile(models.Model):
def duplicate(self, **kwargs):
areas = [area for area in self.areas.all()]
+ external_sources = [external_source for external_source in self.external_sources.all()]
new_item = self
new_item.pk = None
name = self.name
@@ -3061,6 +3065,8 @@ class UserProfile(models.Model):
new_item.save()
for area in areas:
new_item.areas.add(area)
+ for src in external_sources:
+ new_item.external_sources.add(src)
return new_item
def save(
diff --git a/ishtar_common/models_rest.py b/ishtar_common/models_rest.py
index 18f6c4c3f..b0ed5cbd4 100644
--- a/ishtar_common/models_rest.py
+++ b/ishtar_common/models_rest.py
@@ -93,6 +93,7 @@ class ApiExternalSource(models.Model):
url = models.URLField(verbose_name=_("URL"))
name = models.CharField(verbose_name=_("Name"), max_length=200)
key = models.CharField(_("Key"), max_length=40)
+ users = models.ManyToManyField("IshtarUser", blank=True)
match_document = models.FileField(
_("Match document"),
blank=True,
@@ -108,10 +109,22 @@ class ApiExternalSource(models.Model):
class Meta:
verbose_name = _("API - Search - External source")
verbose_name_plural = _("API - Search - External sources")
+ ordering = ("name",)
def __str__(self):
return self.name
+ def save(self, force_insert=False, force_update=False, using=None,
+ update_fields=None):
+ super().save(force_insert, force_update, using, update_fields)
+ # remove external sources from profiles if not in user anymore
+ UserProfile = apps.get_model("ishtar_common", "UserProfile")
+ q = UserProfile.objects.filter(external_sources=self).exclude(
+ person__ishtaruser__in=list(self.users.all())
+ )
+ for profile in q.all():
+ profile.external_sources.remove(self)
+
def update_matches(self, content):
result = {
"created": 0,