Skip to content

fix(weko-gridlayout): ウィジェットのアップロードファイルを未ログインでも取得できるようにする - #1937

Merged
ivis-miyachi merged 1 commit into
develop_v2.1.0from
fix/widget-uploaded-file-permission
Oct 5, 2026
Merged

ivis-miyachi merged 1 commit into
develop_v2.1.0from
fix/widget-uploaded-file-permission

Conversation

@mhaya

@mhaya mhaya commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

概要 (Summary)

develop_v2.1.0 では、ウィジェット経由でアップロードした画像などが、公開ページで未ログインの利用者や一般ユーザに表示されない。

  • facd5ab で、/widget/uploaded/<filename>[/<community_id>](weko_gridlayout.views.uploaded_file)に、System/Repository/Community Administrator のロールを必須とする @roles_required が付いた。
  • この URL は、ウィジェットのアップロード時に WidgetBucket.save_file が返すもの。ウィジェット(自由記述など)に埋め込まれ、公開ページでブラウザが直接読み込む。
  • そのため、未ログインでは 401、管理者ロールの無いユーザでは 403 になり、公開ページのウィジェット画像が表示されなくなっていた。

変更内容

  • uploaded_file:ロールの必須化を外し、未ログインでも取得できる元の挙動に戻す。docstring に理由を書いた。
  • load_widget_type(/api/admin/load_widget_type):facd5abf7 で管理者に限定された。管理画面のウィジェット作成でだけ使う API なので、限定は残す。
  • テスト
    • test_uploaded_file が同じ名前で2つ定義されていて、後の定義が前を上書きしていた。そのため、ロールごとの判定を確かめるテストは実際には実行されていなかった。これを1つにまとめ、未ログイン・各管理者ロール・Contributor・ロールの無いユーザが、Root Index と通常のコミュニティの両方で 200 になることを確認する。1セグメントの URL(/widget/uploaded/<filename>)も確認する。
    • test_load_widget_type は users[id]['obj'] でログインしていた。users フィクスチャでは users[4](generaluser)の obj が sysadmin になっているため、実際にはシステム管理者としてログインし、403 を期待した確認が失敗していた(develop_v2.1.0 でも失敗する)。ほかのテストと同じく email でログインするように直した。

関連Issue / チケット (Related Issues)

  • facd5ab(fix widget permission issue)の回帰の修正

変更タイプ (Type of Change)

  • 🚀 新機能追加 (Feature)
  • 🐛 バグ修正 (Bug Fix)
  • 🔒 セキュリティ修正 (Security Fix)
  • 🚫 機能のクローズ・非公開化・削除 (Feature Deprecation/Disable)
  • ⚠️ 破壊的変更・データ移行を伴う修正 (Breaking Change / Migration)
  • 📚 仕様書・マニュアル・APIリストの更新 (Documentation)

🤖 0. CI 自動チェック (API Inventory Drift)

  • CI が PASS している、または FAIL の各項目に対処済み
    • 認証系デコレータを削除する変更なので、G2 として検出される見込み。この URL は公開ページで使われており、無認証での配信が仕様である。台帳の根拠を更新してベースラインを更新する想定。

API を追加・変更した場合(必須)

  • プライベートリポジトリ側の作業ブランチを、この PR のブランチと同名で切った
  • プライベートリポジトリの api_snapshot.json を更新し、対応する PR を出した
  • プライベートリポジトリの台帳の該当行(/widget/uploaded/... の2行)を更新した
  • 台帳・スナップショット・実測結果をこの公開リポジトリにコミットしていない

🔒 1. セキュリティ & API アクセス制御チェック (必須)

  • 新規/変更された View に適切なデコレータ / Permission を設定している:uploaded_file は公開ページの静的ファイル配信なので、認証は付けない(facd5abf7 より前の挙動)。load_widget_type の管理者限定は維持している。
  • 状態変更・破壊的メソッドの権限が正しく制限されている:変更したのは GET のみ。アップロード(POST /widget/uploads/...)は変更していない。
  • 未ログイン(Anonymous)状態でアクセスした際、意図しないデータ取得・変更が拒絶される:取得できるのはウィジェット用バケットのファイルだけで、facd5abf7 より前と同じ範囲。
  • 認可を config の permission factory に委ねていない

🧪 2. テストコード観点チェック

  • 未認証アクセス:uploaded_file は未ログインで 200(公開配信が仕様)であることをテストで確認した。
  • 権限不足ユーザー:load_widget_type は、管理者ロールの無いユーザ(Contributor、General)で 403 になることを確認した(ログイン方法を直したテスト)。

🛡️ 3. データ保護 & 破壊的変更防止チェック

対象外(データの書き込みに変更はない)。

⚙️ 4. マイグレーション & システム影響チェック

対象外(DB・検索インデックス・設定に変更はない)。


📚 5. ドキュメント・仕様書更新チェック (weko-document)

  • 更新不要な場合(理由): 公開ページのウィジェット画像を表示できる状態(facd5abf7 より前の挙動)に戻すだけで、画面や操作手順は変わらない。

📋 6. 動作検証エビデンス (Verification Evidence)

CI と同じ手順(scripts/ci/run-module-tests.sh、docker-compose2.yml:docker-compose.ci.yml)で weko-gridlayout のテストを実行した。手元で動いていた別の WEKO スタックとホストのポートがぶつかるため、サービスはホストにポートを公開しない設定で起動している。実行環境は aarch64。

=========== 329 passed, 3 xfailed, 788 warnings in 491.07s (0:08:11) ===========
  • test_uploaded_file:12ケースと test_uploaded_file_without_community がすべて PASSED。
  • test_load_widget_type:[0-403] [1-200] [2-200] [3-200] [4-403] がすべて PASSED。修正前は [4-403] が失敗していた。

🤖 Generated with Claude Code

Summary by Sourcery

Restore anonymous access to widget-uploaded files while retaining administrator-only access for widget type loading.

Bug Fixes:

  • Restore public access to widget-uploaded files so images and other embedded assets are available to anonymous and non-administrator users.
  • Correct widget type access tests to authenticate with the intended fixture users and accurately verify administrator restrictions.

Tests:

  • Consolidate uploaded-file coverage across anonymous users, administrator roles, ordinary users, communities, the root index, and URLs without a community identifier.

facd5ab で /widget/uploaded/<filename>[/<community_id>] (uploaded_file)
に System/Repository/Community Administrator のロール必須が付いた。この URL は
ウィジェットに埋め込んだ画像などを公開ページのブラウザが直接読み込むもの
(WidgetBucket.save_file が返す URL) なので、未ログインでは 401、一般ユーザでは
403 になり、公開ページのウィジェット画像が表示されなくなっていた。

- uploaded_file のロール必須を外す。load_widget_type (管理画面の
  ウィジェット作成でだけ使う) は管理者限定のまま
- test_uploaded_file が同名で2つ定義され、後の定義が前を上書きしていたので、
  未ログイン・各ロールで取得できることを確かめる1つのテストにまとめる
- test_load_widget_type が users[id]['obj'] でログインしていたため、
  users[4] (generaluser) の obj が sysadmin になっている fixture では
  システム管理者としてログインし、403 の確認が失敗していた。email で
  ログインするように直す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

This PR fixes the regression that prevented public pages from loading widget-uploaded assets by removing authentication requirements from the file-serving GET endpoint, while preserving admin-only widget-type loading and strengthening authorization regression tests. The module test suite passed with 329 tests passed and 3 expected failures.

Sequence diagram for public widget asset loading

sequenceDiagram
    actor Visitor
    participant Browser
    participant UploadedFile as uploaded_file
    participant WidgetBucket

    Visitor->>Browser: Open public page
    Browser->>UploadedFile: GET /widget/uploaded/filename/community_id
    UploadedFile->>WidgetBucket: Read widget asset
    WidgetBucket-->>UploadedFile: File contents
    UploadedFile-->>Browser: 200 asset response
    Browser-->>Visitor: Display widget asset
Loading

File-Level Changes

Change Details Files
Restore anonymous access to widget-uploaded files while retaining administrator protection for widget-type loading.
  • Removed the role requirement from the public uploaded-file GET view.
  • Documented that widget-embedded assets must load on public pages without authentication.
  • Left the admin-only load-widget-type API unchanged.
modules/weko-gridlayout/weko_gridlayout/views.py
Expand uploaded-file coverage to verify public access across user types, community scopes, and URL forms.
  • Merged the duplicate uploaded-file tests that previously caused one definition to overwrite the other.
  • Verified HTTP 200 responses for anonymous users, administrators, contributors, and users without roles in Root Index and regular communities.
  • Added assertions for the one-segment URL and the resolved WidgetBucket arguments.
modules/weko-gridlayout/tests/test_views.py
Correct the load-widget-type authorization test to authenticate as the intended fixture users.
  • Changed session login to use each fixture user's email rather than the potentially mismatched obj email.
  • Preserved coverage for administrator success and non-administrator 403 responses.
modules/weko-gridlayout/tests/test_views.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3c267457-9b15-483d-a344-4af60f208ff7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. This removes the authorization check from a file-download endpoint, making every uploaded widget file reachable by unauthenticated callers who can guess or obtain its filename and community ID. Reverting stops future unauthenticated access, but any files already exposed or downloaded cannot be recovered; the access-policy change is also wrong for everyone immediately if these uploads were not all intended to be public.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

API インベントリ差分(件数のみ)

台帳ブランチ: develop_v2.1.0

明細は公開できないため件数のみ表示しています。該当箇所はプライベートリポジトリ側の台帳・レポートで確認してください。

ベースラインとの差分

(生成されませんでした)

台帳との突き合わせ

(生成されませんでした)

ソース由来の経路検知

(生成されませんでした)

@ivis-miyachi
ivis-miyachi merged commit e97bad6 into develop_v2.1.0 Oct 5, 2026
145 of 159 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants