-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1138 from TOMToolkit/feature/persistent_sharing
Add in persistentshare model and views and hook it into the target sh…
- Loading branch information
Showing
23 changed files
with
625 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
Setting up Continuous Sharing | ||
--------------------------------------- | ||
|
||
After setting up your TOM's `DATA_SHARING` destinations in your settings, you can set up individual Targets to share | ||
their data automatically with a sharing destination as the data arrives in the TOM. Continuous Sharing is handled through | ||
the `PersistentShare` model in the `tom_targets` module. | ||
|
||
|
||
Permissions: | ||
############################# | ||
|
||
In order to setup continuous sharing, your user account must have the proper permissions, which means permissions to | ||
add, view, and delete `PersistentShare` objects. A superuser account will have all permissions by default, but to give | ||
permissions to another user, you can use code like this one time in the console: | ||
|
||
.. code:: python | ||
from guardian.shortcuts import assign_perm | ||
# To assign the permission to a single user | ||
user = User.objects.get(username='myusername') | ||
assign_perm('tom_targets.view_persistentshare', user) | ||
assign_perm('tom_targets.add_persistentshare', user) | ||
assign_perm('tom_targets.delete_persistentshare', user) | ||
# To assign the permission to all users of a group | ||
group = Group.objects.get(name='mygroupname') | ||
assign_perm('tom_targets.view_persistentshare', group) | ||
assign_perm('tom_targets.add_persistentshare', group) | ||
assign_perm('tom_targets.delete_persistentshare', group) | ||
The user must also have `change_target` permissions on the specific Target they are attempting to continuously share. | ||
|
||
|
||
Managing Continuous Sharing: | ||
************************************************* | ||
|
||
There are a few ways to manage continuous sharing. First, you can navigate to any Target's share page `/targets/<target_pk>/share` | ||
and you should see a tab for creating and viewing continuous sharing for that Target. You can also navigate to | ||
`/targets/persistentshare/manage` to create and view all persistentshare objects you have permissions to see. There is also | ||
a REST API for persistentshare objects that can be accessed at `/targets/persistentshare/`, which is used internally from the | ||
manage pages. | ||
|
||
If you have a custom target details page, you can integrate the controls for creating or managing continuous sharing using the | ||
template partials below: | ||
|
||
.. code:: html | ||
|
||
<h3>Continously Share data for Target <a href="{% url 'targets:detail' pk=target.id %}" title="Back">{{ target.name }}</a></h3> | ||
<div id='target-persistent-share-create'> | ||
{% create_persistent_share target %} | ||
</div> | ||
<h3>Manage Continuous Sharing for Target <a href="{% url 'targets:detail' pk=target.id %}" | ||
title="Back">{{ target.name }}</a></h3> | ||
<div id='target-persistent-share-table'> | ||
{% persistent_share_table target %} | ||
</div> | ||
|
||
Note that setting up Continuous Sharing stores the destination from your `DATA_SHARING` settings. If you later change or remove that | ||
destination then continuous shares using it will fail. | ||
|
||
Also note that by default, continuous sharing will occur when a ReducedDatum is saved, or when the default `tom_base` `DataProcessor` is used | ||
to load in a `DataProduct`. If you create your own `DataProcessor` subclass in your TOM, you must add the following lines to trigger continuous | ||
sharing after you have bulk created the `ReducedDatums`: | ||
|
||
.. code:: python | ||
from tom_dataproducts.sharing import continuous_share_data | ||
# After all your logic to bulk_create ReducedDatums | ||
# Trigger any sharing you may have set to occur when new data comes in | ||
# Encapsulate this in a try/catch so sharing failure doesn't prevent dataproduct ingestion | ||
try: | ||
continuous_share_data(dp.target, reduced_datums) | ||
except Exception as e: | ||
logger.warning(f"Failed to share new dataproduct {dp.product_id}: {repr(e)}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
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') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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')}, | ||
}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Oops, something went wrong.