mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
remote_billing: Implement confirmation flow for RemoteRealm auth.
The way the flow goes now is this: 1. The user initiaties login via "Billing" in the gear menu. 2. That takes them to `/self-hosted-billing/` (possibly with a `next_page` param if we use that for some gear menu options). 3. The server queries the bouncer to give the user a link with a signed access token. 4. The user is redirected to that link (on `selfhosting.zulipchat.com`). Now we have two cases, either the user is logging in for the first time and already did in the past. If this is the first time, we have: 5. The user is asked to fill in their email in a form that's shown, pre-filled with the value provided inside the signed access token. They POST this to the next endpoint. 6. The next endpoint sends a confirmation email to that address and asks the user to go check their email. 7. The user clicks the link in their email is taken to the from_confirmation endpoint. 8. Their initial RemoteBillingUser is created, a new signed link like in (3) is generated and they're transparently taken back to (4), where now that they have a RemoteBillingUser, they're handled just like a user who already logged in before: If the user already logged in before, they go straight here: 9. "Confirm login" page - they're shown their information (email and full_name), can update their full name in the form if they want. They also accept ToS here if necessary. They POST this form back to the endpoint and finally have a logged in session. 10. They're redirected to billing (or `next_page`) now that they have access.
This commit is contained in:
committed by
Tim Abbott
parent
18ec4cd198
commit
423aebf98e
@@ -154,17 +154,40 @@ class RemoteRealm(models.Model):
|
||||
return f"{self.host} {str(self.uuid)[0:12]}"
|
||||
|
||||
|
||||
class RemoteRealmBillingUser(models.Model):
|
||||
class AbstractRemoteRealmBillingUser(models.Model):
|
||||
remote_realm = models.ForeignKey(RemoteRealm, on_delete=models.CASCADE)
|
||||
|
||||
# The .uuid of the UserProfile on the remote server
|
||||
user_uuid = models.UUIDField()
|
||||
full_name = models.TextField(default="")
|
||||
email = models.EmailField()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class RemoteRealmBillingUser(AbstractRemoteRealmBillingUser):
|
||||
full_name = models.TextField(default="")
|
||||
|
||||
TOS_VERSION_BEFORE_FIRST_LOGIN = UserProfile.TOS_VERSION_BEFORE_FIRST_LOGIN
|
||||
tos_version = models.TextField(default=TOS_VERSION_BEFORE_FIRST_LOGIN)
|
||||
|
||||
class Meta:
|
||||
unique_together = [
|
||||
("remote_realm", "user_uuid"),
|
||||
]
|
||||
|
||||
|
||||
class PreregistrationRemoteRealmBillingUser(AbstractRemoteRealmBillingUser):
|
||||
# status: whether an object has been confirmed.
|
||||
# if confirmed, set to confirmation.settings.STATUS_USED
|
||||
status = models.IntegerField(default=0)
|
||||
|
||||
# These are for carrying certain information that's originally
|
||||
# in an IdentityDict across the confirmation link flow. These
|
||||
# values will be restored in the final, fully authenticated IdentityDict.
|
||||
next_page = models.TextField(null=True)
|
||||
uri_scheme = models.TextField()
|
||||
|
||||
|
||||
class AbstractRemoteServerBillingUser(models.Model):
|
||||
remote_server = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
||||
|
Reference in New Issue
Block a user