|
@@ -56,6 +56,17 @@ class User(Model):
|
|
except peewee.IntegrityError:
|
|
except peewee.IntegrityError:
|
|
raise e.UserExists(name=user.name)
|
|
raise e.UserExists(name=user.name)
|
|
|
|
|
|
|
|
+ @staticmethod
|
|
|
|
+ def from_invite(user: r.User, token: str) -> "User":
|
|
|
|
+ invite = UserInvite.by_code(token)
|
|
|
|
+ if invite.claimed_by is not None or invite.claimed_at is not None:
|
|
|
|
+ raise e.AlreadyUsedInvite(invite=token)
|
|
|
|
+ u = User.from_request(user)
|
|
|
|
+ invite.claimed_at = datetime.datetime.now()
|
|
|
|
+ invite.claimed_by = u
|
|
|
|
+ invite.save()
|
|
|
|
+ return u
|
|
|
|
+
|
|
def authenticate(self, password: str) -> bool:
|
|
def authenticate(self, password: str) -> bool:
|
|
return pwd.verify(password, self.passhash)
|
|
return pwd.verify(password, self.passhash)
|
|
|
|
|
|
@@ -185,7 +196,7 @@ class HasTag(Model):
|
|
|
|
|
|
|
|
|
|
class UserInvite(Model):
|
|
class UserInvite(Model):
|
|
- token = peewee.TextField()
|
|
|
|
|
|
+ token = peewee.TextField(unique=True)
|
|
|
|
|
|
created_by = peewee.ForeignKeyField(User, backref="invites")
|
|
created_by = peewee.ForeignKeyField(User, backref="invites")
|
|
created_at = peewee.DateTimeField()
|
|
created_at = peewee.DateTimeField()
|
|
@@ -193,6 +204,12 @@ class UserInvite(Model):
|
|
claimed_by = peewee.ForeignKeyField(User, null=True)
|
|
claimed_by = peewee.ForeignKeyField(User, null=True)
|
|
claimed_at = peewee.DateTimeField(null=True)
|
|
claimed_at = peewee.DateTimeField(null=True)
|
|
|
|
|
|
|
|
+ @staticmethod
|
|
|
|
+ def by_code(token: str) -> "UserInvite":
|
|
|
|
+ if (u := UserInvite.get_or_none(token=token)):
|
|
|
|
+ return u
|
|
|
|
+ raise e.NoSuchInvite(invite=token)
|
|
|
|
+
|
|
@staticmethod
|
|
@staticmethod
|
|
def manufacture(creator: User) -> "UserInvite":
|
|
def manufacture(creator: User) -> "UserInvite":
|
|
now = datetime.datetime.now()
|
|
now = datetime.datetime.now()
|