Gitea Issue #37371: Private users can be selected as a reviewer BUG CONFIRMED

Version: v1.26.0 | Issue: https://github.com/go-gitea/gitea/issues/37371

BUG CONFIRMED

BUG: privateuser (visibility=private) and/or restricteduser (is_restricted=true) are returned by /api/v1/repos/testorg/testrepo/reviewers when called by a non-admin org member. These users should be hidden from reviewer selection.

Root Cause

GetReviewers() in services/pull/reviewer.go does not filter by user.visibility or user.is_restricted. The final user query: e.In("id", uniqueUserIDs.Values()).Where(builder.Eq{"`user`.is_active": true}) is missing visibility and restricted checks.

Expected: Users with visibility=private or is_restricted=true should not appear as reviewer candidates to non-admin org members.

Actual: Both privateuser (visibility=private) and restricteduser (is_restricted=true) appear in the reviewer candidate list returned to a non-admin org member (publicuser).

API Evidence

Endpoint: GET /api/v1/repos/testorg/testrepo/reviewers
Called as: publicuser (non-admin org member, visibility=public)
HTTP status: 200

Login visibility is_restricted Status
admin public false OK
privateuser private ⚠ false Should be hidden — BUG
publicuser public false OK
restricteduser public true ⚠ Should be hidden — BUG

privateuser in response: true — BUG
restricteduser in response: true — BUG

Raw Evidence

{
  "issueUrl": "https://github.com/go-gitea/gitea/issues/37371",
  "appVersion": "1.26.0",
  "appUrl": "http://localhost:46547",
  "verdict": "BUG: privateuser (visibility=private) and/or restricteduser (is_restricted=true) are returned by /api/v1/repos/testorg/testrepo/reviewers when called by a non-admin org member. These users should be hidden from reviewer selection.",
  "apiEvidence": {
    "endpoint": "http://localhost:46547/api/v1/repos/testorg/testrepo/reviewers",
    "calledAs": "publicuser (non-admin org member, visibility=public)",
    "httpStatus": 200,
    "returnsPrivateUser": true,
    "returnsRestrictedUser": true,
    "allReviewers": [
      {
        "login": "admin",
        "visibility": "public",
        "restricted": false
      },
      {
        "login": "privateuser",
        "visibility": "private",
        "restricted": false
      },
      {
        "login": "publicuser",
        "visibility": "public",
        "restricted": false
      },
      {
        "login": "restricteduser",
        "visibility": "public",
        "restricted": true
      }
    ]
  },
  "rootCause": "GetReviewers() in services/pull/reviewer.go does not filter by user.visibility or user.is_restricted. The final user query: e.In(\"id\", uniqueUserIDs.Values()).Where(builder.Eq{\"`user`.is_active\": true}) is missing visibility and restricted checks.",
  "expectedBehavior": "Users with visibility=private or is_restricted=true should not appear as reviewer candidates to non-admin org members.",
  "actualBehavior": "Both privateuser (visibility=private) and restricteduser (is_restricted=true) appear in the reviewer candidate list returned to a non-admin org member (publicuser)."
}