Repository navigation
fix 63714 - #1953
fix 63714#1953
Conversation
Reviewer's GuideThe PR broadens selected item and group operations to support guest-token access, introduces activity-owner or item-permission checks for email/index validation, and adds comprehensive authorization-focused tests for the new 401/403/404 behavior. Sequence diagram for guest and activity authorizationsequenceDiagram
actor Client
participant API as validate_user_email_and_index
participant Auth as login_required_customize
participant Activity as WorkActivity
participant Permission as item_permission
participant Session as session
Client->>API: POST validate_user_email_and_index
API->>Auth: login_required_customize
Auth-->>API: continue
API->>Activity: get_activity_by_id(activity_id)
alt activity is missing
Activity-->>API: None
API-->>Client: 404 Not Found
else activity exists
API->>Session: get(guest_token)
API->>Permission: can()
alt guest token or item permission or activity user email matches
API-->>Client: validate email and index
else no access
API-->>Client: 403 Forbidden
end
end
Sequence diagram for guest-token item editingsequenceDiagram
actor Client
participant API as item edit endpoint
participant Guard as require_item_edit_permission
participant Session as session
participant Permission as edit_permission_factory
participant Record as RecordMetadata
Client->>API: item edit request
API->>Guard: require_item_edit_permission
Guard->>Session: get(guest_token)
Guard->>Record: query item metadata
alt item is missing
Record-->>Guard: None
Guard-->>Client: 404 Not Found
else authenticated user or guest token
Guard->>Permission: can()
alt permission granted or guest token exists
Guard-->>API: continue
API-->>Client: item edit response
else permission denied
Guard-->>Client: 403 Forbidden
end
else no authenticated user and no guest token
Guard-->>Client: 401 Unauthorized
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="modules/weko-items-ui/weko_items_ui/views.py" line_range="897" />
<code_context>
-@login_required
-@item_permission.require(http_exception=403)
+@login_required_customize
+@require_activity_user_or_item_access
def validate_user_email_and_index():
"""Validate user mail and index.
</code_context>
<issue_to_address>
**Concurrent assignments overwrite each other**
When two guest-token requests for the same activity concurrently assign different users to the same action, `validate_user_mail_and_index` reaches `validate_user_mail`, which updates the same activity action’s `action_handler` without locking or checking its prior value. Two guest-token requests assigning different users to that action can both succeed, with the last commit silently replacing the other assignment.
Serialize updates to each activity action or use optimistic conflict detection so competing assignments are not silently overwritten.
</issue_to_address>
### Comment 2
<location path="modules/weko-deposit/weko_deposit/rest.py" line_range="27" />
<code_context>
import sys
from functools import wraps
from wsgiref.util import request_uri
+from flask import session
import redis
</code_context>
<issue_to_address>
**Import ordering check fails**
`from flask import session` is separate from the existing Flask import and appears before imports that should precede Flask, so `isort .` rewrites this block and the formatting check reports a finding.
Merge `session` into the existing Flask import and order the imports with isort.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and a session containing any guest_token now bypasses the item edit permission check, and the activity endpoint likewise accepts that token instead of requiring item access or a matching activity email. If this trust rule is too broad, token holders can gain access across items; reverting stops future access but cannot undo edits or data already exposed.
Blocking findings: modules/weko-items-ui/weko_items_ui/views.py:897
| @login_required | ||
| @item_permission.require(http_exception=403) | ||
| @login_required_customize | ||
| @require_activity_user_or_item_access |
There was a problem hiding this comment.
🟡 Medium · Concurrent assignments overwrite each other
When two guest-token requests for the same activity concurrently assign different users to the same action, validate_user_mail_and_index reaches validate_user_mail, which updates the same activity action’s action_handler without locking or checking its prior value. Two guest-token requests assigning different users to that action can both succeed, with the last commit silently replacing the other assignment.
Serialize updates to each activity action or use optimistic conflict detection so competing assignments are not silently overwritten.
Prompt for AI agents
In `modules/weko-items-ui/weko_items_ui/views.py` at line 897:
**Concurrent assignments overwrite each other**
When two guest-token requests for the same activity concurrently assign different users to the same action, `validate_user_mail_and_index` reaches `validate_user_mail`, which updates the same activity action’s `action_handler` without locking or checking its prior value. Two guest-token requests assigning different users to that action can both succeed, with the last commit silently replacing the other assignment.
Serialize updates to each activity action or use optimistic conflict detection so competing assignments are not silently overwritten.| import sys | ||
| from functools import wraps | ||
| from wsgiref.util import request_uri | ||
| from flask import session |
There was a problem hiding this comment.
⚪ Low · Import ordering check fails
from flask import session is separate from the existing Flask import and appears before imports that should precede Flask, so isort . rewrites this block and the formatting check reports a finding.
Merge session into the existing Flask import and order the imports with isort.
Prompt for AI agents
In `modules/weko-deposit/weko_deposit/rest.py` at line 27:
**Import ordering check fails**
`from flask import session` is separate from the existing Flask import and appears before imports that should precede Flask, so `isort .` rewrites this block and the formatting check reports a finding.
Merge `session` into the existing Flask import and order the imports with isort.From AGENTS.md L70-73:
- フォーマッター: **Black** を使用(`black .` でソースコードを整形)
- リンター: **Flake8** を使用(`flake8` で静的解析チェック)
- インポート順の整理: **isort** を使用(`isort .` でインポート並び替え)
- これらのフォーマットチェックはコミット前に必ず実行し、指摘がない状態にしてください
概要 (Summary)
関連Issue / チケット (Related Issues)
変更タイプ (Type of Change)
🤖 0. CI 自動チェック (API Inventory Drift)
PR ごとに WEKO3 コンテナを起動し、
url_mapのダンプ・台帳との突き合わせ・変更行の到達可否測定を自動実行する。結果は PR コメントと Actions の artifact
(
api-inventory-summary) に出る。このリポジトリは public のため、台帳もベースラインも同梱していない。
実データはプライベートリポジトリ
RCOSDP/weko-secretにあり、CI は Secret 経由で取得する。以降この文書では、そこを単にプライベートリポジトリと呼ぶ。
台帳はブランチごとに内容が違うため、CI は weko 側と同名のブランチを
プライベートリポジトリから探して使う(head → base → 既定ブランチ の順)。
採用されたブランチ名は PR コメントの冒頭に出るので、件数を読む前にそこを見ること。
対応ブランチが無い場合は既定ブランチと比較され、コメント冒頭に警告が出る。
その件数は当てにならないので、PASS でも「確認済み」と読まないこと。
詳細:
tools/api-inventory/ci/README.md§3aSecret (
API_INVENTORY_REPO/API_INVENTORY_SSH_KEY) が未設定のリポジトリ、および fork からの PR では、このジョブは何もせずスキップされる。
API を追加・変更した場合(必須)
この PR が
fix/issue62569→develop_v2.0.4なら、プライベート側もfix/issue62569→develop_v2.0.4。同名にしておけば台帳 PR が未マージでもCI がそれを見るので、2つの PR のマージ順を気にしなくてよい。
api_snapshot.jsonを更新し、対応する PR を出したbash export WEKO_API_INVENTORY_DIR=/path/to/weko-secret ./install.sh python3 tools/api-inventory/scripts/snapshot.py --out "$WEKO_API_INVENTORY_DIR/api_snapshot.json"更新しないと CI が落ちる。公開リポジトリのコード変更とは別の PRになる。
weko3_api_list_full.tsvに行を追加・更新し、build_checklist.pyで 24 列版を再生成した(未収載だと reconcile が FAIL する)(
git statusに*.tsv/api_snapshot.jsonが出ていないこと)FAIL したときの対処(要約)
まず PR コメント冒頭の台帳ブランチを見る。警告が出ていれば、件数を追う前に
プライベートリポジトリ側の対応ブランチを用意すること(比較相手が違うので件数に意味がない)。
ジョブが落ちる条件は 3 つある。PR コメントのどのセクションに件数が出ているかで切り分ける。
drift.md)reconcile.md)*_PERMISSION_FACTORY/ CSRF 保護 等が危険側の値に変わったcan_delete/can_exportがFalse→Truedata_opを更新data_opが作成/更新/削除の経路に、未認証で到達したdata_opの記載誤りなら台帳を直すurl_mapに無いreconcile B のうち、実機に存在しないことが正当な行(プラグイン未登録・config で無効等)は
プライベートリポジトリの
reconcile_allow.jsonに理由付きで登録する。理由なしの登録は不可。登録済みの行は B'(既知・許容)として集計され、E'(endpoint が実機に無い)と併せてゲート対象外になる。
W1〜W6 は WARN でゲートは通るが、レビューでは見ること
(ModelView の追加 / 実装本体の変化 / HTTP メソッド・URL の変化 / 監視対象 config の変化 /
依存パッケージの版の変化)。特に W6(依存の版)は、ベースラインを CI と異なる環境で作ると
毎回出続けて形骸化するため、ベースラインは
install.shで作った環境から生成する。🔒 1. セキュリティ & API アクセス制御チェック (必須)
認証・認可 (Authentication & Authorization)
@login_required,@pass_record,need(...), Invenio Access Action/api/*ではPermission.require(http_exception=403)を使うこと。@login_requiredは API アプリにsecurity.loginが無いため 401 ではなく 500 になる--allow-writes付きでGET / HEAD 以外も叩く)
起動した経路のみ。ワークフロー系など未解決プレースホルダの行は skip される
Noneで無効化していない*_PERMISSION_FACTORY等を監視機能クローズ・非公開化の場合 (Feature Disable)
404 Not Foundまたは403 Forbiddenが返ることを確認した🧪 2. テストコード観点チェック (pytest / Invenio Test Suite)
権限・異常系テスト (Negative & Authorization Tests)
401 Unauthorizedまたは403 Forbidden/404 Not Foundが返ることを検証するテストがある403になるテストがある404/403を返すテストがある境界値・入力バリデーションテスト (Boundary & Validation)
400 Bad Request/ バリデーションエラーが返るテストがあるデータ整合性・トランザクションテスト (Integrity & Rollback)
🛡️ 3. データ保護 & 破壊的変更防止チェック (Data Safety)
⚙️ 4. マイグレーション & システム影響チェック (Invenio / WEKO3 Stack)
データベース (DB / Alembic)
invenio alembic upgrade(適用)およびdowngrade(ロールバック)スクリプトを作成・検証した検索インデックス (Elasticsearch / OpenSearch)
設定 & 非同期処理 (Config / Celery / Cache)
invenio.cfg/ 環境変数のデフォルト値を設定した📚 5. ドキュメント・仕様書更新チェック (weko-document)
tools/api-inventory/、台帳・調査記録はプライベートリポジトリ(public リポジトリには置かない)。
§0 のチェック項目で対応済みなら、ここは確認のみ。
weko3_api_auth_findings.md)もプライベートリポジトリに置く。台帳は二重管理しない📋 6. 動作検証エビデンス (Verification Evidence)
テスト実行結果
CI の成果物 (artifact:
api-inventory-summary)drift.mdreconcile.md明細(該当した経路名・実測結果)は公開できないため artifact に含めていない。
プライベートリポジトリ側で同じコマンドを
--summary-onlyなしで実行して確認する。手動で確認したこと
Summary by Sourcery
Fix authorization handling for guest-token-based item and activity workflows.
Bug Fixes:
Enhancements:
Tests: