Add polymorphic properties to User

This adds the ability to search for any user based on the generic
User case and be given back the specific LocalUser or RemoteUser.

This will require any code using the model to look which attributes
they are searching on and specify the specific User model they are
on if they're not on the generic User model. This will also require
new users to be created with LocalUser.
This commit is contained in:
Jessica Tallon 2015-07-17 17:49:18 +02:00
parent aa9ba3ed80
commit 283e6d8b9f
2 changed files with 25 additions and 3 deletions

View File

@ -1460,15 +1460,15 @@ def federation_user_create_tables(db):
"""
Create all the tables
"""
metadata = MetaData(bind=db.bind)
user_table = inspect_table(metadata, "core__users")
# Create tables needed
LocalUser_V0.__table__.create(db.bind)
RemoteUser_V0.__table__.create(db.bind)
db.commit()
# Create the fields
metadata = MetaData(bind=db.bind)
user_table = inspect_table(metadata, "core__users")
updated_column = Column(
"updated",
DateTime,
@ -1476,6 +1476,12 @@ def federation_user_create_tables(db):
)
updated_column.create(user_table)
type_column = Column(
"type",
Unicode
)
type_column.create(user_table)
name_column = Column(
"name",
Unicode

View File

@ -237,6 +237,9 @@ class User(Base, UserMixin):
bio = Column(UnicodeText)
name = Column(Unicode)
# This is required for the polymorphic inheritance
type = Column(Unicode)
created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
updated = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
@ -245,6 +248,11 @@ class User(Base, UserMixin):
# Lazy getters
get_location = relationship("Location", lazy="joined")
__mapper_args__ = {
'polymorphic_identity': 'user',
'polymorphic_on': type
}
def has_privilege(self, privilege, allow_admin=True):
"""
This method checks to make sure a user has all the correct privileges
@ -324,6 +332,10 @@ class LocalUser(User):
uploaded = Column(Integer, default=0)
upload_limit = Column(Integer)
__mapper_args__ = {
'polymorphic_identity': 'user_local'
}
## TODO
# plugin data would be in a separate model
@ -394,6 +406,10 @@ class RemoteUser(User):
id = Column(Integer, ForeignKey("core__users.id"), primary_key=True)
webfinger = Column(Unicode, unique=True)
__mapper_args__ = {
'polymorphic_identity': 'user_remote'
}
def __repr__(self):
return "<{0} #{1} {2}>".format(
self.__class__.__name__,