Repository: zulip/zulip

Issue:
two factor authentication domain name
Is it possible to configure the "domain" part or label of the generated QR-Code somewhere ?
Right now it seems to always be "example.net" if I scan the QR-Code.


Discussion:
The native 2FA integration in Zulip is unfinished (that's why it's turned off by default).  #10921 has some more details.  

This is in Google authenticator?  It's a good question where that would come from; we don't have the string "example.net" anywhere in our codebase or in that of django-two-factor, the library we use for this.  
Yeah, I think so, too.
Must be somewhere near https://github.com/Bouke/django-two-factor-auth/blob/d000074089ff02ee616a0c5f2e6b03d175f3b9ff/two_factor/views/core.py#L557
I guess, but I am not very good with python and django tbh :-)

We tried to set OTP_HOTP_ISSUER in the settings.py, but that did not help.

I tried a bit around with the "Sites" Framework in the shell and I found:

```
In [7]: from django.contrib.sites.models import Site

In [8]: Site.objects.get_current().domain
Out[8]: 'collab.oss.ewetel.de'

In [9]: Site.objects.get_current().name
Out[9]: 'example.com'
```

Could be that its coming from there ? I just have no idea how to actually change it. And is there a way to change the domain, too ? That url is not the right one anymore anyways.
Ok, found out how to change + save it with the shell. Now the QR-Code is OK :-)

I have no idea where/if the sites Framework is used in zulip though. Would be cool if it would be possible to set this in the settings maybe
Ugh, it uses the Django "Sites" framework.  We don't use that for anything in Zulip (other than, apparently indirectly, this).  I think our near-term fix might be to monkey-patch `from django.contrib.sites.shortcuts import get_current_site` to return effectively the `realm.host` value, since that's where to get the correct value for the current realm/subdomain.  Thanks for investigating!
Changing that `issuer` line to ` issuer=request.user.realm.host` seems to do the right thing.  So we just need to figure out a good way to make that change without forking social-auth.
Ahh, there's a better solution: If we just remove the Site Django middleware (which we're not using), it'll automatically do the right thing.  So I'll do that.

Resolving patch:
diff --git a/zerver/management/commands/initialize_voyager_db.py b/zerver/management/commands/initialize_voyager_db.py
--- a/zerver/management/commands/initialize_voyager_db.py
+++ b/zerver/management/commands/initialize_voyager_db.py
@@ -3,7 +3,6 @@
 from typing import Any, Iterable, Tuple, Optional
 
 from django.conf import settings
-from django.contrib.sites.models import Site
 from django.core.management.base import BaseCommand
 
 from zerver.lib.bulk_create import bulk_create_users
@@ -58,7 +57,3 @@ def handle(self, *args: Any, **options: Any) -> None:
         self.stdout.write("Successfully populated database with initial data.\n")
         self.stdout.write("Please run ./manage.py generate_realm_creation_link "
                           "to generate link for creating organization")
-
-    site = Site.objects.get_current()
-    site.domain = settings.EXTERNAL_HOST
-    site.save()
diff --git a/zproject/settings.py b/zproject/settings.py
--- a/zproject/settings.py
+++ b/zproject/settings.py
@@ -492,13 +492,6 @@ def get_config(section: str, key: str, default_value: Optional[Any]=None) -> Opt
 # http://www.i18nguy.com/unicode/language-identifiers.html
 LANGUAGE_CODE = 'en-us'
 
-# The ID, as an integer, of the current site in the django_site database table.
-# This is used so that application data can hook into specific site(s) and a
-# single database can manage content for multiple sites.
-#
-# We set this site's string_id to 'zulip' in populate_db.
-SITE_ID = 1
-
 # If you set this to False, Django will make some optimizations so as not
 # to load the internationalization machinery.
 USE_I18N = True
@@ -566,7 +559,6 @@ def get_dirs(self):
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
-    'django.contrib.sites',
     'django.contrib.staticfiles',
     'confirmation',
     'pipeline',


Test patch:
diff --git a/zerver/tests/test_signup.py b/zerver/tests/test_signup.py
--- a/zerver/tests/test_signup.py
+++ b/zerver/tests/test_signup.py
@@ -6,7 +6,6 @@
 import django_otp
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
-from django.contrib.sites.models import Site
 from django.http import HttpResponse, HttpRequest
 from django.test import TestCase, override_settings
 from django.utils.timezone import now as timezone_now
@@ -459,7 +458,6 @@ def test_register(self) -> None:
         # Clear all the caches.
         flush_per_request_caches()
         ContentType.objects.clear_cache()
-        Site.objects.clear_cache()
 
         with queries_captured() as queries:
             self.register(self.nonreg_email('test'), "test")