Commit graph

5 commits

Author SHA1 Message Date
Brook Miles
9354efceb1 fix: quota evaluation rules not working properly (#9033)
This patch is mainly intended to fix forgejo/forgejo#7721, and to fix forgejo/forgejo#9019.

It also changes the evaluation of 0 limits to prevent all writes, instead of allowing one write and then failing on subsequent writes after the limit has been exceeded.  This matches the expectation of the existing tests, and I believe it will better match the expectations of users.

Tests have been updated accordingly where necessary, and some additional test coverage added.

The fixes in this PR depend on each other in order for the quota system to function correctly, so I'm submitting them as a single PR instead of individually.

## Test Cases

### Quota subjects not covered by their parent subjects

Before enabling quotas, create a test user and test repository for that user.

Enable quotas, and set a default total to some large value.  (Do not use unit suffixes forgejo/forgejo#8996)

```ini
[quota]
ENABLED = true

[quota.default]
TOTAL = 1073741824
```

With the test user, navigate to "Storage overview" and verify that the quota group "Global quota" is the only group listed, containing the rule "Default", and displays the configured limit, and that the limit has not been exceeded (eg. `42 MiB / 1 GiB`).

The default quota rule has the subject `size:all`, so any write action should be allowed.

#### Attempt to create a new repository.

Expected result: Repository is created.
Actual result: Error 413, You have exhausted your quota.

#### Attempt to create a new file in the existing repository.

Expected result: File is created.
Actual result: Error 413, You have exhausted your quota.

#### Create an issue on the test repository, and attempt to upload an image to the issue.

Expected result: Image is uploaded.
Actual Result: Quota exceeded. Displays error message: `JavaScript promise rejection: can't access property "submitted", oi[ji.uuid] is undefined. Open browser console to see more details.`

### Unlimited quota rules incorrectly allow all writes

With quotas enabled, [Use the API](https://forgejo.org/docs/latest/admin/advanced/quota/#advanced-usage-via-api) to create a quota group containing a single rule with a subject of `size:git:lfs`, and a limit of `-1` (Unlimited).  Add the test user to this group.

```json
{
  "name": "git-lfs-unlimited",
  "rules": [
    {
      "name": "git-lfs-unlimited",
      "limit": -1,
      "subjects": ["size:git:lfs"]
    }
  ]
}
```

With the test user, navigate to "Storage overview" and verify that the user has been added to this group, that it is the only group the user is assigned to, and that the rule limit displays as "Unlimited".

The user should only have the ability to write to Git LFS storage, all other writes should be denied.

#### Attempt to create a new repository.

Expected result: Error 413, You have exhausted your quota.
Actual result: Repository is created.

#### Attempt to create a new file in the test repository.

Expected result: Error 413, You have exhausted your quota.
Actual result: File is created.

#### Create an issue on the test repository, and attempt to upload an image to the issue.

Expected Result: Quota exceeded.
Actual result: Image is uploaded.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9033
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Brook Miles <brook@noreply.codeberg.org>
Co-committed-by: Brook Miles <brook@noreply.codeberg.org>
2025-09-08 01:05:55 +02:00
Renovate Bot
fed2d81c44 Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367)
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-03-28 22:22:21 +00:00
Gusted
2457f5ff22 chore: branding import path (#7337)
- Massive replacement of changing `code.gitea.io/gitea` to `forgejo.org`.
- Resolves forgejo/discussions#258

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7337
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Beowulf <beowulf@beocode.eu>
Reviewed-by: Panagiotis "Ivory" Vasilopoulos <git@n0toose.net>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-03-27 19:40:14 +00:00
Gusted
f78e397dd6
[TESTS] Move CreateDeclarativeRepo to more accessible location
- This allows `CreateDeclarativeRepo` to be used by other testing
packages such as E2EE testing.
- Removes unused function in `services/webhook/sourcehut/builds_test.go`.
2024-08-25 02:54:43 +02:00
Gergely Nagy
67fa52dedb
feat(quota): Quota enforcement
The previous commit laid out the foundation of the quota engine, this
one builds on top of it, and implements the actual enforcement.

Enforcement happens at the route decoration level, whenever possible. In
case of the API, when over quota, a 413 error is returned, with an
appropriate JSON payload. In case of web routes, a 413 HTML page is
rendered with similar information.

This implementation is for a **soft quota**: quota usage is checked
before an operation is to be performed, and the operation is *only*
denied if the user is already over quota. This makes it possible to go
over quota, but has the significant advantage of being practically
implementable within the current Forgejo architecture.

The goal of enforcement is to deny actions that can make the user go
over quota, and allow the rest. As such, deleting things should - in
almost all cases - be possible. A prime exemption is deleting files via
the web ui: that creates a new commit, which in turn increases repo
size, thus, is denied if the user is over quota.

Limitations
-----------

Because we generally work at a route decorator level, and rarely
look *into* the operation itself, `size:repos:public` and
`size:repos:private` are not enforced at this level, the engine enforces
against `size:repos:all`. This will be improved in the future.

AGit does not play very well with this system, because AGit PRs count
toward the repo they're opened against, while in the GitHub-style fork +
pull model, it counts against the fork. This too, can be improved in the
future.

There's very little done on the UI side to guard against going over
quota. What this patch implements, is enforcement, not prevention. The
UI will still let you *try* operations that *will* result in a denial.

Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
2024-08-02 11:10:34 +02:00