mirror of https://github.com/zulip/zulip.git
registration: Allow UI flow to import org from slack.
This commit is contained in:
parent
e1a752c0c1
commit
1f1beb1452
|
@ -39,13 +39,6 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="bottom-text">
|
||||
{% trans %}
|
||||
Or import
|
||||
from <a href="/help/import-from-slack">Slack</a>, <a href="/help/import-from-mattermost">Mattermost</a>,
|
||||
or <a href="/help/import-from-rocketchat">Rocket.Chat</a>.
|
||||
{% endtrans %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -85,4 +85,26 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not user_registration_form %}
|
||||
<div class="input-box">
|
||||
<div class="inline-block" id="realm-creation-import-from-wrapper">
|
||||
<select id="import_from" name="import_from">
|
||||
{% for key, choice in import_from_choices %}
|
||||
<option value="{{ key }}" {% if key == "none" %}selected{% endif %}>{{ _(choice) }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="not-editable-realm-field extra-info-realm-creation-import-from">
|
||||
{% trans %}
|
||||
You can also import from
|
||||
<a href="/help/import-from-mattermost">Mattermost</a> or
|
||||
<a href="/help/import-from-rocketchat">Rocket.Chat</a>.
|
||||
{% endtrans %}
|
||||
</div>
|
||||
</div>
|
||||
<label for="import_from" class="inline-block">
|
||||
{{ _('Import chat history?') }}
|
||||
</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
<div class="white-box">
|
||||
{% if poll_for_import_completion %}
|
||||
<input type='hidden' name='key' value='{{ key }}' id="auth_key" />
|
||||
<input type='hidden' name='key' value='{{ key }}' id="auth_key_for_polling" />
|
||||
<div class="input-box">
|
||||
<label for="uploaded-file-info">{{ _("Import progress") }}</label>
|
||||
<div id="slack-import-poll-status" class="not-editable-realm-field">
|
||||
|
@ -25,7 +25,7 @@
|
|||
<form method="post" class="form-inline" action="{{ url('import_realm_from_slack') }}">
|
||||
{{ csrf_input }}
|
||||
<div class="input-box no-validation">
|
||||
<input type='hidden' name='key' value='{{ key }}' />
|
||||
<input type='hidden' name='key' value='{{ key }}' id="auth_key_for_file_upload"/>
|
||||
</div>
|
||||
<div class="input-box slack-import-extra-info">
|
||||
<div class="not-editable-realm-field">
|
||||
|
|
|
@ -348,7 +348,7 @@ $(() => {
|
|||
});
|
||||
|
||||
if ($("#slack-import-drag-and-drop").length > 0) {
|
||||
const key = $<HTMLInputElement>("#auth_key").val();
|
||||
const key = $<HTMLInputElement>("#auth_key_for_file_upload").val();
|
||||
const uppy = new Uppy({
|
||||
debug: true,
|
||||
autoProceed: true,
|
||||
|
@ -370,6 +370,7 @@ $(() => {
|
|||
"Drag and drop your Slack export file here, or click to browse.",
|
||||
}),
|
||||
},
|
||||
pluralize: () => 0,
|
||||
},
|
||||
});
|
||||
uppy.use(Tus, {endpoint: "/api/v1/tus/", removeFingerprintOnSuccess: true});
|
||||
|
@ -384,7 +385,7 @@ $(() => {
|
|||
}
|
||||
|
||||
if ($("#slack-import-poll-status").length > 0) {
|
||||
const key = $<HTMLInputElement>("#auth_key").val();
|
||||
const key = $<HTMLInputElement>("#auth_key_for_polling").val();
|
||||
const pollInterval = 2000; // Poll every 2 seconds
|
||||
|
||||
let poll_id: ReturnType<typeof setTimeout> | undefined;
|
||||
|
|
|
@ -22,7 +22,7 @@ from zerver.lib.realm_icon import get_realm_icon_url
|
|||
from zerver.lib.request import RequestNotes
|
||||
from zerver.lib.send_email import FromAddress
|
||||
from zerver.lib.subdomains import get_subdomain, is_root_domain_available
|
||||
from zerver.models import Realm, UserProfile
|
||||
from zerver.models import PreregistrationRealm, Realm, UserProfile
|
||||
from zerver.models.realms import get_realm
|
||||
from zproject.backends import (
|
||||
AUTH_BACKEND_NAME_MAP,
|
||||
|
@ -293,5 +293,6 @@ def get_realm_create_form_context() -> dict[str, Any]:
|
|||
"MAX_REALM_SUBDOMAIN_LENGTH": str(Realm.MAX_REALM_SUBDOMAIN_LENGTH),
|
||||
"root_domain_available": is_root_domain_available(),
|
||||
"sorted_realm_types": sorted(Realm.ORG_TYPES.values(), key=lambda d: d["display_order"]),
|
||||
"import_from_choices": PreregistrationRealm.IMPORT_FROM_CHOICES,
|
||||
}
|
||||
return context
|
||||
|
|
|
@ -32,7 +32,7 @@ from zerver.lib.name_restrictions import is_reserved_subdomain
|
|||
from zerver.lib.rate_limiter import RateLimitedObject, rate_limit_request_by_ip
|
||||
from zerver.lib.subdomains import get_subdomain, is_root_domain_available
|
||||
from zerver.lib.users import check_full_name
|
||||
from zerver.models import Realm, UserProfile
|
||||
from zerver.models import PreregistrationRealm, Realm, UserProfile
|
||||
from zerver.models.realm_audit_logs import RealmAuditLog
|
||||
from zerver.models.realms import (
|
||||
DisposableEmailError,
|
||||
|
@ -325,6 +325,9 @@ class ImportRealmOwnerSelectionForm(forms.Form):
|
|||
class RealmCreationForm(RealmDetailsForm):
|
||||
# This form determines whether users can create a new realm.
|
||||
email = forms.EmailField(validators=[email_not_system_bot, email_is_not_disposable])
|
||||
import_from = forms.ChoiceField(
|
||||
choices=PreregistrationRealm.IMPORT_FROM_CHOICES,
|
||||
)
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
kwargs["realm_creation"] = True
|
||||
|
|
|
@ -896,6 +896,7 @@ Output:
|
|||
"realm_type": realm_type,
|
||||
"realm_default_language": realm_default_language,
|
||||
"realm_subdomain": realm_subdomain,
|
||||
"import_from": "none",
|
||||
}
|
||||
if realm_in_root_domain is not None:
|
||||
payload["realm_in_root_domain"] = realm_in_root_domain
|
||||
|
|
|
@ -50,6 +50,10 @@ class PreregistrationRealm(models.Model):
|
|||
UserProfile, null=True, related_name="+", on_delete=models.SET_NULL
|
||||
)
|
||||
|
||||
IMPORT_FROM_CHOICES = [
|
||||
("none", "Don't import"),
|
||||
("slack", "Import from Slack"),
|
||||
]
|
||||
data_import_metadata = models.JSONField(default=dict, encoder=DjangoJSONEncoder)
|
||||
|
||||
|
||||
|
|
|
@ -306,6 +306,7 @@ class TestGenerateRealmCreationLink(ZulipTestCase):
|
|||
"realm_type": Realm.ORG_TYPES["business"]["id"],
|
||||
"realm_default_language": "en",
|
||||
"realm_subdomain": "custom-test",
|
||||
"import_from": "none",
|
||||
},
|
||||
)
|
||||
self.assertEqual(result.status_code, 302)
|
||||
|
@ -334,6 +335,7 @@ class TestGenerateRealmCreationLink(ZulipTestCase):
|
|||
"realm_type": Realm.ORG_TYPES["business"]["id"],
|
||||
"realm_default_language": "en",
|
||||
"realm_subdomain": string_id,
|
||||
"import_from": "none",
|
||||
},
|
||||
)
|
||||
self.assertEqual(result.status_code, 302)
|
||||
|
|
|
@ -145,6 +145,7 @@ def create_preregistration_realm(
|
|||
string_id: str,
|
||||
org_type: int,
|
||||
default_language: str,
|
||||
import_from: str | None = None,
|
||||
) -> PreregistrationRealm:
|
||||
return PreregistrationRealm.objects.create(
|
||||
email=email,
|
||||
|
@ -152,6 +153,7 @@ def create_preregistration_realm(
|
|||
string_id=string_id,
|
||||
org_type=org_type,
|
||||
default_language=default_language,
|
||||
data_import_metadata={"import_from": import_from},
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -157,7 +157,11 @@ def get_prereg_key_and_redirect(
|
|||
|
||||
registration_url = reverse("accounts_register")
|
||||
if realm_creation:
|
||||
registration_url = reverse("realm_register")
|
||||
assert isinstance(prereg_object, PreregistrationRealm)
|
||||
if prereg_object.data_import_metadata.get("import_from") == "slack":
|
||||
registration_url = reverse("import_realm_from_slack")
|
||||
else:
|
||||
registration_url = reverse("realm_register")
|
||||
|
||||
return render(
|
||||
request,
|
||||
|
@ -235,6 +239,11 @@ def accounts_register(*args: Any, **kwargs: Any) -> HttpResponse:
|
|||
return registration_helper(*args, **kwargs)
|
||||
|
||||
|
||||
@require_post
|
||||
def import_realm_from_slack(*args: Any, **kwargs: Any) -> HttpResponse:
|
||||
return registration_helper(*args, **kwargs)
|
||||
|
||||
|
||||
@typed_endpoint
|
||||
def registration_helper(
|
||||
request: HttpRequest,
|
||||
|
@ -298,6 +307,35 @@ def registration_helper(
|
|||
"key": key,
|
||||
},
|
||||
)
|
||||
|
||||
elif prereg_realm.data_import_metadata.get("import_from") == "slack":
|
||||
context: dict[str, Any] = {
|
||||
"key": key,
|
||||
}
|
||||
|
||||
saved_slack_access_token = prereg_realm.data_import_metadata.get("slack_access_token")
|
||||
if saved_slack_access_token or slack_access_token:
|
||||
if slack_access_token and slack_access_token != saved_slack_access_token:
|
||||
# Verify slack token access.
|
||||
from zerver.data_import.slack import check_token_access
|
||||
|
||||
check_token_access(slack_access_token)
|
||||
|
||||
saved_slack_access_token = slack_access_token
|
||||
prereg_realm.data_import_metadata["slack_access_token"] = slack_access_token
|
||||
prereg_realm.save(update_fields=["data_import_metadata"])
|
||||
|
||||
context["slack_access_token"] = saved_slack_access_token
|
||||
context["uploaded_import_file_name"] = prereg_realm.data_import_metadata.get(
|
||||
"uploaded_import_file_name"
|
||||
)
|
||||
|
||||
return TemplateResponse(
|
||||
request,
|
||||
"zerver/slack_import.html",
|
||||
context,
|
||||
)
|
||||
|
||||
password_required = True
|
||||
role = UserProfile.ROLE_REALM_OWNER
|
||||
else:
|
||||
|
@ -874,9 +912,15 @@ def prepare_realm_activation_url(
|
|||
string_id: str,
|
||||
org_type: int,
|
||||
default_language: str,
|
||||
import_form: str,
|
||||
) -> str:
|
||||
prereg_realm = create_preregistration_realm(
|
||||
email, realm_name, string_id, org_type, default_language
|
||||
email,
|
||||
realm_name,
|
||||
string_id,
|
||||
org_type,
|
||||
default_language,
|
||||
import_form,
|
||||
)
|
||||
activation_url = create_confirmation_link(
|
||||
prereg_realm, Confirmation.REALM_CREATION, no_associated_realm_object=True
|
||||
|
@ -1092,6 +1136,7 @@ def create_realm(request: HttpRequest, creation_key: str | None = None) -> HttpR
|
|||
realm_type = form.cleaned_data["realm_type"]
|
||||
realm_default_language = form.cleaned_data["realm_default_language"]
|
||||
realm_subdomain = form.cleaned_data["realm_subdomain"]
|
||||
import_from = form.cleaned_data["import_from"]
|
||||
activation_url = prepare_realm_activation_url(
|
||||
email,
|
||||
request.session,
|
||||
|
@ -1099,6 +1144,7 @@ def create_realm(request: HttpRequest, creation_key: str | None = None) -> HttpR
|
|||
realm_subdomain,
|
||||
realm_type,
|
||||
realm_default_language,
|
||||
import_from,
|
||||
)
|
||||
if key_record is not None and key_record.presume_email_valid:
|
||||
# The user has a token created from the server command line;
|
||||
|
|
|
@ -142,6 +142,7 @@ from zerver.views.registration import (
|
|||
create_realm,
|
||||
find_account,
|
||||
get_prereg_key_and_redirect,
|
||||
import_realm_from_slack,
|
||||
new_realm_send_confirm,
|
||||
realm_import_post_process,
|
||||
realm_import_status,
|
||||
|
@ -604,6 +605,7 @@ i18n_urls = [
|
|||
realm_import_post_process,
|
||||
name="realm_import_post_process",
|
||||
),
|
||||
path("new/import/slack/", import_realm_from_slack, name="import_realm_from_slack"),
|
||||
path(
|
||||
"accounts/do_confirm/<confirmation_key>",
|
||||
get_prereg_key_and_redirect,
|
||||
|
|
Loading…
Reference in New Issue