Esempio n. 1
0
 def enable_otp_session(self, user=None):
     user.totpdevice_set.create(name="default")
     assert self.client.login(username=user.username, password="******")
     if default_device(user):
         session = self.client.session
         session[DEVICE_ID_SESSION_KEY] = default_device(user).persistent_id
         session.save()
Esempio n. 2
0
def django_2fa_mixin_hack(request):
    raise_anonymous = False
    if not request.user or not request.user.is_authenticated or \
            (not request.user.is_verified() and default_device(request.user)):
        # If the user has not authenticated raise or redirect to the login
        # page. Also if the user just enabled two-factor authentication and
        # has not yet logged in since should also have the same result. If
        # the user receives a 'you need to enable TFA' by now, he gets
        # confuses as TFA has just been enabled. So we either raise or
        # redirect to the login page.
        if raise_anonymous:
            raise PermissionDenied()
        else:
            return redirect_to_login(request.get_full_path(),
                                     reverse('two_factor:login'))
    device = default_device(request.user)

    if not request.user.is_verified():
        if device:
            return redirect_to_login(request.get_full_path(),
                                     reverse('two_factor:login'))
        else:
            return render(
                request,
                'two_factor/core/otp_required.html',
                status=403,
            )
Esempio n. 3
0
 def login_user(self, user=None):
     username = user.get_username()
     assert self.client.login(username=username, password=self.password)
     if default_device(user):
         session = self.client.session
         session[DEVICE_ID_SESSION_KEY] = default_device(user).persistent_id
         session.save()
Esempio n. 4
0
 def login_user(self):
     user = list(self._passwords.keys())[0]
     username = user.get_username()
     assert self.client.login(username=username,
                              password=self._passwords[user])
     if default_device(user):
         session = self.client.session
         session[DEVICE_ID_SESSION_KEY] = default_device(user).persistent_id
         session.save()
Esempio n. 5
0
    def test_default_device(self):
        user = User.objects.create_user('bouke')
        self.assertEqual(default_device(user), None)

        user.phonedevice_set.create(name='backup')
        self.assertEqual(default_device(user), None)

        default = user.phonedevice_set.create(name='default')
        self.assertEqual(default_device(user).pk, default.pk)
Esempio n. 6
0
    def test_default_device(self):
        user = self.create_user()
        self.assertEqual(default_device(user), None)

        PhoneDevice.objects.create(user=user, name='backup')
        self.assertEqual(default_device(user), None)

        default = PhoneDevice.objects.create(user=user, name='default')
        self.assertEqual(default_device(user).pk, default.pk)
Esempio n. 7
0
    def test_default_device(self):
        user = self.create_user()
        self.assertEqual(default_device(user), None)

        user.phonedevice_set.create(name="backup", number="+1")
        self.assertEqual(default_device(user), None)

        default = user.phonedevice_set.create(name="default", number="+1")
        self.assertEqual(default_device(user).pk, default.pk)
Esempio n. 8
0
 def login_user(self, user=None):
     if not user:
         user = list(self._passwords.keys())[0]
     username = user.get_username()
     assert self.client.login(username=username, password=self._passwords[user])
     if default_device(user):
         session = self.client.session
         session[DEVICE_ID_SESSION_KEY] = default_device(user).persistent_id
         session.save()
    def test_default_device(self):
        user = User.objects.create_user("bouke")
        self.assertEqual(default_device(user), None)

        user.phonedevice_set.create(name="backup")
        self.assertEqual(default_device(user), None)

        default = user.phonedevice_set.create(name="default")
        self.assertEqual(default_device(user).pk, default.pk)
    def test_default_device(self):
        user = self.create_user()
        self.assertEqual(default_device(user), None)

        user.phonedevice_set.create(name='backup', number='+1')
        self.assertEqual(default_device(user), None)

        default = user.phonedevice_set.create(name='default', number='+1')
        self.assertEqual(default_device(user).pk, default.pk)
    def test_default_device(self):
        user = self.create_user()
        self.assertEqual(default_device(user), None)

        user.phonedevice_set.create(name='backup', number='+1')
        self.assertEqual(default_device(user), None)

        default = user.phonedevice_set.create(name='default', number='+1')
        self.assertEqual(default_device(user).pk, default.pk)
Esempio n. 12
0
    def get_context_data(self, **kwargs):
        try:
            backup_device = self.request.user.staticdevice_set.get(name='backup')
        except StaticDevice.DoesNotExist:
            backup_device = None

        return {
            'default_device': default_device(self.request.user),
            'default_device_type': default_device(self.request.user).__class__.__name__,
            'backup_device': backup_device,
        }
 def login_user(self, user=None):
     if not user:
         user = list(self._passwords.keys())[0]
     try:
         username = user.get_username()
     except AttributeError:
         username = user.username
     assert self.client.login(username=username,
                              password=self._passwords[user])
     if default_device(user):
         session = self.client.session
         session[DEVICE_ID_SESSION_KEY] = default_device(user).persistent_id
         session.save()
Esempio n. 14
0
 def get_context_data(self, **kwargs):
     try:
         backup_tokens = self.request.user.staticdevice_set.all(
         )[0].token_set.count()
     except Exception:
         backup_tokens = 0
     form = UserForm()
     return {
         'default_device': default_device(self.request.user),
         'default_device_type':
         default_device(self.request.user).__class__.__name__,
         'form': form,
     }
Esempio n. 15
0
def account(request):
	try:
		backup_tokens = request.user.staticdevice_set.all()[0].token_set.count()
	except Exception:
		backup_tokens = 0

	status = {
		'default_device': default_device(request.user),
		'default_device_type': default_device(request.user).__class__.__name__,
		'backup_phones': backup_phones(request.user),
		'backup_tokens': backup_tokens,
		'site_user': request.user
	}

	return render_to_response('account.html', status, context_instance=RequestContext(request))
Esempio n. 16
0
    def get_context_data(self, **kwargs):
        try:
            backup_tokens = self.request.user.staticdevice_set.all(
            )[0].token_set.count()
        except Exception:
            backup_tokens = 0

        return {
            'default_device': default_device(self.request.user),
            'default_device_type':
            default_device(self.request.user).__class__.__name__,
            'backup_phones': backup_phones(self.request.user),
            'backup_tokens': backup_tokens,
            'available_phone_methods': get_available_phone_methods()
        }
Esempio n. 17
0
def profile(request):
    # Get a list of the users API Keys
    keys = ApiKey.objects.filter(user=request.user)
    try:
        backup_tokens = request.user.staticdevice_set.all()[0].token_set.count()
    except IndexError:
        backup_tokens = 0

    # Get a list of the users current sessions
    sessions = request.user.session_set.filter(expire_date__gt=now())

    # Get the current session key
    session_key = request.session.session_key

    # Process the form if we have data coming in
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance=request.user.profile)
        if form.is_valid():
            form.save()
    else:
        form = UserProfileForm(instance=request.user.profile)

    # Show the template
    return render(request, 'account_profile.html', {
        'keys': keys,
        'sessions': sessions,
        'session_key': session_key,
        'form': form,
        'user': request.user,
        'default_device': default_device(request.user),
        'backup_tokens': backup_tokens,
    })
Esempio n. 18
0
def teacher_edit_account(request):
    teacher = request.user.userprofile.teacher

    backup_tokens = 0
    # For teachers using 2FA, find out how many backup tokens they have
    if default_device(request.user):
        try:
            backup_tokens = request.user.staticdevice_set.all()[0].token_set.count()
        except Exception:
            backup_tokens = 0

    if request.method == "POST":
        form = TeacherEditAccountForm(request.user, request.POST)
        if form.is_valid():
            data = form.cleaned_data
            changing_email = False

            # check not default value for CharField
            if data["password"] != "":
                teacher.user.user.set_password(data["password"])
                teacher.user.user.save()
                update_session_auth_hash(request, form.user)

            teacher.title = data["title"]
            teacher.user.user.first_name = data["first_name"]
            teacher.user.user.last_name = data["last_name"]
            new_email = data["email"]
            if new_email != "" and new_email != teacher.user.user.email:
                # new email to set and verify
                changing_email = True
                send_verification_email(request, teacher.user, new_email)

            teacher.save()
            teacher.user.user.save()

            if changing_email:
                logout(request)
                messages.success(
                    request,
                    "Your account details have been successfully changed. Your email will be changed once you have verified it, until then you can still log in with your old email.",
                )
                return render(
                    request, "portal/email_verification_needed.html", {"userprofile": teacher.user, "email": new_email}
                )

            messages.success(request, "Your account details have been successfully changed.")

            return HttpResponseRedirect(reverse_lazy("teacher_home"))
    else:
        form = TeacherEditAccountForm(
            request.user,
            initial={
                "title": teacher.title,
                "first_name": teacher.user.user.first_name,
                "last_name": teacher.user.user.last_name,
                "school": teacher.school,
            },
        )

    return render(request, "portal/teach/teacher_edit_account.html", {"form": form, "backup_tokens": backup_tokens})
Esempio n. 19
0
    def get_context_data(self, **kwargs):
        context = super(EditProfileView, self).get_context_data(**kwargs)

        # Check if user has 2fa enabled
        if default_device(self.request.user):
            context["2fa_enabled"] = True
        return context
Esempio n. 20
0
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated() or \
                (not request.user.is_verified() and default_device(request.user)):
            # If the user has not authenticated raise or redirect to the login
            # page. Also if the user just enabled two-factor authentication and
            # has not yet logged in since should also have the same result. If
            # the user receives a 'you need to enable TFA' by now, he gets
            # confuses as TFA has just been enabled. So we either raise or
            # redirect to the login page.
            if self.raise_anonymous:
                raise PermissionDenied()
            else:
                return redirect(
                    '%s?%s' %
                    (self.get_login_url(),
                     urlencode(
                         {self.redirect_field_name: request.get_full_path()})))

        if not request.user.is_verified():
            if self.raise_unverified:
                raise PermissionDenied()
            elif self.get_verification_url():
                return redirect(
                    '%s?%s' %
                    (self.verification_url,
                     urlencode(
                         {self.redirect_field_name: request.get_full_path()})))
            else:
                return TemplateResponse(
                    request=request,
                    template='two_factor/core/otp_required.html',
                    status=403,
                )
        return super(OTPRequiredMixin, self).dispatch(request, *args, **kwargs)
Esempio n. 21
0
def two_form_authentication_warnings(request, teacher):
    # For teachers using 2FA, warn if they don't have any backup tokens set, and warn solo-admins to set up another admin
    if default_device(request.user):
        # check backup tokens
        try:
            backup_tokens = request.user.staticdevice_set.all()[0].token_set.count()
        except Exception:
            backup_tokens = 0
        if not backup_tokens > 0:
            link = reverse('two_factor:profile')
            messages.warning(request,
                             'You do not have any backup tokens set up for two factor authentication, so could lose '
                             'access to your account if you have problems with your smartphone or tablet. '
                             '<a href="{link}">Set up backup tokens now</a>.'.format(link = link), extra_tags='safe')
        # check admin
        if teacher.is_admin:
            admins = Teacher.objects.filter(school=teacher.school, is_admin=True)
            manageSchoolLink = reverse('organisation_manage')
            if len(admins) == 1:
                messages.warning(request,
                                'You are the only administrator in your school and are using Two Factor Authentication '
                                '(2FA). We recommend you <a href="{manageSchoolLink}">set up another '
                                'administrator</a> who will be able to disable your 2FA should you have problems with '
                                'your smartphone or tablet.'.format(manageSchoolLink = manageSchoolLink),
                                 extra_tags='safe')
Esempio n. 22
0
    def wrapped(request, *args, **kwargs):
        u = request.user
        if (not hasattr(u, 'userprofile') or not hasattr(u.userprofile, 'teacher') or
                (not u.is_verified() and default_device(u))):
            return HttpResponseRedirect(reverse_lazy('teach'))

        return view_func(request, *args, **kwargs)
Esempio n. 23
0
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated() or \
                (not request.user.is_verified() and default_device(request.user)):
            # If the user has not authenticated raise or redirect to the login
            # page. Also if the user just enabled two-factor authentication and
            # has not yet logged in since should also have the same result. If
            # the user receives a 'you need to enable TFA' by now, he gets
            # confuses as TFA has just been enabled. So we either raise or
            # redirect to the login page.
            if self.raise_anonymous:
                raise PermissionDenied()
            else:
                return redirect('%s?%s' % (
                    self.get_login_url(),
                    urlencode({self.redirect_field_name: request.get_full_path()})
                ))

        if not request.user.is_verified():
            if self.raise_unverified:
                raise PermissionDenied()
            elif self.get_verification_url():
                return redirect('%s?%s' % (
                    self.verification_url,
                    urlencode({self.redirect_field_name: request.get_full_path()})
                ))
            else:
                return TemplateResponse(
                    request=request,
                    template='two_factor/core/otp_required.html',
                    status=403,
                )
        return super(OTPRequiredMixin, self).dispatch(request, *args, **kwargs)
Esempio n. 24
0
def profile(request):
    # Get a list of the users API Keys
    keys = ApiKey.objects.filter(user=request.user)
    try:
        backup_tokens = request.user.staticdevice_set.all()[0].token_set.count(
        )
    except IndexError:
        backup_tokens = 0

    # Get a list of the users current sessions
    sessions = request.user.session_set.filter(expire_date__gt=now())

    # Get the current session key
    session_key = request.session.session_key

    # Process the form if we have data coming in
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance=request.user.profile)
        if form.is_valid():
            form.save()
    else:
        form = UserProfileForm(instance=request.user.profile)

    # Show the template
    return render(
        request, 'account_profile.html', {
            'keys': keys,
            'sessions': sessions,
            'session_key': session_key,
            'form': form,
            'user': request.user,
            'default_device': default_device(request.user),
            'backup_tokens': backup_tokens,
        })
Esempio n. 25
0
def account(request):
    try:
        backup_tokens = request.user.staticdevice_set.all()[0].token_set.count(
        )
    except Exception:
        backup_tokens = 0

    status = {
        'default_device': default_device(request.user),
        'default_device_type': default_device(request.user).__class__.__name__,
        'backup_phones': backup_phones(request.user),
        'backup_tokens': backup_tokens,
        'site_user': request.user
    }

    return render_to_response('account.html',
                              status,
                              context_instance=RequestContext(request))
Esempio n. 26
0
    def login(self, request, redirect_url=None):
        # prevent admin users hijacking this login page to circumvent
        # two factor authentication
        if site_settings.ADMIN_ENABLED:
            if default_device(self.user):
                raise Http404

        if request.limited:
            return render(request, 'account/ratelimit_triggered.html', {})
        return super(RatelimitedLoginForm, self).login(request, redirect_url)
Esempio n. 27
0
 def process_request(self, request):
     if settings.ADMIN_ENABLED:
         allowed_urls = [reverse('admin:logout')]
         requested_url = request.get_full_path()
         two_factor_base = reverse('two_factor:profile')
         if two_factor_base not in requested_url \
            and requested_url not in allowed_urls \
            and request.user and any([request.user.is_superuser, request.user.is_staff]) \
            and not default_device(request.user):
             return HttpResponseRedirect(reverse('two_factor:setup'))
Esempio n. 28
0
 def process_request(self, request):
     if settings.ADMIN_ENABLED:
         allowed_urls = [reverse('admin:logout')]
         requested_url = request.get_full_path()
         two_factor_base = reverse('two_factor:profile')
         if two_factor_base not in requested_url \
            and requested_url not in allowed_urls \
            and request.user and any([request.user.is_superuser, request.user.is_staff]) \
            and not default_device(request.user):
                 return HttpResponseRedirect(reverse('two_factor:setup'))
Esempio n. 29
0
    def login(self, request, redirect_url=None):
        # prevent admin users hijacking this login page to circumvent
        # two factor authentication
        if site_settings.ADMIN_ENABLED:
            if default_device(self.user):
                raise Http404

        if request.limited:
            return render(request, 'account/ratelimit_triggered.html', {})
        return super(RatelimitedLoginForm, self).login(request, redirect_url)
Esempio n. 30
0
def user_login_callback(sender, request=None, user=None, **kwargs):
    if is_user_privileged(
            user
    ) and not user.require_2_fact_auth and default_device(user) is None:
        link = '<a href="%(url)s" class="alert-link">' + _('click here') + \
            '</a>' % {'url': reverse('two_factor:setup')}
        msg = mark_safe(
            _('We strongly recommend that you protect your account with Two-Factor authentication. '
              'Please %(link)s to set it up.') % {'link': link})

        if msg not in [m.message for m in messages.get_messages(request)]:
            messages.info(request, msg)
Esempio n. 31
0
    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)
        try:
            backup_tokens = self.request.user.staticdevice_set.all(
            )[0].token_set.count()
        except Exception:
            backup_tokens = 0

        data["backup_tokens"] = backup_tokens
        data["default_device"] = default_device(self.request.user)

        return data
Esempio n. 32
0
def teacher_edit_account(request):
    teacher = request.user.userprofile.teacher

    backup_tokens = 0
    # For teachers using 2FA, find out how many backup tokens they have
    if default_device(request.user):
        try:
            backup_tokens = request.user.staticdevice_set.all()[0].token_set.count()
        except Exception:
            backup_tokens = 0

    if request.method == 'POST':
        form = TeacherEditAccountForm(request.user, request.POST)
        if form.is_valid():
            data = form.cleaned_data
            changing_email=False

            # check not default value for CharField
            if (data['password'] != ''):
                teacher.user.user.set_password(data['password'])
                teacher.user.user.save()
                update_session_auth_hash(request, form.user)

            teacher.title = data['title']
            teacher.user.user.first_name = data['first_name']
            teacher.user.user.last_name = data['last_name']
            new_email = data['email']
            if new_email != '' and new_email != teacher.user.user.email:
                    # new email to set and verify
                    changing_email=True
                    send_verification_email(request, teacher.user, new_email)

            teacher.save()
            teacher.user.user.save()

            if changing_email:
                logout(request)
                messages.success(request, 'Your account details have been successfully changed. Your email will be changed once you have verified it, until then you can still log in with your old email.')
                return render(request, 'portal/email_verification_needed.html', { 'userprofile': teacher.user, 'email': new_email })

            messages.success(request, 'Your account details have been successfully changed.')

            return HttpResponseRedirect(reverse_lazy('teacher_home'))
    else:
        form = TeacherEditAccountForm(request.user, initial={
            'title' : teacher.title,
            'first_name': teacher.user.user.first_name,
            'last_name': teacher.user.user.last_name,
            'school': teacher.school,
        })

    return render(request, 'portal/teach/teacher_edit_account.html', { 'form': form, 'backup_tokens': backup_tokens })
Esempio n. 33
0
 def otp_setup(self, obj):
     if default_device(obj):
         # we can't just user method.boolean = True,
         # because we want a setup OTP link
         return format_html(
             "<img src='/assets/admin/img/icon-yes.svg' alt='True'>")
     else:
         if obj.is_staff or obj.is_superuser:
             url = reverse("two-factor-setup")
         else:
             url = reverse("two-factor-setup-redirect",
                           kwargs={"username": obj.username})
         return format_html("<a href='{url}'>Set up OTP</a>", url=url)
Esempio n. 34
0
    def get_context_data(self, **kwargs):
        if self.request.user.is_superuser and settings.HIJACK_ENABLE:
            swappable_form = BecomeUserForm()
        else:
            swappable_form = None

        show_change_password = password_management_enabled(
        ) and self.request.user.has_usable_password(),

        return super().get_context_data(
            swappable_form=swappable_form,
            default_device=default_device(self.request.user),
            show_change_password=show_change_password,
            **kwargs,
        )
Esempio n. 35
0
def perform_two_factor(backend,
                       user=None,
                       user_id=None,
                       two_factor_complete=False,
                       **kwargs):
    if not user and user_id:
        User = get_user_model()
        user = User.objects.get(id=uuid.UUID(user_id))

    if user and default_device(user) and not two_factor_complete:
        if not settings.TWO_FACTOR_ENABLED:
            raise TwoFactorDisabled(backend)
        return HttpResponseRedirect(reverse('login') + '?from-social')

    return {'user': user}
Esempio n. 36
0
    def list(self, request):
        try:
            token_set = request.user.staticdevice_set.first().token_set.all()
        except AttributeError:
            token_set = []

        return Response({
            'default': get_info_text_for_device(default_device(request.user)),
            'backup_phone_numbers': [
                {
                    'id': phone.pk,
                    'number': mask_phone_number(format_phone_number(phone.number)),
                } for phone in backup_phones(request.user)
            ],
            'backup_tokens': [token.token for token in token_set],
        })
Esempio n. 37
0
    def list(self, request):
        try:
            token_set = request.user.staticdevice_set.first().token_set.all()
        except AttributeError:
            token_set = []

        return Response({
            'default': get_info_text_for_device(default_device(request.user)),
            'backup_phone_numbers': [
                {
                    'id': phone.pk,
                    'number': mask_phone_number(format_phone_number(phone.number)),
                } for phone in backup_phones(request.user)
            ],
            'backup_tokens': [token.token for token in token_set],
        })
Esempio n. 38
0
 def get_context_data(self, **kwargs):
     return {
         **super().get_context_data(**kwargs),
         'associated': [
             BackendMeta.wrap(user_social_auth)
             for user_social_auth in self.request.user.social_auth.all()
         ],
         'two_factor_default_device':
         default_device(self.request.user),
         'social_backends':
         list(
             sorted([
                 bm for bm in backend_meta.BackendMeta.registry.values()
                 if bm.show
             ],
                    key=lambda sb: sb.name)),
     }
Esempio n. 39
0
def manage_user_view(request, user):
    user_object = get_object_or_404(get_user_model(), username=user)
    patients = list(Patient.objects.filter(user=user_object))
    context = {
        "username":
        user_object.username,
        "user_id":
        user_object.id,
        "reset_password_form":
        ResetPasswordForm(),
        "attributes": [
            {
                "key": "First Name",
                "value": user_object.first_name
            },
            {
                "key": "Last Name",
                "value": user_object.last_name
            },
            {
                "key": "Last Login",
                "value": user_object.last_login
            },
            {
                "key": "Signup Time",
                "value": user_object.date_joined
            },
            {
                "key": "Administrator",
                "value": user_object.is_superuser
            },
            {
                "key": "Account Enabled",
                "value": user_object.is_active
            },
        ],
        "patients":
        patients,
        "twofa":
        default_device(user_object),
        "disable_2fa_form":
        Disable2FAForm(),
        "addpatient_form":
        AddPatientForm(),
    }
    return render(request, "administration/manage_user.html", context)
Esempio n. 40
0
def profile(request):
    # Delete our expired keys
    ApiKey.delete_expired(user=request.user)

    # Get a list of the users API Keys
    keys = ApiKey.objects.filter(user=request.user)
    try:
        backup_tokens = request.user.staticdevice_set.all()[0].token_set.count(
        )
    except IndexError:
        backup_tokens = 0

    # Get list of current user sessions
    sessions = UserSession.objects.filter(user_id=request.user.id)

    # Get the current session key
    session_key = request.session.session_key

    # Process the form if we have data coming in
    if request.method == "POST":
        form = UserProfileForm(request.POST, instance=request.user.profile)

        if form.is_valid():
            saved_form = form.save()

            if request.FILES.getlist("icon"):
                f = request.FILES.getlist("icon")[0]
                saved_form.avatar = b64encode(f.file.read())
                saved_form.save()
    else:
        form = UserProfileForm(instance=request.user.profile)

    # Show the template
    return render(
        request,
        "account_profile.html",
        {
            "keys": keys,
            "sessions": sessions,
            "session_key": session_key,
            "form": form,
            "user": request.user,
            "default_device": default_device(request.user),
            "backup_tokens": backup_tokens,
        },
    )
Esempio n. 41
0
    def clean_otp(self, user):
        if user is None:
            return

        device = default_device(user)
        token = self.cleaned_data.get('otp_token')

        user.otp_device = None

        try:
            if self.cleaned_data.get('otp_challenge'):
                self._handle_challenge(device)
            elif token:
                user.otp_device = self._verify_token(user, token, device)
            else:
                raise forms.ValidationError(_('Please enter your OTP token.'),
                                            code='required')
        finally:
            if user.otp_device is None:
                self._update_form(user)
Esempio n. 42
0
def view(request, state_slug=''):
    try:
        state = StateEnum[state_slug.upper()]
    except KeyError:
        return redirect(
            'admin:view',
            StateEnum.WAITING_FOR_APPROVAL.name.lower(),
        )

    jobs = Job.objects.filter(state=state)
    page = AutoPaginator(request, jobs, 20).current_page()

    by_state = Job.objects.by_state()

    return render(
        request, 'admin/view.html', {
            'page': page,
            'state': state,
            'by_state': by_state,
            'default_device': default_device(request.user),
        })
Esempio n. 43
0
    def post_login(self, request, *args, **kwargs):
        next = request.POST.get('next')
        if not is_safe_url(next):
            next = settings.LOGIN_REDIRECT_URL
        form = PleioAuthenticationForm(request=request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            user = User.objects.get(email=username)
            request.session['username'] = username
            device = default_device(user)
            if not device:
                auth_login(request,
                           user,
                           backend='django.contrib.auth.backends.ModelBackend')
                return redirect(next)
            else:
                request.session['login_step'] = 'token'
                form = PleioAuthenticationTokenForm(user, request)
        else:
            for key, value in form.errors.items():
                if value[0] == 'inactive':
                    try:
                        username = request.POST.get('username')
                        user = User.objects.get(email=username)
                        user.send_activation_token()
                        return redirect('register_complete')
                    except:
                        pass
            EventLog.add_event(request, 'invalid login')

        return render(
            request, 'login.html', {
                'form': form,
                'login_step': request.session.get('login_step'),
                'reCAPTCHA': EventLog.reCAPTCHA_needed(request),
                'next': next
            })
Esempio n. 44
0
def do_two_factor_login(request: HttpRequest, user_profile: UserProfile) -> None:
    device = default_device(user_profile)
    if device:
        django_otp.login(request, device)
Esempio n. 45
0
 def get(self, request, *args, **kwargs):
     default_device(request.user).delete()
     return super(NewPhoneView, self).get(request, *args, **kwargs)
Esempio n. 46
0
def do_two_factor_login(request: HttpRequest, user_profile: UserProfile) -> None:
    device = default_device(user_profile)
    if device:
        django_otp.login(request, device)
Esempio n. 47
0
def build_page_params_for_home_page_load(
    request: HttpRequest,
    user_profile: Optional[UserProfile],
    realm: Realm,
    insecure_desktop_app: bool,
    narrow: List[List[str]],
    narrow_stream: Optional[Stream],
    narrow_topic: Optional[str],
    first_in_realm: bool,
    prompt_for_invites: bool,
    needs_tutorial: bool,
) -> Tuple[int, Dict[str, Any]]:
    """
    This function computes page_params for when we load the home page.

    The page_params data structure gets sent to the client.
    """
    client_capabilities = {
        "notification_settings_null": True,
        "bulk_message_deletion": True,
        "user_avatar_url_field_optional": True,
        "stream_typing_notifications": False,  # Set this to True when frontend support is implemented.
        "user_settings_object": True,
    }

    if user_profile is not None:
        client = RequestNotes.get_notes(request).client
        assert client is not None
        register_ret = do_events_register(
            user_profile,
            client,
            apply_markdown=True,
            client_gravatar=True,
            slim_presence=True,
            client_capabilities=client_capabilities,
            narrow=narrow,
            include_streams=False,
        )
    else:
        # Since events for spectator is not implemented, we only fetch the data
        # at the time of request and don't register for any events.
        # TODO: Implement events for spectator.
        from zerver.lib.events import fetch_initial_state_data, post_process_state

        register_ret = fetch_initial_state_data(
            user_profile,
            realm=realm,
            event_types=None,
            queue_id=None,
            client_gravatar=False,
            user_avatar_url_field_optional=client_capabilities["user_avatar_url_field_optional"],
            user_settings_object=client_capabilities["user_settings_object"],
            slim_presence=False,
            include_subscribers=False,
            include_streams=False,
        )

        post_process_state(user_profile, register_ret, False)

    furthest_read_time = get_furthest_read_time(user_profile)

    request_language = get_and_set_request_language(
        request,
        register_ret["user_settings"]["default_language"],
        translation.get_language_from_path(request.path_info),
    )

    two_fa_enabled = settings.TWO_FACTOR_AUTHENTICATION_ENABLED and user_profile is not None
    billing_info = get_billing_info(user_profile)
    user_permission_info = get_user_permission_info(user_profile)

    # Pass parameters to the client-side JavaScript code.
    # These end up in a JavaScript Object named 'page_params'.
    page_params = dict(
        ## Server settings.
        test_suite=settings.TEST_SUITE,
        insecure_desktop_app=insecure_desktop_app,
        login_page=settings.HOME_NOT_LOGGED_IN,
        warn_no_email=settings.WARN_NO_EMAIL,
        search_pills_enabled=settings.SEARCH_PILLS_ENABLED,
        # Only show marketing email settings if on Zulip Cloud
        corporate_enabled=settings.CORPORATE_ENABLED,
        ## Misc. extra data.
        language_list=get_language_list(),
        needs_tutorial=needs_tutorial,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        furthest_read_time=furthest_read_time,
        bot_types=get_bot_types(user_profile),
        two_fa_enabled=two_fa_enabled,
        apps_page_url=get_apps_page_url(),
        show_billing=billing_info.show_billing,
        promote_sponsoring_zulip=promote_sponsoring_zulip_in_realm(realm),
        show_plans=billing_info.show_plans,
        show_webathena=user_permission_info.show_webathena,
        # Adding two_fa_enabled as condition saves us 3 queries when
        # 2FA is not enabled.
        two_fa_enabled_user=two_fa_enabled and bool(default_device(user_profile)),
        is_spectator=user_profile is None,
        # There is no event queue for spectators since
        # events support for spectators is not implemented yet.
        no_event_queue=user_profile is None,
    )

    for field_name in register_ret.keys():
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = narrow_stream.recipient
        try:
            max_message_id = (
                Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id
            )
        except IndexError:
            max_message_id = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [dict(operator=term[0], operand=term[1]) for term in narrow]
        page_params["max_message_id"] = max_message_id
        assert isinstance(page_params["user_settings"], dict)
        page_params["user_settings"]["enable_desktop_notifications"] = False

    page_params["translation_data"] = get_language_translation_data(request_language)

    return register_ret["queue_id"], page_params
Esempio n. 48
0
def teach(request):
    invalid_form = False
    limits = getattr(request, 'limits', {'ip': [0], 'email': [0]})
    captcha_limit = 5

    using_captcha = (limits['ip'][0] > captcha_limit or limits['email'][0] > captcha_limit)
    should_use_captcha = (limits['ip'][0] >= captcha_limit or limits['email'][0] >= captcha_limit)

    LoginFormWithCaptcha = partial(
        create_form_subclass_with_recaptcha(TeacherLoginForm, recaptcha_client), request)
    InputLoginForm = LoginFormWithCaptcha if using_captcha else TeacherLoginForm
    OutputLoginForm = LoginFormWithCaptcha if should_use_captcha else TeacherLoginForm

    login_form = OutputLoginForm(prefix='login')
    signup_form = TeacherSignupForm(prefix='signup')

    if request.method == 'POST':
        if 'login' in request.POST:
            login_form = InputLoginForm(request.POST, prefix='login')
            if login_form.is_valid():
                userProfile = login_form.user.userprofile
                if userProfile.awaiting_email_verification:
                    send_verification_email(request, userProfile)
                    return render(request, 'portal/email_verification_needed.html',
                                  {'userprofile': userProfile})

                login(request, login_form.user)

                if default_device(request.user):
                    return render(request, 'portal/2FA_redirect.html', {
                        'form': AuthenticationForm(),
                        'username': request.user.username,
                        'password': login_form.cleaned_data['password'],
                    })
                else:
                    link = reverse('two_factor:profile')
                    messages.info(
                        request, ("You are not currently set up with two-factor authentication. "
                                  + "Use your phone or tablet to enhance your account's security. "
                                  + "Click <a href='" + link + "'>here</a> to find out more and "
                                  + "set it up or go to your account page at any time."),
                        extra_tags='safe')

                next_url = request.GET.get('next', None)
                if next_url:
                    return HttpResponseRedirect(next_url)

                return HttpResponseRedirect(reverse_lazy('teacher_home'))

            else:
                login_form = OutputLoginForm(request.POST, prefix='login')
                invalid_form = True

        if 'signup' in request.POST:
            signup_form = TeacherSignupForm(request.POST, prefix='signup')
            if signup_form.is_valid():
                data = signup_form.cleaned_data

                teacher = Teacher.objects.factory(
                    title=data['title'],
                    first_name=data['first_name'],
                    last_name=data['last_name'],
                    email=data['email'],
                    password=data['password'])

                send_verification_email(request, teacher.user)

                return render(request, 'portal/email_verification_needed.html',
                              {'userprofile': teacher.user})

    logged_in_as_teacher = hasattr(request.user, 'userprofile') and \
        hasattr(request.user.userprofile, 'teacher') and \
        (request.user.is_verified() or not default_device(request.user))

    res = render(request, 'portal/teach.html', {
        'login_form': login_form,
        'signup_form': signup_form,
        'logged_in_as_teacher': logged_in_as_teacher,
    })

    res.count = invalid_form
    return res
Esempio n. 49
0
def has_2FA(u):
    return default_device(u)
Esempio n. 50
0
 def get(self, request, *args, **kwargs):
     default_device(request.user).delete()
     return super(NewPhoneView, self).get(request, *args, **kwargs)
Esempio n. 51
0
def aggregated_data(request):

    tables = []

    table_head = ["Data description", "Value", "More info"]
    table_data = []

    """
    Overall statistics
    """

    table_data.append(
        [
            "Number of users",
            Teacher.objects.count() + Student.objects.count(),
            "Number of teachers + Number of students",
        ]
    )

    tables.append(
        {
            "title": "Overall Statistics",
            "description": "CFL site overall statistics",
            "header": table_head,
            "data": table_data,
        }
    )

    """
    School statistics
    """
    table_data = []
    table_data.append(["Number of schools signed up", School.objects.count(), ""])
    num_of_teachers_per_school = School.objects.annotate(num_teachers=Count("teacher_school"))
    stats_teachers_per_school = num_of_teachers_per_school.aggregate(Avg("num_teachers"))

    table_data.append(["Average number of teachers per school", stats_teachers_per_school["num_teachers__avg"], ""])

    tables.append({"title": "Schools or Clubs", "description": "", "header": table_head, "data": table_data})

    """
    Teacher statistics
    """
    table_data = []
    table_data.append(["Number of teachers signed up", Teacher.objects.count(), ""])
    table_data.append(["Number of teachers not in a school", Teacher.objects.filter(school=None).count(), ""])
    table_data.append(
        [
            "Number of teachers with request pending to join a school",
            Teacher.objects.exclude(pending_join_request=None).count(),
            "",
        ]
    )
    table_data.append(
        [
            "Number of teachers with unverified email address",
            Teacher.objects.filter(user__awaiting_email_verification=True).count(),
            "",
        ]
    )
    teachers = Teacher.objects.all()
    two_factor_teachers = 0
    for teacher in teachers:
        if default_device(teacher.user.user):
            two_factor_teachers += 1
    table_data.append(["Number of teachers setup with 2FA", two_factor_teachers, ""])
    num_of_classes_per_teacher = Teacher.objects.annotate(num_classes=Count("class_teacher"))
    stats_classes_per_teacher = num_of_classes_per_teacher.aggregate(Avg("num_classes"))
    num_of_classes_per_active_teacher = num_of_classes_per_teacher.exclude(school=None)
    stats_classes_per_active_teacher = num_of_classes_per_active_teacher.aggregate(Avg("num_classes"))

    table_data.append(["Average number of classes per teacher", stats_classes_per_teacher["num_classes__avg"], ""])
    table_data.append(
        [
            "Average number of classes per active teacher",
            stats_classes_per_active_teacher["num_classes__avg"],
            "Excludes teachers without a school",
        ]
    )
    table_data.append(
        ["Number of of teachers with no classes", num_of_classes_per_teacher.filter(num_classes=0).count(), ""]
    )
    table_data.append(
        [
            "Number of of active teachers with no classes",
            num_of_classes_per_active_teacher.filter(num_classes=0).count(),
            "Excludes teachers without a school",
        ]
    )

    tables.append({"title": "Teachers", "description": "", "header": table_head, "data": table_data})

    """
    Class statistics
    """
    table_data = []
    table_data.append(["Number of classes", Class.objects.count(), ""])

    num_students_per_class = Class.objects.annotate(num_students=Count("students"))
    stats_students_per_class = num_students_per_class.aggregate(Avg("num_students"))
    stats_students_per_active_class = num_students_per_class.exclude(num_students=0).aggregate(Avg("num_students"))

    table_data.append(["Average number of students per class", stats_students_per_class["num_students__avg"], ""])
    table_data.append(
        [
            "Average number of students per active class",
            stats_students_per_active_class["num_students__avg"],
            "Excludes classes which are empty",
        ]
    )

    tables.append({"title": "Classes", "description": "", "header": table_head, "data": table_data})

    """
    Student statistics
    """
    table_data = []
    table_data.append(["Number of students", Student.objects.count(), ""])

    independent_students = Student.objects.filter(class_field=None)
    table_data.append(["Number of independent students", independent_students.count(), ""])
    table_data.append(
        [
            "Number of independent students with unverified email address",
            independent_students.filter(user__awaiting_email_verification=True).count(),
            "",
        ]
    )

    table_data.append(["Number of school students", Student.objects.exclude(class_field=None).count(), ""])

    tables.append({"title": "Students", "description": "", "header": table_head, "data": table_data})

    """
    Rapid Router Student Progress statistics
    """
    table_data = []

    students_with_attempts = Student.objects.annotate(num_attempts=Count("attempts")).exclude(num_attempts=0)
    table_data.append(["Number of students who have started RR", students_with_attempts.count(), ""])

    school_students_with_attempts = students_with_attempts.exclude(class_field=None)
    table_data.append(["Number of school students who have started RR", school_students_with_attempts.count(), ""])

    independent_students_with_attempts = students_with_attempts.filter(class_field=None)
    table_data.append(
        ["Number of independent students who have started RR", independent_students_with_attempts.count(), ""]
    )

    # TODO revisit this once episodes have been restructured, as this doesn't work because of episode being a PROPERTY of level...

    # Need to filter out so we're only looking at attempts on levels that could be relevant, and don't look at null scores
    # default_level_attempts = Attempt.objects.filter(level__default=True).exclude(level__episode=None).exclude(level__episode__in_development=True).exclude(score=None)
    # table_data.append(["Average score recorded on default RR levels", default_level_attempts.aggregate(Avg('score'))['score__avg'], ""])

    # perfect_default_level_attempts = default_level_attempts.filter(score=20)
    # perfect_attempts = perfect_default_level_attempts.count()
    # all_attempts = default_level_attempts.count()
    # percentage = None
    # if all_attempts != 0:
    #   percentage =  (float(perfect_attempts)/float(all_attempts))*100
    # table_data.append(["Percentage of perfect scores on default RR levels", percentage, ""])

    # school_default_level_attempts = default_level_attempts.exclude(student__class_field=None)
    # table_data.append(["Average score recorded amongst school students on default RR levels", school_default_level_attempts.aggregate(Avg('score'))['score__avg'], ""])

    # school_perfect_default_level_attempts = school_default_level_attempts.filter(score=20)
    # school_perfect_attempts = school_perfect_default_level_attempts.count()
    # school_all_attempts = school_default_level_attempts.count()
    # percentage = None
    # if school_all_attempts != 0:
    #   percentage = (float(school_perfect_attempts)/float(school_all_attempts))*100
    # table_data.append(["Percentage of perfect scores amongst school students on default RR levels", percentage, ""])

    # independent_default_level_attempts = default_level_attempts.filter(student__class_field=None)
    # table_data.append(["Average score recorded amongst independent students on default RR levels", independent_default_level_attempts.aggregate(Avg('score'))['score__avg'], ""])

    # independent_perfect_default_level_attempts = independent_default_level_attempts.filter(score=20)
    # independent_perfect_attempts = independent_perfect_default_level_attempts.count()
    # independent_all_attempts = independent_default_level_attempts.count()
    # percentage = None
    # if independent_all_attempts != 0:
    #   percentage = (float(independent_perfect_attempts)/float(independent_all_attempts))*100
    # table_data.append(["Percentage of perfect scores amongst independent students on default RR levels", percentage, ""])

    # student_attempts_on_default_levels = default_level_attempts.values('student').annotate(num_completed=Count('level'))
    # school_student_attempts_on_default_levels = school_default_level_attempts.values('student').annotate(num_completed=Count('level'))
    # independent_student_attempts_on_default_levels =  independent_default_level_attempts.values('student').annotate(num_completed=Count('level'))

    # avg_levels_completed = student_attempts_on_default_levels.aggregate(Avg('num_completed'))['num_completed__avg']
    # table_data.append(["Average number of levels completed by students", avg_levels_completed, ""])
    # avg_levels_completed = school_student_attempts_on_default_levels.aggregate(Avg('num_completed'))['num_completed__avg']
    # table_data.append(["Average number of levels completed by school students", avg_levels_completed, ""])
    # avg_levels_completed = independent_student_attempts_on_default_levels.aggregate(Avg('num_completed'))['num_completed__avg']
    # table_data.append(["Average number of levels completed by independent students", avg_levels_completed, ""])

    # default_levels = Level.objects.filter(default=True)
    # available_levels = [level for level in default_levels if level.episode and not level.episode.in_development]
    # print len(available_levels)

    tables.append(
        {"title": "Rapid Router Student Progress", "description": "", "header": table_head, "data": table_data}
    )

    """
    Rapid Router Levels statistics
    """
    table_data = []
    num_user_levels = UserProfile.objects.annotate(num_custom_levels=Count("levels")).exclude(num_custom_levels=0)
    stats_user_levels = num_user_levels.aggregate(Avg("num_custom_levels"))

    table_data.append(["Number of users with custom levels", num_user_levels.count(), ""])
    table_data.append(
        [
            "Of users with custom levels, average number of custom levels",
            stats_user_levels["num_custom_levels__avg"],
            "",
        ]
    )

    num_teacher_levels = num_user_levels.exclude(teacher=None)
    stats_teacher_levels = num_teacher_levels.aggregate(Avg("num_custom_levels"))

    table_data.append(["Number of teachers with custom levels", num_teacher_levels.count(), ""])
    table_data.append(
        [
            "Of teachers with custom levels, average number of custom levels",
            stats_teacher_levels["num_custom_levels__avg"],
            "",
        ]
    )

    num_student_levels = num_user_levels.exclude(student=None)
    stats_student_levels = num_student_levels.aggregate(Avg("num_custom_levels"))

    table_data.append(["Number of students with custom levels", num_student_levels.count(), ""])
    table_data.append(
        [
            "Of students with custom levels, average number of custom levels",
            stats_student_levels["num_custom_levels__avg"],
            "",
        ]
    )

    num_school_student_levels = num_student_levels.exclude(student__class_field=None)
    stats_school_student_levels = num_school_student_levels.aggregate(Avg("num_custom_levels"))

    table_data.append(["Number of school students with custom levels", num_school_student_levels.count(), ""])
    table_data.append(
        [
            "Of school students with custom levels, average number of custom levels",
            stats_school_student_levels["num_custom_levels__avg"],
            "",
        ]
    )

    num_independent_student_levels = num_student_levels.filter(student__class_field=None)
    stats_independent_student_levels = num_independent_student_levels.aggregate(Avg("num_custom_levels"))

    table_data.append(["Number of independent students with custom levels", num_independent_student_levels.count(), ""])
    table_data.append(
        [
            "Of independent students with custom levels, average number of custom levels",
            stats_independent_student_levels["num_custom_levels__avg"],
            "",
        ]
    )

    tables.append({"title": "Rapid Router Levels", "description": "", "header": table_head, "data": table_data})

    return render(request, "portal/admin/aggregated_data.html", {"tables": tables})
Esempio n. 52
0
 def get(self, request, *args, **kwargs):
     default_device(request.user).delete()
     return super(TwoFactorResetView, self).get(request, *args, **kwargs)
Esempio n. 53
0
def _using_two_factor(user):
    '''Returns whether the user is using 2fa or not.'''
    return default_device(user)
Esempio n. 54
0
def logged_in_as_teacher(u):
    if not hasattr(u, 'userprofile') or not hasattr(u.userprofile, 'teacher'):
        return False

    return u.is_verified() or not default_device(u)
Esempio n. 55
0
def is_logged_in(u):
    return u.is_authenticated() and (not default_device(u) or (hasattr(u, 'is_verified') and u.is_verified()))
Esempio n. 56
0
def home_real(request: HttpRequest) -> HttpResponse:
    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    user_profile = request.user

    # If a user hasn't signed the current Terms of Service, send them there
    if settings.TERMS_OF_SERVICE is not None and settings.TOS_VERSION is not None and \
       int(settings.TOS_VERSION.split('.')[0]) > user_profile.major_tos_version():
        return accounts_accept_terms(request)

    narrow = []  # type: List[List[str]]
    narrow_stream = None
    narrow_topic = request.GET.get("topic")
    if request.GET.get("stream"):
        try:
            narrow_stream_name = request.GET.get("stream")
            (narrow_stream, ignored_rec, ignored_sub) = access_stream_by_name(
                user_profile, narrow_stream_name)
            narrow = [["stream", narrow_stream.name]]
        except Exception:
            logging.exception("Narrow parsing exception", extra=dict(request=request))
        if narrow_stream is not None and narrow_topic is not None:
            narrow.append(["topic", narrow_topic])

    register_ret = do_events_register(user_profile, request.client,
                                      apply_markdown=True, client_gravatar=True,
                                      narrow=narrow)
    user_has_messages = (register_ret['max_message_id'] != -1)

    # Reset our don't-spam-users-with-email counter since the
    # user has since logged in
    if user_profile.last_reminder is not None:  # nocoverage
        # TODO: Look into the history of last_reminder; we may have
        # eliminated that as a useful concept for non-bot users.
        user_profile.last_reminder = None
        user_profile.save(update_fields=["last_reminder"])

    # Brand new users get narrowed to PM with welcome-bot
    needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING

    first_in_realm = realm_user_count(user_profile.realm) == 1
    # If you are the only person in the realm and you didn't invite
    # anyone, we'll continue to encourage you to do so on the frontend.
    prompt_for_invites = first_in_realm and \
        not PreregistrationUser.objects.filter(referred_by=user_profile).count()

    if user_profile.pointer == -1 and user_has_messages:
        # Put the new user's pointer at the bottom
        #
        # This improves performance, because we limit backfilling of messages
        # before the pointer.  It's also likely that someone joining an
        # organization is interested in recent messages more than the very
        # first messages on the system.

        register_ret['pointer'] = register_ret['max_message_id']
        user_profile.last_pointer_updater = request.session.session_key

    if user_profile.pointer == -1:
        latest_read = None
    else:
        latest_read = get_usermessage_by_message_id(user_profile, user_profile.pointer)
        if latest_read is None:
            # Don't completely fail if your saved pointer ID is invalid
            logging.warning("%s has invalid pointer %s" % (user_profile.email, user_profile.pointer))

    # We pick a language for the user as follows:
    # * First priority is the language in the URL, for debugging.
    # * If not in the URL, we use the language from the user's settings.
    request_language = translation.get_language_from_path(request.path_info)
    if request_language is None:
        request_language = register_ret['default_language']
    translation.activate(request_language)
    # We also save the language to the user's session, so that
    # something reasonable will happen in logged-in portico pages.
    request.session[translation.LANGUAGE_SESSION_KEY] = translation.get_language()

    two_fa_enabled = settings.TWO_FACTOR_AUTHENTICATION_ENABLED
    # Pass parameters to the client-side JavaScript code.
    # These end up in a global JavaScript Object named 'page_params'.
    page_params = dict(
        # Server settings.
        development_environment = settings.DEVELOPMENT,
        debug_mode            = settings.DEBUG,
        test_suite            = settings.TEST_SUITE,
        poll_timeout          = settings.POLL_TIMEOUT,
        login_page            = settings.HOME_NOT_LOGGED_IN,
        root_domain_uri       = settings.ROOT_DOMAIN_URI,
        maxfilesize           = settings.MAX_FILE_UPLOAD_SIZE,
        max_avatar_file_size  = settings.MAX_AVATAR_FILE_SIZE,
        server_generation     = settings.SERVER_GENERATION,
        use_websockets        = settings.USE_WEBSOCKETS,
        save_stacktraces      = settings.SAVE_FRONTEND_STACKTRACES,
        warn_no_email         = settings.WARN_NO_EMAIL,
        server_inline_image_preview = settings.INLINE_IMAGE_PREVIEW,
        server_inline_url_embed_preview = settings.INLINE_URL_EMBED_PREVIEW,
        password_min_length = settings.PASSWORD_MIN_LENGTH,
        password_min_guesses  = settings.PASSWORD_MIN_GUESSES,
        jitsi_server_url      = settings.JITSI_SERVER_URL,
        search_pills_enabled  = settings.SEARCH_PILLS_ENABLED,

        # Misc. extra data.
        have_initial_messages = user_has_messages,
        initial_servertime    = time.time(),  # Used for calculating relative presence age
        default_language_name = get_language_name(register_ret['default_language']),
        language_list_dbl_col = get_language_list_for_templates(register_ret['default_language']),
        language_list         = get_language_list(),
        needs_tutorial        = needs_tutorial,
        first_in_realm        = first_in_realm,
        prompt_for_invites    = prompt_for_invites,
        furthest_read_time    = sent_time_in_epoch_seconds(latest_read),
        has_mobile_devices    = num_push_devices_for_user(user_profile) > 0,
        bot_types             = get_bot_types(user_profile),
        two_fa_enabled        = two_fa_enabled,
        # Adding two_fa_enabled as condition saves us 3 queries when
        # 2FA is not enabled.
        two_fa_enabled_user   = two_fa_enabled and bool(default_device(user_profile)),
    )

    undesired_register_ret_fields = [
        'streams',
    ]
    for field_name in set(register_ret.keys()) - set(undesired_register_ret_fields):
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = get_stream_recipient(narrow_stream.id)
        try:
            initial_pointer = Message.objects.filter(recipient=recipient).order_by('id').reverse()[0].id
        except IndexError:
            initial_pointer = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [dict(operator=term[0], operand=term[1]) for term in narrow]
        page_params["max_message_id"] = initial_pointer
        page_params["pointer"] = initial_pointer
        page_params["have_initial_messages"] = (initial_pointer != -1)
        page_params["enable_desktop_notifications"] = False

    statsd.incr('views.home')
    show_invites = True

    # Some realms only allow admins to invite users
    if user_profile.realm.invite_by_admins_only and not user_profile.is_realm_admin:
        show_invites = False
    if user_profile.is_guest:
        show_invites = False

    show_billing = False
    show_plans = False
    if settings.CORPORATE_ENABLED:
        from corporate.models import Customer
        if user_profile.is_billing_admin or user_profile.is_realm_admin:
            customer = Customer.objects.filter(realm=user_profile.realm).first()
            if customer is not None and customer.has_billing_relationship:
                show_billing = True
        if user_profile.realm.plan_type == Realm.LIMITED:
            show_plans = True

    request._log_data['extra'] = "[%s]" % (register_ret["queue_id"],)

    page_params['translation_data'] = {}
    if request_language != 'en':
        page_params['translation_data'] = get_language_translation_data(request_language)

    csp_nonce = generate_random_token(48)
    emojiset = user_profile.emojiset
    if emojiset == UserProfile.TEXT_EMOJISET:
        # If current emojiset is `TEXT_EMOJISET`, then fallback to
        # GOOGLE_EMOJISET for picking which spritesheet's CSS to
        # include (and thus how to display emojis in the emoji picker
        # and composebox typeahead).
        emojiset = UserProfile.GOOGLE_BLOB_EMOJISET
    response = render(request, 'zerver/app/index.html',
                      context={'user_profile': user_profile,
                               'emojiset': emojiset,
                               'page_params': JSONEncoderForHTML().encode(page_params),
                               'csp_nonce': csp_nonce,
                               'avatar_url': avatar_url(user_profile),
                               'show_debug':
                               settings.DEBUG and ('show_debug' in request.GET),
                               'pipeline': settings.PIPELINE_ENABLED,
                               'search_pills_enabled': settings.SEARCH_PILLS_ENABLED,
                               'show_invites': show_invites,
                               'show_billing': show_billing,
                               'show_plans': show_plans,
                               'is_admin': user_profile.is_realm_admin,
                               'is_guest': user_profile.is_guest,
                               'show_webathena': user_profile.realm.webathena_enabled,
                               'enable_feedback': settings.ENABLE_FEEDBACK,
                               'embedded': narrow_stream is not None,
                               'invite_as': PreregistrationUser.INVITE_AS,
                               },)
    patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
    return response