kopia lustrzana https://gitlab.com/marnanel/chapeau
Tombstones. Closes #7.
rodzic
fb1444e4ef
commit
7a57d691df
|
@ -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):
|
||||
|
|
|
@ -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']:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
)
|
||||
|
|
Ładowanie…
Reference in New Issue