コード例 #1
0
    def handle(self, **options):
        # type: (**Any) -> None
        string_id = 'realm%02d' % (
            Realm.objects.filter(string_id__startswith='realm').count(),)
        realm = do_create_realm(string_id, string_id)
        setup_initial_streams(realm)

        name = '%02d-user' % (
            UserProfile.objects.filter(email__contains='user@').count(),)
        user = do_create_user('%s@%s.zulip.com' % (name, string_id),
                              'password', realm, name, name, is_realm_admin=True)
        send_initial_pms(user)
        setup_initial_private_stream(user)

        send_initial_realm_messages(realm)
コード例 #2
0
ファイル: add_new_user.py プロジェクト: waveyuk/zulip
    def handle(self, **options):
        # type: (**Any) -> None
        realm = self.get_realm(options)
        if realm is None:
            realm = Realm.objects.filter(string_id__startswith='realm') \
                                 .order_by('-string_id').first()
        if realm is None:
            print('Warning: Using default zulip realm, which has an unusual configuration.\n'
                  'Try running `python manage.py add_new_realm`, and then running this again.')
            realm = Realm.objects.get(string_id='zulip')
            domain = 'zulip.com'
        else:
            domain = realm.string_id + '.zulip.com'

        name = '%02d-user' % (UserProfile.objects.filter(email__contains='user@').count(),)
        user = do_create_user('%s@%s' % (name, domain),
                              'password', realm, name, name)
        send_initial_pms(user)
コード例 #3
0
ファイル: backends.py プロジェクト: waveyuk/zulip
    def get_or_create_user(self, username, ldap_user):
        # type: (str, _LDAPUser) -> Tuple[UserProfile, bool]
        try:
            if settings.LDAP_EMAIL_ATTR is not None:
                # Get email from ldap attributes.
                if settings.LDAP_EMAIL_ATTR not in ldap_user.attrs:
                    raise ZulipLDAPException("LDAP user doesn't have the needed %s attribute" % (settings.LDAP_EMAIL_ATTR,))

                username = ldap_user.attrs[settings.LDAP_EMAIL_ATTR][0]

            user_profile = get_user_profile_by_email(username)
            if not user_profile.is_active or user_profile.realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")
            if not ldap_auth_enabled(user_profile.realm):
                raise ZulipLDAPException("LDAP Authentication is not enabled")
            return user_profile, False
        except UserProfile.DoesNotExist:
            if self._realm is None:
                raise ZulipLDAPConfigurationError("Realm is None", self.REALM_IS_NONE_ERROR)
            # No need to check for an inactive user since they don't exist yet
            if self._realm.deactivated:
                raise ZulipLDAPException("Realm has been deactivated")

            full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
            short_name = full_name = ldap_user.attrs[full_name_attr][0]
            try:
                full_name = check_full_name(full_name)
            except JsonableError as e:
                raise ZulipLDAPException(e.msg)
            if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
                short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
                short_name = ldap_user.attrs[short_name_attr][0]

            user_profile = do_create_user(username, None, self._realm, full_name, short_name)
            send_initial_pms(user_profile)

            return user_profile, True
コード例 #4
0
ファイル: create_user.py プロジェクト: priyank-p/zulip
def process_new_human_user(
    user_profile: UserProfile,
    prereg_user: Optional[PreregistrationUser] = None,
    default_stream_groups: Sequence[DefaultStreamGroup] = [],
    realm_creation: bool = False,
) -> None:
    realm = user_profile.realm

    mit_beta_user = realm.is_zephyr_mirror_realm
    if prereg_user is not None:
        streams: List[Stream] = list(prereg_user.streams.all())
        acting_user: Optional[UserProfile] = prereg_user.referred_by

        # A PregistrationUser should not be used for another UserProfile
        assert prereg_user.created_user is None, "PregistrationUser should not be reused"
    else:
        streams = []
        acting_user = None

    # If the user's invitation didn't explicitly list some streams, we
    # add the default streams
    if len(streams) == 0:
        streams = get_default_subs(user_profile)

    for default_stream_group in default_stream_groups:
        default_stream_group_streams = default_stream_group.streams.all()
        for stream in default_stream_group_streams:
            if stream not in streams:
                streams.append(stream)

    bulk_add_subscriptions(
        realm,
        streams,
        [user_profile],
        from_user_creation=True,
        acting_user=acting_user,
    )

    add_new_user_history(user_profile, streams)

    # mit_beta_users don't have a referred_by field
    if (not mit_beta_user and prereg_user is not None
            and prereg_user.referred_by is not None
            and prereg_user.referred_by.is_active):
        # This is a cross-realm private message.
        with override_language(prereg_user.referred_by.default_language):
            internal_send_private_message(
                get_system_bot(settings.NOTIFICATION_BOT,
                               prereg_user.referred_by.realm_id),
                prereg_user.referred_by,
                _("{user} accepted your invitation to join Zulip!").format(
                    user=f"{user_profile.full_name} <`{user_profile.email}`>"),
            )

    # Revoke all preregistration users except prereg_user, and link prereg_user to
    # the created user
    if prereg_user is None:
        assert not realm_creation, "realm_creation should only happen with a PreregistrationUser"

    if prereg_user is not None:
        prereg_user.status = confirmation_settings.STATUS_ACTIVE
        prereg_user.created_user = user_profile
        prereg_user.save(update_fields=["status", "created_user"])

    # In the special case of realm creation, there can be no additional PreregistrationUser
    # for us to want to modify - because other realm_creation PreregistrationUsers should be
    # left usable for creating different realms.
    if not realm_creation:
        # Mark any other PreregistrationUsers in the realm that are STATUS_ACTIVE as
        # inactive so we can keep track of the PreregistrationUser we
        # actually used for analytics.
        if prereg_user is not None:
            PreregistrationUser.objects.filter(
                email__iexact=user_profile.delivery_email,
                realm=user_profile.realm).exclude(id=prereg_user.id).update(
                    status=confirmation_settings.STATUS_REVOKED)
        else:
            PreregistrationUser.objects.filter(
                email__iexact=user_profile.delivery_email,
                realm=user_profile.realm).update(
                    status=confirmation_settings.STATUS_REVOKED)

        if prereg_user is not None and prereg_user.referred_by is not None:
            notify_invites_changed(user_profile.realm)

    notify_new_user(user_profile)
    # Clear any scheduled invitation emails to prevent them
    # from being sent after the user is created.
    clear_scheduled_invitation_emails(user_profile.delivery_email)
    if realm.send_welcome_emails:
        enqueue_welcome_emails(user_profile, realm_creation)

    # We have an import loop here; it's intentional, because we want
    # to keep all the onboarding code in zerver/lib/onboarding.py.
    from zerver.lib.onboarding import send_initial_pms

    send_initial_pms(user_profile)
コード例 #5
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)

        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

        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)
        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']})

        send_initial_pms(user_profile)

        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.
        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('/')

        # Mark the user as having been just created, so no login email is sent
        auth_result.just_registered = True
        do_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,
            'password_required': password_auth_enabled(realm)
            and password_required,
            '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)
        })
コード例 #6
0
ファイル: registration.py プロジェクト: yhl-python/zulip
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
    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  # type: Optional[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})

    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 ""},
                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)[0]
            setup_initial_streams(realm)
        assert(realm is not None)

        full_name = form.cleaned_data['full_name']
        short_name = email_to_username(email)

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

        # 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, 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,
                                          tos_version=settings.TOS_VERSION,
                                          timezone=timezone,
                                          newsletter_data={"IP": request.META['REMOTE_ADDR']})

        send_initial_pms(user_profile)

        if realm_creation:
            do_change_is_admin(user_profile, True)
            setup_initial_private_stream(user_profile)
            send_initial_realm_messages(realm)

        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_required': password_auth_enabled(realm) and password_required,
                 '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)
                 }
    )