Esempio n. 1
0
 def test_invalid_hesiod(self) -> None:
     with mock.patch('DNS.dnslookup',
                     side_effect=DNS.Base.ServerError(
                         'DNS query status: NXDOMAIN', 3)):
         self.assertEqual(compute_mit_user_fullname("*****@*****.**"),
                          "*****@*****.**")
     with mock.patch('DNS.dnslookup',
                     side_effect=DNS.Base.ServerError(
                         'DNS query status: NXDOMAIN', 3)):
         self.assertEqual(compute_mit_user_fullname("*****@*****.**"),
                          "*****@*****.**")
Esempio n. 2
0
 def test_valid_hesiod(self) -> None:
     with mock.patch(
             'DNS.dnslookup',
             return_value=
         [[
             'starnine:*:84233:101:Athena Consulting Exchange User,,,:/mit/starnine:/bin/bash'
         ]]):
         self.assertEqual(
             compute_mit_user_fullname(self.mit_email("starnine")),
             "Athena Consulting Exchange User")
     with mock.patch(
             'DNS.dnslookup',
             return_value=
         [[
             'sipbexch:*:87824:101:Exch Sipb,,,:/mit/sipbexch:/bin/athena/bash'
         ]]):
         self.assertEqual(compute_mit_user_fullname("*****@*****.**"),
                          "Exch Sipb")
Esempio n. 3
0
def accounts_register(request):
    # type: (HttpRequest) -> HttpResponse
    key = request.POST['key']
    confirmation = Confirmation.objects.get(confirmation_key=key)
    prereg_user = confirmation.content_object
    email = prereg_user.email
    realm_creation = prereg_user.realm_creation
    password_required = prereg_user.password_required

    validators.validate_email(email)
    if prereg_user.referred_by:
        # If someone invited you, you are joining their realm regardless
        # of your e-mail address.
        realm = prereg_user.referred_by.realm
    elif realm_creation:
        # For creating a new realm, there is no existing realm or domain
        realm = None
    else:
        realm = get_realm(get_subdomain(request))

    if realm and not email_allowed_for_realm(email, realm):
        return render(request,
                      "zerver/closed_realm.html",
                      context={"closed_domain_name": realm.name})

    if realm and realm.deactivated:
        # The user is trying to register for a deactivated realm. Advise them to
        # contact support.
        return redirect_to_deactivation_notice()

    try:
        validate_email_for_realm(realm, email)
    except ValidationError:
        return HttpResponseRedirect(
            reverse('django.contrib.auth.views.login') + '?email=' +
            urllib.parse.quote_plus(email))

    name_validated = False
    full_name = None

    if request.POST.get('from_confirmation'):
        try:
            del request.session['authenticated_full_name']
        except KeyError:
            pass
        if realm is not None and realm.is_zephyr_mirror_realm:
            # For MIT users, we can get an authoritative name from Hesiod.
            # Technically we should check that this is actually an MIT
            # realm, but we can cross that bridge if we ever get a non-MIT
            # zephyr mirroring realm.
            hesiod_name = compute_mit_user_fullname(email)
            form = RegistrationForm(initial={
                'full_name':
                hesiod_name if "@" not in hesiod_name else ""
            },
                                    realm_creation=realm_creation)
            name_validated = True
        elif settings.POPULATE_PROFILE_VIA_LDAP:
            for backend in get_backends():
                if isinstance(backend, LDAPBackend):
                    ldap_attrs = _LDAPUser(
                        backend, backend.django_to_ldap_username(email)).attrs
                    try:
                        ldap_full_name = ldap_attrs[
                            settings.AUTH_LDAP_USER_ATTR_MAP['full_name']][0]
                        request.session[
                            'authenticated_full_name'] = ldap_full_name
                        name_validated = True
                        # We don't use initial= here, because if the form is
                        # complete (that is, no additional fields need to be
                        # filled out by the user) we want the form to validate,
                        # so they can be directly registered without having to
                        # go through this interstitial.
                        form = RegistrationForm({'full_name': ldap_full_name},
                                                realm_creation=realm_creation)
                        # FIXME: This will result in the user getting
                        # validation errors if they have to enter a password.
                        # Not relevant for ONLY_SSO, though.
                        break
                    except TypeError:
                        # Let the user fill out a name and/or try another backend
                        form = RegistrationForm(realm_creation=realm_creation)
        elif 'full_name' in request.POST:
            form = RegistrationForm(
                initial={'full_name': request.POST.get('full_name')},
                realm_creation=realm_creation)
        else:
            form = RegistrationForm(realm_creation=realm_creation)
    else:
        postdata = request.POST.copy()
        if name_changes_disabled(realm):
            # If we populate profile information via LDAP and we have a
            # verified name from you on file, use that. Otherwise, fall
            # back to the full name in the request.
            try:
                postdata.update(
                    {'full_name': request.session['authenticated_full_name']})
                name_validated = True
            except KeyError:
                pass
        form = RegistrationForm(postdata, realm_creation=realm_creation)
        if not (password_auth_enabled(realm) and password_required):
            form['password'].field.required = False

    if form.is_valid():
        if password_auth_enabled(realm):
            password = form.cleaned_data['password']
        else:
            # SSO users don't need no passwords
            password = None

        if realm_creation:
            string_id = form.cleaned_data['realm_subdomain']
            realm_name = form.cleaned_data['realm_name']
            realm = do_create_realm(string_id, realm_name)
            setup_initial_streams(realm)
        assert (realm is not None)

        full_name = form.cleaned_data['full_name']
        short_name = email_to_username(email)
        default_stream_group_names = request.POST.getlist(
            'default_stream_group')
        default_stream_groups = lookup_default_stream_groups(
            default_stream_group_names, realm)

        timezone = u""
        if 'timezone' in request.POST and request.POST[
                'timezone'] in get_all_timezones():
            timezone = request.POST['timezone']

        try:
            existing_user_profile = get_user_profile_by_email(email)
        except UserProfile.DoesNotExist:
            existing_user_profile = None

        return_data = {}  # type: Dict[str, bool]
        if ldap_auth_enabled(realm):
            # If the user was authenticated using an external SSO
            # mechanism like Google or GitHub auth, then authentication
            # will have already been done before creating the
            # PreregistrationUser object with password_required=False, and
            # so we don't need to worry about passwords.
            #
            # If instead the realm is using EmailAuthBackend, we will
            # set their password above.
            #
            # But if the realm is using LDAPAuthBackend, we need to verify
            # their LDAP password (which will, as a side effect, create
            # the user account) here using authenticate.
            auth_result = authenticate(request,
                                       username=email,
                                       password=password,
                                       realm_subdomain=realm.subdomain,
                                       return_data=return_data)
            if auth_result is None:
                # TODO: This probably isn't going to give a
                # user-friendly error message, but it doesn't
                # particularly matter, because the registration form
                # is hidden for most users.
                return HttpResponseRedirect(
                    reverse('django.contrib.auth.views.login') + '?email=' +
                    urllib.parse.quote_plus(email))

            # Since we'll have created a user, we now just log them in.
            return login_and_go_to_home(request, auth_result)
        elif existing_user_profile is not None and existing_user_profile.is_mirror_dummy:
            user_profile = existing_user_profile
            do_activate_user(user_profile)
            do_change_password(user_profile, password)
            do_change_full_name(user_profile, full_name, user_profile)
            do_set_user_display_setting(user_profile, 'timezone', timezone)
        else:
            user_profile = do_create_user(
                email,
                password,
                realm,
                full_name,
                short_name,
                prereg_user=prereg_user,
                is_realm_admin=realm_creation,
                tos_version=settings.TOS_VERSION,
                timezone=timezone,
                newsletter_data={"IP": request.META['REMOTE_ADDR']},
                default_stream_groups=default_stream_groups)

        if realm_creation:
            setup_initial_private_stream(user_profile)
            send_initial_realm_messages(realm)

        if realm_creation:
            # Because for realm creation, registration happens on the
            # root domain, we need to log them into the subdomain for
            # their new realm.
            return redirect_and_log_into_subdomain(realm, full_name, email)

        # This dummy_backend check below confirms the user is
        # authenticating to the correct subdomain.
        auth_result = authenticate(username=user_profile.email,
                                   realm_subdomain=realm.subdomain,
                                   return_data=return_data,
                                   use_dummy_backend=True)
        if return_data.get('invalid_subdomain'):
            # By construction, this should never happen.
            logging.error("Subdomain mismatch in registration %s: %s" % (
                realm.subdomain,
                user_profile.email,
            ))
            return redirect('/')

        return login_and_go_to_home(request, auth_result)

    return render(
        request,
        'zerver/register.html',
        context={
            'form': form,
            'email': email,
            'key': key,
            'full_name': request.session.get('authenticated_full_name', None),
            'lock_name': name_validated and name_changes_disabled(realm),
            # password_auth_enabled is normally set via our context processor,
            # but for the registration form, there is no logged in user yet, so
            # we have to set it here.
            'creating_new_team': realm_creation,
            'password_required': password_auth_enabled(realm)
            and password_required,
            'password_auth_enabled': password_auth_enabled(realm),
            'root_domain_available': is_root_domain_available(),
            'default_stream_groups': get_default_stream_groups(realm),
            'MAX_REALM_NAME_LENGTH': str(Realm.MAX_REALM_NAME_LENGTH),
            'MAX_NAME_LENGTH': str(UserProfile.MAX_NAME_LENGTH),
            'MAX_PASSWORD_LENGTH': str(form.MAX_PASSWORD_LENGTH),
            'MAX_REALM_SUBDOMAIN_LENGTH': str(Realm.MAX_REALM_SUBDOMAIN_LENGTH)
        })
Esempio n. 4
0
def accounts_register(request):
    # type: (HttpRequest) -> HttpResponse
    key = request.POST['key']
    confirmation = Confirmation.objects.get(confirmation_key=key)
    prereg_user = confirmation.content_object
    email = prereg_user.email
    realm_creation = prereg_user.realm_creation
    try:
        existing_user_profile = get_user_profile_by_email(email)
    except UserProfile.DoesNotExist:
        existing_user_profile = None

    validators.validate_email(email)
    # If OPEN_REALM_CREATION is enabled all user sign ups should go through the
    # special URL with domain name so that REALM can be identified if multiple realms exist
    unique_open_realm = get_unique_open_realm()
    if unique_open_realm is not None:
        realm = unique_open_realm
    elif prereg_user.referred_by:
        # If someone invited you, you are joining their realm regardless
        # of your e-mail address.
        realm = prereg_user.referred_by.realm
    elif prereg_user.realm:
        # You have a realm set, even though nobody referred you. This
        # happens if you sign up through a special URL for an open realm.
        realm = prereg_user.realm
    elif realm_creation:
        # For creating a new realm, there is no existing realm or domain
        realm = None
    elif settings.REALMS_HAVE_SUBDOMAINS:
        realm = get_realm(get_subdomain(request))
    else:
        realm = get_realm_by_email_domain(email)

    if realm and not email_allowed_for_realm(email, realm):
        return render(request,
                      "zerver/closed_realm.html",
                      context={"closed_domain_name": realm.name})

    if realm and realm.deactivated:
        # The user is trying to register for a deactivated realm. Advise them to
        # contact support.
        return render(request,
                      "zerver/deactivated.html",
                      context={
                          "deactivated_domain_name": realm.name,
                          "zulip_administrator": settings.ZULIP_ADMINISTRATOR
                      })

    try:
        if existing_user_profile is not None and existing_user_profile.is_mirror_dummy:
            # Mirror dummy users to be activated must be inactive
            is_inactive(email)
        else:
            # Other users should not already exist at all.
            user_email_is_unique(email)
    except ValidationError:
        return HttpResponseRedirect(
            reverse('django.contrib.auth.views.login') + '?email=' +
            urllib.parse.quote_plus(email))

    name_validated = False
    full_name = None

    if request.POST.get('from_confirmation'):
        try:
            del request.session['authenticated_full_name']
        except KeyError:
            pass
        if realm is not None and realm.is_zephyr_mirror_realm:
            # For MIT users, we can get an authoritative name from Hesiod.
            # Technically we should check that this is actually an MIT
            # realm, but we can cross that bridge if we ever get a non-MIT
            # zephyr mirroring realm.
            hesiod_name = compute_mit_user_fullname(email)
            form = RegistrationForm(
                initial={
                    'full_name': hesiod_name if "@" not in hesiod_name else ""
                })
            name_validated = True
        elif settings.POPULATE_PROFILE_VIA_LDAP:
            for backend in get_backends():
                if isinstance(backend, LDAPBackend):
                    ldap_attrs = _LDAPUser(
                        backend, backend.django_to_ldap_username(email)).attrs
                    try:
                        ldap_full_name = ldap_attrs[
                            settings.AUTH_LDAP_USER_ATTR_MAP['full_name']][0]
                        request.session[
                            'authenticated_full_name'] = ldap_full_name
                        name_validated = True
                        # We don't use initial= here, because if the form is
                        # complete (that is, no additional fields need to be
                        # filled out by the user) we want the form to validate,
                        # so they can be directly registered without having to
                        # go through this interstitial.
                        form = RegistrationForm({'full_name': ldap_full_name})
                        # FIXME: This will result in the user getting
                        # validation errors if they have to enter a password.
                        # Not relevant for ONLY_SSO, though.
                        break
                    except TypeError:
                        # Let the user fill out a name and/or try another backend
                        form = RegistrationForm()
        elif 'full_name' in request.POST:
            form = RegistrationForm(
                initial={'full_name': request.POST.get('full_name')})
        else:
            form = RegistrationForm()
    else:
        postdata = request.POST.copy()
        if name_changes_disabled(realm):
            # If we populate profile information via LDAP and we have a
            # verified name from you on file, use that. Otherwise, fall
            # back to the full name in the request.
            try:
                postdata.update(
                    {'full_name': request.session['authenticated_full_name']})
                name_validated = True
            except KeyError:
                pass
        form = RegistrationForm(postdata)
        if not password_auth_enabled(realm):
            form['password'].field.required = False

    if form.is_valid():
        if password_auth_enabled(realm):
            password = form.cleaned_data['password']
        else:
            # SSO users don't need no passwords
            password = None

        if realm_creation:
            string_id = form.cleaned_data['realm_subdomain']
            realm_name = form.cleaned_data['realm_name']
            org_type = int(form.cleaned_data['realm_org_type'])
            realm = do_create_realm(string_id, realm_name,
                                    org_type=org_type)[0]

            set_default_streams(realm, settings.DEFAULT_NEW_REALM_STREAMS)

        full_name = form.cleaned_data['full_name']
        short_name = email_to_username(email)
        first_in_realm = len(
            UserProfile.objects.filter(realm=realm, is_bot=False)) == 0

        # FIXME: sanitize email addresses and fullname
        if existing_user_profile is not None and existing_user_profile.is_mirror_dummy:
            user_profile = existing_user_profile
            do_activate_user(user_profile)
            do_change_password(user_profile, password)
            do_change_full_name(user_profile, full_name)
        else:
            user_profile = do_create_user(
                email,
                password,
                realm,
                full_name,
                short_name,
                prereg_user=prereg_user,
                tos_version=settings.TOS_VERSION,
                newsletter_data={"IP": request.META['REMOTE_ADDR']})

        if first_in_realm:
            do_change_is_admin(user_profile, True)

        if realm_creation and settings.REALMS_HAVE_SUBDOMAINS:
            # Because for realm creation, registration happens on the
            # root domain, we need to log them into the subdomain for
            # their new realm.
            return redirect_and_log_into_subdomain(realm, full_name, email)

        # This dummy_backend check below confirms the user is
        # authenticating to the correct subdomain.
        return_data = {}  # type: Dict[str, bool]
        auth_result = authenticate(username=user_profile.email,
                                   realm_subdomain=realm.subdomain,
                                   return_data=return_data,
                                   use_dummy_backend=True)
        if return_data.get('invalid_subdomain'):
            # By construction, this should never happen.
            logging.error("Subdomain mismatch in registration %s: %s" % (
                realm.subdomain,
                user_profile.email,
            ))
            return redirect('/')
        login(request, auth_result)
        return HttpResponseRedirect(realm.uri +
                                    reverse('zerver.views.home.home'))

    return render(
        request,
        'zerver/register.html',
        context={
            'form': form,
            'email': email,
            'key': key,
            'full_name': request.session.get('authenticated_full_name', None),
            'lock_name': name_validated and name_changes_disabled(realm),
            # password_auth_enabled is normally set via our context processor,
            # but for the registration form, there is no logged in user yet, so
            # we have to set it here.
            'creating_new_team': realm_creation,
            'realms_have_subdomains': settings.REALMS_HAVE_SUBDOMAINS,
            'password_auth_enabled': password_auth_enabled(realm),
            'MAX_REALM_NAME_LENGTH': str(Realm.MAX_REALM_NAME_LENGTH),
            'MAX_NAME_LENGTH': str(UserProfile.MAX_NAME_LENGTH),
            'MAX_PASSWORD_LENGTH': str(form.MAX_PASSWORD_LENGTH),
            'MAX_REALM_SUBDOMAIN_LENGTH': str(Realm.MAX_REALM_SUBDOMAIN_LENGTH)
        })
Esempio n. 5
0
def accounts_register(request: HttpRequest) -> HttpResponse:
    key = request.POST['key']
    confirmation = Confirmation.objects.get(confirmation_key=key)
    prereg_user = confirmation.content_object
    email = prereg_user.email
    realm_creation = prereg_user.realm_creation
    password_required = prereg_user.password_required
    is_realm_admin = prereg_user.invited_as_admin or realm_creation

    try:
        validators.validate_email(email)
    except ValidationError:
        return render(request, "zerver/invalid_email.html", context={"invalid_email": True})

    if realm_creation:
        # For creating a new realm, there is no existing realm or domain
        realm = None
    else:
        realm = get_realm(get_subdomain(request))
        if realm is None or realm != prereg_user.realm:
            return render_confirmation_key_error(
                request, ConfirmationKeyException(ConfirmationKeyException.DOES_NOT_EXIST))

        try:
            email_allowed_for_realm(email, realm)
        except DomainNotAllowedForRealmError:
            return render(request, "zerver/invalid_email.html",
                          context={"realm_name": realm.name, "closed_domain": True})
        except DisposableEmailError:
            return render(request, "zerver/invalid_email.html",
                          context={"realm_name": realm.name, "disposable_emails_not_allowed": True})
        except EmailContainsPlusError:
            return render(request, "zerver/invalid_email.html",
                          context={"realm_name": realm.name, "email_contains_plus": True})

        if realm.deactivated:
            # The user is trying to register for a deactivated realm. Advise them to
            # contact support.
            return redirect_to_deactivation_notice()

        try:
            validate_email_for_realm(realm, email)
        except ValidationError:  # nocoverage # We need to add a test for this.
            return HttpResponseRedirect(reverse('django.contrib.auth.views.login') + '?email=' +
                                        urllib.parse.quote_plus(email))

    name_validated = False
    full_name = None

    if request.POST.get('from_confirmation'):
        try:
            del request.session['authenticated_full_name']
        except KeyError:
            pass
        if realm is not None and realm.is_zephyr_mirror_realm:
            # For MIT users, we can get an authoritative name from Hesiod.
            # Technically we should check that this is actually an MIT
            # realm, but we can cross that bridge if we ever get a non-MIT
            # zephyr mirroring realm.
            hesiod_name = compute_mit_user_fullname(email)
            form = RegistrationForm(
                initial={'full_name': hesiod_name if "@" not in hesiod_name else ""},
                realm_creation=realm_creation)
            name_validated = True
        elif settings.POPULATE_PROFILE_VIA_LDAP:
            for backend in get_backends():
                if isinstance(backend, LDAPBackend):
                    try:
                        ldap_username = backend.django_to_ldap_username(email)
                    except ZulipLDAPException:
                        logging.warning("New account email %s could not be found in LDAP" % (email,))
                        form = RegistrationForm(realm_creation=realm_creation)
                        break

                    ldap_attrs = _LDAPUser(backend, ldap_username).attrs

                    try:
                        ldap_full_name = ldap_attrs[settings.AUTH_LDAP_USER_ATTR_MAP['full_name']][0]
                        request.session['authenticated_full_name'] = ldap_full_name
                        name_validated = True
                        # We don't use initial= here, because if the form is
                        # complete (that is, no additional fields need to be
                        # filled out by the user) we want the form to validate,
                        # so they can be directly registered without having to
                        # go through this interstitial.
                        form = RegistrationForm({'full_name': ldap_full_name},
                                                realm_creation=realm_creation)
                        # FIXME: This will result in the user getting
                        # validation errors if they have to enter a password.
                        # Not relevant for ONLY_SSO, though.
                        break
                    except TypeError:
                        # Let the user fill out a name and/or try another backend
                        form = RegistrationForm(realm_creation=realm_creation)
        elif 'full_name' in request.POST:
            form = RegistrationForm(
                initial={'full_name': request.POST.get('full_name')},
                realm_creation=realm_creation
            )
        else:
            form = RegistrationForm(realm_creation=realm_creation)
    else:
        postdata = request.POST.copy()
        if name_changes_disabled(realm):
            # If we populate profile information via LDAP and we have a
            # verified name from you on file, use that. Otherwise, fall
            # back to the full name in the request.
            try:
                postdata.update({'full_name': request.session['authenticated_full_name']})
                name_validated = True
            except KeyError:
                pass
        form = RegistrationForm(postdata, realm_creation=realm_creation)
        if not (password_auth_enabled(realm) and password_required):
            form['password'].field.required = False

    if form.is_valid():
        if password_auth_enabled(realm):
            password = form.cleaned_data['password']
        else:
            # SSO users don't need no passwords
            password = None

        if realm_creation:
            string_id = form.cleaned_data['realm_subdomain']
            realm_name = form.cleaned_data['realm_name']
            realm = do_create_realm(string_id, realm_name)
            setup_initial_streams(realm)
            setup_realm_internal_bots(realm)
        assert(realm is not None)

        full_name = form.cleaned_data['full_name']
        short_name = email_to_username(email)
        default_stream_group_names = request.POST.getlist('default_stream_group')
        default_stream_groups = lookup_default_stream_groups(default_stream_group_names, realm)

        timezone = ""
        if 'timezone' in request.POST and request.POST['timezone'] in get_all_timezones():
            timezone = request.POST['timezone']

        if 'source_realm' in request.POST and request.POST["source_realm"] != "on":
            source_profile = get_source_profile(email, request.POST["source_realm"])
        else:
            source_profile = None

        if not realm_creation:
            try:
                existing_user_profile = get_user(email, realm)  # type: Optional[UserProfile]
            except UserProfile.DoesNotExist:
                existing_user_profile = None
        else:
            existing_user_profile = None

        return_data = {}  # type: Dict[str, bool]
        if ldap_auth_enabled(realm):
            # If the user was authenticated using an external SSO
            # mechanism like Google or GitHub auth, then authentication
            # will have already been done before creating the
            # PreregistrationUser object with password_required=False, and
            # so we don't need to worry about passwords.
            #
            # If instead the realm is using EmailAuthBackend, we will
            # set their password above.
            #
            # But if the realm is using LDAPAuthBackend, we need to verify
            # their LDAP password (which will, as a side effect, create
            # the user account) here using authenticate.
            auth_result = authenticate(request,
                                       username=email,
                                       password=password,
                                       realm=realm,
                                       return_data=return_data)
            if auth_result is not None:
                # Since we'll have created a user, we now just log them in.
                return login_and_go_to_home(request, auth_result)

            if return_data.get("outside_ldap_domain") and email_auth_enabled(realm):
                # If both the LDAP and Email auth backends are
                # enabled, and the user's email is outside the LDAP
                # domain, then the intent is to create a user in the
                # realm with their email outside the LDAP organization
                # (with e.g. a password stored in the Zulip database,
                # not LDAP).  So we fall through and create the new
                # account.
                #
                # It's likely that we can extend this block to the
                # Google and GitHub auth backends with no code changes
                # other than here.
                pass
            else:
                # TODO: This probably isn't going to give a
                # user-friendly error message, but it doesn't
                # particularly matter, because the registration form
                # is hidden for most users.
                return HttpResponseRedirect(reverse('django.contrib.auth.views.login') + '?email=' +
                                            urllib.parse.quote_plus(email))

        if existing_user_profile is not None and existing_user_profile.is_mirror_dummy:
            user_profile = existing_user_profile
            do_activate_user(user_profile)
            do_change_password(user_profile, password)
            do_change_full_name(user_profile, full_name, user_profile)
            do_set_user_display_setting(user_profile, 'timezone', timezone)
            # TODO: When we clean up the `do_activate_user` code path,
            # make it respect invited_as_admin / is_realm_admin.
        else:
            user_profile = do_create_user(email, password, realm, full_name, short_name,
                                          prereg_user=prereg_user, is_realm_admin=is_realm_admin,
                                          tos_version=settings.TOS_VERSION,
                                          timezone=timezone,
                                          newsletter_data={"IP": request.META['REMOTE_ADDR']},
                                          default_stream_groups=default_stream_groups,
                                          source_profile=source_profile)

        if realm_creation:
            bulk_add_subscriptions([realm.signup_notifications_stream], [user_profile])
            send_initial_realm_messages(realm)

            # Because for realm creation, registration happens on the
            # root domain, we need to log them into the subdomain for
            # their new realm.
            return redirect_and_log_into_subdomain(realm, full_name, email)

        # This dummy_backend check below confirms the user is
        # authenticating to the correct subdomain.
        auth_result = authenticate(username=user_profile.email,
                                   realm=realm,
                                   return_data=return_data,
                                   use_dummy_backend=True)
        if return_data.get('invalid_subdomain'):
            # By construction, this should never happen.
            logging.error("Subdomain mismatch in registration %s: %s" % (
                realm.subdomain, user_profile.email,))
            return redirect('/')

        return login_and_go_to_home(request, auth_result)

    return render(
        request,
        'zerver/register.html',
        context={'form': form,
                 'email': email,
                 'key': key,
                 'full_name': request.session.get('authenticated_full_name', None),
                 'lock_name': name_validated and name_changes_disabled(realm),
                 # password_auth_enabled is normally set via our context processor,
                 # but for the registration form, there is no logged in user yet, so
                 # we have to set it here.
                 'creating_new_team': realm_creation,
                 'password_required': password_auth_enabled(realm) and password_required,
                 'password_auth_enabled': password_auth_enabled(realm),
                 'root_domain_available': is_root_domain_available(),
                 'default_stream_groups': get_default_stream_groups(realm),
                 'accounts': get_accounts_for_email(email),
                 'MAX_REALM_NAME_LENGTH': str(Realm.MAX_REALM_NAME_LENGTH),
                 'MAX_NAME_LENGTH': str(UserProfile.MAX_NAME_LENGTH),
                 'MAX_PASSWORD_LENGTH': str(form.MAX_PASSWORD_LENGTH),
                 'MAX_REALM_SUBDOMAIN_LENGTH': str(Realm.MAX_REALM_SUBDOMAIN_LENGTH)
                 }
    )
Esempio n. 6
0
def accounts_register(request):
    # type: (HttpRequest) -> HttpResponse
    key = request.POST['key']
    confirmation = Confirmation.objects.get(confirmation_key=key)
    prereg_user = confirmation.content_object
    email = prereg_user.email
    realm_creation = prereg_user.realm_creation
    try:
        existing_user_profile = get_user_profile_by_email(email)
    except UserProfile.DoesNotExist:
        existing_user_profile = None

    validators.validate_email(email)
    # If OPEN_REALM_CREATION is enabled all user sign ups should go through the
    # special URL with domain name so that REALM can be identified if multiple realms exist
    unique_open_realm = get_unique_open_realm()
    if unique_open_realm is not None:
        realm = unique_open_realm
        domain = realm.domain
    elif prereg_user.referred_by:
        # If someone invited you, you are joining their realm regardless
        # of your e-mail address.
        realm = prereg_user.referred_by.realm
        domain = realm.domain
        if not email_allowed_for_realm(email, realm):
            return render_to_response("zerver/closed_realm.html", {"closed_domain_name": realm.name})
    elif prereg_user.realm:
        # You have a realm set, even though nobody referred you. This
        # happens if you sign up through a special URL for an open
        # realm.
        domain = prereg_user.realm.domain
        realm = get_realm(domain)
    else:
        domain = resolve_email_to_domain(email)
        realm = get_realm(domain)

    if realm and realm.deactivated:
        # The user is trying to register for a deactivated realm. Advise them to
        # contact support.
        return render_to_response("zerver/deactivated.html",
                                  {"deactivated_domain_name": realm.name,
                                   "zulip_administrator": settings.ZULIP_ADMINISTRATOR})

    try:
        if existing_user_profile is not None and existing_user_profile.is_mirror_dummy:
            # Mirror dummy users to be activated must be inactive
            is_inactive(email)
        else:
            # Other users should not already exist at all.
            user_email_is_unique(email)
    except ValidationError:
        return HttpResponseRedirect(reverse('django.contrib.auth.views.login') + '?email=' +
                                    urllib.parse.quote_plus(email))

    name_validated = False
    full_name = None

    if request.POST.get('from_confirmation'):
        try:
            del request.session['authenticated_full_name']
        except KeyError:
            pass
        if realm is not None and realm.is_zephyr_mirror_realm and domain == "mit.edu":
            # for MIT users, we can get an authoritative name from Hesiod
            hesiod_name = compute_mit_user_fullname(email)
            form = RegistrationForm(
                    initial={'full_name': hesiod_name if "@" not in hesiod_name else ""})
            name_validated = True
        elif settings.POPULATE_PROFILE_VIA_LDAP:
            for backend in get_backends():
                if isinstance(backend, LDAPBackend):
                    ldap_attrs = _LDAPUser(backend, backend.django_to_ldap_username(email)).attrs
                    try:
                        ldap_full_name = ldap_attrs[settings.AUTH_LDAP_USER_ATTR_MAP['full_name']][0]
                        request.session['authenticated_full_name'] = ldap_full_name
                        name_validated = True
                        # We don't use initial= here, because if the form is
                        # complete (that is, no additional fields need to be
                        # filled out by the user) we want the form to validate,
                        # so they can be directly registered without having to
                        # go through this interstitial.
                        form = RegistrationForm({'full_name': ldap_full_name})
                        # FIXME: This will result in the user getting
                        # validation errors if they have to enter a password.
                        # Not relevant for ONLY_SSO, though.
                        break
                    except TypeError:
                        # Let the user fill out a name and/or try another backend
                        form = RegistrationForm()
        elif 'full_name' in request.POST:
            form = RegistrationForm(
                initial={'full_name': request.POST.get('full_name')}
            )
        else:
            form = RegistrationForm()
    else:
        postdata = request.POST.copy()
        if name_changes_disabled(realm):
            # If we populate profile information via LDAP and we have a
            # verified name from you on file, use that. Otherwise, fall
            # back to the full name in the request.
            try:
                postdata.update({'full_name': request.session['authenticated_full_name']})
                name_validated = True
            except KeyError:
                pass
        form = RegistrationForm(postdata)
        if not password_auth_enabled(realm):
            form['password'].field.required = False

    if form.is_valid():
        if password_auth_enabled(realm):
            password = form.cleaned_data['password']
        else:
            # SSO users don't need no passwords
            password = None

        if realm_creation:
            string_id = form.cleaned_data['realm_subdomain']
            realm_name = form.cleaned_data['realm_name']
            org_type = int(form.cleaned_data['realm_org_type'])
            domain = split_email_to_domain(email)
            realm = do_create_realm(string_id, realm_name, org_type=org_type,
                                    domain=domain)[0]

            set_default_streams(realm, settings.DEFAULT_NEW_REALM_STREAMS)

        full_name = form.cleaned_data['full_name']
        short_name = email_to_username(email)
        first_in_realm = len(UserProfile.objects.filter(realm=realm, is_bot=False)) == 0

        # FIXME: sanitize email addresses and fullname
        if existing_user_profile is not None and existing_user_profile.is_mirror_dummy:
            try:
                user_profile = existing_user_profile
                do_activate_user(user_profile)
                do_change_password(user_profile, password)
                do_change_full_name(user_profile, full_name)
            except UserProfile.DoesNotExist:
                user_profile = do_create_user(email, password, realm, full_name, short_name,
                                              prereg_user=prereg_user,
                                              tos_version=settings.TOS_VERSION,
                                              newsletter_data={"IP": request.META['REMOTE_ADDR']})
        else:
            user_profile = do_create_user(email, password, realm, full_name, short_name,
                                          prereg_user=prereg_user,
                                          tos_version=settings.TOS_VERSION,
                                          newsletter_data={"IP": request.META['REMOTE_ADDR']})

        if first_in_realm:
            do_change_is_admin(user_profile, True)

        if realm_creation and settings.REALMS_HAVE_SUBDOMAINS:
            # Because for realm creation, registration happens on the
            # root domain, we need to log them into the subdomain for
            # their new realm.
            return redirect_and_log_into_subdomain(realm, full_name, email)

        # This dummy_backend check below confirms the user is
        # authenticating to the correct subdomain.
        return_data = {} # type: Dict[str, bool]
        auth_result = authenticate(username=user_profile.email,
                                   realm_subdomain=realm.subdomain,
                                   return_data=return_data,
                                   use_dummy_backend=True)
        if return_data.get('invalid_subdomain'):
            # By construction, this should never happen.
            logging.error("Subdomain mismatch in registration %s: %s" % (
                realm.subdomain, user_profile.email,))
            return redirect('/')
        login(request, auth_result)
        return HttpResponseRedirect(realm.uri + reverse('zerver.views.home'))

    return render_to_response('zerver/register.html',
            {'form': form,
             'company_name': domain,
             'email': email,
             'key': key,
             'full_name': request.session.get('authenticated_full_name', None),
             'lock_name': name_validated and name_changes_disabled(realm),
             # password_auth_enabled is normally set via our context processor,
             # but for the registration form, there is no logged in user yet, so
             # we have to set it here.
             'creating_new_team': realm_creation,
             'realms_have_subdomains': settings.REALMS_HAVE_SUBDOMAINS,
             'password_auth_enabled': password_auth_enabled(realm),
            },
        request=request)
Esempio n. 7
0
 def test_invalid_hesiod(self) -> None:
     with mock.patch('DNS.dnslookup', side_effect=DNS.Base.ServerError('DNS query status: NXDOMAIN', 3)):
         self.assertEqual(compute_mit_user_fullname("*****@*****.**"), "*****@*****.**")
     with mock.patch('DNS.dnslookup', side_effect=DNS.Base.ServerError('DNS query status: NXDOMAIN', 3)):
         self.assertEqual(compute_mit_user_fullname("*****@*****.**"), "*****@*****.**")
Esempio n. 8
0
 def test_valid_hesiod(self) -> None:
     with mock.patch('DNS.dnslookup', return_value=[['starnine:*:84233:101:Athena Consulting Exchange User,,,:/mit/starnine:/bin/bash']]):
         self.assertEqual(compute_mit_user_fullname(self.mit_email("starnine")), "Athena Consulting Exchange User")
     with mock.patch('DNS.dnslookup', return_value=[['sipbexch:*:87824:101:Exch Sipb,,,:/mit/sipbexch:/bin/athena/bash']]):
         self.assertEqual(compute_mit_user_fullname("*****@*****.**"), "Exch Sipb")
Esempio n. 9
0
 def test_invalid_hesiod(self):
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"), "*****@*****.**")
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"), "*****@*****.**")
Esempio n. 10
0
 def test_valid_hesiod(self):
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"), "Athena Consulting Exchange User")
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"), "Exch Sipb")
Esempio n. 11
0
 def test_invalid_hesiod(self):
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"),
                       "*****@*****.**")
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"),
                       "*****@*****.**")
Esempio n. 12
0
 def test_valid_hesiod(self):
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"),
                       "Athena Consulting Exchange User")
     self.assertEquals(compute_mit_user_fullname("*****@*****.**"),
                       "Exch Sipb")