Remove outdated user fields

This commit is contained in:
Mouse Reeve 2020-11-30 10:32:54 -08:00
parent 74a58e5267
commit 8bc0a57bd4
7 changed files with 96 additions and 33 deletions

View file

@ -13,6 +13,7 @@ def copy_rsa_keys(app_registry, schema_editor):
for user in users.objects.using(db_alias):
if user.public_key or user.private_key:
user.key_pair = keypair.objects.create(
remote_id='%s/#main-key' % user.remote_id,
private_key=user.private_key,
public_key=user.public_key
)

View file

@ -0,0 +1,25 @@
# Generated by Django 3.0.7 on 2020-11-30 18:32
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0017_auto_20201130_1819'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='following',
),
migrations.RemoveField(
model_name='user',
name='private_key',
),
migrations.RemoveField(
model_name='user',
name='public_key',
),
]

View file

@ -0,0 +1,24 @@
# Generated by Django 3.0.7 on 2020-11-30 19:39
import bookwyrm.models.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0018_auto_20201130_1832'),
]
operations = [
migrations.AlterField(
model_name='user',
name='name',
field=bookwyrm.models.fields.CharField(default='', max_length=100),
),
migrations.AlterField(
model_name='user',
name='summary',
field=bookwyrm.models.fields.TextField(default=''),
),
]

View file

@ -14,7 +14,7 @@ from .attachment import Image
from .tag import Tag, UserTag
from .user import User
from .user import User, KeyPair
from .relationship import UserFollows, UserFollowRequest, UserBlocks
from .federated_server import FederatedServer

View file

@ -1,5 +1,4 @@
''' base model with default fields '''
from datetime import datetime
from base64 import b64encode
from dataclasses import dataclass
from typing import Callable
@ -10,9 +9,6 @@ from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from django.db import models
from django.db.models.fields.files import ImageFileDescriptor
from django.db.models.fields.related_descriptors \
import ManyToManyDescriptor, ReverseManyToOneDescriptor
from django.dispatch import receiver
from bookwyrm import activitypub
@ -56,24 +52,34 @@ def execute_after_save(sender, instance, created, *args, **kwargs):
instance.save()
def get_field_name(field):
''' model_field_name to activitypubFieldName '''
if field.activitypub_field:
return field.activitypub_field
name = field.name.split('.')[-1]
components = name.split('_')
return components[0] + ''.join(x.title() for x in components[1:])
class ActivitypubMixin:
''' add this mixin for models that are AP serializable '''
activity_serializer = lambda: {}
def to_activity(self, pure=False):
def to_activity(self):
''' convert from a model to an activity '''
activity = {}
for field in self.__class__._meta.fields:
key, value = field.to_activity(getattr(self, field.name))
activity[key] = value
for related_object in self.__class__.meta.related_objects:
# TODO: check if it's serializable
related_model = related_object.related_model
key = related_object.name
related_values = getattr(self, key)
activity[key] = [i.remote_id for i in related_values]
for field in self.__class__._meta.get_fields():
if not hasattr(field, 'to_activity'):
continue
key = get_field_name(field)
value = field.to_activity(getattr(self, field.name))
if value is not None:
activity[key] = value
if hasattr(self, 'serialize_reverse_fields'):
for field_name in self.serialize_reverse_fields:
activity[field_name] = getattr(self, field_name).remote_id
return self.activity_serializer(**activity_json).serialize()
return self.activity_serializer(**activity).serialize()
def to_create_activity(self, user, pure=False):

View file

@ -21,25 +21,22 @@ def validate_remote_id(value):
)
def to_camel_case(snake_string):
''' model_field_name to activitypubFieldName '''
components = snake_string.split('_')
return components[0] + ''.join(x.title() for x in components[1:])
class ActivitypubFieldMixin:
''' make a database field serializable '''
def __init__(self, *args, \
activitypub_field=None, activitypub_wrapper=None, **kwargs):
self.activitypub_wrapper = activitypub_wrapper
self.activitypub_field = activitypub_field
if activitypub_wrapper:
self.activitypub_wrapper = activitypub_field
self.activitypub_field = activitypub_wrapper
else:
self.activitypub_field = activitypub_field
super().__init__(*args, **kwargs)
def to_activity(self, value):
''' formatter to convert a model value into activitypub '''
if self.activitypub_wrapper:
if hasattr(self, 'activitypub_wrapper'):
value = {self.activitypub_wrapper: value}
return (self.activitypub_field, value)
return value
def from_activity(self, activity_data):
''' formatter to convert activitypub into a model value '''
@ -96,11 +93,9 @@ class ForeignKey(ActivitypubFieldMixin, models.ForeignKey):
class OneToOneField(ActivitypubFieldMixin, models.OneToOneField):
''' activitypub-aware foreign key field '''
def __init__(self, *args, **kwargs):
super(ActivitypubFieldMixin, self).__init__(*args, **kwargs)
def to_activity(self, value):
return value.remote_id
return value.to_activity()
def from_activity(self, activity_data):
pass# TODO
@ -113,7 +108,7 @@ class ManyToManyField(ActivitypubFieldMixin, models.ManyToManyField):
def to_activity(self, value):
if self.link_only:
return '%s/followers' % self.instance.remote_id
return '%s/followers' % value.instance.remote_id
return [i.remote_id for i in value]
def from_activity(self, activity_data):

View file

@ -26,10 +26,12 @@ class User(OrderedCollectionPageMixin, AbstractUser):
'KeyPair',
on_delete=models.CASCADE,
blank=True, null=True,
activitypub_field='publicKey',
related_name='owner'
)
inbox = fields.RemoteIdField(unique=True)
shared_inbox = fields.RemoteIdField(
activitypub_field='sharedInbox',
activitypub_wrapper='endpoints', null=True)
federated_server = models.ForeignKey(
'FederatedServer',
@ -38,7 +40,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
blank=True,
)
outbox = fields.RemoteIdField(unique=True)
summary = fields.TextField(blank=True, null=True)
summary = fields.TextField(default='')
local = models.BooleanField(default=False)
bookwyrm_user = fields.BooleanField(default=True)
localname = models.CharField(
@ -47,7 +49,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
unique=True
)
# name is your display name, which you can change at will
name = fields.CharField(max_length=100, blank=True, null=True)
name = fields.CharField(max_length=100, default='')
avatar = fields.ImageField(
upload_to='avatars/', blank=True, null=True, activitypub_field='icon')
followers = fields.ManyToManyField(
@ -87,6 +89,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
manually_approves_followers = fields.BooleanField(default=False)
activity_serializer = activitypub.Person
serialize_related = []
def to_outbox(self, **kwargs):
''' an ordered collection of statuses '''
@ -159,6 +162,7 @@ class KeyPair(ActivitypubMixin, BookWyrmModel):
blank=True, null=True, activitypub_field='publicKeyPem')
activity_serializer = activitypub.PublicKey
serialize_reverse_fields = ['owner']
def get_remote_id(self):
# self.owner is set by the OneToOneField on User
@ -169,6 +173,14 @@ class KeyPair(ActivitypubMixin, BookWyrmModel):
self.private_key, self.public_key = create_key_pair()
return super().save(*args, **kwargs)
def to_activity(self):
''' override default AP serializer to add context object
idk if this is the best way to go about this '''
activity_object = super().to_activity()
del activity_object['@context']
del activity_object['type']
return activity_object
@receiver(models.signals.post_save, sender=User)
def execute_after_save(sender, instance, created, *args, **kwargs):