From 595ba2fd09eb3ed7c27b5e46b40752a4faea461e Mon Sep 17 00:00:00 2001 From: Jon Date: Tue, 10 Dec 2024 06:37:49 -0100 Subject: [PATCH 01/13] Add in persistentshare model and views and hook it into the target share page. --- tom_dataproducts/alertstreams/hermes.py | 2 +- tom_dataproducts/serializers.py | 2 +- tom_dataproducts/sharing.py | 23 +++++ tom_targets/admin.py | 24 +++++- tom_targets/base_models.py | 2 + tom_targets/fields.py | 15 ++++ tom_targets/forms.py | 34 +++++++- .../migrations/0022_persistentshare.py | 30 +++++++ .../0023_alter_basetarget_options.py | 17 ++++ tom_targets/models.py | 30 +++++++ tom_targets/serializers.py | 19 ++--- tom_targets/signals/__init__.py | 0 tom_targets/signals/handlers.py | 17 ++++ .../partials/create_persistent_share.html | 73 ++++++++++++++++ .../partials/persistent_share_table.html | 52 ++++++++++++ .../target_manage_persistent_shares.html | 22 +++++ .../templates/tom_targets/target_share.html | 84 +++++++++++++------ tom_targets/templatetags/targets_extras.py | 30 ++++++- tom_targets/urls.py | 12 ++- tom_targets/views.py | 38 ++++++++- tom_targets/viewsets.py | 38 +++++++++ 21 files changed, 516 insertions(+), 48 deletions(-) create mode 100644 tom_targets/fields.py create mode 100644 tom_targets/migrations/0022_persistentshare.py create mode 100644 tom_targets/migrations/0023_alter_basetarget_options.py create mode 100644 tom_targets/signals/__init__.py create mode 100644 tom_targets/signals/handlers.py create mode 100644 tom_targets/templates/tom_targets/partials/create_persistent_share.html create mode 100644 tom_targets/templates/tom_targets/partials/persistent_share_table.html create mode 100644 tom_targets/templates/tom_targets/target_manage_persistent_shares.html create mode 100644 tom_targets/viewsets.py diff --git a/tom_dataproducts/alertstreams/hermes.py b/tom_dataproducts/alertstreams/hermes.py index c20b107f8..18f4bc50c 100644 --- a/tom_dataproducts/alertstreams/hermes.py +++ b/tom_dataproducts/alertstreams/hermes.py @@ -209,7 +209,7 @@ def publish_to_hermes(message_info, datums, targets=Target.objects.none(), **kwa response = requests.post(url=submit_url, json=alert, headers=headers) response.raise_for_status() # Only mark the datums as shared if the sharing was successful - hermes_alert = AlertStreamMessage(topic=message_info.topic, exchange_status='published') + hermes_alert = AlertStreamMessage(topic=message_info.topic, message_id=response.json().get('uuid'), exchange_status='published') hermes_alert.save() for tomtoolkit_photometry in datums: tomtoolkit_photometry.message.add(hermes_alert) diff --git a/tom_dataproducts/serializers.py b/tom_dataproducts/serializers.py index 7d6ba9993..7c1d92c0f 100644 --- a/tom_dataproducts/serializers.py +++ b/tom_dataproducts/serializers.py @@ -8,7 +8,7 @@ from tom_observations.models import ObservationRecord from tom_observations.serializers import ObservationRecordFilteredPrimaryKeyRelatedField from tom_targets.models import Target -from tom_targets.serializers import TargetFilteredPrimaryKeyRelatedField +from tom_targets.fields import TargetFilteredPrimaryKeyRelatedField class DataProductGroupSerializer(serializers.ModelSerializer): diff --git a/tom_dataproducts/sharing.py b/tom_dataproducts/sharing.py index b9be43fd6..b0458b9d1 100644 --- a/tom_dataproducts/sharing.py +++ b/tom_dataproducts/sharing.py @@ -17,6 +17,29 @@ from tom_dataproducts.serializers import DataProductSerializer, ReducedDatumSerializer +def share_data_with_destination(share_destination, reduced_datum): + """ + Triggered by PersistentShare when new ReducedDatums are created. Shares that ReducedDatum to the sharing destination. + :param share_destination: Topic or location to share data to from `DATA_SHARING` settings + :param reduced_datum: ReducedDatum instance to share + """ + if 'HERMES' in share_destination.upper(): + hermes_topic = share_destination.split(':')[1] + destination = share_destination.split(':')[0] + filtered_reduced_datums = check_for_share_safe_datums( + destination, ReducedDatum.objects.filter(pk=reduced_datum.pk), topic=hermes_topic) + sharing = getattr(settings, "DATA_SHARING", {}) + message = BuildHermesMessage(title=f"Updated data for {reduced_datum.target.name} from " + f"{getattr(settings, 'TOM_NAME', 'TOM Toolkit')}.", + authors=sharing.get('hermes', {}).get('DEFAULT_AUTHORS', None), + message=None, + topic=hermes_topic + ) + publish_to_hermes(message, filtered_reduced_datums) + else: + share_data_with_tom(share_destination, None, None, None, selected_data=[reduced_datum.pk]) + + def share_target_list_with_hermes(share_destination, form_data, selected_targets=None, include_all_data=False): """ Serialize and share a set of selected targets and their data with Hermes diff --git a/tom_targets/admin.py b/tom_targets/admin.py index ac5362edc..53dafbc2c 100644 --- a/tom_targets/admin.py +++ b/tom_targets/admin.py @@ -1,5 +1,7 @@ +import functools from django.contrib import admin -from .models import Target, TargetList, TargetExtra +from .models import Target, TargetList, TargetExtra, PersistentShare +from .forms import PersistentShareForm class TargetExtraInline(admin.TabularInline): @@ -17,6 +19,26 @@ class TargetListAdmin(admin.ModelAdmin): model = TargetList +class PersistentShareAdmin(admin.ModelAdmin): + model = PersistentShare + form = PersistentShareForm + raw_id_fields = ( + 'target', + 'user' + ) + + def get_form(self, request, obj=None, change=False, **kwargs): + Form = super().get_form(request, obj=obj, change=change, **kwargs) + # This line is needed because the ModelAdmin uses the form to get its fields if fields is passed as None + # In that case, a partial will not work, so just return the base form. The partial is necessary to filter + # On the targets a user has access to. + if kwargs.get('fields') == None: + return Form + return functools.partial(Form, user=request.user) + + admin.site.register(Target, TargetAdmin) admin.site.register(TargetList, TargetListAdmin) + +admin.site.register(PersistentShare, PersistentShareAdmin) diff --git a/tom_targets/base_models.py b/tom_targets/base_models.py index 9801d2118..f785ea43c 100644 --- a/tom_targets/base_models.py +++ b/tom_targets/base_models.py @@ -403,6 +403,7 @@ class Meta: permissions = ( ('view_target', 'View Target'), ('add_target', 'Add Target'), + ('share_target', 'Share Target'), ('change_target', 'Change Target'), ('delete_target', 'Delete Target'), ) @@ -573,5 +574,6 @@ def give_user_access(self, user): :return: """ assign_perm('tom_targets.view_target', user, self) + assign_perm('tom_targets.share_target', user, self) assign_perm('tom_targets.change_target', user, self) assign_perm('tom_targets.delete_target', user, self) diff --git a/tom_targets/fields.py b/tom_targets/fields.py new file mode 100644 index 000000000..6077b49fe --- /dev/null +++ b/tom_targets/fields.py @@ -0,0 +1,15 @@ +from guardian.shortcuts import get_objects_for_user +from rest_framework import serializers + + +class TargetFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField): + # This PrimaryKeyRelatedField subclass is used to implement get_queryset based on the permissions of the user + # submitting the request. The pattern was taken from this StackOverflow answer: https://stackoverflow.com/a/32683066 + + def get_queryset(self): + request = self.context.get('request', None) + queryset = super().get_queryset() + if not (request and queryset): + return None + return get_objects_for_user(request.user, 'tom_targets.change_target') + diff --git a/tom_targets/forms.py b/tom_targets/forms.py index 559d87457..c23fc7600 100644 --- a/tom_targets/forms.py +++ b/tom_targets/forms.py @@ -3,11 +3,11 @@ from astropy import units as u from django.forms import ValidationError, inlineformset_factory from django.conf import settings -from django.contrib.auth.models import Group -from guardian.shortcuts import assign_perm, get_groups_with_perms, remove_perm +from django.contrib.auth.models import Group, User +from guardian.shortcuts import assign_perm, get_groups_with_perms, remove_perm, get_objects_for_user from tom_dataproducts.sharing import get_sharing_destination_options -from .models import Target, TargetExtra, TargetName, TargetList +from .models import Target, TargetExtra, TargetName, TargetList, PersistentShare from tom_targets.base_models import (SIDEREAL_FIELDS, NON_SIDEREAL_FIELDS, REQUIRED_SIDEREAL_FIELDS, REQUIRED_NON_SIDEREAL_FIELDS, REQUIRED_NON_SIDEREAL_FIELDS_PER_SCHEME, IGNORE_FIELDS) @@ -241,3 +241,31 @@ class TargetMergeForm(forms.Form): 'hx-target': '#id_target_merge_fields', # replace name_select element }) ) + + +class PersistentShareForm(forms.ModelForm): + destination = forms.ChoiceField(choices=[], label='Share Destination', required=True) + target = forms.ModelChoiceField(queryset=Target.objects.all(), label='Target', initial=0, required=True) + + class Meta: + model = PersistentShare + fields = '__all__' + + def __init__(self, *args, **kwargs): + try: + self.target_id = kwargs.pop('target_id') + except KeyError: + self.target_id = None + try: + self.user = kwargs.pop('user') + except KeyError: + self.user = None + super().__init__(*args, **kwargs) + self.fields['destination'].choices = get_sharing_destination_options() + if self.target_id: + self.fields['target'].queryset = Target.objects.filter(pk=self.target_id) + else: + if self.user: + self.fields['target'].queryset = get_objects_for_user(self.user, f'{Target._meta.app_label}.share_target') + else: + self.fields['target'].queryset = Target.objects.none() diff --git a/tom_targets/migrations/0022_persistentshare.py b/tom_targets/migrations/0022_persistentshare.py new file mode 100644 index 000000000..98ee3cecc --- /dev/null +++ b/tom_targets/migrations/0022_persistentshare.py @@ -0,0 +1,30 @@ +# Generated by Django 4.2.13 on 2024-11-22 22:29 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('tom_targets', '0021_rename_target_basetarget_alter_basetarget_options'), + ] + + operations = [ + migrations.CreateModel( + name='PersistentShare', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('destination', models.CharField(help_text='The sharing destination, as it appears in your DATA_SHARING settings dict', max_length=200)), + ('created', models.DateTimeField(auto_now_add=True, help_text='The time which this PersistentShare was created in the TOM database.')), + ('target', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tom_targets.basetarget')), + ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('-created',), + 'unique_together': {('target', 'destination')}, + }, + ), + ] diff --git a/tom_targets/migrations/0023_alter_basetarget_options.py b/tom_targets/migrations/0023_alter_basetarget_options.py new file mode 100644 index 000000000..78eb632c6 --- /dev/null +++ b/tom_targets/migrations/0023_alter_basetarget_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.13 on 2024-12-05 01:06 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('tom_targets', '0022_persistentshare'), + ] + + operations = [ + migrations.AlterModelOptions( + name='basetarget', + options={'permissions': (('view_target', 'View Target'), ('add_target', 'Add Target'), ('share_target', 'Share Target'), ('change_target', 'Change Target'), ('delete_target', 'Delete Target')), 'verbose_name': 'target'}, + ), + ] diff --git a/tom_targets/models.py b/tom_targets/models.py index 49fa4404e..942ab9485 100644 --- a/tom_targets/models.py +++ b/tom_targets/models.py @@ -3,6 +3,7 @@ import logging from django.conf import settings +from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.db import models from django.utils.module_loading import import_string @@ -193,3 +194,32 @@ class Meta: def __str__(self): return self.name + + +class PersistentShare(models.Model): + """ + Class representing a persistent share setup between a sharing destination and a Target + + :param target: The ``Target`` you want to share + + :param user: The ``User`` that created this PersistentShare, for accountability purposes. + + :param destination: The sharing destination, as it appears in your TOM's DATA_SHARING settings dict + :type destination: str + + :param created: The time at which this PersistentShare was created + :type created: datetime + """ + target = models.ForeignKey(BaseTarget, on_delete=models.CASCADE) + user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL) + destination = models.CharField(max_length=200, help_text='The sharing destination, as it appears in your DATA_SHARING settings dict') + created = models.DateTimeField( + auto_now_add=True, help_text='The time which this PersistentShare was created in the TOM database.' + ) + + class Meta: + ordering = ('-created',) + unique_together = ['target', 'destination'] + + def __str__(self): + return f'{self.target}-{self.destination}' diff --git a/tom_targets/serializers.py b/tom_targets/serializers.py index a589a7bc9..dc21563eb 100644 --- a/tom_targets/serializers.py +++ b/tom_targets/serializers.py @@ -3,8 +3,10 @@ from rest_framework import serializers from tom_common.serializers import GroupSerializer -from tom_targets.models import Target, TargetExtra, TargetName, TargetList +from tom_targets.models import Target, TargetExtra, TargetName, TargetList, PersistentShare from tom_targets.validators import RequiredFieldsTogetherValidator +from tom_targets.fields import TargetFilteredPrimaryKeyRelatedField +from tom_dataproducts.sharing import get_sharing_destination_options class TargetNameSerializer(serializers.ModelSerializer): @@ -181,13 +183,10 @@ def update(self, instance, validated_data): return instance -class TargetFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField): - # This PrimaryKeyRelatedField subclass is used to implement get_queryset based on the permissions of the user - # submitting the request. The pattern was taken from this StackOverflow answer: https://stackoverflow.com/a/32683066 +class PersistentShareSerializer(serializers.ModelSerializer): + destination = serializers.ChoiceField(choices=get_sharing_destination_options(), required=True) + target = TargetFilteredPrimaryKeyRelatedField(queryset=Target.objects.all(), required=True) - def get_queryset(self): - request = self.context.get('request', None) - queryset = super().get_queryset() - if not (request and queryset): - return None - return get_objects_for_user(request.user, 'tom_targets.change_target') + class Meta: + model = PersistentShare + fields = ('id', 'target', 'destination', 'user', 'created') diff --git a/tom_targets/signals/__init__.py b/tom_targets/signals/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tom_targets/signals/handlers.py b/tom_targets/signals/handlers.py new file mode 100644 index 000000000..ca24f2a18 --- /dev/null +++ b/tom_targets/signals/handlers.py @@ -0,0 +1,17 @@ +from django.dispatch import receiver +from django.db.models.signals import post_save + +from tom_dataproducts.models import ReducedDatum +from tom_dataproducts.sharing import share_data_with_destination +from tom_targets.models import PersistentShare + + +@receiver(post_save, sender=ReducedDatum) +def cb_dataproduct_post_save(sender, instance, *args, **kwargs): + # When a new dataproduct is created or updated, check for any persistentshare instances on that target + # and if they exist, attempt to share the new data + target = instance.target + persistentshares = PersistentShare.objects.filter(target=target) + for persistentshare in persistentshares: + share_destination = persistentshare.destination + share_data_with_destination(share_destination, instance) diff --git a/tom_targets/templates/tom_targets/partials/create_persistent_share.html b/tom_targets/templates/tom_targets/partials/create_persistent_share.html new file mode 100644 index 000000000..7f025b56f --- /dev/null +++ b/tom_targets/templates/tom_targets/partials/create_persistent_share.html @@ -0,0 +1,73 @@ +{% load bootstrap4 targets_extras static %} + +
+ {% csrf_token %} +
+
+ {% bootstrap_field form.destination %} +
+
+ {% bootstrap_field form.target %} +
+
+ {% if target %} + + {% else %} + + {% endif %} +
+
+
+ +
+ {% buttons %} + {% endbuttons %} +
+ \ No newline at end of file diff --git a/tom_targets/templates/tom_targets/partials/persistent_share_table.html b/tom_targets/templates/tom_targets/partials/persistent_share_table.html new file mode 100644 index 000000000..b2ee43789 --- /dev/null +++ b/tom_targets/templates/tom_targets/partials/persistent_share_table.html @@ -0,0 +1,52 @@ + + + + + + + + + + + {% for persistentshare in persistentshares %} + + + + + + {% endfor %} + +
TargetShare DestinationCreatorDelete?
+ {{ persistentshare.target.names|join:", " }} + {{ persistentshare.destination }}{{ persistentshare.user.username }} + {% if target %} + + {% else %} + + {% endif %} +
+ \ No newline at end of file diff --git a/tom_targets/templates/tom_targets/target_manage_persistent_shares.html b/tom_targets/templates/tom_targets/target_manage_persistent_shares.html new file mode 100644 index 000000000..28e6610c1 --- /dev/null +++ b/tom_targets/templates/tom_targets/target_manage_persistent_shares.html @@ -0,0 +1,22 @@ +{% extends 'tom_common/base.html' %} +{% load bootstrap4 targets_extras static %} +{% block title %}Persistent Share Form{% endblock %} +{% block additional_css %} + + + +{% endblock %} +{% block content %} +

Create Persistent Share {% if target %} for Target {{ target.name }}{% endif %}

+
+ {% create_persistent_share target %} +
+

Manage Persistent Shares {% if target %} for Target {{ target.name }}{% endif %}

+
+ {% csrf_token %} + {% persistent_share_table target %} + {% buttons %} + {% endbuttons %} +
+ +{% endblock %} diff --git a/tom_targets/templates/tom_targets/target_share.html b/tom_targets/templates/tom_targets/target_share.html index 1262eb892..9fa7261d6 100644 --- a/tom_targets/templates/tom_targets/target_share.html +++ b/tom_targets/templates/tom_targets/target_share.html @@ -1,5 +1,5 @@ {% extends 'tom_common/base.html' %} -{% load bootstrap4 dataproduct_extras static %} +{% load bootstrap4 targets_extras dataproduct_extras static %} {% block title %}Share Target {{ target.name }}{% endblock %} {% block additional_css %} @@ -8,39 +8,71 @@ {% endblock %} {% block content %}

Share {{ target.name }}

-
-
-
+ +
+
+
+ +
+
{% bootstrap_field form.share_destination %} -
-
+
+
{% bootstrap_field form.share_title %} -
-
- -
- {% if hermes_sharing %} -
+
+
+ +
+ {% if hermes_sharing %} +
or +
+
+ +
+ {% endif %}
-
- -
- {% endif %} -
-
-
+
+
{% bootstrap_field form.share_message %} +
-
-

Include Data

- {% with target_share=True %} +

Include Data

+ {% with target_share=True %} {% get_photometry_data target target_share %} - {% endwith %} - {% buttons %} + {% endwith %} + {% buttons %} Back - {% endbuttons %} - + {% endbuttons %} + +
+
+
+
+

Create Persistent Share for Target {{ target.name }}

+
+ {% create_persistent_share target %} +
+

Manage Persistent Shares for Target {{ target.name }}

+
+ {% persistent_share_table target %} +
+
+
\ No newline at end of file + diff --git a/tom_targets/templates/tom_targets/partials/persistent_share_table.html b/tom_targets/templates/tom_targets/partials/persistent_share_table.html index b2ee43789..f97301a24 100644 --- a/tom_targets/templates/tom_targets/partials/persistent_share_table.html +++ b/tom_targets/templates/tom_targets/partials/persistent_share_table.html @@ -49,4 +49,4 @@ table.innerHTML = html; }) } - \ No newline at end of file + From 030c19412841911e673662847f4d958f1b22ea2b Mon Sep 17 00:00:00 2001 From: Jon Date: Wed, 11 Dec 2024 16:52:16 -0100 Subject: [PATCH 05/13] Fix indentation --- tom_dataproducts/sharing.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tom_dataproducts/sharing.py b/tom_dataproducts/sharing.py index 1b102d575..ae815ef01 100644 --- a/tom_dataproducts/sharing.py +++ b/tom_dataproducts/sharing.py @@ -35,11 +35,11 @@ def continuous_share_data(target, reduced_datums): destination, ReducedDatum.objects.filter(pk__in=reduced_datum_pks), topic=hermes_topic) sharing = getattr(settings, "DATA_SHARING", {}) message = BuildHermesMessage(title=f"Updated data for {target.name} from " - f"{getattr(settings, 'TOM_NAME', 'TOM Toolkit')}.", - authors=sharing.get('hermes', {}).get('DEFAULT_AUTHORS', None), - message=None, - topic=hermes_topic - ) + f"{getattr(settings, 'TOM_NAME', 'TOM Toolkit')}.", + authors=sharing.get('hermes', {}).get('DEFAULT_AUTHORS', None), + message=None, + topic=hermes_topic + ) publish_to_hermes(message, filtered_reduced_datums) else: share_data_with_tom(share_destination, None, None, None, selected_data=reduced_datum_pks) From fa299f0b6d591c94762cb1ee13da7da4e7967bf9 Mon Sep 17 00:00:00 2001 From: Jon Date: Wed, 11 Dec 2024 20:30:39 -0100 Subject: [PATCH 06/13] Rename persistent sharing to continuously share in templates --- tom_targets/apps.py | 4 ++++ tom_targets/signals/handlers.py | 4 ++-- .../tom_targets/target_manage_persistent_shares.html | 10 ++++------ tom_targets/templates/tom_targets/target_share.html | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/tom_targets/apps.py b/tom_targets/apps.py index b858f7340..0b79ef450 100644 --- a/tom_targets/apps.py +++ b/tom_targets/apps.py @@ -3,3 +3,7 @@ class TomTargetsConfig(AppConfig): name = 'tom_targets' + + def ready(self): + import tom_targets.signals.handlers # noqa + super().ready() diff --git a/tom_targets/signals/handlers.py b/tom_targets/signals/handlers.py index 1a55da254..659305c17 100644 --- a/tom_targets/signals/handlers.py +++ b/tom_targets/signals/handlers.py @@ -6,8 +6,8 @@ @receiver(post_save, sender=ReducedDatum) -def cb_dataproduct_post_save(sender, instance, *args, **kwargs): - # When a new dataproduct is created or updated, check for any persistentshare instances on that target +def cb_reduceddatum_post_save(sender, instance, *args, **kwargs): + # When a new ReducedDatum is created or updated, check for any persistentshare instances on that target # and if they exist, attempt to share the new data target = instance.target continuous_share_data(target, reduced_datums=[instance]) diff --git a/tom_targets/templates/tom_targets/target_manage_persistent_shares.html b/tom_targets/templates/tom_targets/target_manage_persistent_shares.html index 28e6610c1..c0adc58f2 100644 --- a/tom_targets/templates/tom_targets/target_manage_persistent_shares.html +++ b/tom_targets/templates/tom_targets/target_manage_persistent_shares.html @@ -7,16 +7,14 @@ {% endblock %} {% block content %} -

Create Persistent Share {% if target %} for Target {{ target.name }}{% endif %}

+

Continuously Share data {% if target %} for Target {{ target.name }}{% endif %}

{% create_persistent_share target %}
-

Manage Persistent Shares {% if target %} for Target {{ target.name }}{% endif %}

+

Manage Continous Sharing {% if target %} for Target {{ target.name }}{% endif %}

- {% csrf_token %} {% persistent_share_table target %} - {% buttons %} - {% endbuttons %}
- +{% buttons %} +{% endbuttons %} {% endblock %} diff --git a/tom_targets/templates/tom_targets/target_share.html b/tom_targets/templates/tom_targets/target_share.html index 9fa7261d6..ddcd9c74d 100644 --- a/tom_targets/templates/tom_targets/target_share.html +++ b/tom_targets/templates/tom_targets/target_share.html @@ -62,11 +62,11 @@

Include Data

-

Create Persistent Share for Target {{ target.name }}

+

Continously Share data for Target {{ target.name }}

{% create_persistent_share target %}
-

Manage Persistent Shares for Target Manage Continuous Sharing for Target {{ target.name }}

{% persistent_share_table target %} From 8fda99f08ca4cdc48be9c99ca511773e23ef0427 Mon Sep 17 00:00:00 2001 From: Jon Date: Thu, 12 Dec 2024 06:43:38 -0100 Subject: [PATCH 07/13] Changed the permission handling to work better and updated views to use the permissions better --- tom_targets/base_models.py | 2 -- tom_targets/forms.py | 2 +- .../0023_alter_basetarget_options.py | 17 -------------- .../partials/create_persistent_share.html | 18 +++++++++++---- .../partials/persistent_share_table.html | 10 +++++++-- tom_targets/templatetags/targets_extras.py | 22 +++++++++++-------- tom_targets/views.py | 16 ++++++++------ tom_targets/viewsets.py | 18 ++++++++++++--- 8 files changed, 60 insertions(+), 45 deletions(-) delete mode 100644 tom_targets/migrations/0023_alter_basetarget_options.py diff --git a/tom_targets/base_models.py b/tom_targets/base_models.py index f785ea43c..9801d2118 100644 --- a/tom_targets/base_models.py +++ b/tom_targets/base_models.py @@ -403,7 +403,6 @@ class Meta: permissions = ( ('view_target', 'View Target'), ('add_target', 'Add Target'), - ('share_target', 'Share Target'), ('change_target', 'Change Target'), ('delete_target', 'Delete Target'), ) @@ -574,6 +573,5 @@ def give_user_access(self, user): :return: """ assign_perm('tom_targets.view_target', user, self) - assign_perm('tom_targets.share_target', user, self) assign_perm('tom_targets.change_target', user, self) assign_perm('tom_targets.delete_target', user, self) diff --git a/tom_targets/forms.py b/tom_targets/forms.py index 8a1d4fe77..05ea831ee 100644 --- a/tom_targets/forms.py +++ b/tom_targets/forms.py @@ -267,6 +267,6 @@ def __init__(self, *args, **kwargs): else: if self.user: self.fields['target'].queryset = get_objects_for_user( - self.user, f'{Target._meta.app_label}.share_target') + self.user, f'{Target._meta.app_label}.change_target') else: self.fields['target'].queryset = Target.objects.none() diff --git a/tom_targets/migrations/0023_alter_basetarget_options.py b/tom_targets/migrations/0023_alter_basetarget_options.py deleted file mode 100644 index 78eb632c6..000000000 --- a/tom_targets/migrations/0023_alter_basetarget_options.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2.13 on 2024-12-05 01:06 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('tom_targets', '0022_persistentshare'), - ] - - operations = [ - migrations.AlterModelOptions( - name='basetarget', - options={'permissions': (('view_target', 'View Target'), ('add_target', 'Add Target'), ('share_target', 'Share Target'), ('change_target', 'Change Target'), ('delete_target', 'Delete Target')), 'verbose_name': 'target'}, - ), - ] diff --git a/tom_targets/templates/tom_targets/partials/create_persistent_share.html b/tom_targets/templates/tom_targets/partials/create_persistent_share.html index e7aa06e90..215a15852 100644 --- a/tom_targets/templates/tom_targets/partials/create_persistent_share.html +++ b/tom_targets/templates/tom_targets/partials/create_persistent_share.html @@ -1,5 +1,5 @@ {% load bootstrap4 targets_extras static %} - +{% if form %}
{% csrf_token %}
@@ -34,6 +34,11 @@ {% buttons %} {% endbuttons %} +{% else %} +
+

You do not have permission to Continuously Share data. Please contact the TOM administrator.

+
+{% endif %}