This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new bbd0db0  Ensure that permissions of directories are consistent
bbd0db0 is described below

commit bbd0db0317935cac842f0369c71259aaad929fb9
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed May 28 15:29:27 2025 +0100

    Ensure that permissions of directories are consistent
---
 atr/revision.py                    |   3 +
 atr/routes/announce.py             |   7 ++-
 atr/routes/finish.py               |   1 -
 atr/templates/finish-selected.html | 116 ++++++++++++++++++-------------------
 atr/util.py                        |   8 +++
 5 files changed, 72 insertions(+), 63 deletions(-)

diff --git a/atr/revision.py b/atr/revision.py
index 5c0e08f..eb849fb 100644
--- a/atr/revision.py
+++ b/atr/revision.py
@@ -85,6 +85,9 @@ async def create_and_manage(
         await aioshutil.rmtree(temp_dir)  # type: ignore[call-arg]
         raise
 
+    # Ensure that the permissions of every directory are 755
+    await asyncio.to_thread(util.chmod_directories, temp_dir_path)
+
     # Create a revision row, holding the write lock
     async with db.session() as data:
         # This is the only place where models.Revision is constructed
diff --git a/atr/routes/announce.py b/atr/routes/announce.py
index fae5ced..404985d 100644
--- a/atr/routes/announce.py
+++ b/atr/routes/announce.py
@@ -15,6 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
+import asyncio
 import datetime
 import logging
 from typing import TYPE_CHECKING, Any, Protocol
@@ -193,10 +194,14 @@ async def selected_post(
         # Do not put it in the data block after data.commit()
         # Otherwise util.release_directory() will not work
         release = await 
data.release(name=release.name).demand(RuntimeError(f"Release {release.name} 
does not exist"))
-        target = str(util.release_directory(release))
+        target_path = util.release_directory(release)
+        target = str(target_path)
         if await aiofiles.os.path.exists(target):
             raise routes.FlashError("Release already exists")
 
+    # Ensure that the permissions of every directory are 755
+    await asyncio.to_thread(util.chmod_directories, target_path)
+
     try:
         await aioshutil.move(source, target)
         if source_base:
diff --git a/atr/routes/finish.py b/atr/routes/finish.py
index 889e515..979a745 100644
--- a/atr/routes/finish.py
+++ b/atr/routes/finish.py
@@ -145,7 +145,6 @@ async def selected(
         source_files=sorted(source_files_rel),
         form=move_form,
         delete_dir_form=delete_dir_form,
-        can_move=can_move,
         user_ssh_keys=user_ssh_keys,
         target_dirs=sorted(list(target_dirs)),
         max_files_to_show=10,
diff --git a/atr/templates/finish-selected.html 
b/atr/templates/finish-selected.html
index aadabe0..60c1255 100644
--- a/atr/templates/finish-selected.html
+++ b/atr/templates/finish-selected.html
@@ -107,75 +107,69 @@
     </p>
   </div>
 
-  {% if can_move %}
-    <h2>Move items to a different directory</h2>
-    <p>
-      Note that files with associated metadata (e.g. <code>.asc</code> or 
<code>.sha512</code> files) are treated as a single unit and will be moved 
together if any one of them is selected for movement.
-    </p>
-    <div id="move-error-alert"
-         class="alert alert-danger d-none"
-         role="alert"
-         aria-live="assertive"></div>
-    <form class="atr-canary">
-      <div class="row">
-        <div class="col-lg-6">
-          <div class="card mb-4">
-            <div class="card-header bg-light">
-              <h3 class="mb-0">Select items to move</h3>
-            </div>
-            <div class="card-body">
-              <input type="text"
-                     id="file-filter"
-                     class="form-control mb-2"
-                     placeholder="Search for an item to move..." />
-              <table class="table table-sm table-striped border mt-3">
-                <tbody id="file-list-table-body">
-                </tbody>
-              </table>
-              <div id="file-list-more-info" class="text-muted small 
mt-1"></div>
-            </div>
+  <h2>Move items to a different directory</h2>
+  <p>
+    Note that files with associated metadata (e.g. <code>.asc</code> or 
<code>.sha512</code> files) are treated as a single unit and will be moved 
together if any one of them is selected for movement.
+  </p>
+  <div id="move-error-alert"
+       class="alert alert-danger d-none"
+       role="alert"
+       aria-live="assertive"></div>
+  <form class="atr-canary">
+    <div class="row">
+      <div class="col-lg-6">
+        <div class="card mb-4">
+          <div class="card-header bg-light">
+            <h3 class="mb-0">Select items to move</h3>
+          </div>
+          <div class="card-body">
+            <input type="text"
+                   id="file-filter"
+                   class="form-control mb-2"
+                   placeholder="Search for an item to move..." />
+            <table class="table table-sm table-striped border mt-3">
+              <tbody id="file-list-table-body">
+              </tbody>
+            </table>
+            <div id="file-list-more-info" class="text-muted small mt-1"></div>
           </div>
         </div>
-        <div class="col-lg-6">
-          <div class="card mb-4">
-            <div class="card-header bg-light">
-              <h3 class="mb-0">
-                <span id="selected-file-name-title">Select a destination for 
the file</span>
-              </h3>
-            </div>
-            <div class="card-body">
-              <input type="text"
-                     id="dir-filter-input"
-                     class="form-control mb-2"
-                     placeholder="Search for a directory to move to..." />
-              <table class="table table-sm table-striped border mt-3">
-                <tbody id="dir-list-table-body">
-                </tbody>
-              </table>
-              <div id="dir-list-more-info" class="text-muted small mt-1"></div>
-            </div>
+      </div>
+      <div class="col-lg-6">
+        <div class="card mb-4">
+          <div class="card-header bg-light">
+            <h3 class="mb-0">
+              <span id="selected-file-name-title">Select a destination for the 
file</span>
+            </h3>
+          </div>
+          <div class="card-body">
+            <input type="text"
+                   id="dir-filter-input"
+                   class="form-control mb-2"
+                   placeholder="Search for a directory to move to..." />
+            <table class="table table-sm table-striped border mt-3">
+              <tbody id="dir-list-table-body">
+              </tbody>
+            </table>
+            <div id="dir-list-more-info" class="text-muted small mt-1"></div>
           </div>
         </div>
       </div>
+    </div>
 
-      <div>
-        <div class="mb-3">
-          <label for="maxFilesInput" class="form-label">Items to show per 
list:</label>
-          <input type="number"
-                 class="form-control form-control-sm w-25"
-                 id="max-files-input"
-                 value="{{ max_files_to_show }}"
-                 min="1" />
-        </div>
-        <div id="current-move-selection-info" class="text-muted">Please select 
a file and a destination.</div>
-        <button type="button" id="confirm-move-button" class="btn btn-success 
mt-2">Move to selected directory</button>
+    <div>
+      <div class="mb-3">
+        <label for="maxFilesInput" class="form-label">Items to show per 
list:</label>
+        <input type="number"
+               class="form-control form-control-sm w-25"
+               id="max-files-input"
+               value="{{ max_files_to_show }}"
+               min="1" />
       </div>
-    </form>
-  {% else %}
-    <div class="alert alert-info" role="alert">
-      File moving is disabled as all files are currently in the same directory 
or the revision is empty.
+      <div id="current-move-selection-info" class="text-muted">Please select a 
file and a destination.</div>
+      <button type="button" id="confirm-move-button" class="btn btn-success 
mt-2">Move to selected directory</button>
     </div>
-  {% endif %}
+  </form>
   {% if delete_dir_form.directory_to_delete.choices %}
     <h2>Delete an empty directory</h2>
     <form method="post" class="mb-4">
diff --git a/atr/util.py b/atr/util.py
index a427210..a97b49f 100644
--- a/atr/util.py
+++ b/atr/util.py
@@ -22,6 +22,7 @@ import dataclasses
 import datetime
 import hashlib
 import logging
+import os
 import pathlib
 import re
 import tarfile
@@ -160,6 +161,13 @@ async def compute_sha512(file_path: pathlib.Path) -> str:
     return sha512.hexdigest()
 
 
+def chmod_directories(path: pathlib.Path, permissions: int = 0o755) -> None:
+    os.chmod(path, permissions)
+    for dir_path in path.rglob("*"):
+        if dir_path.is_dir():
+            os.chmod(dir_path, permissions)
+
+
 async def content_list(
     phase_subdir: pathlib.Path, project_name: str, version_name: str, 
revision_name: str | None = None
 ) -> AsyncGenerator[FileStat]:


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to