* chore(pre-commit): match black version with requirements-dev
* run `make black` against repo
* ci: switch to black 24.4.2
* fix: py312
* fix: flake8 errors
* fix: flake8 conflicts
* chore: add git blame ignore revs file
When FEATURE_SUPERUSERS_FULL_ACCESS=false, regular superusers could
create/update/delete quotas for other users' organizations (returning 201/200),
but couldn't view them (returning 403). This was a security bug - both read
and write operations should require FULL_ACCESS permission to access other
organizations' quotas.
Root cause: Organization quota write endpoints used SuperUserPermission().can()
instead of allow_if_superuser_with_full_access(), allowing any superuser to
modify other orgs' quotas regardless of the FULL_ACCESS setting.
Changes:
- endpoints/api/namespacequota.py: Replace SuperUserPermission().can() with
allow_if_superuser_with_full_access() in all quota write operations:
* OrganizationQuotaList.post() - create quota
* OrganizationQuota.put() - update quota
* OrganizationQuota.delete() - delete quota
* OrganizationQuotaLimitList.post() - create quota limit
* OrganizationQuotaLimit.put() - update quota limit
* OrganizationQuotaLimit.delete() - delete quota limit
- endpoints/api/test/test_superuser_full_access.py: Add comprehensive tests
for quota operations with and without FULL_ACCESS enabled (6 new tests)
Note: Superuser panel endpoints (/v1/superuser/users/<namespace>/quota)
were intentionally NOT changed - these are admin panel functions that should
work with basic superuser permission, consistent with other panel operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
* fix(ui): Enable organization/user visibility for read-only superusers (PROJQUAY-6882)
Users listed under GLOBAL_READONLY_SUPER_USERS can now see all
organizations and users in the UI, matching regular superuser visibility
with read-only restrictions on actions.
- Update UseCurrentUser to include global_readonly_super_user in isSuperUser check
- Add Cypress tests for read-only superuser visibility and action restrictions
- Settings column actions correctly hidden via existing canModify permission
* fix(ui): Add global_readonly_super_user field to API responses (PROJQUAY-6882)
- Add global_readonly_super_user field to user API response in endpoints/api/user.py
- Allow read-only superusers to view organization teams in endpoints/api/organization.py
- Allow read-only superusers to view robot permissions in endpoints/api/robot.py
* fix(ui): Prevent read-only superusers from deleting orgs/users
Security fix: Read-only superusers should not be able to delete
orgs or users they don't own, even though they can view them.
* Fix inline import + incorrect assert + add codecov tests
---------
Co-authored-by: Claude <noreply@anthropic.com>
This fixes an issue where global readonly superusers were blocked from
accessing organization quota limit endpoints when FEATURE_SUPERUSERS_FULL_ACCESS
was set to false.
Fixed endpoints in endpoints/api/namespacequota.py:
- OrganizationQuotaLimitList.get() - List quota limits
- OrganizationQuotaLimit.get() - Get individual quota limit
Both endpoints now use the consistent permission pattern:
permission.can() OR
allow_if_global_readonly_superuser() OR
allow_if_superuser_with_full_access()
Added comprehensive tests in test_global_readonly_superuser.py:
- test_global_readonly_superuser_can_access_quota_limit_list
- test_global_readonly_superuser_can_access_individual_quota_limit
- test_regular_superuser_cannot_access_quota_limits_without_full_access
Test implementation uses autouse fixture to ensure FEATURE_SUPERUSERS_FULL_ACCESS
is disabled for all tests in the class, following the pattern from
TestOrganizationLogsAccessWithoutFullAccess.
Tests verify:
1. Global readonly superusers CAN access quota limits for auditing,
regardless of FEATURE_SUPERUSERS_FULL_ACCESS setting
2. Regular superusers are still blocked when FEATURE_SUPERUSERS_FULL_ACCESS
is false (correct security behavior)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
* fix: allow global readonly superusers to access all organization data without FULL_ACCESS (PROJQUAY-9798)
This is a comprehensive fix for multiple endpoints where global readonly superusers
were incorrectly blocked from accessing organization data when
FEATURE_SUPERUSERS_FULL_ACCESS was set to false.
Fixed endpoints in endpoints/api/logs.py:
- OrgLogs.get() - Organization audit logs
- OrgAggregateLogs.get() - Aggregated organization logs
- ExportOrgLogs.post() - Export organization logs
Fixed endpoints in endpoints/api/team.py:
- TeamMemberList.get() - Team member list
- TeamPermissions.get() - Team repository permissions
Fixed endpoints in endpoints/api/organization.py:
- OrganizationMemberList.get() - Organization member list
- OrganizationMember.get() - Individual member details
- OrganizationApplications.get() - OAuth application list
- OrganizationApplication.get() - Individual application details
Fixed endpoints in endpoints/api/prototype.py:
- PermissionPrototypeList.get() - Default permission prototypes
All endpoints now use consistent permission logic:
permission.can() OR
allow_if_global_readonly_superuser() OR
allow_if_superuser_with_full_access()
Added comprehensive tests verifying:
1. Global readonly superusers CAN access all data for auditing, regardless
of FEATURE_SUPERUSERS_FULL_ACCESS setting
2. Regular superusers are still blocked when FEATURE_SUPERUSERS_FULL_ACCESS
is false (correct behavior)
* fix(test): ensure owners team exists for testorglogs org in test setup
Addresses review feedback from PR #4549 comment #2539202868.
The test was attempting to access the 'owners' team in 'testorglogs'
org, but the fixture only created the organization without creating
any teams. This could cause the test to receive a 404 (team not found)
instead of 403 (permission denied), making it pass for the wrong reason.
Also simplified the test logic to only expect 403 since the team now
exists in the fixtures, ensuring the test validates permission blocking
rather than missing resources.
This fixes a bug where global readonly superusers were incorrectly blocked
from accessing organization logs when FEATURE_SUPERUSERS_FULL_ACCESS was
set to false.
Changes:
- Updated OrgLogs.get() to allow global readonly superusers
- Updated OrgAggregateLogs.get() to allow global readonly superusers
- Updated ExportOrgLogs.post() to allow global readonly superusers
- Added comprehensive tests verifying the fix
The fix ensures that:
1. Global readonly superusers can ALWAYS access organization logs for
auditing purposes, regardless of FEATURE_SUPERUSERS_FULL_ACCESS setting
2. Regular superusers are still blocked from accessing organization logs
when FEATURE_SUPERUSERS_FULL_ACCESS is false (correct behavior)
All three endpoints now use consistent permission logic:
permission.can() OR
allow_if_global_readonly_superuser() OR
allow_if_superuser_with_full_access()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
fix(api): implement proper superuser permission model and fix access controls
Fixes multiple issues with superuser functionality and implements a comprehensive
permission model for FEATURE_SUPERUSERS_FULL_ACCESS:
**Permission Model:**
- Global Readonly Superusers (auditors): Always have read access to all content,
independent of FEATURE_SUPERUSERS_FULL_ACCESS setting
- Regular Superusers: Can access /v1/superuser endpoints and their own content.
Require FEATURE_SUPERUSERS_FULL_ACCESS=true for cross-namespace read access
- Full Access Superusers: Regular superusers with FULL_ACCESS enabled, can
perform CRUD on content they don't own
- Write operations: Only allowed for full access superusers (global readonly
superusers never get write access)
**Key Fixes:**
1. Fixed superuser panel endpoints returning 403 when FULL_ACCESS was disabled.
Basic panel operations (user list, logs, org list, messages) now work with
just FEATURE_SUPER_USERS enabled.
2. Updated decorators to properly differentiate between basic superuser
operations and permission bypass operations.
3. Implemented license bypass: Superusers with FULL_ACCESS now bypass
license/quota limits when creating or modifying private repositories.
4. Fixed 18 permission checks across 7 files to properly implement cross-namespace
access controls for different superuser types.
**Changes:**
- endpoints/api/__init__.py: Fixed allow_if_superuser(), require_repo_permission, and decorators
- endpoints/api/superuser.py: Updated SuperUserAppTokens permission check
- endpoints/api/organization.py: Updated 4 GET endpoints to require FULL_ACCESS
- endpoints/api/namespacequota.py: Updated 2 GET endpoints to require FULL_ACCESS
- endpoints/api/team.py: Updated 2 GET endpoints to require FULL_ACCESS
- endpoints/api/prototype.py: Updated 1 GET endpoint to require FULL_ACCESS
- endpoints/api/policy.py: Updated auto-prune policy endpoints
- endpoints/api/robot.py: Updated robot endpoints
- endpoints/api/build.py: Updated repository build logs
- endpoints/api/repository.py: Added license bypass for superusers with FULL_ACCESS
- endpoints/api/repository_models_pre_oci.py: Updated repository visibility query
- endpoints/api/logs.py: Fixed log access to require FULL_ACCESS for permission bypass
- endpoints/api/test/test_superuser_full_access.py: Added comprehensive test suite
- endpoints/api/test/test_appspecifictoken.py: Updated test mocking and added 403 test
- test/test_api_usage.py: Updated test expectations for license bypass behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
feat: Add image pull statistics API endpoints and UI integration
- Add new API endpoints for tag and manifest pull statistics
- Integrate pull metrics into web UI with new table columns
- Add FEATURE_IMAGE_PULL_STATS feature flag and PULL_METRICS_REDIS config
- Add pullstatsredisflushworker to supervisord configuration
- Add comprehensive test coverage for pull statistics functionality
Co-authored-by: shudeshp <shudeshp@redhat.com>
Implements global read-only superuser permissions for v1 endpoints, adjusts superuser write checks, and updates app token listing and detail endpoints; includes comprehensive tests.
---------
Co-authored-by: Claude <noreply@anthropic.com>
test(oidc): add comprehensive PKCE test coverage with improved diagnostics (PROJQUAY-9281)
Add extensive test suite for PKCE (Proof Key for Code Exchange) functionality
across multiple layers of the application:
Test Coverage:
- Core PKCE utilities (code_verifier generation, S256 challenge computation)
- OAuth base class integration with PKCE parameters
- OIDC service with PKCE fixtures and authorization scenarios
- Dedicated PKCE flow testing (S256/plain methods, public client support)
- API endpoint integration for user PKCE operations
- Login flow integration with session-based verifier storage
Features Tested:
- S256 and plain code challenge methods
- Public client support (omitting client_secret)
- Session-based code_verifier storage and retrieval
- Error handling for missing/invalid verifiers
- Integration with existing OIDC authorization flows
- Descriptive assertion messages for CI diagnostics
All tests include informative error messages with expected vs actual values
to improve debugging in CI environments.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* mirror: Add job timeout to mirror configurations (PROJQUAY-7249)
Previous global job timeout of 5 minutes was inadequate for big images. The timeout should now be configurable in much the same way as sync is. Minimum job length is 300 seconds/5 minutes.
The PR is still work in progress.
* Fix init db, remove reference to user data in logs
* Fix tests, change repo mirror configuration
* Fix tests, make mirroring cancellable through UI
* Add cancel mirror test, change HTML document to reflect mirror timeout
* Flake8 doesn't like when '==' is used with 'None'
* Fix mirror registry tests
* Add new cypress data to fix cypress tests
* Added ability to define upload chunk size to RADOS driver, small changes to repo mirror HTML page
* Fix database migration to follow HEAD
* Upload new database data for Cypress tests
* Make skopeo_timeout_interval mandatory on API calls
---------
Co-authored-by: Ivan Bazulic <ibazulic@redhat.com>
* db: use iterator chain for _get_user_repo_permissions (PROJQUAY-8839)
Unwrapping can cause increase in CPU. Use iterator chain to let
the caller unwrap
* initial checkin for the superuser/config endpoint to show how its intended to return data
bug: fixing NaN value error for quota displayed on member org page (PROJQUAY-6465) (#3224)
bug: fixing NaN value error for quota displayed on member org page (PROJQUAY-6465)
fixed black formatting
fixed flake and black formatting
fixed isort formatting
test need to be updated for superuser endpoints. There is no explicit superuser token test so globalreadonlysuperuser shall succeed too
fixed double json encoding
changed naming to comply with other SuperUserClasses, added SuperUserPermission check as scope only isnt sufficient
fixed another black error
fixed response for devtable check
fixed response for devtable as that is a superuser
fixed black format :/
added allow_if_global_readonly_superuser to config endpoint
repush for checks
fixed app.logger to module specific logger ; added missed SCHEMA return
added unittest for checking superuser config dump API call (no clue if the unittests build up a full setup since we mock all kind of stuff in the other calls)
removed env PWD check as it seems to be unset in the github runners
added missing unittest step
added FeatureFlag for config dump
formatting
* removed wrong commit in the branch
* changed from route decorator to in method check and changed unittests to fail as the default config is to deny the request
* added one test for security_tests
* rebumped the security tests
* db: optimize _get_user_repo_permissions to send to read replica (PROJQUAY-8839)
it uses a union query which doesn't invoke the replica selection
logic. Make this into 2 seperate queries
* fix unit tests
Fixes a bug where the annotation is required at the manifest level even if artifactType is present. The modelcard should only be indicated by the artifact type and layer annotation for oci artifacts.
* ui: implement change to render modelcard stored in layers (PROJQUAY-8412)
When a manifest has certain annotations or artifactTypes, render the
applicable modelcard markdown in a new tags detail tab.
* removing untar when fetching model card
* removing extra api calls
* Add modelcar check tests
---------
Co-authored-by: bcaton <bcaton@redhat.com>
* auth: Implement is_restricted_user for OIDC and allow super users to create content regardless of set restriction (PROJQUAY-8208)
Currently, if OIDC is set as an authentication mechanism and restricted users is set, Quay will return a `501 Not Implemented` on invocation. Now, Quay will properly check the restricted user whitelist for federated users.
Additionally, if user restriction is in place and super user's username was **not** explicitly whitelisted, super users would not be able to create new content inside the registry. Now, the username is explicitly checked in the UI to allow super users to create both organizations and repos regardless of restricted users whitelist.
* Add tests
* Add tests for usermanager
robots: Add robot federation for keyless auth (PROJQUAY-7652)
adds the ability to configure federated auth for robots by
using external OIDC providers. Each robot can be configured
to have multiple external OIDC providers as the source for
authentication.
Allows users to specify a regex tag pattern when creating namespace/repository autoprune policies via the new UI. Users will have the option to prune tags that only match the tag pattern or exclude tags that match the tag pattern.
* database: adding subject_backfilled index to manifest table (PROJQUAY-7360) (#2963)
adding subject_backfilled index to manifest table
* Rebasing with main
* updating cypress data
* fixing conflicts and rebasing with latest code
* adding tests
* Forcing an empty commit.
* Forcing an empty commit.
* skip_locked test fix
* adding tests
* minor fixes
---------
Co-authored-by: Brandon Caton <bcaton@redhat.com>
Reducing the number of DB calls in the repo list endpoint with quota enabled by:
- Adding the id to RepositoryBaseElement when the repositories are initially fetched, removing the need to fetch the repository ID's again
- Fetching the repository sizes with a single DB call using the IN operator
* feat: Add support for auto pruning at repository level (PROJQUAY-6354)
* Add repositoryautoprunepolicy table to alembic migration script
* Add repository auto-prune policy endpoints
* Add UI for repository auto-pruning policies
* case: apply repo auto-prune policy when no namespace policy given
* case: both namespace and repo pruning policy are given
* Add tests for repository autoprune endpoint
* Add cypress test for repository auto-prune
* Add repo auto-prune policy clean-up for repository deletion
* Add repository auto pruning tables to quay db snapshot for cypress tests
* Address review comments
* Add more tests + fix CI + reformat files
* Address review comments #2
---------
Signed-off-by: harishsurf <hgovinda@redhat.com>
* billing: marketplace UI
adds UI in billing section for managing user and org-bound skus
add more unit tests for org binding
changed endpoint for bulk attaching skus to orgs
* update reconciliationworker to use webCustomerId instead of
ebsAccountNumber
* fix reconciler where it was incorrectly using the ebsAccountNumber to
create subscriptions
* add job to reconciler so that it reconciles different ids between the
database and the user api
* separate skus to be used by billing and skus to be used by reconciler
* chore: pass config to isort as it doesn't always detect it
* chore: mark package "test" as local, not stdlib
* chore: remove "isort: skip_file"
* chore: fix app in test_load_security_information
* chore: fix app in test_notification
* chore: fix app in test_index_report
* add migration for orgrhskus table
* add endpoints for managing and listing skus bound to an org
* create checks in billing flow to look for org-bound skus
* refactor RH marketplace api objects to be more usable in tests
* update cypress test db data and exclude it from pre-commit hook formatting
Allows superusers to trigger a calculation of the deduplicated registry size. A superuser can go to the organization panel of the superuser page and select Calculate to queue a calculation of the registry total. The total will only be calculated when requested. Includes warning to user of increase of database load when running calculation.
Allows for only unique blobs are counted at the namespace and repository level. Calculation includes manifest list sizes.
Add's the following internal configurations that default to true:
QUOTA_INVALIDATE_TOTALS: Invalidates calculated totals when FEATURE_QUOTA_MANAGEMENT is set to false
RESET_CHILD_MANIFEST_EXPIRATION: Resets the expiry for child manifests on push of the manifest list for immediate GC eligibility
PERMANENTLY_DELETE_TAGS: Enables features related to the permanent deletion of tags outside the configured time machine window
* API/UI: Filtering of tags API through query parameter (PROJQUAY-5362)
* Changing syntax of query param to add operation + added propagation of filtering from new UI
* added exception to return 400 on incorrect syntax
* Added tests to test filtering of /tags endpoint
* Minor fixes