Tombstones. Closes #7.

2019-08-17
Marnanel Thurman 2019-05-29 12:37:51 +01:00
rodzic fb1444e4ef
commit 7a57d691df
4 zmienionych plików z 85 dodań i 3 usunięć

Wyświetl plik

@ -140,6 +140,14 @@ class ThingRequest(HttpRequest):
self.method = 'ACTIVITY'
class TombstoneException(Exception):
def __init__(self, tombstone, *args, **kwargs):
self.tombstone = tombstone
super().__init__(*args, **kwargs)
def __str__(self):
return self.tombstone.__str__()
def find_local(path):
try:
@ -160,6 +168,9 @@ def find_local(path):
**resolved.kwargs)
logger.debug('%s: resulting in %s', path, str(result))
if result.f_type == 'Tombstone':
raise TombstoneException(result)
return result
def find_remote(url):

Wyświetl plik

@ -1,6 +1,6 @@
from django.db import models, IntegrityError
from django.conf import settings
from django_kepi.find import find
from django_kepi.find import find, is_local
from django_kepi.delivery import deliver
import django_kepi.models.following
import logging
@ -211,6 +211,39 @@ class Thing(models.Model):
following = self['actor'],
)
@property
def is_local(self):
if not self.remote_url:
return True
return is_local(self.remote_url)
def entomb(self):
logger.info('%s: entombing', self)
if self.f_type=='Tombstone':
logger.warn(' -- already entombed; ignoring')
return
if not self.is_local:
raise ValueError("%s: you can't entomb remote things %s",
self, str(self.remote_url))
former_type = self.f_type
self.f_type = 'Tombstone'
self.active = True
ThingField.objects.filter(parent=self).delete()
for f,v in [
('former_type', former_type),
# XXX 'deleted', when we're doing timestamps
]:
ThingField(parent=self, name=f, value=json.dumps(v)).save()
self.save()
logger.info('%s: entombing finished', self)
TYPES = {
# actor object target
@ -335,8 +368,6 @@ class Thing(models.Model):
record_fields['f_type'] = value['type']
if 'id' in value:
# FIXME this allows people to create "remote" Activities
# with local URLs, which is weird and shouldn't happen.
record_fields['remote_url'] = value['id']
for f in ['id', 'type', 'actor', 'name']:

Wyświetl plik

@ -97,6 +97,10 @@ class KepiView(django.views.View):
result['Content-Type'] = 'application/activity+json'
if data['type']=='Tombstone':
result.reason = 'Entombed'
result.status_code = 410
return result
def _collection_get(self, request, items):
@ -252,6 +256,9 @@ class ActorView(ThingView):
def activity(self, request, *args, **kwargs):
thing = super().activity(request, *args, **kwargs)
if thing.f_type=='Tombstone':
return thing
logger.debug(' -- found Thing %s; does it have an Actor?',
thing)

Wyświetl plik

@ -78,3 +78,36 @@ class TestKepiView(TestCase):
}
)
class TestTombstone(TestCase):
def test_tombstone(self):
queen_anne = create_local_person('queen_anne')
c = Client()
response = c.get('/users/queen_anne')
self.assertEqual(response.status_code, 200)
self.assertDictEqual(
_response_to_dict(response),
{
'name': 'queen_anne',
'id': 'https://altair.example.com/users/queen_anne',
'type': 'Person',
},
)
queen_anne.entomb()
response = c.get('/users/queen_anne')
self.assertEqual(response.status_code, 410)
self.assertDictEqual(
_response_to_dict(response),
{
'id': 'https://altair.example.com/users/queen_anne',
'type': 'Tombstone',
'former_type': 'Person',
'name': 'queen_anne',
},
)