浏览代码

[ENG-4149] require login to deploy named templates (#4450)

* integration_tests.yml: init masenf/rx_shout as a template

fix test

* [ENG-4149] require login to deploy template

* Send loginv2 telemetry event
Masen Furer 5 月之前
父节点
当前提交
a894f21ce5
共有 4 个文件被更改,包括 52 次插入21 次删除
  1. 29 0
      .github/workflows/integration_tests.yml
  2. 3 1
      reflex/reflex.py
  3. 19 19
      reflex/utils/prerequisites.py
  4. 1 1
      reflex/utils/telemetry.py

+ 29 - 0
.github/workflows/integration_tests.yml

@@ -162,7 +162,36 @@ jobs:
           --python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
           --pr-id "${{ github.event.pull_request.id }}" --branch-name "${{ github.head_ref || github.ref_name }}"
           --app-name "reflex-web" --path ./reflex-web/.web
+
+  rx-shout-from-template:
+    strategy:
+      fail-fast: false
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: ./.github/actions/setup_build_env
+        with:
+          python-version: '3.11.4'
+          run-poetry-install: true
+          create-venv-at-path: .venv
+      - name: Create app directory
+        run: mkdir rx-shout-from-template
+      - name: Init reflex-web from template
+        run: poetry run reflex init --template https://github.com/masenf/rx_shout
+        working-directory: ./rx-shout-from-template
+      - name: ignore reflex pin in requirements
+        run: sed -i -e '/reflex==/d' requirements.txt
+        working-directory: ./rx-shout-from-template
+      - name: Install additional dependencies
+        run: poetry run uv pip install -r requirements.txt
+        working-directory: ./rx-shout-from-template
+      - name: Run Website and Check for errors
+        run: |
+          # Check that npm is home
+          npm -v
+          poetry run bash scripts/integration.sh ./rx-shout-from-template prod
   
+
   reflex-web-macos:
     if: github.event_name == 'push' && github.ref == 'refs/heads/main'
     strategy:

+ 3 - 1
reflex/reflex.py

@@ -370,7 +370,9 @@ def loginv2(loglevel: constants.LogLevel = typer.Option(config.loglevel)):
 
     check_version()
 
-    hosting_cli.login()
+    validated_info = hosting_cli.login()
+    if validated_info is not None:
+        telemetry.send("loginv2", user_uuid=validated_info.get("user_id"))
 
 
 @cli.command()

+ 19 - 19
reflex/utils/prerequisites.py

@@ -1408,13 +1408,22 @@ def validate_and_create_app_using_remote_template(app_name, template, templates)
     """
     # If user selects a template, it needs to exist.
     if template in templates:
+        from reflex_cli.v2.utils import hosting
+
+        authenticated_token = hosting.authenticated_token()
+        if not authenticated_token or not authenticated_token[0]:
+            console.print(
+                f"Please use `reflex loginv2` to access the '{template}' template."
+            )
+            raise typer.Exit(3)
+
         template_url = templates[template].code_url
     else:
         # Check if the template is a github repo.
         if template.startswith("https://github.com"):
             template_url = f"{template.strip('/').replace('.git', '')}/archive/main.zip"
         else:
-            console.error(f"Template `{template}` not found.")
+            console.error(f"Template `{template}` not found or invalid.")
             raise typer.Exit(1)
 
     if template_url is None:
@@ -1451,7 +1460,7 @@ def generate_template_using_ai(template: str | None = None) -> str:
 
 
 def fetch_remote_templates(
-    template: Optional[str] = None,
+    template: str,
 ) -> tuple[str, dict[str, Template]]:
     """Fetch the available remote templates.
 
@@ -1460,9 +1469,6 @@ def fetch_remote_templates(
 
     Returns:
         The selected template and the available templates.
-
-    Raises:
-        Exit: If the template is not valid or if the template is not specified.
     """
     available_templates = {}
 
@@ -1474,19 +1480,7 @@ def fetch_remote_templates(
         console.debug(f"Error while fetching templates: {e}")
         template = constants.Templates.DEFAULT
 
-    if template == constants.Templates.DEFAULT:
-        return template, available_templates
-
-    if template in available_templates:
-        return template, available_templates
-
-    else:
-        if template is not None:
-            console.error(f"{template!r} is not a valid template name.")
-        console.print(
-            f"Go to the templates page ({constants.Templates.REFLEX_TEMPLATES_URL}) and copy the command to init with a template."
-        )
-        raise typer.Exit(0)
+    return template, available_templates
 
 
 def initialize_app(
@@ -1501,6 +1495,9 @@ def initialize_app(
 
     Returns:
         The name of the template.
+
+    Raises:
+        Exit: If the template is not valid or unspecified.
     """
     # Local imports to avoid circular imports.
     from reflex.utils import telemetry
@@ -1528,7 +1525,10 @@ def initialize_app(
             # change to the default to allow creation of default app
             template = constants.Templates.DEFAULT
         elif template == constants.Templates.CHOOSE_TEMPLATES:
-            template, templates = fetch_remote_templates()
+            console.print(
+                f"Go to the templates page ({constants.Templates.REFLEX_TEMPLATES_URL}) and copy the command to init with a template."
+            )
+            raise typer.Exit(0)
 
     # If the blank template is selected, create a blank app.
     if template in (constants.Templates.DEFAULT,):

+ 1 - 1
reflex/utils/telemetry.py

@@ -129,7 +129,7 @@ def _prepare_event(event: str, **kwargs) -> dict:
 
     cpuinfo = get_cpu_info()
 
-    additional_keys = ["template", "context", "detail"]
+    additional_keys = ["template", "context", "detail", "user_uuid"]
     additional_fields = {
         key: value for key in additional_keys if (value := kwargs.get(key)) is not None
     }