Compare commits

...

308 commits

Author SHA1 Message Date
Matthias Riße
0a767458c5 Cache git-annex UUID to repository path mappings (#54)
Always walking the filesystem and searching for UUIDs slowed p2phttp
operations down significantly on a production server with more than a
handful of repositories. This caching strategy ensures that only the
first call is rather slow, and subsequent ones should be much faster.

This should better be implemented as a background job, but for now this
is a simple solution to the problem.

Fixes #53.

Reviewed-on: https://codeberg.org/forgejo-aneksajo/forgejo-aneksajo/pulls/54
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
676aa26f51 Explicitly set http(s) default ports in annex.url (#55)
Otherwise, git-annex tries to use its own default port (9417) and fails.

Fixes #52.

Reviewed-on: https://codeberg.org/forgejo-aneksajo/forgejo-aneksajo/pulls/55
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
7e26a31d40 Fix Forgejo version in published OCI images (#51)
The Forgejo version is derived from the git history, so the image build
needs to happen in the context of a full repository clone.

Also, the post-processing of the version string needs to remove the
second occurrence of "-g", as the first one is now part of the added
"-git-annex" part.

Reviewed-on: https://codeberg.org/forgejo-aneksajo/forgejo-aneksajo/pulls/51
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
0060a01037 Add an OCI image build and publish workflow (#50)
Fixes #49.

Reviewed-on: https://codeberg.org/forgejo-aneksajo/forgejo-aneksajo/pulls/50
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
d420606d5b Simplify git blob to annex key lookup (#43)
Fixes #27.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/43
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
2156267087 Add git-annex p2phttp support (#42)
This adds a new endpoint under `/git-annex-p2phttp` which acts as an
authenticating proxy to git-annex' p2phttp server. This makes it
possible to set `annex+<server-url>/git-annex-p2phttp` as
`remote.<name>.annexurl` and use git-annex fully over http(s) with the
normal credentials and access tokens provided by Forgejo.

Fixes #25.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/42
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
9397f06242 Add tests for git annex drop (#47)
This adds some rudimentary tests that drop files in a repository's clone
as well as from a repository on Forgejo.

Fixes #4.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/47
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
c5cab5db55 Add git-annex' testremote to the test suite (#48)
The `git annex testremote` command runs a built-in set of tests against
a remote. It cannot hurt to check our implementation of a git-annex
remote against it too.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/48
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
2aebfe3041 Only upload to annex in doAnnexUploadTest (#46)
The previous implementation both uploaded to the annex and pushed to the
git repository. This meant that the tests checking that uploads without
permission fail actually could pass when the git push failed but the
git-annex upload didn't. The tests didn't catch the situation where
unauthorized users could modify the annex.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/46
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
ecadd69dc1 Use the latest git-annex-standalone release in CI (#45)
This is a prerequisite for #25, as p2phttp requires a newer git-annex
version than is available from NeuroDebian.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/45
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
06e14867ec Use PATH when looking for git commands (#44)
This fixes some issues when using a git-annex that is installed in a
different location than where git is installed, e.g. when using the
git-annex-standalone release or one installed with nix.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/44
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
9b509264e4 Allow anonymous HEAD requests to annex/objects (#41)
Git-annex emits HEAD requests for keys while trying to drop them from a
repository that was cloned via http. Forgejo asked for authentication
for these HEAD requests. This meant that cloning and getting files was
possible without authentication, but dropping was not.

Since the response to a HEAD request is a subset of the response to a
GET request it is safe to make those unauthenticated as well. That is
what this change does, although limited to the
:username/:reponame/annex/objects endpoint.

Fixes #40.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/41
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Michael Hanke
92694c3eb7 Elevate external markup renderer interface for annexed file content (#36)
Previously, an external renderer that matched on an annexed file would
only see its content streamed via `STDIN`, or a temporary file with a copy
of its content would be generated and passed-by-filepath (with
`IS_INPUT_FILE=true`). Whether that happens, is also subject to
`MAX_DISPLAY_FILE_SIZE` (which defaults to 8MB).

This was problematic, because annexed files tend to be large. Moreover,
if present, they already exist as write-protected files on the
file-system. Creating a copy is both expensive and serves no particular
purpose.

This commit changes how external renderers are called.

1) With `IS_INPUT_FILE=true`, the renderer is passed the true location
   of an annex key, if present, and an empty path, if not.
2) The original, repository-relative path of the rendering target is
   made available to the renderer via the `GITEA_RELATIVE_PATH`
   environment variable.

To achieve a lean implementation, the `Blob` of the rendering target
is passed on to the `RenderContext` (because the implementation of
the annex-related functionality is centered on this dtype.

This change makes it less costly to increase `MAX_DISPLAY_FILE_SIZE`,
in order to make large, annexed files eligible for markup rendering,
because no content copies will be made any longer.

External renderers can now use the original file path, with the full
original filename, including extensions, for decision making. For
example, to detect particular compression formats based in a file name
extension, or to alter the rendering based on contextual information
encoded in the file path (e.g., a multi-file data structure with a
particular organization pattern).

Apart from the additional environment variable, there is no change to
the handling of renderers that take their input via `STDIN` (i.e.,
`IS_INPUT_FILE=false`).

Fixes #35.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/36
Reviewed-by: matrss <matrss@noreply.codeberg.org>
Co-authored-by: Michael Hanke <michael.hanke@gmail.com>
Co-committed-by: Michael Hanke <michael.hanke@gmail.com>
2024-12-16 08:23:15 +01:00
Matthias Riße
5b10daf327 Change the icon for annexed files to file-binary (#29)
Fixes #26.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/29
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
0bd997ac3a Improve views for annexed but missing files (#28)
Previously, trying to view files that were annexed, but missing, just
led to an uninformative error 500. This was rather confusing.

With these changes it now shows the pointer target instead of the
(missing) content of the file, and also indicates this situation in the
"stored with git-annex" message. For semantic correctness views for
missing files return a 404 instead of a 200, as they would with the
content present.

Fixes #7, fixes #13.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/28
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Michael Hanke
a930583ff3 Add git-annex also to the rootless container (#24)
Same as 89f8aa0bf5, but for the rootless container.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/24
Reviewed-by: matrss <matrss@noreply.codeberg.org>
Co-authored-by: Michael Hanke <michael.hanke@gmail.com>
Co-committed-by: Michael Hanke <michael.hanke@gmail.com>
2024-12-16 08:23:15 +01:00
Matthias Riße
fedaedc758 Git-annex web uploads (#21)
This implements support for uploading files into the annex using the web
interface.

If a repository is a git-annex-enabled repository all files will be
added to it using git annex add. This means that the repository's
configuration for what to put into the annex (annex.largefiles in
gitattributes) will be respected.

Plain git repositories without git-annex will work as before, directly
uploading to git.

Fixes #5.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/21
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
d42570d616 Error if git-annex is enabled but missing (#16)
Copied from https://github.com/neuropoly/gitea/pull/47

This adds a check so that if `setting.Annex.Enabled` is true and git-annex is not in the PATH Forgejo will abort on startup with a reasonable error message.

Fixes #15.

Reviewed-on: https://codeberg.org/matrss/forgejo-aneksajo/pulls/16
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2024-12-16 08:23:15 +01:00
Matthias Riße
67824b8917 Add git-annex to docker image 2024-12-16 08:23:15 +01:00
Matthias Riße
1b64d1a5be Adapt patch to upstream changes
Test with different objectFormats.
2024-12-16 08:23:15 +01:00
Nick
60b3b755ae git-annex: views for annex files
This updates the repo index/file view endpoints so annex files match the way
LFS files are rendered, making annexed files accessible via the web instead of
being black boxes only accessible by git clone.

This mostly just duplicates the existing LFS logic. It doesn't try to combine itself
with the existing logic, to make merging with upstream easier. If upstream ever
decides to accept, I would like to try to merge the redundant logic.

The one bit that doesn't directly copy LFS is my choice to hide annex-symlinks.
LFS files are always _pointer files_ and therefore always render with the "file"
icon and no special label, but annex files come in two flavours: symlinks or
pointer files. I've conflated both kinds to try to give a consistent experience.

The tests in here ensure the correct download link (/media, from the last PR)
renders in both the toolbar and, if a binary file (like most annexed files will be),
in the main pane, but it also adds quite a bit of code to make sure text files
that happen to be annexed are dug out and rendered inline like LFS files are.
2024-12-16 08:23:15 +01:00
Matthias Riße
c48a1bc3c1 Adapt patch to upstream changes
Use tests.FileCmp instead of util.FileCmp.
2024-12-16 08:20:21 +01:00
Matthias Riße
363748d684 Adapt patch to upstream changes
Test with different objectFormats.
2024-12-16 08:20:21 +01:00
Nick
5ad3cd4f10 git-annex: make /media/ download annexed content
Previously, Gitea's LFS support allowed direct-downloads of LFS content,
via http://$HOSTNAME:$PORT/$USER/$REPO/media/branch/$BRANCH/$FILE
Expand that grace to git-annex too. Now /media should provide the
relevant *content* from the .git/annex/objects/ folder.

This adds tests too. And expands the tests to try symlink-based annexing,
since /media implicitly supports both that and pointer-file-based annexing.
2024-12-16 08:20:21 +01:00
Matthias Riße
522f17fc03 Adapt patch to upstream changes
The git repository must be closed after using it. Without this change
some tests started to fail due to the lingering repository running into
a timeout.
2024-12-16 08:20:21 +01:00
Nick
8453d0f55a git-annex: create modules/annex
This moves the `annexObjectPath()` helper out of the tests and into a
dedicated sub-package as `annex.ContentLocation()`, and expands it with
`.Pointer()` (which validates using `git annex examinekey`),
`.IsAnnexed()` and `.Content()` to make it a more useful module.

The tests retain their own wrapper version of `ContentLocation()`
because I tried to follow close to the API modules/lfs uses, which in
terms of abstract `git.Blob` and `git.TreeEntry` objects, not in terms
of `repoPath string`s which are more convenient for the tests.
2024-12-16 08:20:21 +01:00
Matthias Riße
f1dd61c94f Adapt patch to upstream changes
The "context_service" import was changed to use the default name of just
"context". The patch set had to be adapted for that.
2024-12-16 08:20:21 +01:00
Matthias Riße
e25811bafd Adapt patch to upstream changes
Usage of `path` was replaced by `path/filepath` in upstream forgejo, and
it made sense to use that as well where `path` was previously used. The
`setHeaderCacheForever` function and the `sendFile` method had their
signature changed.
2024-12-16 08:20:21 +01:00
Matthias Riße
dda21c92b9 Fix exit code check for git command
The err.IsExitCode method was changed to a function IsErrorExitCode
taking err as its first argument in
1e7a6483b8.
2024-12-16 08:20:21 +01:00
Matthias Riße
09c61ca291 Replace m.GetOptions with m.Methods
This applies the same changes that were done in
265cd70bdb to the git-annex specific
routes as well.
2024-12-16 08:20:21 +01:00
Nick
aba4fdb268 git-annex: support downloading over HTTP
This makes HTTP symmetric with SSH clone URLs.

This gives us the fancy feature of _anonymous_ downloads,
so people can access datasets without having to set up an
account or manage ssh keys.

Previously, to access "open access" data shared this way,
users would need to:

  1. Create an account on gitea.example.com
  2. Create ssh keys
  3. Upload ssh keys (and make sure to find and upload the correct file)
  4. `git clone git@gitea.example.com:user/dataset.git`
  5. `cd dataset`
  6. `git annex get`

This cuts that down to just the last three steps:

  1. `git clone https://gitea.example.com/user/dataset.git`
  2. `cd dataset`
  3. `git annex get`

This is significantly simpler for downstream users, especially for those
unfamiliar with the command line.

Unfortunately there's no uploading. While git-annex supports uploading
over HTTP to S3 and some other special remotes, it seems to fail on a
_plain_ HTTP remote. See https://github.com/neuropoly/gitea/issues/7
and https://git-annex.branchable.com/forum/HTTP_uploads/#comment-ce28adc128fdefe4c4c49628174d9b92.

This is not a major loss since no one wants uploading to be anonymous anyway.

To support private repos, I had to hunt down and patch a secret extra security
corner that Gitea only applies to HTTP for some reason (services/auth/basic.go).

This was guided by https://git-annex.branchable.com/tips/setup_a_public_repository_on_a_web_site/

Fixes https://github.com/neuropoly/gitea/issues/3

Co-authored-by: Mathieu Guay-Paquet <mathieu.guaypaquet@polymtl.ca>
2024-12-16 08:20:21 +01:00
Nick
25e0ad154f git-annex: add configuration setting [annex].ENABLED
Fixes https://github.com/neuropoly/gitea/issues/8

Co-authored-by: Mathieu Guay-Paquet <mathieu.guaypaquet@gmail.com>
2024-12-16 08:20:21 +01:00
Matthias Riße
a641732624 Fix failing tests
Multiple tests that worked fine on v1.20.4-1 started to fail after the
rebase onto v1.20.5-1. These tests are:
- TestGitAnnexPermissions/Private/Owner/HTTP/Init
- TestGitAnnexPermissions/Private/Owner/HTTP/Download
- TestGitAnnexPermissions/Private/Writer/HTTP/Init
- TestGitAnnexPermissions/Private/Writer/HTTP/Download
- TestGitAnnexPermissions/Private/Reader/HTTP/Init
- TestGitAnnexPermissions/Private/Reader/HTTP/Download

What these tests have in common is that they all operate on a private
repository via http with authentication.

They broke at some point between v1.20.4-1 and v1.20.5-1, so I did a
bisect between these two points running the offending tests. This
brought me to the conclusion that
ee48c0d5ea introduced the issue.

The thing is, this commit does not change any code, it only changes the
test environment. Among other things that didn't look as suspicious, it
changes the container image from a bespoke test_env image based on
debian bullseye to a node image based on debian bookworm. Obviously,
this means that there are many version differences between the two.

The first one I looked at was git. The previous bullseye image used a
manually installed git version 2.40.0, while the bookworm image has
2.39.2 installed. Updating git in the new image did not fix the issue,
however.

The next thing I looked at was the git-annex version. Bullseye had
8.20210223 installed and worked, while bookworm used 10.20230126 when
the tests broke. So I tried my luck upgrading to a more recent version
via neurodebian (10.20240227-1~ndall+1). This still worked fine on
bullseye and now also works fine on bookworm.

I have no idea why this specific version of git-annex broke the tests,
but at least there was a commit to pinpoint this to, which isn't always
the case with docker images silently changing beneath you...

Below are the versions as they are reported by git and git-annex:

bullseye (works):

    git version 2.30.2
    git-annex version: 8.20210223
    build flags: Assistant Webapp Pairing Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite S3 WebDAV
    dependency versions: aws-0.22 bloomfilter-2.0.1.0 cryptonite-0.26 DAV-1.3.4 feed-1.3.0.1 ghc-8.8.4 http-client-0.6.4.1 persistent-sqlite-2.10.6.2 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.1.0
    key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
    remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
    operating system: linux x86_64
    supported repository versions: 8
    upgrade supported from repository versions: 0 1 2 3 4 5 6 7

bullseye + git-annex from neurodebian (works):

    git version 2.30.2
    git-annex version: 10.20240227-1~ndall+1
    build flags: Assistant Webapp Pairing Inotify DBus DesktopNotify TorrentParser MagicMime Benchmark Feeds Testsuite S3 WebDAV
    dependency versions: aws-0.22.1 bloomfilter-2.0.1.0 cryptonite-0.29 DAV-1.3.4 feed-1.3.2.1 ghc-9.0.2 http-client-0.7.13.1 persistent-sqlite-2.13.1.0 torrent-10000.1.1 uuid-1.3.15 yesod-1.6.2.1
    key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
    remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
    operating system: linux x86_64
    supported repository versions: 8 9 10
    upgrade supported from repository versions: 0 1 2 3 4 5 6 7 8 9 10

bookworm (fails):

    git version 2.39.2
    git-annex version: 10.20230126
    build flags: Assistant Webapp Pairing Inotify DBus DesktopNotify TorrentParser MagicMime Benchmark Feeds Testsuite S3 WebDAV
    dependency versions: aws-0.22.1 bloomfilter-2.0.1.0 cryptonite-0.29 DAV-1.3.4 feed-1.3.2.1 ghc-9.0.2 http-client-0.7.13.1 persistent-sqlite-2.13.1.0 torrent-10000.1.1 uuid-1.3.15 yesod-1.6.2.1
    key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
    remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
    operating system: linux x86_64
    supported repository versions: 8 9 10
    upgrade supported from repository versions: 0 1 2 3 4 5 6 7 8 9 10

bookworm + git-annex from neurodebian (works):

    git version 2.39.2
    git-annex version: 10.20240227-1~ndall+1
    build flags: Assistant Webapp Pairing Inotify DBus DesktopNotify TorrentParser MagicMime Benchmark Feeds Testsuite S3 WebDAV
    dependency versions: aws-0.22.1 bloomfilter-2.0.1.0 cryptonite-0.29 DAV-1.3.4 feed-1.3.2.1 ghc-9.0.2 http-client-0.7.13.1 persistent-sqlite-2.13.1.0 torrent-10000.1.1 uuid-1.3.15 yesod-1.6.2.1
    key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
    remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
    operating system: linux x86_64
    supported repository versions: 8 9 10
    upgrade supported from repository versions: 0 1 2 3 4 5 6 7 8 9 10
2024-12-16 08:20:21 +01:00
Matthias Riße
e055a4e2b5 Install git-annex in the testing workflow 2024-12-16 08:20:21 +01:00
Matthias Riße
42d2e534d8 Adapt patch to upstream changes 2024-12-16 08:20:21 +01:00
Matthias Riße
2561339dfa Adapt patch to upstream changes
A dead code check started to complain because FileCmp was only used in
tests. Moved the function to test_utils.
2024-12-16 08:20:21 +01:00
Matthias Riße
fa7b28d0a7 Adapt patch to upstream changes
Repository creation now expects an objectFormat to be specified for git.
2024-12-16 08:20:21 +01:00
Nick
1917545953 git-annex tests
Fixes https://github.com/neuropoly/gitea/issues/11

Tests:

* `git annex init`
* `git annex copy --from origin`
* `git annex copy --to origin`

over:

* ssh

for:

* the owner
* a collaborator
* a read-only collaborator
* a stranger

in a

* public repo
* private repo

And then confirms:

* Deletion of the remote repo (to ensure lockdown isn't messing with us: https://git-annex.branchable.com/internals/lockdown/#comment-0cc5225dc5abe8eddeb843bfd2fdc382)

------

To support all this:

* Add util.FileCmp()
* Patch withKeyFile() so it can be nested in other copies of itself

-------

Many thanks to Mathieu for giving style tips and catching several bugs,
including a subtle one in util.filecmp() which neutered it.

Co-authored-by: Mathieu Guay-Paquet <mathieu.guay-paquet@polymtl.ca>
2024-12-16 08:20:21 +01:00
Nick Guenther
4cc80314c9 git-annex support
[git-annex](https://git-annex.branchable.com/) is a more complicated cousin to
git-lfs, storing large files in an optional-download side content.  Unlike lfs,
it allows mixing and matching storage remotes, so the content remote(s) doesn't
need to be on the same server as the git remote, making it feasible to scatter
a collection across cloud storage, old harddrives, or anywhere else storage can
be scavenged.  Since this can get complicated, fast, it has a content-tracking
database (`git annex whereis`) to help find everything later.

The use-case we imagine for including it in Gitea is just the simple case, where
we're primarily emulating git-lfs: each repo has its large content at the same URL.

Our motivation is so we can self-host https://www.datalad.org/ datasets, which
currently are only hostable by fragilely scrounging together cloud storage --
and having to manage all the credentials associated with all the pieces -- or at
https://openneuro.org which is fragile in its own ways.

Supporting git-annex also allows multiple Gitea instance to be annex remotes for
each other, mirroring the content or otherwise collaborating the split up the
hosting costs.

Enabling
--------

TODO

HTTP
----

TODO

Permission Checking
-------------------

This tweaks the API in routers/private/serv.go to expose the calling user's
computed permission, instead of just returning HTTP 403.

This doesn't fit in super well. It's the opposite from how the git-lfs support is
done, where there's a complete list of possible subcommands and their matching
permission levels, and then the API compares the requested with the actual level
and returns HTTP 403 if the check fails.

But it's necessary. The main git-annex verbs, 'git-annex-shell configlist' and
'git-annex-shell p2pstdio' are both either read-only or read-write operations,
depending on the state on disk on either end of the connection and what the user
asked it to ask for, with no way to know before git-annex examines the situation.
So tell the level via GIT_ANNEX_READONLY and trust it to handle itself.

In the older Gogs version, the permission was directly read in cmd/serv.go:

```
mode, err = db.UserAccessMode(user.ID, repo)
```
- 966e925cf3/internal/cmd/serv.go (L334)

but in Gitea permission enforcement has been centralized in the API layer.
(perhaps so the cmd layer can avoid making direct DB connections?)

Deletion
--------

git-annex has this "lockdown" feature where it tries
really quite very hard to prevent you deleting its
data, to the point that even an rm -rf won't do it:
each file in annex/objects/ is nested inside a
folder with read-only permissions.

The recommended workaround is to run chmod -R +w when
you're sure you actually want to delete a repo. See
https://git-annex.branchable.com/internals/lockdown

So we edit util.RemoveAll() to do just that, so now
it's `chmod -R +w && rm -rf` instead of just `rm -rf`.
2024-12-16 08:20:20 +01:00
Matthias Riße
4979f33677 Fix name in package-lock.json
The frontend-checks job started failing because the declared name does
not match the repository name.
2024-12-16 08:20:20 +01:00
Matthias Riße
0d1f0e0c05 Run testing workflow unconditionally 2024-12-16 08:20:20 +01:00
Earl Warren
d595393bb6 Merge pull request '[v9.0/forgejo] fix: ensure correct ssh public key is used for authentication' (#6253) from earl-warren/forgejo:wip-9.0-ssh into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6253
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
2024-12-12 07:06:13 +00:00
Earl Warren
83b614e1e8 Merge pull request '[v9.0/forgejo] fix: Revert "allow synchronizing user status from OAuth2 login providers (#31572)"' (#6251) from bp-v9.0/forgejo-7f8f9b8 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6251
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-12 07:02:40 +00:00
Gusted
dc15aefa3e
fix: ensure correct ssh public key is used for authentication
- The root cause is described in b4f1988a35
- Move to a fork of `github.com/gliderlabs/ssh` that exposes the
permissions that was chosen by `x/crypto/ssh` after succesfully
authenticating, this is the recommended mitigation by the Golang
security team. The fork exposes this, since `gliderlabs/ssh` instead
relies on context values to do so, which is vulnerable to the same
attack, although partially mitigated by the fix in `x/crypto/ssh` it
would not be good practice and defense deep to rely on it.
- Existing tests covers that the functionality is preserved.
- No tests are added to ensure it fixes the described security, the
exploit relies on non-standard SSH behavior it would be too hard to
craft SSH packets to exploit this.

(cherry picked from commit 3e1b03838e)

Conflicts:
	go.mod
	go.sum
  trivial context conflict
2024-12-12 07:09:00 +01:00
Gusted
29a0b0131e fix: Revert "allow synchronizing user status from OAuth2 login providers (#31572)"
This commit has a fundamental flaw, in order to syncronize if external
users are still active the commit checks if the refresh token is
accepted by the OAuth provider, if that is not the case it sees that as
the user is disabled and sets the is active field to `false` to signal
that. Because it might be possible (this commit makes this a highly
likelyhood) that the OAuth provider still recognizes this user the
commit introduces code to allow users to re-active themselves via the
oauth flow if they were disabled because of this. However this code
makes no distinction in why the user was disabled and always re-actives
the user.

Thus the reactivation via the OAuth flow allows users to bypass the
manually activation setting (`[service].REGISTER_MANUAL_CONFIRM`) or if
the admin for other reasons disabled the user.

This reverts commit 21fdd28f08.

(cherry picked from commit 7f8f9b878f)
2024-12-12 05:43:20 +00:00
Earl Warren
71dc491a09 Merge pull request 'Update module golang.org/x/crypto to v0.31.0 (v9.0/forgejo)' (#6247) from renovate/v9.0/forgejo-golang.org-x-crypto-0.x into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6247
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-12 05:06:00 +00:00
Renovate Bot
d39571dc53 Update module golang.org/x/crypto to v0.31.0 2024-12-12 04:38:53 +00:00
Earl Warren
591b1f54a3 Merge pull request '[v9.0/forgejo] chore(ci): set the milestone when a pull request is closed (take 4)' (#6231) from bp-v9.0/forgejo-6f53f7d into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6231
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-10 11:59:37 +00:00
Earl Warren
a5e26e3ad0 chore(ci): set the milestone when a pull request is closed (take 4)
The milestone can only be determined to be final when a pull request
is merged.

It is possible that a pull request is opened during the development of
v10 and merged after it is published.

It is also possible that it is permanently closed without being merged.

(cherry picked from commit 6f53f7d007)
2024-12-10 06:21:30 +00:00
Earl Warren
8e3d076750 Merge pull request '[v9.0/forgejo] chore(ci): set the milestone when a pull request is open (take 3)' (#6225) from bp-v9.0/forgejo-bf9e19c into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6225
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-09 23:38:46 +00:00
Earl Warren
2b66ddf352 chore(ci): set the milestone when a pull request is open (take 3)
pull_request_target runs from the target branch, not the default branch

(cherry picked from commit bf9e19cc21)
2024-12-09 22:56:21 +00:00
Earl Warren
d8ca6f0581 Merge pull request '[v9.0/forgejo] chore(ci): set the milestone when a pull request is open' (#6217) from bp-v9.0/forgejo-1f18d8d into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6217
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-09 16:46:29 +00:00
Earl Warren
bf84528109
chore(ci): set the milestone when a pull request is open (take 2)
Use the oci:ci image to get jq

(cherry picked from commit ebfe702df6)
2024-12-09 17:42:44 +01:00
Earl Warren
485ffc4bae chore(ci): set the milestone when a pull request is open
(cherry picked from commit 1f18d8d677)
2024-12-09 16:17:37 +00:00
Gusted
bda9ee9b83 Merge pull request 'Update dependency @github/relative-time-element to v4.4.4 (v9.0/forgejo)' (#6176) from renovate/v9.0/forgejo-github-relative-time-element-4.x into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6176
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-12-06 03:15:14 +00:00
Renovate Bot
f5a32bd4fd Update dependency @github/relative-time-element to v4.4.4 2024-12-06 02:03:50 +00:00
Otto
02844b48c3 Merge pull request '[v9.0/forgejo] Do not rewrite ssh keys files when deleting a user without one' (#6168) from bp-v9.0/forgejo-3c9b3dd into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6168
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-06 00:01:49 +00:00
Andreas Shimokawa
3beefb29b9 Do not rewrite ssh keys files when deleting a user without one (#6097)
### Problem

Big instances can have huge authorized_keys files when using OpenSSH instead of the internal ssh server. Forgejo always re-generates the contents of that file when a user is deleted, even if he does not even have a public key uploaded. In case of codeberg.org, a 15MB file gets rewritten. If we batch delete 100 Spam users without ssh keys, we rewrite 1.5GB, this takes time and wears the SSD. In addition, there is a high chance of hitting a race contidion bug, when deleting users in parallel.

### Solution / Mitigation

This patch prevents rewriting authorized_keys files, when not necessary. It greatly speeds up deleting malicious users, saves IO bandwidth and SSD wear. It also greatly reduces the chance of hitting a race condition bug. Fixing the race condition is not the scope of this patch though.

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [x] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6097
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Andreas Shimokawa <shimokawa@fsfe.org>
Co-committed-by: Andreas Shimokawa <shimokawa@fsfe.org>
(cherry picked from commit 3c9b3ddf5c)
2024-12-05 21:32:48 +00:00
Otto
8fa76300ae Merge pull request '[v9.0/forgejo] fix: remove softbreak from github legacy callout' (#6155) from bp-v9.0/forgejo-216a542 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6155
Reviewed-by: Otto <otto@codeberg.org>
2024-12-05 00:16:18 +00:00
Gusted
e741d0a068 fix: remove softbreak from github legacy callout
- A softbreak was being preserved during the github legacy callout (this
is likely due to a change in Goldmark) while it should not. This caused
an `<br>` to be present between the attention title and attention content.
- Added unit test.

(cherry picked from commit 216a542bfb)
2024-12-04 23:12:58 +00:00
Gusted
ad1aad7b1a Merge pull request '[v9.0/forgejo] fix: correct permission loading for limited organisation' (#6149) from bp-v9.0/forgejo-bc9f1e2 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6149
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-12-04 20:54:15 +00:00
Gusted
48fa9c96a7 fix: correct permission loading for limited organisation
- If a organisation is set to be limited visible, then it will still be
visible for signed-in users. However `UnitPermission` didn't take this
into account, it does now.
- Add unit test.
- Resolves #6141

(cherry picked from commit bc9f1e2533)
2024-12-04 17:57:42 +00:00
Earl Warren
1de8d5b450 Merge pull request '[v9.0/forgejo] fix: clean up log files that no longer exist' (#6131) from bp-v9.0/forgejo-4e8677a into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6131
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-03 08:04:41 +00:00
Gusted
0ce1c56612 fix: clean up log files that no longer exist
- If for some reason a action log file does not longer exist in the
database or on the file system, then mark it as being cleaned up.
- Unit test added.

(cherry picked from commit 4e8677a911)
2024-12-03 07:08:16 +00:00
Gusted
9b29e8add1 Merge pull request '[v9.0/forgejo] fix: dbconsistency check adding missing quotes' (#6129) from bp-v9.0/forgejo-b525eec into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6129
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-12-03 05:07:03 +00:00
Gusted
4069e1c934 Merge pull request '[v9.0/forgejo] fix: return correct type in GetSubModule' (#6127) from bp-v9.0/forgejo-e7cffc3 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6127
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-12-03 04:35:52 +00:00
Gusted
74e1fd16b0 Merge pull request 'fix: dbconsistency check adding missing quotes' (#6124) from 71rd/forgejo:dbconsistency-forgejo into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6124
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
(cherry picked from commit b525eec82b)
2024-12-03 04:07:18 +00:00
Gusted
532c35c25a Fix: return correct type in GetSubModule
- `GetSubModules` already solely stores the URL of the submodule and not
a `*SubModule` entry, so don't try to type assert it to be a struct.
- I am not able to pinpoint when this was regressed but if I had to
guess it might be #4941.
- Added integration test.

(cherry picked from commit e7cffc378f)
2024-12-03 03:24:54 +00:00
Otto
eeb3451a89 Merge pull request '[v9.0/forgejo] Fix wiki search overflowing on wide screens (#6047)' (#6104) from spiffyk/forgejo:bp-v9.0/wiki-search-too-wide into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6104
Reviewed-by: Otto <otto@codeberg.org>
2024-11-30 17:16:10 +00:00
Oto Šťáva
fe6f4fde20
Cap wiki search width at 80% container width
Co-Authored-By: Zuzana Slavíková <zuza.slavik@email.cz>
2024-11-30 17:11:07 +01:00
Oto Šťáva
c98bd3a11d
Fix wiki search overflowing on wide screens (#6047)
Confine the search menu to be at most the width of the page, or 80% of
the viewport width, whichever is smaller. To do this, introduce a new
`--container-width` variable for the descendant elements of
`.ui.container` to be able to access.

Also update the relevant e2e test: add a long 'lorem ipsum' page, add a
search for it, parameterize the width.
2024-11-30 17:10:57 +01:00
Otto
5cffc09c37 Merge pull request '[v9.0/forgejo] Improve Swagger documentation for user endpoints' (#6092) from bp-v9.0/forgejo-b074e08-76fb2af into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6092
Reviewed-by: Otto <otto@codeberg.org>
2024-11-29 13:16:38 +00:00
JakobDev
d3e5d887ee Run make tidy
(cherry picked from commit 76fb2afc40)
2024-11-28 20:44:16 +00:00
JakobDev
72cbefe63e Improve Swagger documentation for user endpoints
(cherry picked from commit b074e08f34)
2024-11-28 20:44:16 +00:00
Earl Warren
a167d7b91c Merge pull request '[v9.0/forgejo] fix: normalize guessed languages from enry' (#6085) from bp-v9.0/forgejo-7aeb1ba into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6085
2024-11-27 21:39:54 +00:00
Gusted
c5f37b6cd8 fix: normalize guessed languages from enry
- In the case that Enry correctly recognized the language, but returns
the language name in a way that isn't recognized by enry. Although
overkill I've added a map such that new entries should be easier to add.
- Resolves #6077
- Added unit test

(cherry picked from commit 7aeb1ba1d5)
2024-11-27 18:25:12 +00:00
Earl Warren
a494510972 Merge pull request '[gitea] week 2024-48-v9.0 cherry pick (gitea/main -> v9.0/forgejo)' (#6064) from earl-warren/wcp/2024-48-v9.0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6064
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-27 18:22:15 +00:00
Gusted
714308506e Merge pull request '[v9.0/forgejo] Show page titles in wiki search results (#6048)' (#6070) from bp-v9.0/forgejo-fc31fa0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6070
Reviewed-by: Shiny Nematoda <snematoda@noreply.codeberg.org>
Reviewed-by: Oto Šťáva <spiffyk@noreply.codeberg.org>
2024-11-25 15:12:06 +00:00
Oto Šťáva
2374f8f47d Show page titles in wiki search results (#6048)
Replace wiki page filenames with page titles in the search results,
fixing the problem with them showing unreadable URI-encoded names.

(cherry picked from commit fc31fa0eeb)
2024-11-25 14:18:18 +00:00
Earl Warren
1f9a1537a5
chore(release-notes): notes for the week 2024-48-v9.0 weekly cherry pick 2024-11-24 16:53:22 +00:00
Rowan Bohde
48872d11ca
allow the actions user to login via the jwt token (#32527)
We have some actions that leverage the Gitea API that began receiving
401 errors, with a message that the user was not found. These actions
use the `ACTIONS_RUNTIME_TOKEN` env var in the actions job to
authenticate with the Gitea API. The format of this env var in actions
jobs changed with go-gitea/gitea/pull/28885 to be a JWT (with a
corresponding update to `act_runner`) Since it was a JWT, the OAuth
parsing logic attempted to parse it as an OAuth token, and would return
user not found, instead of falling back to look up the running task and
assigning it to the actions user.

Make ACTIONS_RUNTIME_TOKEN in action runners could be used,
attempting to parse Oauth JWTs. The code to parse potential old
`ACTION_RUNTIME_TOKEN` was kept in case someone is running an older
version of act_runner that doesn't support the Actions JWT.

(cherry picked from commit 407b6e6dfc7ee9ebb8a16c7f1a786e4c24d0516e)

Conflicts:
	services/auth/oauth2.go
  trivial context conflicts because OAuth2 scopes are in Forgejo and
  not yet in Gitea
2024-11-24 16:51:29 +00:00
Lunny Xiao
1c04f8f10a
Fix submodule parsing
(cherry picked from commit 33850a83fe4ebd23a762a7aac81614c42e303bfa)

This really is just the cherry pick of 407b6e6dfc7ee9ebb8a16c7f1a786e4c24d0516e
which is the first commit of the pull request, the one with the
change. The rest of the changes is a refactor that is unrelated to the
bug fix.

Conflicts:
	modules/git/commit_test.go
  trivial context conflict
2024-11-24 16:49:54 +00:00
Lunny Xiao
bf520f5184
Fix GetInactiveUsers (#32540)
Fix #31480

(cherry picked from commit 9bf821ae6c108379d22ae11d8d5784a4ed7ad647)

Conflicts:
	models/user/user_test.go
  trivial context conflict
2024-11-24 16:46:39 +00:00
0ko
c089228bfa [v9.0/forgejo] i18n: backport of translation updates 5754, 5845, 5960 (#6060)
v9-applicable changes were picked from these commits:
* 600be26638
* e600fe97a3
* b576a2fd40
* also dfe3ffc581

Some changes from these commits were not picked and it's possible that this commit does not include any changes from some of the co-authors listed below.

Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: Anonymous <anonymous@users.noreply.translate.codeberg.org>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: Atalanttore <Atalanttore@users.noreply.translate.codeberg.org>
Co-authored-by: Atul_Eterno <Atul_Eterno@users.noreply.translate.codeberg.org>
Co-authored-by: Benedikt Straub <Nordfriese@users.noreply.translate.codeberg.org>
Co-authored-by: Dirk <Dirk@users.noreply.translate.codeberg.org>
Co-authored-by: dobrvlskyi <dobrvlskyi@users.noreply.translate.codeberg.org>
Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Co-authored-by: Edgarsons <Edgarsons@users.noreply.translate.codeberg.org>
Co-authored-by: faoquad <faoquad@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: kwoot <kwoot@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <Outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: raspher <raspher@users.noreply.translate.codeberg.org>
Co-authored-by: SomeTr <SomeTr@users.noreply.translate.codeberg.org>
Co-authored-by: WithLithum <WithLithum@users.noreply.translate.codeberg.org>
Co-authored-by: xtex <xtexchooser@duck.com>
Co-authored-by: yumechi <yumechi@users.noreply.translate.codeberg.org>

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6060
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-11-24 12:00:31 +00:00
Otto
934e92c346 Merge pull request '[v9.0/forgejo] fix: Do not delete global Oauth2 applications' (#6057) from bp-v9.0/forgejo-665d5f7-1d5aee6 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6057
Reviewed-by: Otto <otto@codeberg.org>
2024-11-24 11:44:23 +00:00
Otto Richter
219d07dc96 fix: Do not delete global Oauth2 applications
(cherry picked from commit 1d5aee6ef8)
2024-11-23 22:48:42 +00:00
Otto Richter
90db3f6132 test: Global OAuth should not be deleted
Expected to fail: Global (instance-wide) OAuth application should not be deleted, but it is

(cherry picked from commit 665d5f7317)
2024-11-23 22:48:41 +00:00
Earl Warren
73d9e14e80 Merge pull request '[v9.0/forgejo] chore(ci): remove unused experimental DNS updates' (#6035) from earl-warren/forgejo:wip-v9.0-dns-update into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6035
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-20 16:46:26 +00:00
Earl Warren
ca45316707
chore(ci): remove unused experimental DNS updates
(cherry picked from commit a69943085a)

Conflicts:
	.forgejo/workflows/publish-release.yml
  trivial context conflict
2024-11-20 15:59:00 +00:00
Earl Warren
6f825ab156 Merge pull request '[gitea] week 2024-47-v9.0 cherry pick (gitea/main -> v9.0/forgejo)' (#5998) from earl-warren/wcp/2024-47-v9.0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5998
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-18 18:30:46 +00:00
Earl Warren
0b0eefd42b Merge pull request '[v9.0/forgejo] fix(test): TestGitAttributeCheckerError must allow broken pipe' (#6016) from bp-v9.0/forgejo-b9697f5 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6016
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-18 12:23:09 +00:00
Earl Warren
3e967fa4a0 fix(test): TestGitAttributeCheckerError must allow broken pipe
Early cancelation can lead to two kinds of error. Either canceled or
broken pipe, depending on when the goroutine stops.

Fixes: forgejo/forgejo#6012
(cherry picked from commit b9697f5227)
2024-11-18 11:32:19 +00:00
Gusted
ee753450a7 Merge pull request '[v9.0/forgejo] fix: use better code to group UID and stopwatches' (#6004) from bp-v9.0/forgejo-e4eb82b into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6004
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-17 21:45:42 +00:00
Earl Warren
616348fc6f Merge pull request '[v9.0/forgejo] fix: check read permissions for code owner review requests' (#6005) from bp-v9.0/forgejo-693f773 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6005
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-17 21:04:31 +00:00
Earl Warren
5b2db9d3ca
chore(release-notes): notes for the week 2024-47-v9.0 weekly cherry pick 2024-11-17 20:52:58 +01:00
wxiaoguang
53c5469511
Fix and refactor markdown rendering (#32522)
(cherry picked from commit 5eebe1dc5fb29a162c51d050396fce7b14e47f4e)

Conflicts:
	models/repo/repo.go
	models/repo/repo_test.go
	modules/markup/html.go
	modules/markup/html_commit.go
	modules/markup/html_email.go
	modules/markup/html_emoji.go
	modules/markup/html_internal_test.go
	modules/markup/html_issue.go
	modules/markup/html_link.go
	modules/markup/html_node.go
	modules/markup/html_test.go
	modules/markup/markdown/goldmark.go
	modules/markup/markdown/markdown_test.go
	modules/markup/markdown/transform_image.go
	modules/markup/orgmode/orgmode.go
	modules/markup/orgmode/orgmode_test.go
	modules/markup/render.go
	modules/markup/render_links.go
	modules/templates/util_render.go
	modules/templates/util_render_test.go
	routers/common/markup.go
	routers/web/feed/convert.go
	routers/web/repo/wiki.go
  but a few lines survived and are useful
2024-11-17 20:50:50 +01:00
Gusted
0ca5b8496b fix: check read permissions for code owner review requests
- Only send a review request based on the code owner file if the code
owner user has read permissions to the pull requests of that repository.
- This avoids leaking title of PRs from private repository when a
CODEOWNER file is present which contains users that do not have access
to the private repository.
- Found by @oliverpool.
- Integration test added.

(cherry picked from commit 693f7731f9)
2024-11-17 19:19:11 +00:00
Gusted
35435c573a fix: use better code to group UID and stopwatches
- Instead of having code that relied on the result being sorted (which
wasn't specified in the query and therefore not safe to assume so). Use
a map where it doesn't care if the result that we get from the database
is sorted or not.
- Added unit test.

(cherry picked from commit e4eb82b738)
2024-11-17 19:18:45 +00:00
Lunny Xiao
8cec637d08
Disable Oauth check if oauth disabled (#32368)
Fix #32367

---------

Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 840ad7eefe2b49ab453b9a89b153a264a8c9f8a2)

Conflicts:
	services/auth/oauth2.go
  trivial context conflict
2024-11-17 11:48:37 +01:00
wxiaoguang
9f05c76b7b
Fix nil panic if repo doesn't exist (#32501)
fix  #32496

(cherry picked from commit 985e2a8af3d6468bac3ab178148c38bdbd8414f5)
2024-11-17 11:45:54 +01:00
Lunny Xiao
6ac04b8c7d
Fix oauth2 error handle not return immediately (#32514)
(cherry picked from commit 4121f952d18a4c3a3c08ae645af3458ef08b439d)
2024-11-17 11:44:09 +01:00
Gusted
004fe296cc Merge pull request '[v9.0/forgejo] fix: api repo compare with commit hashes' (#5993) from bp-v9.0/forgejo-e434ecd-d2dc4fa-1b9d124-01c9c19-ca0cd42 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5993
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-17 00:26:44 +00:00
Angel Nunez Mencias
978542cae4 simplify test based on feedback
(cherry picked from commit ca0cd42d7a)
2024-11-16 23:36:28 +00:00
Angel Nunez Mencias
dc785fdae5 fmt
(cherry picked from commit 01c9c19536)
2024-11-16 23:36:28 +00:00
angelnu
c9a3e963ec add test
(cherry picked from commit 1b9d1240eb)
2024-11-16 23:36:28 +00:00
angelnu
a887612b75 review changes
(cherry picked from commit d2dc4fae3a)
2024-11-16 23:36:27 +00:00
angelnu
a27e4bb586 check IsCommitExist
(cherry picked from commit e434ecdaca)
2024-11-16 23:36:27 +00:00
Earl Warren
5058c76f3e Merge pull request '[v9.0/forgejo] bug: correctly generate oauth2 jwt signing key' (#5992) from bp-v9.0/forgejo-7d59060 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5992
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-16 18:07:38 +00:00
Gusted
90e05e7d52 bug: correctly generate oauth2 jwt signing key
- When RS256, RS384, ES384, ES512 was specified as the JWT signing
algorithm they would generate RS512 and ES256 respectively.
- Added unit test.

(cherry picked from commit 7d59060dc6)
2024-11-16 17:07:01 +00:00
Earl Warren
6569f1f25f Merge pull request '[v9.0/forgejo] fix: 15 November 2024 security fixes batch' (#5975) from earl-warren/forgejo:wip-v9.0-security-15-11 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5975
Reviewed-by: Otto <otto@codeberg.org>
2024-11-15 11:57:38 +00:00
Earl Warren
2f72bec100
[v9.0/forgejo] chore(release-notes): 15 November 2024 security fixes 2024-11-15 11:46:38 +01:00
Gusted
42f3644409
fix: disallow basic authorization when security keys are enrolled
- This unifies the security behavior of enrolling security keys with
enrolling TOTP as a 2FA method. When TOTP is enrolled, you cannot use
basic authorization (user:password) to make API request on behalf of the
user, this is now also the case when you enroll security keys.
- The usage of access tokens are the only method to make API requests on
behalf of the user when a 2FA method is enrolled for the user.
- Integration test added.

(cherry picked from commit e6bbecb02d)
2024-11-15 11:33:45 +01:00
Gusted
1770117178
fix: extend forgejo_auth_token table
- Add a `purpose` column, this allows the `forgejo_auth_token` table to
be used by other parts of Forgejo, while still enjoying the
no-compromise architecture.
- Remove the 'roll your own crypto' time limited code functions and
migrate them to the `forgejo_auth_token` table. This migration ensures
generated codes can only be used for their purpose and ensure they are
invalidated after their usage by deleting it from the database, this
also should help making auditing of the security code easier, as we're
no longer trying to stuff a lot of data into a HMAC construction.
-Helper functions are rewritten to ensure a safe-by-design approach to
these tokens.
- Add the `forgejo_auth_token` to dbconsistency doctor and add it to the
`deleteUser` function.
- TODO: Add cron job to delete expired authorization tokens.
- Unit and integration tests added.

(cherry picked from commit 1ce33aa38d)

v9: Removed migration - XORM can handle this case automatically without
migration. Add `DEFAULT 'long_term_authorization'`.
2024-11-15 11:33:17 +01:00
Gusted
1379914c45
Improve usage of HMAC output for mailer tokens
- If the incoming mail feature is enabled, tokens are being sent with
outgoing mails. These tokens contains information about what type of
action is allow with such token (such as replying to a certain issue
ID), to verify these tokens the code uses the HMAC-SHA256 construction.
- The output of the HMAC is truncated to 80 bits, because this is
recommended by RFC2104, but RFC2104 actually doesn't recommend this. It
recommends, if truncation should need to take place, it should use
max(80, hash_len/2) of the leftmost bits. For HMAC-SHA256 this works out
to 128 bits instead of the currently used 80 bits.
- Update to token version 2 and disallow any usage of token version 1,
token version 2 are generated with 128 bits of HMAC output.
- Add test to verify the deprecation of token version 1 and a general
MAC check test.

(cherry picked from commit 9508aa7713)
2024-11-15 11:33:08 +01:00
Gusted
254bded75e
fix: strict matching of allowed content for sanitizer
- _Simply_ add `^$` to regexp that didn't had it yet, this avoids any
content being allowed that simply had the allowed content as a
substring.
- Fix file-preview regex to have `$` instead of `*`.

(cherry picked from commit 7067cc7da4)

v9: added fix for ref-issue, this is already fixed in forgejo branch but
not backported as it was part of a feature.
2024-11-15 11:32:51 +01:00
Gusted
a88e3e6ac0
fix: anomynous users code search for private/limited user's repository
- Consider private/limited users in the `AccessibleRepositoryCondition`
query, previously this only considered private/limited organization.
This limits the ability for anomynous users to do code search on
private/limited user's repository
- Unit test added.

(cherry picked from commit b70196653f)
2024-11-15 11:32:38 +01:00
Gusted
6c75d1a504
fix: require code permissions for branch feed
- The RSS and atom feed for branches exposes details about the code, it
therefore should be guarded by the requirement that the doer has access
to the code of that repository.
- Added integration testing.

(cherry picked from commit 3e3ef76808)
2024-11-15 11:32:24 +01:00
Gusted
36300be94e
fix: don't show private forks in forks list
- If a repository is forked to a private or limited user/organization,
the fork should not be visible in the list of forks depending on the
doer requesting the list of forks.
- Added integration testing for web and API route.

(cherry picked from commit 061abe6004)
2024-11-15 11:32:09 +01:00
Gusted
c8c8377acb
fix: add ID check for updating push mirror interval
- Ensure that the specified push mirror ID belongs to the requested
repository, otherwise it is possible to modify the intervals of the push
mirrors that do not belong to the requested repository.
- Integration test added.

(cherry picked from commit 786dfc7fb8)
2024-11-15 11:31:28 +01:00
Earl Warren
fd4a68b4de Merge pull request '[v9.0/forgejo] chore(ci): ROLE forgejo-coding & forgejo-testing' (#5952) from earl-warren/forgejo:wip-v9.0-testing-only into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5952
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-14 11:28:49 +00:00
Earl Warren
78f69040fc
chore(ci): ROLE forgejo-coding & forgejo-testing (part two)
When the CI vars.ROLE is forgejo-coding, it is assumed to be the
repository where collaborative coding happens,
i.e. https://codeberg.org/forgejo/forgejo

When the CI vars.ROLE is forgejo-testing, it is assumed that only codebase
testing is to be run and no other tests such as release build
integration, label constraints, backporting etc.

(cherry picked from commit 068558accd)

Conflicts:
	.forgejo/workflows/testing.yml
  was in .forgejo/workflows/e2e.yml
2024-11-14 10:12:36 +01:00
Earl Warren
3465f73e2c
chore(ci): ROLE forgejo-coding & forgejo-testing
When the CI vars.ROLE is forgejo-coding, it is assumed to be the
repository where collaborative coding happens,
i.e. https://codeberg.org/forgejo/forgejo

When the CI vars.ROLE is forgejo-testing, it is assumed that only codebase
testing is to be run and no other tests such as release build
integration, label constraints, backporting etc.

(cherry picked from commit f82840f1ea)

Conflicts:
	.forgejo/workflows/merge-requirements.yml
2024-11-14 10:09:44 +01:00
Otto
86496d701d Merge pull request '[v9.0/forgejo] fix: handle renamed dependency for cargo registry' (#5945) from bp-v9.0/forgejo-bb93d3e into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5945
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-13 23:13:42 +00:00
Gusted
de389f2ecc fix: handle renamed dependency for cargo registery
- When a dependency is renamed, specified via `package="actual-name"` in
Cargo.toml, this should become the name of the depedency when the
package is retrieved from the registery by cargo and the old name should
be available in the `package` field.
- The reference implementation also does this: 490e66a9d6/src/controllers/krate/publish.rs (L702-L705)
- Resolves #5936
- Unit test added.

(cherry picked from commit bb93d3e6c8)
2024-11-13 22:56:30 +00:00
Earl Warren
e43533cd1b Merge pull request '[v9.0/forgejo] chore(release): also copy the release to code.forgejo.org' (#5937) from bp-v9.0/forgejo-7492330 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5937
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-13 18:33:57 +00:00
Earl Warren
2a78dba95b chore(ci): trigger a mirror when a release is publish
Notify https://code.forgejo.org/forgejo/forgejo that a new release was
published by setting the trigger label to
https://code.forgejo.org/forgejo/forgejo/issues/5.

It is only ever useful when a stable release is published, the
experimental releases are not mirrored. But it is triggered in all
cases. This will waste a few mirror check daily, when experimental
releases are built. This is an improvement compared to the current
situation where mirrors are checked hourly:

* Instead of being checked 24 times per day it will be down to less
  than 5
* The mirror happens immediately after the release is published
  instead of waiting for the next run of the cron job.

If a mirror operation is in progress, as evidenced by the presence of
the trigger label on the issure, it means two releases are being
published. Wait up to 1h for the mirror to complete and remove the
trigger label.

(cherry picked from commit 7492330721)
2024-11-13 16:53:43 +00:00
Earl Warren
e9cd753b98 Merge pull request '[v9.0/forgejo] fix(ci): synchronize updates the commit status asynchronously' (#5926) from bp-v9.0/forgejo-983aed4 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5926
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-12 12:33:20 +00:00
Earl Warren
dac13b7fc3 fix(ci): synchronize updates the commit status asynchronously
When a new commit is pushed to an existing pull request, the update of
the commit status will happen asynchronously, via the git hook.

   --- FAIL: TestPullRequestCommitStatus/synchronize (2.14s)
        actions_trigger_test.go:331:
            	Error Trace:	/workspace/forgejo/forgejo/tests/integration/actions_trigger_test.go:331
            	Error:      	Should be true
            	Test:       	TestPullRequestCommitStatus/synchronize

(cherry picked from commit 983aed4268)
2024-11-12 11:53:06 +00:00
Otto
0db515dfec Merge pull request '[v9.0/forgejo] fix: Move forgot_password-link to fix login tab order' (#5887) from fnetx/bp-5838 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5887
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-10 13:41:51 +00:00
Gusted
336ccf45c8 Merge pull request '[v9.0/forgejo] fix(ui): Details icon in repo settings sidebar' (#5891) from bp-v9.0/forgejo-5932b86 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5891
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-10 12:54:50 +00:00
Otto Richter
70aefc810c fix(ui): Details icon in repo settings sidebar
Consistent classes between both details/summary constructs in the sidebar, ensuring they have the same style.

(cherry picked from commit 5932b86af4)
2024-11-10 02:13:45 +00:00
MrSmoer
6025b93664 Remove unused css class "form-field-content-aside-label"
This css class was used to display the "forgot password"-link right and above the password field.
cd75519a0b moves this link, so this class is now unused
2024-11-10 02:24:58 +01:00
MrSmoer
e823122f19 fix: Move "forgot_password"-link to fix login tab order
Previously hitting tab in the username field set the focus to the "forgot password" link. Only on the next hit the password field was selected.
This is an issue for some password managers (keepassdx android keyboard) and not as nice for accessibility.
Now the forgot link is below the sign up link at the bottom of the page.
Using "tabindex" didn't work properly with the templating engine because many elements get assigned a tabindex of "0" by default disrupting the tab selection sequence.
2024-11-10 02:24:58 +01:00
Gusted
ef9df01cd2 Merge pull request '[v9.0/forgejo] [THEME] Copy ansi terminal colours from gitea to forgejo themes' (#5882) from bp-v9.0/forgejo-e58d5d4 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5882
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-09 22:40:07 +00:00
Ragnar Groot Koerkamp
2e114bcaa0 [THEME] Copy ansi terminal colours from gitea to forgejo themes
(cherry picked from commit e58d5d46c1)
2024-11-09 21:57:08 +00:00
Gusted
91a12abdaf Merge pull request '[v9.0/forgejo] [PORT] Fix code owners will not be mentioned when a pull request comes from a forked repository (gitea#30476)' (#5879) from bp-v9.0/forgejo-2efc1f5-536e192 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5879
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-11-09 19:21:37 +00:00
Gusted
79bc6e8c35 chore: add extra integration test
(cherry picked from commit 536e1923b4)
2024-11-09 18:43:38 +00:00
Lunny Xiao
770fa89dc8 [PORT] Fix code owners will not be mentioned when a pull request comes from a forked repository (gitea#30476)
Fix #30277
Caused by #29783

---

- Resolves #5842
- Regression from #2855

(cherry picked from commit c63060b130d34e3f03f28f4dccbf04d381a95c17)
(cherry picked from commit 2efc1f5686)
2024-11-09 18:43:37 +00:00
Earl Warren
9a7b0c3f02 Merge pull request '[v9.0/forgejo] bug: require.Eventually must not test with assert' (#5870) from bp-v9.0/forgejo-2541a94 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5870
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-09 00:39:12 +00:00
Earl Warren
8c51053739 bug: require.Eventually must not test with assert
Otherwise it fails the test instead of retrying if the condition fails
at least once.

(cherry picked from commit 2541a943ce)
2024-11-08 23:42:01 +00:00
Otto
3a4612cb2b Merge pull request '[v9.0/forgejo] chore(renovate): only run if renovate workflow changed' (#5861) from bp-v9.0/forgejo-2eeb2fc into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5861
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-08 12:58:13 +00:00
Michael Kriese
c0113bfbbe chore(renovate): only run if renovate workflow changed
(cherry picked from commit 2eeb2fcd35)
2024-11-08 12:43:09 +00:00
Renovate Bot
08396d566b Update dependency happy-dom to v15.10.2 [SECURITY] (v9.0/forgejo) (#5854)
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2024-11-08 06:39:14 +00:00
Otto
66b6917923 Merge pull request '[v9.0/forgejo] fix: issue labels are not set after deleting one label' (#5844) from bp-v9.0/forgejo-db899c1-f06bdb0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5844
Reviewed-by: Otto <otto@codeberg.org>
2024-11-07 11:22:14 +00:00
Earl Warren
397b3cf88f chore(refactor): split ReloadLabels out of LoadLabels in issue model
Functions modifying the labels in the database (DeleteIssueLabel,
NewIssueLabels, NewIssueLabel, ReplaceIssueLabels) need to force
reload them. Instead of:

	issue.isLabelsLoaded = false
	issue.Labels = nil
	if err = issue.LoadLabels(ctx); err != nil {
		return err
	}

They can now use:

	if err = issue.ReloadLabels(ctx); err != nil {
		return err
	}

(cherry picked from commit f06bdb0552)
2024-11-07 10:38:36 +00:00
Earl Warren
bcb72df356 fix: issue labels are not set after deleting one label
Because issue.isLabelsLoaded = false is missing, LoadLabels is a noop
and the issue.Labels is nil.

(cherry picked from commit db899c19d8)
2024-11-07 10:38:36 +00:00
Earl Warren
ed2d5f6b73 Merge pull request '[v9.0/forgejo] fix: labels are missing in the pull request payload removing a label' (#5834) from bp-v9.0/forgejo-c801838 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5834
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-07 08:03:00 +00:00
Earl Warren
eda6b436dc fix: labels are missing in the pull request payload removing a label
When ReplaceIssueLabels calls issue.LoadLabels it was a noop because
issue.isLabelsLoaded is still set to true because of the call  to
issue.LoadLabels that was done at the beginning of the function.

(cherry picked from commit c801838690)
2024-11-06 17:38:04 +00:00
Earl Warren
09a35a7cb8 Merge pull request '[v9.0/forgejo] Add label to Forgejo Actions PR labeled/unlabeled events and update the commit status' (#5810) from bp-v9.0/forgejo-58e3c1f-66c85b7-f56fc51 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5810
Reviewed-by: Otto <otto@codeberg.org>
2024-11-06 16:13:39 +00:00
Otto
a68a37f59c Merge pull request '[v9.0/forgejo] chore(ci): deprecate legacy infrastructure supporting v*.next' (#5823) from bp-v9.0/forgejo-ece87d0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5823
Reviewed-by: Otto <otto@codeberg.org>
2024-11-05 22:30:44 +00:00
Earl Warren
2b86ff6768 chore(ci): deprecate legacy infrastructure supporting v*.next
https://code.forgejo.org/infrastructure/k8s/ was replaced with
https://code.forgejo.org/infrastructure/k8s-cluster/
(cherry picked from commit ece87d0569)
2024-11-05 21:43:31 +00:00
Earl Warren
8a65c4d28d chore(release-notes): related pull requests workflow fixes
(cherry picked from commit f56fc51c74)
2024-11-04 14:10:27 +00:00
Earl Warren
d624a5edd6 fix: Actions PR workflows must update the commit status
When a workflow has

on:
  pull_request:
    types:
      - labeled
      - unlabeled

The outcome of the workflow (success or failure) must be associated
with the head sha commit status. Otherwise it cannot be used as a
requirement for merging the pull request (branch protections).

(cherry picked from commit 66c85b7d8b)
2024-11-04 14:10:27 +00:00
Earl Warren
11f71dcb09 fix: add label to issues and PR labeled/unlabeled events
When a workflow has

on:
  pull_request:
    types:
      - labeled
      - unlabeled

The payload misses the label field describing the added or removed
label.

The unlabeled event type was also incorrectly mapped to the labeled
event type.

(cherry picked from commit 58e3c1fbdb)
2024-11-04 14:10:27 +00:00
Earl Warren
7ec30b6ee9 Merge pull request '[v9.0/forgejo] chore(ci): notify the k8s cluster about experimental releases' (#5807) from earl-warren/forgejo:wip-v9.0-next-digest into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5807
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-04 13:52:05 +00:00
Earl Warren
13a5d9f3af
[v9.0/forgejo] chore(ci): notify the k8s cluster about experimental releases
This is in preparation of the migration of the v*.next.forgejo.org
instances currently managed at https://code.forgejo.org/infrastructure/k8s

The key difference is that the former system relies on ad-hoc scripts
and creates one k8s cluster for each instance, sharing nothing between
them.

The newer k8s cluster is used for all and requires significantly less
ad-hoc tooling.

See also:

* https://code.forgejo.org/infrastructure/next-digest
* https://code.forgejo.org/infrastructure/k8s-cluster/src/branch/main/k8s.md#updating-v-next-forgejo-org

(cherry picked from commit dab156b452)
2024-11-04 14:30:53 +01:00
Gusted
a429dbad98 Merge pull request '[v9.0/forgejo] fix: support www.github.com for migrations' (#5800) from bp-v9.0/forgejo-284ffe4 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5800
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-03 18:21:04 +00:00
Michael Kriese
0c0fd333f3 fix: support www.github.com for migrations
(cherry picked from commit 284ffe4e00)
2024-11-03 17:28:30 +00:00
Earl Warren
d96cef1ac4 Merge pull request '[v9.0/forgejo] fix: reset history.scrollRestoration if set to manual and no issue anchor in url' (#5753) from bp-v9.0/forgejo-ec4a0e1 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5753
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-01 10:10:25 +00:00
Earl Warren
3f58b8d1bd Merge pull request '[v9.0/forgejo] fix git-grep for code search when git version is below 2.38' (#5759) from earl-warren/forgejo:wip-v9.0-grep into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5759
Reviewed-by: Otto <otto@codeberg.org>
2024-10-31 21:12:18 +00:00
Shiny Nematoda
908bd64238
fix(grep): fix git-grep for code search when git version is below 2.38
(cherry picked from commit f2ab4ff83a)

Conflicts:
	modules/git/grep.go
  trivial context conflict
2024-10-31 21:26:03 +01:00
Earl Warren
be36f91bb7 Merge pull request '[v9.0/forgejo] i18n: update of translations from Codeberg Translate' (#5748) from bp-v9.0/forgejo-031451e into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5748
Reviewed-by: Otto <otto@codeberg.org>
2024-10-31 06:38:23 +00:00
Michael Kriese
8e4536fd98 fix: reset history.scrollRestoration if set to manual and no issue anchor in url
(cherry picked from commit ec4a0e1b6e)
2024-10-31 02:37:43 +00:00
Codeberg Translate
f043fb4495 i18n: update of translations from Codeberg Translate (#5681)
Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: emansije <emansije@users.noreply.translate.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: Outbreak2096 <Outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: Benedikt Straub <Nordfriese@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: Bálint Gonda <balinteus@gmail.com>
Co-authored-by: Wuzzy <Wuzzy@users.noreply.translate.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5681
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit 031451e740)
2024-10-30 15:15:39 +00:00
Earl Warren
1dc03cc1c3 Merge pull request '[v9.0/forgejo] use constant time check for internal token' (#5724) from bp-v9.0/forgejo-53231ba into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5724
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-28 08:03:48 +00:00
Earl Warren
e4dac6a6ab Merge pull request '[v9.0/forgejo] add permission check to 'delete branch after merge'' (#5721) from bp-v9.0/forgejo-266e0b2 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5721
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-28 07:24:05 +00:00
Earl Warren
ff585d0a20 Merge pull request '[gitea] week 2024-44-v9.0 cherry pick (gitea/main -> v9.0/forgejo)' (#5715) from earl-warren/wcp/2024-44-v9.0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5715
2024-10-28 06:59:58 +00:00
Gusted
5f9a2ad1db fix(sec): use constant time check for internal token
(cherry picked from commit 53231bad61)
2024-10-28 06:17:25 +00:00
Gusted
618eb8e72a security: add permission check to 'delete branch after merge'
- Add a permission check that the doer has write permissions to the head
repository if the the 'delete branch after merge' is enabled when
merging a pull request.
- Unify the checks in the web and API router to `DeleteBranchAfterMerge`.
- Added integration tests.

(cherry picked from commit 266e0b2ce9)
2024-10-28 06:04:45 +00:00
Earl Warren
d763886dae
chore(release-notes): notes for the week 2024-44-v9.0 weekly cherry pick 2024-10-27 12:05:14 +01:00
Lunny Xiao
768402c884
Fix disable 2fa bug (#32320)
(cherry picked from commit 2abdbe88b5d16dcb345d27b73f1d9738f2d826dd)
2024-10-27 11:57:08 +01:00
Lunny Xiao
9c6f2a132d
Add warn log when deleting inactive users (#32318)
Add log for the problem #31480

(cherry picked from commit a264c46fb04112c5ec2c1b2acd523a2e4450da40)

Conflicts:
	- services/user/user.go
	  Resolved by manually adding the log line.
2024-10-27 11:54:36 +01:00
Otto
d77096071d Merge pull request '[v9.0/forgejo] fix: use buffered iterate for debian searchpackages' (#5710) from bp-v9.0/forgejo-459ab11 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5710
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-27 01:17:59 +00:00
Gusted
f0abba3eef fix: use buffered iterate for debian searchpackages
- The driver being used for PostgreSQL doesn't handle interleaved
queries (you start a query, read some rows and start another query while
you didn't finish that query yet), this is the case with using
`.Iterate` from XORM.
- Switch to a variant of what exist in the current codebase of
`db.Iterate`, which is a simple buffered iteration and doesn't keep
queries open, which allow other database operations to happen.
- Unit test added. This doesn't cover that postgres does not error on
this case, as this is not run with a postgres database.
- Resolves #5696

(cherry picked from commit 459ab11a8a)
2024-10-27 00:10:02 +00:00
Earl Warren
5d211c101f Merge pull request '[v9.0/forgejo] Fix boolean inputs in workflow_dispatch' (#5708) from bp-v9.0/forgejo-96c4ca2 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5708
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-26 06:42:18 +00:00
Mai-Lapyst
01e9ac0561 Fix boolean inputs in workflow_dispatch; closes #5425
(cherry picked from commit 96c4ca249a)
2024-10-26 06:00:50 +00:00
Earl Warren
a4e5b1b6bc Merge pull request '[v9.0/forgejo] fix: make branch protection work for new branches' (#5691) from bp-v9.0/forgejo-f5e0259 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5691
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-24 21:09:50 +00:00
Gusted
1f62fe8ae0 fix: make branch protection work for new branches
- If `GetAffectedFiles` is called for a push with an empty oldCommitID,
then set the oldCommitID to the empty tree. This will effictively diff
all the changes included in the push, which is the expected behavior for
branches.
- Integration test added.
- Resolves #5683
- Port of gitea#31778 but implemented differently.

(cherry picked from commit f5e025917f)
2024-10-24 20:21:43 +00:00
Earl Warren
96f0c76648 Merge pull request '[v9.0/forgejo] i18n: update of translations from Codeberg Translate' (#5680) from bp-v9.0/forgejo-f72567e into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5680
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-24 05:21:03 +00:00
Codeberg Translate
e37a344ce5 i18n: update of translations from Codeberg Translate (#5583)
Co-authored-by: SomeTr <SomeTr@users.noreply.translate.codeberg.org>
Co-authored-by: eldyj <eldyj@users.noreply.translate.codeberg.org>
Co-authored-by: Benedikt Straub <Nordfriese@users.noreply.translate.codeberg.org>
Co-authored-by: tkbremnes <tkbremnes@users.noreply.translate.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: meskobalazs <meskobalazs@users.noreply.translate.codeberg.org>
Co-authored-by: div72 <div72@users.noreply.translate.codeberg.org>
Co-authored-by: xtex <xtexchooser@duck.com>
Co-authored-by: kmpm <kmpm@users.noreply.translate.codeberg.org>
Co-authored-by: Fnurkla <Fnurkla@users.noreply.translate.codeberg.org>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: buhtz <buhtz@users.noreply.translate.codeberg.org>
Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: Dirk <Dirk@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <Outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: Atul_Eterno <Atul_Eterno@users.noreply.translate.codeberg.org>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5583
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit f72567ee14)
2024-10-24 04:39:43 +00:00
Earl Warren
887a9576b8 Merge pull request '[v9.0/forgejo] link to security policy in security.txt' (#5656) from bp-v9.0/forgejo-d06f1c6 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5656
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-22 18:05:09 +00:00
Earl Warren
edd468323f Merge pull request '[v9.0/forgejo] fix: don't show truncated comments in RSS/Atom feeds' (#5655) from bp-v9.0/forgejo-f4a7132 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5655
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-22 17:45:54 +00:00
Otto Richter
4b7f369290 link to security policy in security.txt
(cherry picked from commit d06f1c6856)
2024-10-22 16:51:21 +00:00
Gusted
ef8f366734 fix: don't show truncated comments in RSS/Atom feeds
- When a truncated comment is detected in the RSS/Atom feeds, fetch the
comment from the database and use the original content.
- Added integration test.
- Resolves #5650

(cherry picked from commit f4a7132a89)
2024-10-22 16:50:57 +00:00
Earl Warren
c5e4694327 Merge pull request '[gitea] week 2024-43-v9.0 cherry pick (gitea/main -> v9.0/forgejo)' (#5647) from earl-warren/wcp/2024-43-v9.0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5647
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-22 16:47:01 +00:00
Gusted
9471083571 Merge pull request '[v9.0/forgejo] fix: typo on releases for source code downloads' (#5654) from bp-v9.0/forgejo-02f8fad into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5654
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-10-22 15:22:50 +00:00
Michael Kriese
804051b9dd fix: typo on releases for source code downloads
Closes #5648

(cherry picked from commit 02f8fad54d)
2024-10-22 14:03:42 +00:00
Earl Warren
893d0941a8
chore(release-notes): weekly cherry-pick week 2024-43-v9.0 2024-10-22 07:36:59 +02:00
Zettat123
1913399d81
Always update expiration time when creating an artifact (#32281)
Fix #32256

(cherry picked from commit 9116665e9c1c01d882c919fb3058f7fdb695350e)
2024-10-22 07:28:30 +02:00
Zettat123
4fe311e7c0
Update scheduled tasks even if changes are pushed by "ActionsUser" (#32246)
Fix #32219

---------

Co-authored-by: delvh <dev.lh@web.de>
(cherry picked from commit 81aec6d621a3ea0dfb02d3b4d20b9be77c30c6ab)
2024-10-22 07:28:30 +02:00
Otto
b8ffb88d1d Merge pull request '[v9.0/forgejo] Revert "add gap between branch dropdown and PR button"' (#5645) from bp-v9.0/forgejo-04e2e15 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5645
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-10-21 22:13:03 +00:00
Otto Richter
fd8565c91a Revert "add gap between branch dropdown and PR button"
This change does not bring the desired benefit, because the button is
reinitialized from a Vue component once loaded, overriding this change
and causing a visual glitch upon page load (the button is moving its
position).

See the comment:

> this code must match the code in BranchTagSelector.vue

This button is also used in other places such as the release list where
the additional margin does not fit well. As such, this needs a new
solution.

This reverts commit 18cad9d342.

(cherry picked from commit 04e2e1510d)
2024-10-21 20:44:28 +00:00
Earl Warren
c87ff7dc1d Merge pull request '[v9.0/forgejo] package arch database not updating when uploading "any" architecture' (#5636) from bp-v9.0/forgejo-95c7599 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5636
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-21 06:04:38 +00:00
Earl Warren
7d3d8ef142 Merge pull request '[v9.0/forgejo] specify default value for EXPLORE_DEFAULT_SORT.' (#5629) from bp-v9.0/forgejo-f4be4e7 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5629
Reviewed-by: Otto <otto@codeberg.org>
2024-10-21 05:18:20 +00:00
Earl Warren
032bb17899 Merge pull request '[v9.0/forgejo] correct SQL query for active issues' (#5631) from bp-v9.0/forgejo-0055fdb into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5631
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-21 05:16:13 +00:00
dragon
fa307f06ac fix arch pkg
(cherry picked from commit 95c7599db5)
2024-10-21 05:10:13 +00:00
Gusted
d5c6036c53 fix: correct SQL query for active issues
- The `OR` should be inside the `AND` condition to not 'bypass' the other
conditions.
- Added minimal unit test.
- Regression from 2675a24649

(cherry picked from commit 0055fdbdc4)
2024-10-20 23:31:54 +00:00
Gusted
f3b16e1363 fix: Specify default value for EXPLORE_DEFAULT_SORT.
- This is another regression from
5a0bc35799, where the default value was
changed to "alphabetically" because it relied on `ExploreDefaultSort`
providing a fallback value.
- Set the default value for `EXPLORE_DEFAULT_SORT` to `recentupdate`,
this was already the behavior explicitly for existing users of this setting
but with 5a0bc35799 it didn't provide a
explicit fallback to `recentupdate`. So opting for a 'easy' fix, that
doesn't add boilerplate code to those instances.

(cherry picked from commit f4be4e733c)
2024-10-20 23:07:18 +00:00
Gusted
240fbc2661 Merge pull request '[v9.0/forgejo] fix: Add recentupdated as recognized sort option' (#5624) from bp-v9.0/forgejo-df38c41 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5624
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-20 12:38:24 +00:00
Gusted
642dd61446 fix: Add recentupdated as recognized sort option
- Add `recentupdated` to the `OrderByMap`.
- Add integration testing for organization and user repository sorting.
- Resolves #5612
- Regression from 12e23ee199 where the
`recentupdated` case was not added to the map, but was handled
seperately as a fallback. The regression came into affect when
5a0bc35799 also relied on this map but
didn't handle the `recentupdated` case.

(cherry picked from commit df38c41c7a)
2024-10-20 10:58:07 +00:00
Otto
c7e52852bb Merge pull request '[v9.0/forgejo] fix: Don't double escape delete branch text' (#5618) from bp-v9.0/forgejo-8c8b31f into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5618
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-10-19 22:28:48 +00:00
Gusted
5d85dc2d91 fix: Don't double escape delete branch text
- Don't double escape the 'Delete branch "$BRANCH"' text. `Locale.Tr`
escapes the argument already and Vue does too by default.
- Let Vue escape the text and add a unit test ensuring that it escapes.
- Resolves #5582

(cherry picked from commit 8c8b31f304)
2024-10-19 21:29:27 +00:00
Gusted
b692da7f6f Merge pull request 'Update dependency mermaid to v11.3.0 (v9.0/forgejo)' (#5616) from renovate/v9.0/forgejo-mermaid-11.x into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5616
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-19 21:12:44 +00:00
Renovate Bot
2c5d47ec1f Update dependency mermaid to v11.3.0 2024-10-19 20:03:44 +00:00
Otto
e740aa05a4 Merge pull request '[v9.0/forgejo] fix: Add server logging for OAuth server errors' (#5596) from bp-v9.0/forgejo-a857007 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5596
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-17 10:29:39 +00:00
Gusted
fb21899097 fix: Add server logging for OAuth server errors
Although an error was presented to the user about that there's an
internal server error, the error itself is never logged.

Relevant: https://codeberg.org/Codeberg/Community/issues/1675
(cherry picked from commit a857007d65)
2024-10-17 09:47:06 +00:00
Earl Warren
0f7020cbef Merge pull request '[v9.0/forgejo] forgejo-cli is now a symlink and cannot be used for sanity checks' (#5594) from bp-v9.0/forgejo-1a7a905-54c8ac3 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5594
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-17 06:46:15 +00:00
Earl Warren
e491b05935 vars.SKIP_END_TO_END optionally skip tests when building a release
The end-to-end tests will always fail when more than one release is
broken. When trying to fix one, the other will get in the way and vice
versa. The only way to get out of this deadlock is to replace all
broken releases but one by doing the following on forgejo-integration:

* set SKIP_END_TO_END to true in the actions vars tab
* pushing a commit to the corresponding branch, fixing the problem

(cherry picked from commit 54c8ac3e39)
2024-10-17 06:00:05 +00:00
Earl Warren
7845659322 forgejo-cli is now a symlink and cannot be used for sanity checks
It could be used but then `cp --dereference` would need to be used instead in
the forgejo-build-publish action.

+ docker cp forgejo-amd64:/app/gitea/forgejo-cli forgejo-9.0-test-linux-amd64
+ chmod +x forgejo-9.0-test-linux-amd64
chmod: cannot operate on dangling symlink 'forgejo-9.0-test-linux-amd64'

(cherry picked from commit 1a7a9055e4)
2024-10-17 06:00:05 +00:00
Earl Warren
9011f73da3 Merge pull request '[v9.0/forgejo] Dockerfile: use alpine:3.20 instead of golang:1.23-alpine3.20' (#5588) from bp-v9.0/forgejo-a99bb2c into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5588
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-16 21:45:29 +00:00
Earl Warren
b1ffd0f58f Dockerfile: use alpine:3.20 instead of golang:1.23-alpine3.20
Runtime does not need golang.

(cherry picked from commit a99bb2c61a)
2024-10-16 20:45:09 +00:00
Earl Warren
f5d83f395f Merge pull request '[v9.0/forgejo] unnecessary container image layer duplication' (#5586) from bp-v9.0/forgejo-7d779a7 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5586
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-16 20:34:26 +00:00
Earl Warren
348e083227 unecessary container image layer duplication
container images grew by 100MB when

RUN ln /app/gitea/gitea /app/gitea/forgejo-cli

was added because hard links are not preserved.

Use symbolic links instead.

https://tauri.earth/@AliveDevil/113318561067465279
(cherry picked from commit 7d779a7859)
2024-10-16 19:45:35 +00:00
Earl Warren
704910c7e9 Merge pull request '[v9.0/forgejo] fix: correct documentation for non 200 responses in swagger' (#5575) from bp-v9.0/forgejo-fcc3dd2 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5575
Reviewed-by: Otto <otto@codeberg.org>
2024-10-16 17:54:00 +00:00
Earl Warren
12a277ed65 Merge pull request '[v9.0/forgejo] i18n: update of translations from Codeberg Translate' (#5580) from bp-v9.0/forgejo-2f1c33b into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5580
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-16 03:47:57 +00:00
Codeberg Translate
e43b9edc36 i18n: update of translations from Codeberg Translate (#5555)
Co-authored-by: Benedikt Straub <Nordfriese@users.noreply.translate.codeberg.org>
Co-authored-by: SomeTr <SomeTr@users.noreply.translate.codeberg.org>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: Atul_Eterno <Atul_Eterno@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <Outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: Xinayder <Xinayder@users.noreply.translate.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5555
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit 2f1c33b5e0)
2024-10-16 02:50:28 +00:00
JakobDev
acd7e57295 fix: correct documentation for non 200 responses in swagger
(cherry picked from commit fcc3dd228d)
2024-10-15 20:05:40 +00:00
Otto
c131de73a5 Merge pull request '[v9.0/forgejo] fix: use column flex on mobile to prevent project title from wrapping' (#5571) from bp-v9.0/forgejo-dcae7d3 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5571
Reviewed-by: Otto <otto@codeberg.org>
2024-10-15 19:52:50 +00:00
Michael Zhang
b8fc56885e fix: use column flex on mobile to prevent project title from wrapping
(cherry picked from commit dcae7d368c)
2024-10-15 11:27:04 +00:00
Earl Warren
7f4efb1c34 Merge pull request 'Update dependency go to v1.23.2 (v9.0/forgejo)' (#5570) from renovate/v9.0/forgejo-patch-golang-packages into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5570
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-15 03:29:07 +00:00
Renovate Bot
779ed6cf3f Update dependency go to v1.23.2 2024-10-15 00:07:24 +00:00
Otto
11bb77313e Merge pull request '[v9.0/forgejo] Fix typo in English locale file' (#5566) from bp-v9.0/forgejo-5443bca into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5566
Reviewed-by: Otto <otto@codeberg.org>
2024-10-14 22:03:15 +00:00
jutty
c2f99a5a1f Fix typo in English locale file
Key settings.wiki_rename_branch_main_notices_2 had a duplicated 'the'.

(cherry picked from commit 5443bca39a)
2024-10-14 21:07:04 +00:00
Gusted
d1c4670e45 Merge pull request '[v9.0/forgejo] [BUG] Don't allow owner team with incorrect unit access (includes doctor fix)' (#5565) from bp-v9.0/forgejo-9de9034 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5565
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-14 21:03:04 +00:00
Gusted
fe35a17dbe [BUG] Don't allow owner team with incorrect unit access
- On editting a team, only update the units if the team isn't the
'Owners' team. Otherwise the 'Owners' team end up having all of their
unit access modes set to 'None'; because the request form doesn't send
over any units, as it's simply not shown in the UI.
- Adds a database inconstency check and fix for the case where the
'Owners' team is affected by this bug.
- Adds unit test.
- Adds integration test.
- Resolves #5528
- Regression of https://github.com/go-gitea/gitea/pull/24012

(cherry picked from commit 9de9034400)
2024-10-14 19:59:17 +00:00
Otto
d66a184f45 Merge pull request '[v9.0/forgejo] Fix typo in #5537' (#5556) from bp-v9.0/forgejo-5a21ff8 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5556
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-10-14 11:18:01 +00:00
0ko
932801ae18 i18n(en): fix typo (#5554)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5554
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
(cherry picked from commit 5a21ff8e95)
2024-10-14 05:21:04 +00:00
Earl Warren
d6d6561295 Merge pull request '[v9.0/forgejo] i18n: update of translations from Codeberg Translate' (#5553) from bp-v9.0/forgejo-575276c into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5553
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-14 04:19:04 +00:00
Codeberg Translate
18b60db6ae i18n: update of translations from Codeberg Translate (#5514)
Co-authored-by: CDN18 <CDN18@users.noreply.translate.codeberg.org>
Co-authored-by: q3yi <q3yi@users.noreply.translate.codeberg.org>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: xtex <xtexchooser@duck.com>
Co-authored-by: Benedikt Straub <Nordfriese@users.noreply.translate.codeberg.org>
Co-authored-by: ddogfoodd <ddogfoodd@users.noreply.translate.codeberg.org>
Co-authored-by: Wuzzy <Wuzzy@users.noreply.translate.codeberg.org>
Co-authored-by: mahlzahn <mahlzahn@posteo.de>
Co-authored-by: Beowulf <Beowulf@users.noreply.translate.codeberg.org>
Co-authored-by: qwerty287 <qwerty287@users.noreply.translate.codeberg.org>
Co-authored-by: SteffoSpieler <SteffoSpieler@users.noreply.translate.codeberg.org>
Co-authored-by: sinsky <sinsky@users.noreply.translate.codeberg.org>
Co-authored-by: SomeTr <SomeTr@users.noreply.translate.codeberg.org>
Co-authored-by: fnetX <otto@codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: Fnurkla <Fnurkla@users.noreply.translate.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5514
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit 575276cf79)
2024-10-14 03:35:31 +00:00
Earl Warren
1b36e34fc4 Merge pull request '[v9.0/forgejo] fix: don't cancel schedule workflows on push to main branch' (#5547) from bp-v9.0/forgejo-b20c0b1 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5547
Reviewed-by: Kwonunn <kwonunn@noreply.codeberg.org>
2024-10-13 13:32:25 +00:00
Kwonunn
d2d161ad28 fix: don't cancel schedule workflows on push to main branch
(cherry picked from commit b20c0b1469)
2024-10-13 12:25:59 +00:00
Otto
f2f2d7dab2 Merge pull request '[v9.0/forgejo] i18n: Improve translation strings for webhook events' (#5538) from bp-v9.0/forgejo-86bac2c into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5538
Reviewed-by: Otto <otto@codeberg.org>
2024-10-12 16:13:29 +00:00
Otto Richter
1667fece88 i18n: Improve translation strings for webhook events (#5537)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5537
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Otto Richter <git@otto.splvs.net>
Co-committed-by: Otto Richter <git@otto.splvs.net>
(cherry picked from commit 86bac2c54e)
2024-10-12 15:19:53 +00:00
Earl Warren
044cd5cf7e Merge pull request '[v9.0/forgejo] Fix bug when a token is given public only' (#5526) from earl-warren/forgejo:wip-v9.0-public-scope into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5526
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-11 20:16:28 +00:00
Otto
dfd1b2fdcd Merge pull request '[v9.0/forgejo] i18n: remove unnecessary variable' (#5535) from bp-v9.0/forgejo-aafc1de into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5535
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-10-11 19:34:14 +00:00
Otto
bf1839aed3 Merge pull request '[v9.0/forgejo] i18n: Fine tune language for units' (#5534) from bp-v9.0/forgejo-79a3fe6 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5534
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-10-11 19:22:50 +00:00
Otto
26f0a7e779 Merge pull request '[v9.0/forgejo] [BUG] Make chroma match case-insenstive' (#5532) from bp-v9.0/forgejo-dcc4423 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5532
Reviewed-by: Otto <otto@codeberg.org>
2024-10-11 19:07:06 +00:00
Otto Richter
a7f4346f5e fix(i18n): remove unnecessary variable (#5533)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5533
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Otto Richter <git@otto.splvs.net>
Co-committed-by: Otto Richter <git@otto.splvs.net>
(cherry picked from commit aafc1de0a3)
2024-10-11 18:52:23 +00:00
Otto Richter
d2ee58fb2a i18n: Fine tune language for units (#5523)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5523
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Otto Richter <git@otto.splvs.net>
Co-committed-by: Otto Richter <git@otto.splvs.net>
(cherry picked from commit 79a3fe6cc6)
2024-10-11 18:28:59 +00:00
Gusted
aec4a0dd59 [BUG] Make chroma match case-insenstive
- In the case that [go-enry](https://github.com/go-enry/go-enry/)
returned langauge doesn't match a lexer name (Either because its not
available or because it doesn't match Chroma's name), a last effort
attempt is made to use Chroma's matching.
- go-enry already applies `strings.ToLower` onto the filename to avoid
being case-sensitive, add the same code for Chroma's matching. The code
being used doesn't rely on the filename being case senstive for correct
matching.
- Adds unit test.
- Resolves #752

(cherry picked from commit dcc442351d)
2024-10-11 17:35:54 +00:00
Otto
5ffa1ee883 Merge pull request '[v9.0/forgejo] log concise repo names in lfs doctor' (#5531) from bp-v9.0/forgejo-15a407a into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5531
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-10-11 15:03:30 +00:00
Kwonunn
3cd20d7d37 log concise repo names in lfs doctor
the old log prints the entire repo object

(cherry picked from commit 15a407a617)
2024-10-11 14:26:53 +00:00
Otto
d8c8fa9bae Merge pull request '[v9.0/forgejo] feat: "Assign to me" button on PR and Issues #5215' (#5524) from bp-v9.0/forgejo-2feb3d0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5524
Reviewed-by: Otto <otto@codeberg.org>
2024-10-11 12:33:50 +00:00
Otto
d7e2fd555c Merge pull request '[v9.0/forgejo] fix: correct Discord webhook JSON for issue events' (#5507) from bp-v9.0/forgejo-cf3ebab-6ea6f22 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5507
Reviewed-by: Otto <otto@codeberg.org>
2024-10-11 11:01:23 +00:00
Earl Warren
1f9104d96f
chore(lint): Fix bug when a token is given public only
(cherry picked from commit 14d85597f8)
2024-10-11 05:25:32 +03:00
Lunny Xiao
ea5a8c7809
Fix bug when a token is given public only
Port of https://github.com/go-gitea/gitea/pull/32204

(cherry picked from commit d6d3c96e6555fc91b3e2ef21f4d8d7475564bb3e)

Conflicts:
  routers/api/v1/api.go
	services/context/api.go
  trivial context conflicts
(cherry picked from commit a052d2b602)

Conflicts:
	routers/api/v1/user/user.go
  trivial context conflict (search by email is not in v9.0)
2024-10-11 05:24:23 +03:00
TimedIn
5ae3b81f3c Small fixes and rename for #5482
- New Issue Fixed assign me being hidden after assignees were cleared https://codeberg.org/forgejo/forgejo/pulls/5482/files#issuecomment-2365431
- Test for verifying the above
- Removed wait for network idle from e2e test
- Renamed templ key assigneeId to assigneeIds
2024-10-11 03:41:23 +02:00
TimedIn
6d2c29ae85 feat: "assign to me" button on PRs and issues
includes:
Tests for assignees on issues
Move assignees selector of new Issue to assignees.tmpl

(cherry picked from commit 2feb3d03d7)
2024-10-11 01:39:54 +00:00
Earl Warren
0496e72d15 Merge pull request '[v9.0/forgejo] i18n: update of translations from Codeberg Translate' (#5512) from bp-v9.0/forgejo-90182a6 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5512
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-10 07:00:55 +00:00
Codeberg Translate
e90a48fd4b i18n: update of translations from Codeberg Translate (#5471)
Co-authored-by: 413x1nkp <413x1nkp@users.noreply.translate.codeberg.org>
Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: feroli <feroli@users.noreply.translate.codeberg.org>
Co-authored-by: pgmtx <pgmtx@users.noreply.translate.codeberg.org>
Co-authored-by: kwoot <kwoot@users.noreply.translate.codeberg.org>
Co-authored-by: atarwn <atarwn@users.noreply.translate.codeberg.org>
Co-authored-by: Benny <Benny@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: JoseDouglas26 <JoseDouglas26@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <Outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: whitecold <whitecold@users.noreply.translate.codeberg.org>
Co-authored-by: sinsky <sinsky@users.noreply.translate.codeberg.org>
Co-authored-by: William_Weber_Berrutti <William_Weber_Berrutti@users.noreply.translate.codeberg.org>
Co-authored-by: eldyj <eldyj@users.noreply.translate.codeberg.org>
Co-authored-by: CDN18 <CDN18@users.noreply.translate.codeberg.org>
Co-authored-by: jaahas <jaahas@users.noreply.translate.codeberg.org>
Co-authored-by: aleksi <aleksi@users.noreply.translate.codeberg.org>
Co-authored-by: stevenroose <stevenroose@users.noreply.translate.codeberg.org>
Co-authored-by: lumi200 <lumi200@users.noreply.translate.codeberg.org>
Co-authored-by: marcoaraujojunior <marcoaraujojunior@users.noreply.translate.codeberg.org>
Co-authored-by: SmolLemon <SmolLemon@users.noreply.translate.codeberg.org>
Co-authored-by: timedin <timedin@users.noreply.translate.codeberg.org>
Co-authored-by: Vaclovas Intas <Gateway_31@protonmail.com>
Co-authored-by: thodorisl <thodorisl@users.noreply.translate.codeberg.org>
Co-authored-by: SerikaFrame <SerikaFrame@users.noreply.translate.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5471
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit 90182a6204)
2024-10-10 05:22:51 +00:00
Kidsan
e2ffe12e50 fix: improve discord webhook api conformance
This commit corrects some cases in the discord webhook payload that do
not align with the discord documentation

(cherry picked from commit 6ea6f224b8)
2024-10-09 16:07:34 +00:00
Kidsan
2c0c6f408e fix: add length limit to discord webhook icon_url
(cherry picked from commit cf3ebab4ba)
2024-10-09 16:07:34 +00:00
Earl Warren
092cb967b0 Merge pull request '[v9.0/forgejo] update git book link to v2' (#5504) from bp-v9.0/forgejo-82b1ab5 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5504
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-09 11:38:00 +00:00
ehshi
d62cbfe923 update git book link to v2 (#5503)
## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Co-authored-by: Ehsan Shirvanian <ehsan@duck.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5503
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: ehshi <ehshi@noreply.codeberg.org>
Co-committed-by: ehshi <ehshi@noreply.codeberg.org>
(cherry picked from commit 82b1ab56de)
2024-10-09 09:29:23 +00:00
Otto
43bad93715 Merge pull request '[v9.0/forgejo] fix: "forked from" note alignment on 404 error pages #5324' (#5475) from bp-v9.0/forgejo-8cbb9f3 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5475
Reviewed-by: Otto <otto@codeberg.org>
2024-10-08 19:32:37 +00:00
Otto
eb80c9429e Merge pull request '[v9.0/forgejo] Improve 'Verify' error message, stopgap for #2809' (#5490) from bp-v9.0/forgejo-d17db93 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5490
Reviewed-by: Otto <otto@codeberg.org>
2024-10-08 19:27:41 +00:00
voltagex
946a10a8d5 i18n: improve 'Verify' error message, stopgap for #2809 (#5479)
Signed-off-by: Adam Baxter <codeberg@voltagex.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5479
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: voltagex <voltagex@noreply.codeberg.org>
Co-committed-by: voltagex <voltagex@noreply.codeberg.org>
(cherry picked from commit d17db93fbf)
2024-10-07 16:22:06 +00:00
Earl Warren
a7165d1fb0 Merge pull request '[gitea] week 2024-41-v9.0 cherry pick (gitea/main -> v9.0/forgejo)' (#5480) from earl-warren/wcp/2024-41-v9.0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5480
Reviewed-by: Otto <otto@codeberg.org>
2024-10-07 05:13:25 +00:00
Earl Warren
47b67fcafc
chore(release-notes): weekly cherry-pick week 2024-41-v9.0 2024-10-06 11:48:21 +02:00
Job
7d3a013e5e
Fix PR creation on forked repositories (#31863)
Resolves #20475

(cherry picked from commit 7e68bc88238104d2ee8b5a877fc1ad437f1778a4)

Conflicts:
	tests/integration/pull_create_test.go
  add missing testPullCreateDirectly from
  c63060b130d34e3f03f28f4dccbf04d381a95c17 Fix code owners will not be mentioned when a pull request comes from a forked repository (#30476)
2024-10-06 11:45:22 +02:00
Bruno Sofiato
4cb10ff28a
Fixed race condition when deleting documents by repoId in ElasticSearch (#32185)
Resolves #32184

---------

Signed-off-by: Bruno Sofiato <bruno.sofiato@gmail.com>
(cherry picked from commit d266d190bd744b7b6f572bf69a42013e21b9be62)
2024-10-06 11:45:22 +02:00
Earl Warren
00e5c68060
Fix the logic of finding the latest pull review commit ID (#32139) (followup)
Adjust the tests for review deletion to ignore a newly inserted
fixture. It is a review request and cannot be deleted.
2024-10-06 11:45:22 +02:00
Zettat123
700e9f027b
Fix the logic of finding the latest pull review commit ID (#32139)
Fix #31423

(cherry picked from commit f4b8f6fc40ce2869135372a5c6ec6418d27ebfba)

Conflicts:
	models/fixtures/comment.yml
  comment fixtures have to be shifted because there is one more in Forgejo
2024-10-06 11:34:08 +02:00
TimedIn
9ee88e965e #5324 Fix centered fork note
(cherry picked from commit 8cbb9f3116)
2024-10-06 01:57:24 +00:00
Earl Warren
0ae05e1000 Merge pull request '[v9.0/forgejo] i18n: update of translations from Codeberg Translate' (#5457) from bp-v9.0/forgejo-aca00fa into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5457
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-10-04 06:39:20 +00:00
Codeberg Translate
2ff9e77dba i18n: update of translations from Codeberg Translate (#5413)
Translations update from [Codeberg Translate](https://translate.codeberg.org) for [Forgejo/forgejo](https://translate.codeberg.org/projects/forgejo/forgejo/).

Current translation status:

![Weblate translation status](https://translate.codeberg.org/widget/forgejo/forgejo/horizontal-auto.svg)

Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: fnetX <otto@codeberg.org>
Co-authored-by: be4zad <be4zad@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: hankskyjames777 <hankskyjames777@users.noreply.translate.codeberg.org>
Co-authored-by: kwoot <kwoot@users.noreply.translate.codeberg.org>
Co-authored-by: emansije <emansije@users.noreply.translate.codeberg.org>
Co-authored-by: xtex <xtexchooser@duck.com>
Co-authored-by: Outbreak2096 <Outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: WithLithum <WithLithum@users.noreply.translate.codeberg.org>
Co-authored-by: yeziruo <yeziruo@users.noreply.translate.codeberg.org>
Co-authored-by: kecrily <kecrily@users.noreply.translate.codeberg.org>
Co-authored-by: overloop <overloop@users.noreply.translate.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5413
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit aca00fa346)
2024-10-03 21:23:48 +00:00
Renovate Bot
4ddf4a8fd3 Update actions/setup-node action to v4 (v9.0/forgejo) (#5444)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5444
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2024-10-01 11:38:53 +00:00
Renovate Bot
4c7fef22f6 Update actions/checkout action to v4 (v9.0/forgejo) (#5443)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5443
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2024-10-01 11:36:57 +00:00
Renovate Bot
01e7095968 Update actions/cache action to v4 (v9.0/forgejo) (#5442)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5442
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2024-10-01 11:19:39 +00:00
Earl Warren
f1e413eb7c Merge pull request '[gitea] week 2024-40-v9.0 cherry pick (gitea/main -> v9.0/forgejo)' (#5418) from earl-warren/wcp/2024-40-v9.0 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5418
Reviewed-by: Otto <otto@codeberg.org>
2024-10-01 07:51:16 +00:00
Earl Warren
67b9b0c76e Merge pull request 'Lock file maintenance (v9.0/forgejo)' (#5432) from renovate/v9.0/forgejo-lock-file-maintenance into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5432
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-09-30 19:00:12 +00:00
Earl Warren
56f9ddc9af Merge pull request '[v9.0/forgejo] fix: referenced sha256:* container images may be deleted' (#5433) from bp-v9.0/forgejo-0a5fd7f into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5433
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-09-30 17:36:30 +00:00
Earl Warren
00749b3a8f fix: referenced sha256:* container images may be deleted
The inventory of the sha256:* images and the manifest index that
reference them is incomplete because it does not take into account any
image older than the expiration limit. As a result some sha256:* will
be considered orphaned although they are referenced from a manifest
index that was created more recently than the expiration limit.

There must not be any filtering based on the creation time when
building the inventory. The expiration limit must only be taken into
account when deleting orphaned images: those that are more recent than
the expiration limit must not be deleted.

This limit is specially important because it protects against a race
between a cleanup task and an ongoing mirroring task. A mirroring
task (such as skopeo sync) will first upload sha256:* images and then
create the corresponding manifest index. If a cleanup races against
it, the sha256:* images that are not yet referenced will be deleted
without skopeo noticing and the published index manifest that happens
at a later time will contain references to non-existent images.

(cherry picked from commit 0a5fd7fdb8)
2024-09-30 16:46:11 +00:00
Renovate Bot
8da48fead3 Lock file maintenance 2024-09-30 16:03:41 +00:00
forgejo-renovate-action
b835f0a1b0 Merge pull request 'Update dependency vue to v3.5.10 (v9.0/forgejo)' (#5419) from renovate/v9.0/forgejo-patch-vue-monorepo into v9.0/forgejo 2024-09-30 11:31:28 +00:00
Renovate Bot
f8c0a352ab Update dependency vue to v3.5.10 2024-09-29 18:02:49 +00:00
Earl Warren
859fa4e489 Merge pull request 'Update module github.com/minio/minio-go/v7 to v7.0.77 (v9.0/forgejo)' (#5420) from renovate/v9.0/forgejo-github.com-minio-minio-go-v7-7.x into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5420
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-09-29 16:08:56 +00:00
Renovate Bot
e8a67571a1 Update module github.com/minio/minio-go/v7 to v7.0.77 2024-09-29 12:03:27 +00:00
Earl Warren
28c8a889bb Merge pull request 'Update dependency monaco-editor to v0.51.0 (v9.0/forgejo)' (#5399) from renovate/v9.0/forgejo-monaco-editor-0.x into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5399
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-09-29 10:49:31 +00:00
Earl Warren
3003195ad7
chore(release-notes): weekly cherry-pick week 2024-40-v9.0 2024-09-29 11:58:17 +02:00
yp05327
c400f26e6c
Fix wrong status of Set up Job when first step is skipped (#32120)
Fix #32089

(cherry picked from commit 6fa962f409c84477a7a4cf35b4a38a4a93fc3224)
2024-09-29 11:52:09 +02:00
Lunny Xiao
0a0a3cea1b
Fix bug when deleting a migrated branch (#32075)
After migrating a repository with pull request, the branch is missed and
after the pull request merged, the branch cannot be deleted.

(cherry picked from commit 5a8568459d22e57cac506465463660526ca6a08f)

Conflicts:
	services/repository/branch.go
  conflict because of [GITEA] Fix typo in formatting error e71b5a038e
2024-09-29 11:51:47 +02:00
Lunny Xiao
cb88d55837
Include collaboration repositories on dashboard source/forks/mirrors list (#31946)
Fix #13489

In the original implementation, only `All` will display your owned and
collaborated repositories. For other filters like `Source`, `Mirrors`
and etc. will only display your owned repositories.

This PR removed the limitations. Now except `collbrations`, other
filters will always display your owned and collaborated repositories.

(cherry picked from commit 4947bec8360c152daca23e120eae1732d3848492)
2024-09-29 11:51:31 +02:00
Kemal Zebari
e1e7299bd9
Truncate commit message during Discord webhook push events (#31970)
Resolves #31668.

(cherry picked from commit aadbe0488f454b9f7f5a56765f4530f9d1e2c6ec)
2024-09-29 11:50:27 +02:00
Lunny Xiao
d8ae7d9e96
Fix panic when cloning with wrong ssh format. (#32076)
(cherry picked from commit 3f2d8f873035b614b4cdb447d8e16f5af82cefe8)
2024-09-29 11:48:56 +02:00
cloudchamb3r
b28a070a52
Fix Bug in Issue/pulls list (#32081)
fix #32080

## After
### for opened issues
<img width="1199" alt="Screenshot 2024-09-19 at 6 29 31 PM"
src="https://github.com/user-attachments/assets/86cf48ad-5e4b-4dcb-8abe-4d7fd74e0aec">

### for closed issues
<img width="1208" alt="Screenshot 2024-09-19 at 6 29 37 PM"
src="https://github.com/user-attachments/assets/a16bc545-bfcf-49a4-be52-3e7334910482">

### for all issues
<img width="1340" alt="Screenshot 2024-09-20 at 12 07 12 PM"
src="https://github.com/user-attachments/assets/b2309c8f-e59d-44e9-ae3b-bf54e1196169">

(cherry picked from commit e1f0598c8f5af5ac95f5e13b74fbab99506762db)
2024-09-29 11:46:14 +02:00
Earl Warren
b2483b2ae0
Fix artifact v4 upload above 8MB (#31664) (fix lint errors) 2024-09-29 11:43:20 +02:00
ChristopherHX
14c7055494
Fix artifact v4 upload above 8MB (#31664)
Multiple chunks are uploaded with type "block" without using
"appendBlock" and eventually out of order for bigger uploads.
8MB seems to be the chunk size

This change parses the blockList uploaded after all blocks to get the
final artifact size and order them correctly before calculating the
sha256 checksum over all blocks

Fixes #31354

(cherry picked from commit b594cec2bda6f861effedb2e8e0a7ebba191c0e9)

Conflicts:
	routers/api/actions/artifactsv4.go
  conflict because of Refactor AppURL usage (#30885) 67c1a07285008cc00036a87cef966c3bd519a50c
    that was not cherry-picked in Forgejo
    the resolution consist of removing the extra ctx argument
2024-09-29 11:43:18 +02:00
Earl Warren
81b9977540 Merge pull request 'Update dependency webpack to v5.95.0 (v9.0/forgejo)' (#5417) from renovate/v9.0/forgejo-webpack-5.x into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5417
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-09-29 09:23:08 +00:00
Renovate Bot
a75862bd7d Update dependency webpack to v5.95.0 2024-09-29 08:03:17 +00:00
Otto
99baeb47e5 Merge pull request '[v9.0/forgejo] i18n: update of translations from Codeberg Translate' (#5412) from bp-v9.0/forgejo-e40554f into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5412
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-09-28 10:41:31 +00:00
Codeberg Translate
7d45c1c6c7 i18n: update of translations from Codeberg Translate (#5355)
Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Co-authored-by: Vaclovas Intas <Gateway_31@protonmail.com>
Co-authored-by: Zughy <Zughy@users.noreply.translate.codeberg.org>
Co-authored-by: aleksi <aleksi@users.noreply.translate.codeberg.org>
Co-authored-by: Application-Maker <Application-Maker@users.noreply.translate.codeberg.org>
Co-authored-by: Salif Mehmed <mail@salif.eu>
Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Panagiotis \"Ivory\" Vasilopoulos <git@n0toose.net>
Co-authored-by: claudep <claudep@users.noreply.translate.codeberg.org>
Co-authored-by: vri <vri@users.noreply.translate.codeberg.org>
Co-authored-by: nicokaiser <nicokaiser@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <Outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: robines <robines@users.noreply.translate.codeberg.org>
Co-authored-by: nazrin <nazrin@users.noreply.translate.codeberg.org>
Co-authored-by: Kaede Fujisaki <ledyba@users.noreply.translate.codeberg.org>

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5355
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit e40554f89b)
2024-09-28 09:41:02 +00:00
Earl Warren
5442b0a6b1 Merge pull request '[v9.0/forgejo] feat: add architecture-specific removal support for arch package' (#5407) from bp-v9.0/forgejo-89742c4 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5407
2024-09-27 12:09:01 +00:00
Earl Warren
da0c4ab199 Merge pull request '[v9.0/forgejo] [gitea] week 2024-39 cherry pick (gitea/main -> forgejo)' (#5406) from bp-v9.0/forgejo-e3deb88-2ffb08b-9d34731-f709de2-2675a24-5260543-6275d1b-1ae3b12-1bdf334-9d5f409-0cafec4-9617667 into v9.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5406
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-09-27 12:07:43 +00:00
Exploding Dragon
658ed564cb feat: add architecture-specific removal support for arch package (#5351)
- [x] add architecture-specific removal support
- [x] Fix upload competition
- [x] Fix not checking input when downloading

docs: https://codeberg.org/forgejo/docs/pulls/874

### Release notes

- [ ] I do not want this change to show in the release notes.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5351
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Exploding Dragon <explodingfkl@gmail.com>
Co-committed-by: Exploding Dragon <explodingfkl@gmail.com>
(cherry picked from commit 89742c4913)
2024-09-27 08:29:09 +00:00
Earl Warren
eb4f1de8ec chore(release-notes): weekly cherry-pick week 2024-39
(cherry picked from commit e3deb88a8d)
2024-09-27 08:13:30 +00:00
Lunny Xiao
ba7da0af31 Use camo.Always instead of camo.Allways (#32097)
Fix #31575

https://gitea.com/gitea/docs/pulls/73
(cherry picked from commit 8e2dd5d3ddfb442937c79f05df88d18b856952cb)
(cherry picked from commit 2ffb08bb88)
2024-09-27 08:13:30 +00:00
Jamie Schouten
74712e3400 Add bin to Composer Metadata (#32099)
This PR addresses the missing `bin` field in Composer metadata, which
currently causes vendor-provided binaries to not be symlinked to
`vendor/bin` during installation.

In the current implementation, running `composer install` does not
publish the binaries, leading to issues where expected binaries are not
available.

By properly declaring the `bin` field, this PR ensures that binaries are
correctly symlinked upon installation, as described in the [Composer
documentation](https://getcomposer.org/doc/articles/vendor-binaries.md).

(cherry picked from commit d351a42494e71b5e2da63302c2f9b46c78e6dbde)
(cherry picked from commit 9d34731198)
2024-09-27 08:13:30 +00:00
Lunny Xiao
6c16834d28 Fix wrong last modify time (#32102)
(cherry picked from commit a802508f88e546bf18990559e44bf27a09c869ee)
(cherry picked from commit f709de2403)
2024-09-27 08:13:30 +00:00
Timon van der Berg
81308159fd Repo Activity: count new issues that were closed (#31776)
I'm new to go and contributing to gitea, your guidance is much
appreciated.

This is meant to solve https://github.com/go-gitea/gitea/issues/13309

Previously, closed issues would not be shown under new issues in the
activity tab, even if they were newly created.

changes:
* Split out newlyCreatedIssues from issuesForActivityStatement to count
  both currently open and closed issues.
* Use a seperate function to count active issues to prevent
double-counting issues after the above change.

Result is that new issues that have been closed are shown both under
"new" and "closed".

Signed-off-by: Timon van der Berg <tmnvanderberg@gmail.com>
(cherry picked from commit ebfde845294cc681de6b1fe1adcf27e35f61b89b)
(cherry picked from commit 2675a24649)
2024-09-27 08:13:30 +00:00
KN4CK3R
2f1a737769 Fix incorrect /tokens api (#32085)
Fixes #32078

- Add missing scopes output.
- Disallow empty scope.

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
(cherry picked from commit 08adbc468f8875fd4763c3656b334203c11adc0a)
(cherry picked from commit 526054332a)
2024-09-27 08:13:30 +00:00
Earl Warren
5b6d8a303d Refactor CSRF protector (#32057) (fix forgejo tests)
Fix the tests unique to Forgejo that are impacted by the refactor.

(cherry picked from commit 6275d1bc50)
2024-09-27 08:13:29 +00:00
wxiaoguang
d26b7902ec Refactor CSRF protector (#32057)
Remove unused CSRF options, decouple "new csrf protector" and "prepare"
logic, do not redirect to home page if CSRF validation falis (it
shouldn't happen in daily usage, if it happens, redirecting to home
doesn't help either but just makes the problem more complex for "fetch")

(cherry picked from commit 1fede04b83288d8a91304a83b7601699bb5cba04)

Conflicts:
	options/locale/locale_en-US.ini
	tests/integration/repo_branch_test.go
  trivial context conflicts
(cherry picked from commit 1ae3b127fc)
2024-09-27 08:13:29 +00:00
Earl Warren
1a8f1482af feat: add IfZero utility function
(cherry picked from commit 43de021ac1ca017212ec75fd88a8a80a9db27c4c)
(cherry picked from commit 1bdf334844)
2024-09-27 08:13:29 +00:00
hiifong
84718e7b17 Lazy load avatar images (#32051)
(cherry picked from commit f38e1014483b84f4541ffb354cd5dfdd7e000e2c)
(cherry picked from commit 9d5f409a5a)
2024-09-27 08:13:29 +00:00
KN4CK3R
232179aa3d Do not escape relative path in RPM primary index (#32038)
Fixes #32021

Do not escape the relative path.

(cherry picked from commit f528df944bb9436afcb9272add2ee0cccefbdb55)
(cherry picked from commit 0cafec4c7a)
2024-09-27 08:13:29 +00:00
Zettat123
300e01f733 Check if the due_date is nil when editing issues (#32035)
(cherry picked from commit 3a51c37672d2fbad1f222922e75ce704d5a1ac71)
(cherry picked from commit 961766744b)
2024-09-27 08:13:29 +00:00
Renovate Bot
d727757cfb Update dependency monaco-editor to v0.51.0 2024-09-26 08:03:00 +00:00
351 changed files with 18693 additions and 4527 deletions

View file

@ -3,4 +3,4 @@ ARG RELEASE_VERSION=unkown
LABEL maintainer="contact@forgejo.org" \
org.opencontainers.image.version="${RELEASE_VERSION}"
RUN mkdir -p /app/gitea
RUN ( echo '#!/bin/sh' ; echo "echo forgejo v$RELEASE_VERSION" ) > /app/gitea/forgejo-cli ; chmod +x /app/gitea/forgejo-cli
RUN ( echo '#!/bin/sh' ; echo "echo forgejo v$RELEASE_VERSION" ) > /app/gitea/gitea ; chmod +x /app/gitea/gitea

View file

@ -1,3 +1,3 @@
module code.gitea.io/gitea
go 1.23.1
go 1.23.2

View file

@ -31,7 +31,7 @@ on:
jobs:
backporting:
if: >
!startsWith(vars.ROLE, 'forgejo-') && (
( vars.ROLE == 'forgejo-coding' ) && (
github.event.pull_request.merged
&&
contains(toJSON(github.event.pull_request.labels), 'backport/v')

View file

@ -0,0 +1,41 @@
on:
push:
branches:
- 'forgejo'
tags:
- '*-git-annex*'
jobs:
build-oci-image:
runs-on: docker
strategy:
matrix:
type: ["rootful", "rootless"]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # fetch the full history so that the Forgejo version is determined properly
- name: Determine registry and username
id: determine-registry-and-username
run: |
echo "registry=${GITHUB_SERVER_URL#https://}" >> "$GITHUB_OUTPUT"
echo "username=${GITHUB_REPOSITORY%/*}" >> "$GITHUB_OUTPUT"
- name: Install Docker
run: curl -fsSL https://get.docker.com | sh
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ steps.determine-registry-and-username.outputs.registry }}
username: ${{ steps.determine-registry-and-username.outputs.username }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ${{ (matrix.type == 'rootful' && 'Dockerfile') || (matrix.type == 'rootless' && 'Dockerfile.rootless') }}
push: true
tags: ${{ steps.determine-registry-and-username.outputs.registry }}/${{ github.repository }}:${{ github.ref_name }}${{ (matrix.type == 'rootful' && ' ') || (matrix.type == 'rootless' && '-rootless') }}

View file

@ -22,10 +22,10 @@ on:
jobs:
release-simulation:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
if: vars.ROLE == 'forgejo-coding'
runs-on: self-hosted
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- id: forgejo
uses: https://code.forgejo.org/actions/setup-forgejo@v1

View file

@ -27,7 +27,7 @@ jobs:
# root is used for testing, allow it
if: vars.ROLE == 'forgejo-integration' || github.repository_owner == 'root'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
@ -37,7 +37,7 @@ jobs:
repository="${{ github.repository }}"
echo "value=${repository##*/}" >> "$GITHUB_OUTPUT"
- uses: https://code.forgejo.org/actions/setup-node@v3
- uses: https://code.forgejo.org/actions/setup-node@v4
with:
node-version: 20
@ -87,7 +87,7 @@ jobs:
- name: cache node_modules
id: node
uses: https://code.forgejo.org/actions/cache@v3
uses: https://code.forgejo.org/actions/cache@v4
with:
path: |
node_modules
@ -170,7 +170,7 @@ jobs:
platforms: linux/amd64,linux/arm64,linux/arm/v6
release-notes: "${{ steps.release-notes.outputs.value }}"
binary-name: forgejo
binary-path: /app/gitea/forgejo-cli
binary-path: /app/gitea/gitea
override: "${{ steps.release-info.outputs.override }}"
verify-labels: "maintainer=contact@forgejo.org,org.opencontainers.image.version=${{ steps.release-info.outputs.version }}"
verbose: ${{ vars.VERBOSE || secrets.VERBOSE || 'false' }}
@ -194,7 +194,7 @@ jobs:
verbose: ${{ vars.VERBOSE || secrets.VERBOSE || 'false' }}
- name: end-to-end tests
if: ${{ secrets.TOKEN != '' && vars.ROLE == 'forgejo-integration' }}
if: ${{ secrets.TOKEN != '' && vars.ROLE == 'forgejo-integration' && vars.SKIP_END_TO_END != 'true' }}
uses: https://code.forgejo.org/actions/cascading-pr@v2
with:
origin-url: ${{ env.GITHUB_SERVER_URL }}

View file

@ -24,7 +24,7 @@ on:
jobs:
info:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
if: vars.ROLE == 'forgejo-coding'
runs-on: docker
container:
image: code.forgejo.org/oci/node:20-bookworm
@ -44,7 +44,7 @@ jobs:
cascade:
if: >
!startsWith(vars.ROLE, 'forgejo-') && (
vars.ROLE == 'forgejo-coding' && (
github.event_name == 'push' ||
(
github.event.action == 'label_updated' && contains(github.event.pull_request.labels.*.name, 'run-end-to-end-tests')

View file

@ -14,7 +14,7 @@ on:
jobs:
test-e2e:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
container:
image: 'code.forgejo.org/oci/playwright:latest'

View file

@ -0,0 +1,24 @@
# Copyright 2024 The Forgejo Authors
# SPDX-License-Identifier: MIT
#
name: milestone
on:
pull_request_target:
types:
- closed
jobs:
set:
if: vars.ROLE == 'forgejo-coding' && github.event.pull_request.merged
runs-on: docker
container:
image: 'code.forgejo.org/oci/ci:1'
steps:
- uses: https://code.forgejo.org/forgejo/set-milestone@v1.0.0
with:
forgejo: https://codeberg.org
repository: forgejo/forgejo
token: ${{ secrets.SET_MILESTONE_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
verbose: ${{ vars.SET_MILESTONE_VERBOSE }}

View file

@ -39,7 +39,7 @@ jobs:
runs-on: self-hosted
if: vars.DOER != '' && vars.FORGEJO != '' && vars.TO_OWNER != '' && vars.FROM_OWNER != '' && secrets.TOKEN != ''
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: copy & sign
uses: https://code.forgejo.org/forgejo/forgejo-build-publish/publish@v5
@ -59,30 +59,28 @@ jobs:
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
verbose: ${{ vars.VERBOSE }}
- name: upgrade v*.next.forgejo.org
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get -q install -y -qq curl
version="${{ github.ref_name }}"
version=${version##*v}
major=$(echo $version | sed -E -e 's/^([0-9]+).*/\1/')
# https://forgejo.org/docs/next/developer/infrastructure
curl -o /dev/null -sS https://v$major.next.forgejo.org/.well-known/wakeup-on-logs/forgejo-v$major
- name: get trigger mirror issue
id: mirror
uses: https://code.forgejo.org/infrastructure/issue-action/get@v1.1.0
with:
forgejo: https://code.forgejo.org
repository: forgejo/forgejo
labels: mirror-trigger
- name: set up go for the DNS update below
if: vars.ROLE == 'forgejo-experimental' && secrets.OVH_APP_KEY != ''
uses: https://code.forgejo.org/actions/setup-go@v4
- name: trigger the mirror
uses: https://code.forgejo.org/infrastructure/issue-action/set@v1.1.0
with:
go-version-file: "go.mod"
- name: update the _release.experimental DNS record
if: vars.ROLE == 'forgejo-experimental' && secrets.OVH_APP_KEY != ''
uses: https://code.forgejo.org/actions/ovh-dns-update@v1
forgejo: https://code.forgejo.org
repository: forgejo/forgejo
token: ${{ secrets.LABEL_ISSUE_FORGEJO_MIRROR_TOKEN }}
numbers: ${{ steps.mirror.outputs.numbers }}
label-wait-if-exists: 3600
label: trigger
- name: upgrade v*.next.forgejo.org
uses: https://code.forgejo.org/infrastructure/next-digest@v1.1.0
with:
subdomain: _release.experimental
domain: forgejo.com # there is a CNAME from .org to .com (for security reasons)
record-id: 5283602601
value: v=${{ github.ref_name }}
ovh-app-key: ${{ secrets.OVH_APP_KEY }}
ovh-app-secret: ${{ secrets.OVH_APP_SECRET }}
ovh-consumer-key: ${{ secrets.OVH_CON_KEY }}
url: https://placeholder:${{ secrets.TOKEN_NEXT_DIGEST }}@code.forgejo.org/infrastructure/next-digest
ref_name: '${{ github.ref_name }}'
image: 'codeberg.org/forgejo-experimental/forgejo'
tag_suffix: '-rootless'

View file

@ -6,12 +6,12 @@ on:
jobs:
release-notes:
if: ${{ !startsWith(vars.ROLE, 'forgejo-')
if: vars.ROLE == 'forgejo-coding'
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:

View file

@ -7,12 +7,12 @@ on:
jobs:
release-notes:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') && contains(github.event.pull_request.labels.*.name, 'worth a release-note') }}
if: ( vars.ROLE == 'forgejo-coding' ) && contains(github.event.pull_request.labels.*.name, 'worth a release-note')
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- name: event
run: |

View file

@ -8,7 +8,9 @@ name: renovate
on:
push:
branches:
- 'renovate/**' # self-test updates
- renovate/** # self-test updates
paths:
- .forgejo/workflows/renovate.yml
schedule:
- cron: '0 0/2 * * *'
workflow_dispatch:
@ -19,7 +21,7 @@ env:
jobs:
renovate:
if: ${{ secrets.RENOVATE_TOKEN != '' }}
if: vars.ROLE == 'forgejo-coding' && secrets.RENOVATE_TOKEN != ''
runs-on: docker
container:

View file

@ -9,7 +9,6 @@ on:
jobs:
backend-checks:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
@ -19,7 +18,7 @@ jobs:
cat <<'EOF'
${{ toJSON(github) }}
EOF
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:
go-version-file: "go.mod"
@ -34,19 +33,17 @@ jobs:
path: '/workspace/forgejo/forgejo/gitea'
key: backend-build-${{ github.sha }}
frontend-checks:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- run: make deps-frontend
- run: make lint-frontend
- run: make checks-frontend
- run: make test-frontend-coverage
- run: make frontend
test-unit:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
@ -66,7 +63,7 @@ jobs:
MINIO_ROOT_USER: 123456
MINIO_ROOT_PASSWORD: 12345678
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:
go-version-file: "go.mod"
@ -106,7 +103,6 @@ jobs:
TAGS: bindata
TEST_ELASTICSEARCH_URL: http://elasticsearch:9200
test-remote-cacher:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
@ -131,7 +127,7 @@ jobs:
image: ${{ matrix.cacher.image }}
options: ${{ matrix.cacher.options }}
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:
go-version-file: "go.mod"
@ -167,7 +163,6 @@ jobs:
TAGS: bindata
TEST_REDIS_SERVER: cacher:${{ matrix.cacher.port }}
test-mysql:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
@ -183,7 +178,7 @@ jobs:
#
MYSQL_EXTRA_FLAGS: --innodb-adaptive-flushing=OFF --innodb-buffer-pool-size=4G --innodb-log-buffer-size=128M --innodb-flush-log-at-trx-commit=0 --innodb-flush-log-at-timeout=30 --innodb-flush-method=nosync --innodb-fsync-threshold=1000000000
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:
go-version-file: "go.mod"
@ -195,6 +190,16 @@ jobs:
apt-get install --no-install-recommends -qq -y git git-lfs
rm /etc/apt/sources.list.d/testing.list
apt-get update -qq
cd /
wget https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
tar xzvf git-annex-standalone-amd64.tar.gz
ln -s \
/git-annex.linux/git-annex \
/git-annex.linux/git-annex-shell \
/git-annex.linux/git-annex-webapp \
/git-annex.linux/git-remote-annex \
bin
cd -
- name: setup user and permissions
run: |
git config --add safe.directory '*'
@ -214,11 +219,9 @@ jobs:
TAGS: bindata
- run: |
su forgejo -c 'make test-mysql-migration test-mysql'
timeout-minutes: 50
env:
USE_REPO_TEST_DIR: 1
test-pgsql:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
@ -237,7 +240,7 @@ jobs:
POSTGRES_DB: test
POSTGRES_PASSWORD: postgres
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:
go-version-file: "go.mod"
@ -249,6 +252,16 @@ jobs:
apt-get install --no-install-recommends -qq -y git git-lfs
rm /etc/apt/sources.list.d/testing.list
apt-get update -qq
cd /
wget https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
tar xzvf git-annex-standalone-amd64.tar.gz
ln -s \
/git-annex.linux/git-annex \
/git-annex.linux/git-annex-shell \
/git-annex.linux/git-annex-webapp \
/git-annex.linux/git-remote-annex \
bin
cd -
- name: setup user and permissions
run: |
git config --add safe.directory '*'
@ -268,19 +281,17 @@ jobs:
TAGS: bindata
- run: |
su forgejo -c 'make test-pgsql-migration test-pgsql'
timeout-minutes: 50
env:
RACE_ENABLED: true
USE_REPO_TEST_DIR: 1
TEST_LDAP: 1
test-sqlite:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:
go-version-file: "go.mod"
@ -292,6 +303,16 @@ jobs:
apt-get install --no-install-recommends -qq -y git git-lfs
rm /etc/apt/sources.list.d/testing.list
apt-get update -qq
cd /
wget https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
tar xzvf git-annex-standalone-amd64.tar.gz
ln -s \
/git-annex.linux/git-annex \
/git-annex.linux/git-annex-shell \
/git-annex.linux/git-annex-webapp \
/git-annex.linux/git-remote-annex \
bin
cd -
- name: setup user and permissions
run: |
git config --add safe.directory '*'
@ -311,14 +332,12 @@ jobs:
TAGS: bindata sqlite sqlite_unlock_notify
- run: |
su forgejo -c 'make test-sqlite-migration test-sqlite'
timeout-minutes: 50
env:
TAGS: sqlite sqlite_unlock_notify
RACE_ENABLED: true
TEST_TAGS: sqlite sqlite_unlock_notify
USE_REPO_TEST_DIR: 1
security-check:
if: ${{ !startsWith(vars.ROLE, 'forgejo-') }}
runs-on: docker
needs:
- test-sqlite
@ -329,7 +348,7 @@ jobs:
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v4
with:
go-version-file: "go.mod"

View file

@ -51,7 +51,7 @@ RUN chmod 755 /tmp/local/usr/bin/entrypoint \
/go/src/code.gitea.io/gitea/environment-to-ini
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
FROM code.forgejo.org/oci/golang:1.23-alpine3.20
FROM code.forgejo.org/oci/alpine:3.20
ARG RELEASE_VERSION
LABEL maintainer="contact@forgejo.org" \
org.opencontainers.image.authors="Forgejo" \
@ -78,6 +78,7 @@ RUN apk --no-cache add \
sqlite \
su-exec \
gnupg \
git-annex \
&& rm -rf /var/cache/apk/*
RUN addgroup \
@ -103,6 +104,6 @@ CMD ["/bin/s6-svscan", "/etc/s6"]
COPY --from=build-env /tmp/local /
RUN cd /usr/local/bin ; ln -s gitea forgejo
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
RUN ln /app/gitea/gitea /app/gitea/forgejo-cli
RUN ln -s /app/gitea/gitea /app/gitea/forgejo-cli
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh

View file

@ -49,7 +49,7 @@ RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
/go/src/code.gitea.io/gitea/environment-to-ini
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
FROM code.forgejo.org/oci/golang:1.23-alpine3.20
FROM code.forgejo.org/oci/alpine:3.20
LABEL maintainer="contact@forgejo.org" \
org.opencontainers.image.authors="Forgejo" \
org.opencontainers.image.url="https://forgejo.org" \
@ -71,6 +71,7 @@ RUN apk --no-cache add \
git \
curl \
gnupg \
git-annex \
&& rm -rf /var/cache/apk/*
RUN addgroup \
@ -90,7 +91,7 @@ RUN chown git:git /var/lib/gitea /etc/gitea
COPY --from=build-env /tmp/local /
RUN cd /usr/local/bin ; ln -s gitea forgejo
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
RUN ln /app/gitea/gitea /app/gitea/forgejo-cli
RUN ln -s /app/gitea/gitea /app/gitea/forgejo-cli
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh

View file

@ -8,7 +8,7 @@ self := $(location)
@tmpdir=`mktemp --tmpdir -d` ; \
echo Using temporary directory $$tmpdir for test repositories ; \
USE_REPO_TEST_DIR= $(MAKE) -f $(self) --no-print-directory REPO_TEST_DIR=$$tmpdir/ $@ ; \
STATUS=$$? ; rm -r "$$tmpdir" ; exit $$STATUS
STATUS=$$? ; chmod -R +w "$$tmpdir" && rm -r "$$tmpdir" ; exit $$STATUS
else
@ -91,7 +91,7 @@ else
FORGEJO_VERSION_API ?= $(GITEA_VERSION)+${GITEA_COMPATIBILITY}
else
# drop the "g" prefix prepended by git describe to the commit hash
FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always | sed 's/^v//' | sed 's/\-g/-/')+${GITEA_COMPATIBILITY}
FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always | sed 's/^v//' | sed 's/\-g/-/2')+${GITEA_COMPATIBILITY}
endif
endif
FORGEJO_VERSION_MAJOR=$(shell echo $(FORGEJO_VERSION) | sed -e 's/\..*//')

View file

@ -38,6 +38,7 @@ import (
const (
lfsAuthenticateVerb = "git-lfs-authenticate"
gitAnnexShellVerb = "git-annex-shell"
)
// CmdServ represents the available serv sub-command.
@ -79,6 +80,7 @@ var (
"git-upload-archive": perm.AccessModeRead,
"git-receive-pack": perm.AccessModeWrite,
lfsAuthenticateVerb: perm.AccessModeNone,
gitAnnexShellVerb: perm.AccessModeNone, // annex permissions are enforced by GIT_ANNEX_SHELL_READONLY, rather than the Gitea API
}
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
)
@ -147,6 +149,12 @@ func runServ(c *cli.Context) error {
return nil
}
defer func() {
if err := recover(); err != nil {
_ = fail(ctx, "Internal Server Error", "Panic: %v\n%s", err, log.Stack(2))
}
}()
keys := strings.Split(c.Args().First(), "-")
if len(keys) != 2 || keys[0] != "key" {
return fail(ctx, "Key ID format error", "Invalid key argument: %s", c.Args().First())
@ -193,10 +201,7 @@ func runServ(c *cli.Context) error {
}
verb := words[0]
repoPath := words[1]
if repoPath[0] == '/' {
repoPath = repoPath[1:]
}
repoPath := strings.TrimPrefix(words[1], "/")
var lfsVerb string
if verb == lfsAuthenticateVerb {
@ -209,6 +214,28 @@ func runServ(c *cli.Context) error {
}
}
if verb == gitAnnexShellVerb {
if !setting.Annex.Enabled {
return fail(ctx, "Unknown git command", "git-annex request over SSH denied, git-annex support is disabled")
}
if len(words) < 3 {
return fail(ctx, "Too few arguments", "Too few arguments in cmd: %s", cmd)
}
// git-annex always puts the repo in words[2], unlike most other
// git subcommands; and it sometimes names repos like /~/, as if
// $HOME should get expanded while also being rooted. e.g.:
// git-annex-shell 'configlist' '/~/user/repo'
// git-annex-shell 'sendkey' '/user/repo 'key'
repoPath = words[2]
repoPath = strings.TrimPrefix(repoPath, "/")
repoPath = strings.TrimPrefix(repoPath, "~/")
}
// prevent directory traversal attacks
repoPath = filepath.Clean("/" + repoPath)[1:]
rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 2 {
return fail(ctx, "Invalid repository path", "Invalid repository path: %v", repoPath)
@ -222,6 +249,18 @@ func runServ(c *cli.Context) error {
// so that username and reponame are not affected.
repoPath = strings.ToLower(strings.TrimSpace(repoPath))
// put the sanitized repoPath back into the argument list for later
if verb == gitAnnexShellVerb {
// git-annex-shell demands an absolute path
absRepoPath, err := filepath.Abs(filepath.Join(setting.RepoRootPath, repoPath))
if err != nil {
return fail(ctx, "Error locating repoPath", "%v", err)
}
words[2] = absRepoPath
} else {
words[1] = repoPath
}
if alphaDashDotPattern.MatchString(reponame) {
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame)
}
@ -300,21 +339,45 @@ func runServ(c *cli.Context) error {
return nil
}
var gitcmd *exec.Cmd
gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin
gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack
if _, err := os.Stat(gitBinVerb); err != nil {
gitBinVerb, err := exec.LookPath(verb)
if err != nil {
// if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git
// ps: Windows only has "git.exe" in the bin path, so Windows always uses this way
// ps: git-annex-shell and other extensions may not necessarily be in gitBinPath,
// but '{gitBinPath}/git annex-shell' should be able to find them on $PATH.
verbFields := strings.SplitN(verb, "-", 2)
if len(verbFields) == 2 {
// use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ...
gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], repoPath)
gitBinVerb = git.GitExecutable
words = append([]string{verbFields[1]}, words...)
}
}
if gitcmd == nil {
// by default, use the verb (it has been checked above by allowedCommands)
gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath)
// by default, use the verb (it has been checked above by allowedCommands)
gitcmd := exec.CommandContext(ctx, gitBinVerb, words[1:]...)
if verb == gitAnnexShellVerb {
// This doesn't get its own isolated section like LFS does, because LFS
// is handled by internal Gitea routines, but git-annex has to be shelled out
// to like other git subcommands, so we need to build up gitcmd.
// TODO: does this work on Windows?
gitcmd.Env = append(gitcmd.Env,
// "If set, disallows running git-shell to handle unknown commands."
// - git-annex-shell(1)
"GIT_ANNEX_SHELL_LIMITED=True",
// "If set, git-annex-shell will refuse to run commands
// that do not operate on the specified directory."
// - git-annex-shell(1)
fmt.Sprintf("GIT_ANNEX_SHELL_DIRECTORY=%s", words[2]),
)
if results.UserMode < perm.AccessModeWrite {
// "If set, disallows any action that could modify the git-annex repository."
// - git-annex-shell(1)
// We set this when the backend API has told us that we don't have write permission to this repo.
log.Debug("Setting GIT_ANNEX_SHELL_READONLY=True")
gitcmd.Env = append(gitcmd.Env, "GIT_ANNEX_SHELL_READONLY=True")
}
}
process.SetSysProcAttribute(gitcmd)

View file

@ -9,6 +9,7 @@ import (
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
@ -247,6 +248,12 @@ func runWeb(ctx *cli.Context) error {
createPIDFile(ctx.String("pid"))
}
if setting.Annex.Enabled {
if _, err := exec.LookPath("git-annex"); err != nil {
log.Fatal("You have enabled git-annex support but git-annex is not installed. Please make sure that Forgejo's PATH contains the git-annex executable.")
}
}
if !setting.InstallLock {
if err := serveInstall(ctx); err != nil {
return err
@ -311,6 +318,10 @@ func listen(m http.Handler, handleRedirector bool) error {
log.Info("LFS server enabled")
}
if setting.Annex.Enabled {
log.Info("git-annex enabled")
}
var err error
switch setting.Protocol {
case setting.HTTP:

View file

@ -529,7 +529,8 @@ INTERNAL_TOKEN =
;; HMAC to encode urls with, it **is required** if camo is enabled.
;HMAC_KEY =
;; Set to true to use camo for https too lese only non https urls are proxyed
;ALLWAYS = false
;; ALLWAYS is deprecated and will be removed in the future
;ALWAYS = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -2653,6 +2654,17 @@ LEVEL = Info
;; override the minio base path if storage type is minio
;MINIO_BASE_PATH = lfs/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[annex]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Whether git-annex is enabled; defaults to false
;ENABLED = false
;; Whether to disable p2phttp support; default is the same as repository.DISABLE_HTTP_GIT
;DISABLE_P2PHTTP = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; settings for packages, will override storage setting

18
go.mod
View file

@ -1,6 +1,6 @@
module code.gitea.io/gitea
go 1.23.1
go 1.23.2
require (
code.forgejo.org/f3/gof3/v3 v3.7.0
@ -45,6 +45,7 @@ require (
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
github.com/go-git/go-git/v5 v5.11.0
github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-openapi/spec v0.20.14
github.com/go-sql-driver/mysql v1.8.1
github.com/go-swagger/go-swagger v0.30.5
github.com/go-testfixtures/testfixtures/v3 v3.12.0
@ -75,7 +76,7 @@ require (
github.com/meilisearch/meilisearch-go v0.28.0
github.com/mholt/archiver/v3 v3.5.1
github.com/microcosm-cc/bluemonday v1.0.27
github.com/minio/minio-go/v7 v7.0.74
github.com/minio/minio-go/v7 v7.0.77
github.com/msteinert/pam v1.2.0
github.com/nektos/act v0.2.52
github.com/niklasfasching/go-org v1.7.0
@ -101,12 +102,12 @@ require (
github.com/yuin/goldmark v1.7.4
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
go.uber.org/mock v0.4.0
golang.org/x/crypto v0.27.0
golang.org/x/crypto v0.31.0
golang.org/x/image v0.20.0
golang.org/x/net v0.29.0
golang.org/x/oauth2 v0.23.0
golang.org/x/sys v0.25.0
golang.org/x/text v0.18.0
golang.org/x/sys v0.28.0
golang.org/x/text v0.21.0
golang.org/x/tools v0.25.0
google.golang.org/grpc v1.66.2
google.golang.org/protobuf v1.34.2
@ -187,7 +188,6 @@ require (
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/loads v0.21.5 // indirect
github.com/go-openapi/runtime v0.26.2 // indirect
github.com/go-openapi/spec v0.20.14 // indirect
github.com/go-openapi/strfmt v0.22.0 // indirect
github.com/go-openapi/swag v0.22.7 // indirect
github.com/go-openapi/validate v0.22.6 // indirect
@ -250,7 +250,7 @@ require (
github.com/rhysd/actionlint v1.6.27 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@ -281,7 +281,7 @@ require (
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
@ -296,3 +296,5 @@ replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142
replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.21.3
replace github.com/mholt/archiver/v3 => code.forgejo.org/forgejo/archiver/v3 v3.5.1
replace github.com/gliderlabs/ssh => code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616

32
go.sum
View file

@ -10,6 +10,8 @@ code.forgejo.org/forgejo/archiver/v3 v3.5.1 h1:UmmbA7D5550uf71SQjarmrn6yKwOGxtEj
code.forgejo.org/forgejo/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
code.forgejo.org/forgejo/reply v1.0.2 h1:dMhQCHV6/O3L5CLWNTol+dNzDAuyCK88z4J/lCdgFuQ=
code.forgejo.org/forgejo/reply v1.0.2/go.mod h1:RyZUfzQLc+fuLIGjTSQWDAJWPiL4WtKXB/FifT5fM7U=
code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616 h1:kEZL84+02jY9RxXM4zHBWZ3Fml0B09cmP1LGkDsCfIA=
code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
code.forgejo.org/go-chi/cache v0.0.0-20240912103640-dcb08fba860d h1:nOu/2GX571t4intmtfvpctS148OqsBYrGUySVm93ifc=
code.forgejo.org/go-chi/cache v0.0.0-20240912103640-dcb08fba860d/go.mod h1:OVlZ/TqDYJ+RUJ+R+J+OLxtlyjo3pbjBeK7LAWAB+Vk=
code.forgejo.org/go-chi/captcha v0.0.0-20240905153133-df43b9250ed5 h1:A7P1liXCpJBHEJ5KIDsF0ujnQ8FQ/aX1UixTW0vGrDQ=
@ -225,8 +227,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9 h1:j2TrkUG/NATGi/EQS+MvEoF79CxiRUmT16ErFroNcKI=
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9/go.mod h1:cJ9Ye0ZNSMN7RzZDBRY3E+8M3Bpf/R1JX22Ir9yX6WI=
github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 h1:I2nuhyVI/48VXoRCCZR2hYBgnSXa+EuDJf/VyX06TC0=
@ -502,8 +502,8 @@ github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.74 h1:fTo/XlPBTSpo3BAMshlwKL5RspXRv9us5UeHEGYCFe0=
github.com/minio/minio-go/v7 v7.0.74/go.mod h1:qydcVzV8Hqtj1VtEocfxbmVFa2siu6HGa+LDEPogjD8=
github.com/minio/minio-go/v7 v7.0.77 h1:GaGghJRg9nwDVlNbwYjSDJT1rqltQkBFDsypWX1v3Bw=
github.com/minio/minio-go/v7 v7.0.77/go.mod h1:AVM3IUN6WwKzmwBxVdjzhH8xq+f57JSbbvzqvUzR6eg=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@ -599,8 +599,8 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
@ -734,8 +734,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
@ -772,8 +772,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -803,8 +803,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@ -814,8 +814,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -827,8 +827,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -69,7 +69,7 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
OwnerID: t.OwnerID,
CommitSHA: t.CommitSHA,
Status: int64(ArtifactStatusUploadPending),
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + 3600*24*expiredDays),
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
}
if _, err := db.GetEngine(ctx).Insert(artifact); err != nil {
return nil, err
@ -78,6 +78,13 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
} else if err != nil {
return nil, err
}
if _, err := db.GetEngine(ctx).ID(artifact.ID).Cols("expired_unix").Update(&ActionArtifact{
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
}); err != nil {
return nil, err
}
return artifact, nil
}

View file

@ -146,7 +146,11 @@ func (run *ActionRun) GetPushEventPayload() (*api.PushPayload, error) {
}
func (run *ActionRun) GetPullRequestEventPayload() (*api.PullRequestPayload, error) {
if run.Event == webhook_module.HookEventPullRequest || run.Event == webhook_module.HookEventPullRequestSync {
if run.Event == webhook_module.HookEventPullRequest ||
run.Event == webhook_module.HookEventPullRequestSync ||
run.Event == webhook_module.HookEventPullRequestAssign ||
run.Event == webhook_module.HookEventPullRequestMilestone ||
run.Event == webhook_module.HookEventPullRequestLabel {
var payload api.PullRequestPayload
if err := json.Unmarshal([]byte(run.EventPayload), &payload); err != nil {
return nil, err

View file

@ -118,21 +118,23 @@ func DeleteScheduleTaskByRepo(ctx context.Context, id int64) error {
return committer.Commit()
}
func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository) error {
func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository, cancelPreviousJobs bool) error {
// If actions disabled when there is schedule task, this will remove the outdated schedule tasks
// There is no other place we can do this because the app.ini will be changed manually
if err := DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil {
return fmt.Errorf("DeleteCronTaskByRepo: %v", err)
}
// cancel running cron jobs of this repository and delete old schedules
if err := CancelPreviousJobs(
ctx,
repo.ID,
repo.DefaultBranch,
"",
webhook_module.HookEventSchedule,
); err != nil {
return fmt.Errorf("CancelPreviousJobs: %v", err)
if cancelPreviousJobs {
// cancel running cron jobs of this repository and delete old schedules
if err := CancelPreviousJobs(
ctx,
repo.ID,
repo.DefaultBranch,
"",
webhook_module.HookEventSchedule,
); err != nil {
return fmt.Errorf("CancelPreviousJobs: %v", err)
}
}
return nil
}

View file

@ -250,6 +250,9 @@ func (a *Action) GetActDisplayNameTitle(ctx context.Context) string {
// GetRepoUserName returns the name of the action repository owner.
func (a *Action) GetRepoUserName(ctx context.Context) string {
a.loadRepo(ctx)
if a.Repo == nil {
return "(non-existing-repo)"
}
return a.Repo.OwnerName
}
@ -262,6 +265,9 @@ func (a *Action) ShortRepoUserName(ctx context.Context) string {
// GetRepoName returns the name of the action repository.
func (a *Action) GetRepoName(ctx context.Context) string {
a.loadRepo(ctx)
if a.Repo == nil {
return "(non-existing-repo)"
}
return a.Repo.Name
}

View file

@ -34,6 +34,7 @@ type ActivityStats struct {
OpenedPRAuthorCount int64
MergedPRs issues_model.PullRequestList
MergedPRAuthorCount int64
ActiveIssues issues_model.IssueList
OpenedIssues issues_model.IssueList
OpenedIssueAuthorCount int64
ClosedIssues issues_model.IssueList
@ -172,7 +173,7 @@ func (stats *ActivityStats) MergedPRPerc() int {
// ActiveIssueCount returns total active issue count
func (stats *ActivityStats) ActiveIssueCount() int {
return stats.OpenedIssueCount() + stats.ClosedIssueCount()
return len(stats.ActiveIssues)
}
// OpenedIssueCount returns open issue count
@ -285,13 +286,21 @@ func (stats *ActivityStats) FillIssues(ctx context.Context, repoID int64, fromTi
stats.ClosedIssueAuthorCount = count
// New issues
sess = issuesForActivityStatement(ctx, repoID, fromTime, false, false)
sess = newlyCreatedIssues(ctx, repoID, fromTime)
sess.OrderBy("issue.created_unix ASC")
stats.OpenedIssues = make(issues_model.IssueList, 0)
if err = sess.Find(&stats.OpenedIssues); err != nil {
return err
}
// Active issues
sess = activeIssues(ctx, repoID, fromTime)
sess.OrderBy("issue.created_unix ASC")
stats.ActiveIssues = make(issues_model.IssueList, 0)
if err = sess.Find(&stats.ActiveIssues); err != nil {
return err
}
// Opened issue authors
sess = issuesForActivityStatement(ctx, repoID, fromTime, false, false)
if _, err = sess.Select("count(distinct issue.poster_id) as `count`").Table("issue").Get(&count); err != nil {
@ -317,6 +326,22 @@ func (stats *ActivityStats) FillUnresolvedIssues(ctx context.Context, repoID int
return sess.Find(&stats.UnresolvedIssues)
}
func newlyCreatedIssues(ctx context.Context, repoID int64, fromTime time.Time) *xorm.Session {
sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID).
And("issue.is_pull = ?", false). // Retain the is_pull check to exclude pull requests
And("issue.created_unix >= ?", fromTime.Unix()) // Include all issues created after fromTime
return sess
}
func activeIssues(ctx context.Context, repoID int64, fromTime time.Time) *xorm.Session {
sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID).
And("issue.is_pull = ?", false).
And("issue.created_unix >= ? OR issue.closed_unix >= ?", fromTime.Unix(), fromTime.Unix())
return sess
}
func issuesForActivityStatement(ctx context.Context, repoID int64, fromTime time.Time, closed, unresolved bool) *xorm.Session {
sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID).
And("issue.is_closed = ?", closed)

View file

@ -0,0 +1,30 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package activities
import (
"testing"
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetActivityStats(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
stats, err := GetActivityStats(db.DefaultContext, repo, time.Unix(0, 0), true, true, true, true)
require.NoError(t, err)
assert.EqualValues(t, 2, stats.ActiveIssueCount())
assert.EqualValues(t, 2, stats.OpenedIssueCount())
assert.EqualValues(t, 0, stats.ClosedIssueCount())
assert.EqualValues(t, 3, stats.ActivePRCount())
}

View file

@ -23,3 +23,11 @@
redirect_uris: '["http://127.0.0.1", "https://127.0.0.1"]'
created_unix: 1712358091
updated_unix: 1712358091
-
id: 1003
uid: 0
name: "Global Auth source that should be kept"
client_id: "2f3467c1-7b3b-463d-ab04-2ae2b2712826"
redirect_uris: '["http://example.com/globalapp", "https://example.com/globalapp"]'
created_unix: 1732387292
updated_unix: 1732387292

View file

@ -15,12 +15,31 @@ import (
"code.gitea.io/gitea/modules/util"
)
type AuthorizationPurpose string
var (
// Used to store long term authorization tokens.
LongTermAuthorization AuthorizationPurpose = "long_term_authorization"
// Used to activate a user account.
UserActivation AuthorizationPurpose = "user_activation"
// Used to reset the password.
PasswordReset AuthorizationPurpose = "password_reset"
)
// Used to activate the specified email address for a user.
func EmailActivation(email string) AuthorizationPurpose {
return AuthorizationPurpose("email_activation:" + email)
}
// AuthorizationToken represents a authorization token to a user.
type AuthorizationToken struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX"`
LookupKey string `xorm:"INDEX UNIQUE"`
HashedValidator string
Purpose AuthorizationPurpose `xorm:"NOT NULL DEFAULT 'long_term_authorization'"`
Expiry timeutil.TimeStamp
}
@ -41,7 +60,7 @@ func (authToken *AuthorizationToken) IsExpired() bool {
// GenerateAuthToken generates a new authentication token for the given user.
// It returns the lookup key and validator values that should be passed to the
// user via a long-term cookie.
func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeStamp) (lookupKey, validator string, err error) {
func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeStamp, purpose AuthorizationPurpose) (lookupKey, validator string, err error) {
// Request 64 random bytes. The first 32 bytes will be used for the lookupKey
// and the other 32 bytes will be used for the validator.
rBytes, err := util.CryptoRandomBytes(64)
@ -56,14 +75,15 @@ func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeSt
Expiry: expiry,
LookupKey: lookupKey,
HashedValidator: HashValidator(rBytes[32:]),
Purpose: purpose,
})
return lookupKey, validator, err
}
// FindAuthToken will find a authorization token via the lookup key.
func FindAuthToken(ctx context.Context, lookupKey string) (*AuthorizationToken, error) {
func FindAuthToken(ctx context.Context, lookupKey string, purpose AuthorizationPurpose) (*AuthorizationToken, error) {
var authToken AuthorizationToken
has, err := db.GetEngine(ctx).Where("lookup_key = ?", lookupKey).Get(&authToken)
has, err := db.GetEngine(ctx).Where("lookup_key = ? AND purpose = ?", lookupKey, purpose).Get(&authToken)
if err != nil {
return nil, err
} else if !has {

View file

@ -657,6 +657,7 @@ func CountOrphanedOAuth2Applications(ctx context.Context) (int64, error) {
Table("`oauth2_application`").
Join("LEFT", "`user`", "`oauth2_application`.`uid` = `user`.`id`").
Where(builder.IsNull{"`user`.id"}).
Where(builder.Neq{"uid": 0}). // exclude instance-wide admin applications
Where(builder.NotIn("`oauth2_application`.`client_id`", BuiltinApplicationsClientIDs())).
Select("COUNT(`oauth2_application`.`id`)").
Count()
@ -668,6 +669,7 @@ func DeleteOrphanedOAuth2Applications(ctx context.Context) (int64, error) {
From("`oauth2_application`").
Join("LEFT", "`user`", "`oauth2_application`.`uid` = `user`.`id`").
Where(builder.IsNull{"`user`.id"}).
Where(builder.Neq{"uid": 0}). // exclude instance-wide admin applications
Where(builder.NotIn("`oauth2_application`.`client_id`", BuiltinApplicationsClientIDs()))
b := builder.Delete(builder.In("id", subQuery)).From("`oauth2_application`")

View file

@ -296,4 +296,5 @@ func TestOrphanedOAuth2Applications(t *testing.T) {
require.NoError(t, err)
assert.EqualValues(t, 0, count)
unittest.AssertExistsIf(t, false, &auth_model.OAuth2Application{ID: 1002})
unittest.AssertExistsIf(t, true, &auth_model.OAuth2Application{ID: 1003})
}

View file

@ -216,7 +216,7 @@ func CreateSource(ctx context.Context, source *Source) error {
return ErrSourceAlreadyExist{source.Name}
}
// Synchronization is only available with LDAP for now
if !source.IsLDAP() && !source.IsOAuth2() {
if !source.IsLDAP() {
source.IsSyncEnabled = false
}

View file

@ -1,3 +1,22 @@
-
id: 46
attempt: 3
runner_id: 1
status: 3 # 3 is the status code for "cancelled"
started: 1683636528
stopped: 1683636626
repo_id: 4
owner_id: 1
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
is_fork_pull_request: 0
token_hash: 6d8ef48297195edcc8e22c70b3020eaa06c52976db67d39b4260c64a69a2cc1508825121b7b8394e48e00b1bf8718b2aaaaa
token_salt: eeeeeeee
token_last_eight: eeeeeeee
log_filename: artifact-test2/2f/47.log
log_in_storage: 1
log_length: 707
log_size: 90179
log_expired: 0
-
id: 47
job_id: 192

View file

@ -94,3 +94,22 @@
content: "test markup light/dark-mode-only ![GitHub-Mark-Light](https://user-images.githubusercontent.com/3369400/139447912-e0f43f33-6d9f-45f8-be46-2df5bbc91289.png#gh-dark-mode-only)![GitHub-Mark-Dark](https://user-images.githubusercontent.com/3369400/139448065-39a229ba-4b06-434b-bc67-616e2ed80c8f.png#gh-light-mode-only)"
created_unix: 946684813
updated_unix: 946684813
-
id: 11
type: 22 # review
poster_id: 5
issue_id: 3 # in repo_id 1
content: "reviewed by user5"
review_id: 21
created_unix: 946684816
-
id: 12
type: 27 # review request
poster_id: 2
issue_id: 3 # in repo_id 1
content: "review request for user5"
review_id: 22
assignee_id: 5
created_unix: 946684817

View file

@ -91,6 +91,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
created_unix: 1700000001
updated_unix: 1700000001
-
id: 4
@ -152,6 +154,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
created_unix: 1700000002
updated_unix: 1700000002
-
id: 6
@ -182,6 +186,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
created_unix: 1710000001
updated_unix: 1710000001
-
id: 7
@ -212,6 +218,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
created_unix: 1710000003
updated_unix: 1710000003
-
id: 8
@ -242,6 +250,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
created_unix: 1710000002
updated_unix: 1710000002
-
id: 9
@ -968,6 +978,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
created_unix: 1700000003
updated_unix: 1700000003
-
id: 33
@ -1811,4 +1823,4 @@
template_id: 0
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
close_issues_via_commit_in_any_branch: false

View file

@ -179,3 +179,22 @@
content: "Review Comment"
updated_unix: 946684810
created_unix: 946684810
-
id: 21
type: 2
reviewer_id: 5
issue_id: 3
content: "reviewed by user5"
commit_id: 4a357436d925b5c974181ff12a994538ddc5a269
updated_unix: 946684816
created_unix: 946684816
-
id: 22
type: 4
reviewer_id: 5
issue_id: 3
content: "review request for user5"
updated_unix: 946684817
created_unix: 946684817

View file

@ -332,6 +332,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
created_unix: 1730468968
-
id: 10

View file

@ -0,0 +1,11 @@
-
id: 3
user_id: 1
issue_id: 2
created_unix: 1500988004
-
id: 4
user_id: 3
issue_id: 0
created_unix: 1500988003

View file

@ -111,9 +111,7 @@ func NewIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *user_m
return err
}
issue.isLabelsLoaded = false
issue.Labels = nil
if err = issue.LoadLabels(ctx); err != nil {
if err = issue.ReloadLabels(ctx); err != nil {
return err
}
@ -161,10 +159,7 @@ func NewIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *us
return err
}
// reload all labels
issue.isLabelsLoaded = false
issue.Labels = nil
if err = issue.LoadLabels(ctx); err != nil {
if err = issue.ReloadLabels(ctx); err != nil {
return err
}
@ -205,8 +200,7 @@ func DeleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use
return err
}
issue.Labels = nil
return issue.LoadLabels(ctx)
return issue.ReloadLabels(ctx)
}
// DeleteLabelsByRepoID deletes labels of some repository
@ -326,14 +320,23 @@ func FixIssueLabelWithOutsideLabels(ctx context.Context) (int64, error) {
return res.RowsAffected()
}
// LoadLabels loads labels
// LoadLabels only if they are not already set
func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
if !issue.isLabelsLoaded && issue.Labels == nil && issue.ID != 0 {
if !issue.isLabelsLoaded && issue.Labels == nil {
if err := issue.ReloadLabels(ctx); err != nil {
return err
}
issue.isLabelsLoaded = true
}
return nil
}
func (issue *Issue) ReloadLabels(ctx context.Context) (err error) {
if issue.ID != 0 {
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
if err != nil {
return fmt.Errorf("getLabelsByIssueID [%d]: %w", issue.ID, err)
}
issue.isLabelsLoaded = true
}
return nil
}
@ -496,8 +499,7 @@ func ReplaceIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer
}
}
issue.Labels = nil
if err = issue.LoadLabels(ctx); err != nil {
if err = issue.ReloadLabels(ctx); err != nil {
return err
}

View file

@ -15,6 +15,114 @@ import (
"github.com/stretchr/testify/require"
)
func TestIssueNewIssueLabels(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
label3 := &issues_model.Label{RepoID: 1, Name: "label3", Color: "#123"}
require.NoError(t, issues_model.NewLabel(db.DefaultContext, label3))
// label1 is already set, do nothing
// label3 is new, add it
require.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label3}, doer))
assert.Len(t, issue.Labels, 3)
// check that the pre-existing label1 is still present
assert.Equal(t, label1.ID, issue.Labels[0].ID)
// check that new label3 was added
assert.Equal(t, label3.ID, issue.Labels[1].ID)
// check that pre-existing label2 was not removed
assert.Equal(t, label2.ID, issue.Labels[2].ID)
}
func TestIssueNewIssueLabel(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
label := &issues_model.Label{RepoID: 1, Name: "label3", Color: "#123"}
require.NoError(t, issues_model.NewLabel(db.DefaultContext, label))
require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer))
assert.Len(t, issue.Labels, 1)
assert.Equal(t, label.ID, issue.Labels[0].ID)
}
func TestIssueReplaceIssueLabels(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
label3 := &issues_model.Label{RepoID: 1, Name: "label3", Color: "#123"}
require.NoError(t, issues_model.NewLabel(db.DefaultContext, label3))
issue.LoadLabels(db.DefaultContext)
assert.Len(t, issue.Labels, 2)
assert.Equal(t, label1.ID, issue.Labels[0].ID)
assert.Equal(t, label2.ID, issue.Labels[1].ID)
// label1 is already set, do nothing
// label3 is new, add it
// label2 is not in the list but already set, remove it
require.NoError(t, issues_model.ReplaceIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label3}, doer))
assert.Len(t, issue.Labels, 2)
assert.Equal(t, label1.ID, issue.Labels[0].ID)
assert.Equal(t, label3.ID, issue.Labels[1].ID)
}
func TestIssueDeleteIssueLabel(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
issue.LoadLabels(db.DefaultContext)
assert.Len(t, issue.Labels, 2)
assert.Equal(t, label1.ID, issue.Labels[0].ID)
assert.Equal(t, label2.ID, issue.Labels[1].ID)
require.NoError(t, issues_model.DeleteIssueLabel(db.DefaultContext, issue, label2, doer))
assert.Len(t, issue.Labels, 1)
assert.Equal(t, label1.ID, issue.Labels[0].ID)
}
func TestIssueLoadLabels(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
assert.Empty(t, issue.Labels)
issue.LoadLabels(db.DefaultContext)
assert.Len(t, issue.Labels, 2)
assert.Equal(t, label1.ID, issue.Labels[0].ID)
assert.Equal(t, label2.ID, issue.Labels[1].ID)
unittest.AssertSuccessfulDelete(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label2.ID})
// the database change is not noticed because the labels are cached
issue.LoadLabels(db.DefaultContext)
assert.Len(t, issue.Labels, 2)
issue.ReloadLabels(db.DefaultContext)
assert.Len(t, issue.Labels, 1)
assert.Equal(t, label1.ID, issue.Labels[0].ID)
}
func TestNewIssueLabelsScope(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())

View file

@ -408,7 +408,7 @@ func (pr *PullRequest) getReviewedByLines(ctx context.Context, writer io.Writer)
// Note: This doesn't page as we only expect a very limited number of reviews
reviews, err := FindLatestReviews(ctx, FindReviewOptions{
Type: ReviewTypeApprove,
Types: []ReviewType{ReviewTypeApprove},
IssueID: pr.IssueID,
OfficialOnly: setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly,
})

View file

@ -364,7 +364,7 @@ func GetCurrentReview(ctx context.Context, reviewer *user_model.User, issue *Iss
return nil, nil
}
reviews, err := FindReviews(ctx, FindReviewOptions{
Type: ReviewTypePending,
Types: []ReviewType{ReviewTypePending},
IssueID: issue.ID,
ReviewerID: reviewer.ID,
})

View file

@ -92,7 +92,7 @@ func (reviews ReviewList) LoadIssues(ctx context.Context) error {
// FindReviewOptions represent possible filters to find reviews
type FindReviewOptions struct {
db.ListOptions
Type ReviewType
Types []ReviewType
IssueID int64
ReviewerID int64
OfficialOnly bool
@ -107,8 +107,8 @@ func (opts *FindReviewOptions) toCond() builder.Cond {
if opts.ReviewerID > 0 {
cond = cond.And(builder.Eq{"reviewer_id": opts.ReviewerID})
}
if opts.Type != ReviewTypeUnknown {
cond = cond.And(builder.Eq{"type": opts.Type})
if len(opts.Types) > 0 {
cond = cond.And(builder.In("type", opts.Types))
}
if opts.OfficialOnly {
cond = cond.And(builder.Eq{"official": true})

View file

@ -64,7 +64,7 @@ func TestReviewType_Icon(t *testing.T) {
func TestFindReviews(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
reviews, err := issues_model.FindReviews(db.DefaultContext, issues_model.FindReviewOptions{
Type: issues_model.ReviewTypeApprove,
Types: []issues_model.ReviewType{issues_model.ReviewTypeApprove},
IssueID: 2,
ReviewerID: 1,
})
@ -76,7 +76,7 @@ func TestFindReviews(t *testing.T) {
func TestFindLatestReviews(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
reviews, err := issues_model.FindLatestReviews(db.DefaultContext, issues_model.FindReviewOptions{
Type: issues_model.ReviewTypeApprove,
Types: []issues_model.ReviewType{issues_model.ReviewTypeApprove},
IssueID: 11,
})
require.NoError(t, err)

View file

@ -60,34 +60,19 @@ func getStopwatch(ctx context.Context, userID, issueID int64) (sw *Stopwatch, ex
return sw, exists, err
}
// UserIDCount is a simple coalition of UserID and Count
type UserStopwatch struct {
UserID int64
StopWatches []*Stopwatch
}
// GetUIDsAndNotificationCounts between the two provided times
func GetUIDsAndStopwatch(ctx context.Context) ([]*UserStopwatch, error) {
func GetUIDsAndStopwatch(ctx context.Context) (map[int64][]*Stopwatch, error) {
sws := []*Stopwatch{}
if err := db.GetEngine(ctx).Where("issue_id != 0").Find(&sws); err != nil {
return nil, err
}
res := map[int64][]*Stopwatch{}
if len(sws) == 0 {
return []*UserStopwatch{}, nil
return res, nil
}
lastUserID := int64(-1)
res := []*UserStopwatch{}
for _, sw := range sws {
if lastUserID == sw.UserID {
lastUserStopwatch := res[len(res)-1]
lastUserStopwatch.StopWatches = append(lastUserStopwatch.StopWatches, sw)
} else {
res = append(res, &UserStopwatch{
UserID: sw.UserID,
StopWatches: []*Stopwatch{sw},
})
}
res[sw.UserID] = append(res[sw.UserID], sw)
}
return res, nil
}

View file

@ -4,12 +4,14 @@
package issues_test
import (
"path/filepath"
"testing"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert"
@ -77,3 +79,41 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) {
unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: 2, IssueID: 2})
unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 2, IssueID: 2})
}
func TestGetUIDsAndStopwatch(t *testing.T) {
defer unittest.OverrideFixtures(
unittest.FixturesOptions{
Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
Base: setting.AppWorkPath,
Dirs: []string{"models/issues/TestGetUIDsAndStopwatch/"},
},
)()
require.NoError(t, unittest.PrepareTestDatabase())
uidStopwatches, err := issues_model.GetUIDsAndStopwatch(db.DefaultContext)
require.NoError(t, err)
assert.EqualValues(t, map[int64][]*issues_model.Stopwatch{
1: {
{
ID: 1,
UserID: 1,
IssueID: 1,
CreatedUnix: timeutil.TimeStamp(1500988001),
},
{
ID: 3,
UserID: 1,
IssueID: 2,
CreatedUnix: timeutil.TimeStamp(1500988004),
},
},
2: {
{
ID: 2,
UserID: 2,
IssueID: 2,
CreatedUnix: timeutil.TimeStamp(1500988002),
},
},
}, uidStopwatches)
}

View file

@ -0,0 +1,10 @@
-
id: 1000
org_id: 1000
lower_name: owners
name: Owners
authorize: 4 # owner
num_repos: 0
num_members: 0
includes_all_repositories: true
can_create_org_repo: true

View file

@ -0,0 +1,59 @@
-
id: 1000
team_id: 1000
type: 1
access_mode: 0 # None
-
id: 1001
team_id: 1000
type: 2
access_mode: 0
-
id: 1002
team_id: 1000
type: 3
access_mode: 0
-
id: 1003
team_id: 1000
type: 4
access_mode: 0
-
id: 1004
team_id: 1000
type: 5
access_mode: 0
-
id: 1005
team_id: 1000
type: 6
access_mode: 0
-
id: 1006
team_id: 1000
type: 7
access_mode: 0
-
id: 1007
team_id: 1000
type: 8
access_mode: 0
-
id: 1008
team_id: 1000
type: 9
access_mode: 0
-
id: 1009
team_id: 1000
type: 10
access_mode: 0

View file

@ -264,7 +264,7 @@ func (org *Organization) UnitPermission(ctx context.Context, doer *user_model.Us
}
}
if org.Visibility.IsPublic() {
if org.Visibility.IsPublic() || (org.Visibility.IsLimited() && doer != nil) {
return perm.AccessModeRead
}

View file

@ -8,7 +8,9 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/structs"
@ -299,8 +301,8 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, expectedRepoIDs, repoIDs)
}
testSuccess(2, []int64{3, 5, 32})
testSuccess(4, []int64{3, 32})
testSuccess(2, []int64{32, 5, 3})
testSuccess(4, []int64{32, 3})
}
func TestAccessibleReposEnv_Repos(t *testing.T) {
@ -318,8 +320,8 @@ func TestAccessibleReposEnv_Repos(t *testing.T) {
}
assert.Equal(t, expectedRepos, repos)
}
testSuccess(2, []int64{3, 5, 32})
testSuccess(4, []int64{3, 32})
testSuccess(2, []int64{32, 5, 3})
testSuccess(4, []int64{32, 3})
}
func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
@ -512,3 +514,35 @@ func TestCreateOrganization4(t *testing.T) {
assert.True(t, db.IsErrNameReserved(err))
unittest.CheckConsistencyFor(t, &organization.Organization{}, &organization.Team{})
}
func TestUnitPermission(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
publicOrg := &organization.Organization{ID: 1001, Visibility: structs.VisibleTypePublic}
limitedOrg := &organization.Organization{ID: 1001, Visibility: structs.VisibleTypeLimited}
privateOrg := &organization.Organization{ID: 1001, Visibility: structs.VisibleTypePrivate}
user := &user_model.User{ID: 1001}
t.Run("Anonymous", func(t *testing.T) {
t.Run("Public", func(t *testing.T) {
assert.EqualValues(t, perm.AccessModeRead, publicOrg.UnitPermission(db.DefaultContext, nil, unit.TypeCode))
})
t.Run("Limited", func(t *testing.T) {
assert.EqualValues(t, perm.AccessModeNone, limitedOrg.UnitPermission(db.DefaultContext, nil, unit.TypeCode))
})
t.Run("Private", func(t *testing.T) {
assert.EqualValues(t, perm.AccessModeNone, privateOrg.UnitPermission(db.DefaultContext, nil, unit.TypeCode))
})
})
t.Run("Logged in", func(t *testing.T) {
t.Run("Public", func(t *testing.T) {
assert.EqualValues(t, perm.AccessModeRead, publicOrg.UnitPermission(db.DefaultContext, user, unit.TypeCode))
})
t.Run("Limited", func(t *testing.T) {
assert.EqualValues(t, perm.AccessModeRead, limitedOrg.UnitPermission(db.DefaultContext, user, unit.TypeCode))
})
t.Run("Private", func(t *testing.T) {
assert.EqualValues(t, perm.AccessModeNone, privateOrg.UnitPermission(db.DefaultContext, user, unit.TypeCode))
})
})
}

View file

@ -268,3 +268,43 @@ func IncrTeamRepoNum(ctx context.Context, teamID int64) error {
_, err := db.GetEngine(ctx).Incr("num_repos").ID(teamID).Update(new(Team))
return err
}
// CountInconsistentOwnerTeams returns the amount of owner teams that have all of
// their access modes set to "None".
func CountInconsistentOwnerTeams(ctx context.Context) (int64, error) {
return db.GetEngine(ctx).Table("team").
Join("INNER", "team_unit", "`team`.id = `team_unit`.team_id").
Where("`team`.lower_name = ?", strings.ToLower(OwnerTeamName)).
GroupBy("`team_unit`.team_id").
Having("SUM(`team_unit`.access_mode) = 0").
Count()
}
// FixInconsistentOwnerTeams fixes inconsistent owner teams that have all of
// their access modes set to "None", it sets it back to "Owner".
func FixInconsistentOwnerTeams(ctx context.Context) (int64, error) {
teamIDs := []int64{}
if err := db.GetEngine(ctx).Table("team").
Select("`team`.id").
Join("INNER", "team_unit", "`team`.id = `team_unit`.team_id").
Where("`team`.lower_name = ?", strings.ToLower(OwnerTeamName)).
GroupBy("`team_unit`.team_id").
Having("SUM(`team_unit`.access_mode) = 0").
Find(&teamIDs); err != nil {
return 0, err
}
if err := db.Iterate(ctx, builder.In("team_id", teamIDs), func(ctx context.Context, bean *TeamUnit) error {
if bean.Type == unit.TypeExternalTracker || bean.Type == unit.TypeExternalWiki {
bean.AccessMode = perm.AccessModeRead
} else {
bean.AccessMode = perm.AccessModeOwner
}
_, err := db.GetEngine(ctx).ID(bean.ID).Table("team_unit").Cols("access_mode").Update(bean)
return err
}); err != nil {
return 0, err
}
return int64(len(teamIDs)), nil
}

View file

@ -4,11 +4,14 @@
package organization_test
import (
"path/filepath"
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -198,3 +201,50 @@ func TestUsersInTeamsCount(t *testing.T) {
test([]int64{1, 2, 3, 4, 5}, []int64{2, 5}, 2) // userid 2,4
test([]int64{1, 2, 3, 4, 5}, []int64{2, 3, 5}, 3) // userid 2,4,5
}
func TestInconsistentOwnerTeam(t *testing.T) {
defer unittest.OverrideFixtures(
unittest.FixturesOptions{
Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
Base: setting.AppWorkPath,
Dirs: []string{"models/organization/TestInconsistentOwnerTeam/"},
},
)()
require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1000, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1001, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1002, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1003, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1004, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1005, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1006, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1007, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1008, TeamID: 1000, AccessMode: perm.AccessModeNone})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1009, TeamID: 1000, AccessMode: perm.AccessModeNone})
count, err := organization.CountInconsistentOwnerTeams(db.DefaultContext)
require.NoError(t, err)
require.EqualValues(t, 1, count)
count, err = organization.FixInconsistentOwnerTeams(db.DefaultContext)
require.NoError(t, err)
require.EqualValues(t, 1, count)
count, err = organization.CountInconsistentOwnerTeams(db.DefaultContext)
require.NoError(t, err)
require.EqualValues(t, 0, count)
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1000, AccessMode: perm.AccessModeOwner})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1001, AccessMode: perm.AccessModeOwner})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1002, AccessMode: perm.AccessModeOwner})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1003, AccessMode: perm.AccessModeOwner})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1004, AccessMode: perm.AccessModeOwner})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1007, AccessMode: perm.AccessModeOwner})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1008, AccessMode: perm.AccessModeOwner})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1009, AccessMode: perm.AccessModeOwner})
// External wiki and issue
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1005, AccessMode: perm.AccessModeRead})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1006, AccessMode: perm.AccessModeRead})
}

View file

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/packages"
debian_module "code.gitea.io/gitea/modules/packages/debian"
"code.gitea.io/gitea/modules/setting"
"xorm.io/builder"
)
@ -76,25 +77,41 @@ func ExistPackages(ctx context.Context, opts *PackageSearchOptions) (bool, error
// SearchPackages gets the packages matching the search options
func SearchPackages(ctx context.Context, opts *PackageSearchOptions, iter func(*packages.PackageFileDescriptor)) error {
return db.GetEngine(ctx).
Table("package_file").
Select("package_file.*").
Join("INNER", "package_version", "package_version.id = package_file.version_id").
Join("INNER", "package", "package.id = package_version.package_id").
Where(opts.toCond()).
Asc("package.lower_name", "package_version.created_unix").
Iterate(new(packages.PackageFile), func(_ int, bean any) error {
pf := bean.(*packages.PackageFile)
var start int
batchSize := setting.Database.IterateBufferSize
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
beans := make([]*packages.PackageFile, 0, batchSize)
pfd, err := packages.GetPackageFileDescriptor(ctx, pf)
if err != nil {
if err := db.GetEngine(ctx).
Table("package_file").
Select("package_file.*").
Join("INNER", "package_version", "package_version.id = package_file.version_id").
Join("INNER", "package", "package.id = package_version.package_id").
Where(opts.toCond()).
Asc("package.lower_name", "package_version.created_unix").
Limit(batchSize, start).
Find(&beans); err != nil {
return err
}
if len(beans) == 0 {
return nil
}
start += len(beans)
iter(pfd)
for _, bean := range beans {
pfd, err := packages.GetPackageFileDescriptor(ctx, bean)
if err != nil {
return err
}
return nil
})
iter(pfd)
}
}
}
}
// GetDistributions gets all available distributions

View file

@ -0,0 +1,93 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
package debian
import (
"strings"
"testing"
"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/packages"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
packages_service "code.gitea.io/gitea/services/packages"
_ "code.gitea.io/gitea/models"
_ "code.gitea.io/gitea/models/actions"
_ "code.gitea.io/gitea/models/activities"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
unittest.MainTest(m)
}
func preparePackage(t *testing.T, owner *user_model.User, name string) {
t.Helper()
data, err := packages.CreateHashedBufferFromReader(strings.NewReader("data"))
require.NoError(t, err)
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
db.DefaultContext,
&packages_service.PackageCreationInfo{
PackageInfo: packages_service.PackageInfo{
Owner: owner,
PackageType: packages_model.TypeDebian,
Name: name,
},
Creator: owner,
},
&packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{
Filename: name,
},
Data: data,
Creator: owner,
IsLead: true,
},
)
require.NoError(t, err)
}
func TestSearchPackages(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
defer test.MockVariableValue(&setting.Database.IterateBufferSize, 1)()
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
preparePackage(t, user2, "debian-1")
preparePackage(t, user2, "debian-2")
preparePackage(t, user3, "debian-1")
packageFiles := []string{}
require.NoError(t, SearchPackages(db.DefaultContext, &PackageSearchOptions{
OwnerID: user2.ID,
}, func(pfd *packages_model.PackageFileDescriptor) {
assert.NotNil(t, pfd)
packageFiles = append(packageFiles, pfd.File.Name)
}))
assert.Len(t, packageFiles, 2)
assert.Contains(t, packageFiles, "debian-1")
assert.Contains(t, packageFiles, "debian-2")
packageFiles = []string{}
require.NoError(t, SearchPackages(db.DefaultContext, &PackageSearchOptions{
OwnerID: user3.ID,
}, func(pfd *packages_model.PackageFileDescriptor) {
assert.NotNil(t, pfd)
packageFiles = append(packageFiles, pfd.File.Name)
}))
assert.Len(t, packageFiles, 1)
assert.Contains(t, packageFiles, "debian-1")
}

View file

@ -0,0 +1,30 @@
-
id: 1001
owner_id: 33
owner_name: user33
lower_name: repo1001
name: repo1001
default_branch: main
num_watches: 0
num_stars: 0
num_forks: 0
num_issues: 0
num_closed_issues: 0
num_pulls: 0
num_closed_pulls: 0
num_milestones: 0
num_closed_milestones: 0
num_projects: 0
num_closed_projects: 0
is_private: false
is_empty: false
is_archived: false
is_mirror: false
status: 0
is_fork: false
fork_id: 0
is_template: false
template_id: 0
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false

View file

@ -7,6 +7,7 @@ import (
"context"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"xorm.io/builder"
@ -54,9 +55,9 @@ func GetUserFork(ctx context.Context, repoID, userID int64) (*Repository, error)
return &forkedRepo, nil
}
// GetForks returns all the forks of the repository
func GetForks(ctx context.Context, repo *Repository, listOptions db.ListOptions) ([]*Repository, error) {
sess := db.GetEngine(ctx)
// GetForks returns all the forks of the repository that are visible to the user.
func GetForks(ctx context.Context, repo *Repository, user *user_model.User, listOptions db.ListOptions) ([]*Repository, int64, error) {
sess := db.GetEngine(ctx).Where(AccessibleRepositoryCondition(user, unit.TypeInvalid))
var forks []*Repository
if listOptions.Page == 0 {
@ -66,7 +67,8 @@ func GetForks(ctx context.Context, repo *Repository, listOptions db.ListOptions)
sess = db.SetSessionPagination(sess, &listOptions)
}
return forks, sess.Find(&forks, &Repository{ForkID: repo.ID})
count, err := sess.FindAndCount(&forks, &Repository{ForkID: repo.ID})
return forks, count, err
}
// IncrementRepoForkNum increment repository fork number

View file

@ -641,12 +641,9 @@ func AccessibleRepositoryCondition(user *user_model.User, unitType unit.Type) bu
// 1. Be able to see all non-private repositories that either:
cond = cond.Or(builder.And(
builder.Eq{"`repository`.is_private": false},
// 2. Aren't in an private organisation or limited organisation if we're not logged in
// 2. Aren't in an private organisation/user or limited organisation/user if the doer is not logged in.
builder.NotIn("`repository`.owner_id", builder.Select("id").From("`user`").Where(
builder.And(
builder.Eq{"type": user_model.UserTypeOrganization},
builder.In("visibility", orgVisibilityLimit)),
))))
builder.In("visibility", orgVisibilityLimit)))))
}
if user != nil {

View file

@ -4,13 +4,18 @@
package repo_test
import (
"path/filepath"
"slices"
"strings"
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -403,3 +408,43 @@ func TestSearchRepositoryByTopicName(t *testing.T) {
})
}
}
func TestSearchRepositoryIDsByCondition(t *testing.T) {
defer unittest.OverrideFixtures(
unittest.FixturesOptions{
Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
Base: setting.AppWorkPath,
Dirs: []string{"models/repo/TestSearchRepositoryIDsByCondition/"},
},
)()
require.NoError(t, unittest.PrepareTestDatabase())
// Sanity check of the database
limitedUser := unittest.AssertExistsAndLoadBean(t, &user.User{ID: 33, Visibility: structs.VisibleTypeLimited})
unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1001, OwnerID: limitedUser.ID})
testCases := []struct {
user *user.User
repoIDs []int64
}{
{
user: nil,
repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1059},
},
{
user: unittest.AssertExistsAndLoadBean(t, &user.User{ID: 4}),
repoIDs: []int64{1, 3, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1001, 1059},
},
{
user: unittest.AssertExistsAndLoadBean(t, &user.User{ID: 5}),
repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1001, 1059},
},
}
for _, testCase := range testCases {
repoIDs, err := repo_model.FindUserCodeAccessibleRepoIDs(db.DefaultContext, testCase.user)
require.NoError(t, err)
slices.Sort(repoIDs)
assert.EqualValues(t, testCase.repoIDs, repoIDs)
}
}

View file

@ -36,6 +36,7 @@ var OrderByMap = map[string]map[string]db.SearchOrderBy{
var OrderByFlatMap = map[string]db.SearchOrderBy{
"newest": OrderByMap["desc"]["created"],
"oldest": OrderByMap["asc"]["created"],
"recentupdate": OrderByMap["desc"]["updated"],
"leastupdate": OrderByMap["asc"]["updated"],
"reversealphabetically": OrderByMap["desc"]["alpha"],
"alphabetically": OrderByMap["asc"]["alpha"],

View file

@ -10,10 +10,8 @@ import (
"net/mail"
"regexp"
"strings"
"time"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
@ -307,23 +305,6 @@ func updateActivation(ctx context.Context, email *EmailAddress, activate bool) e
return UpdateUserCols(ctx, user, "rands")
}
// VerifyActiveEmailCode verifies active email code when active account
func VerifyActiveEmailCode(ctx context.Context, code, email string) *EmailAddress {
if user := GetVerifyUser(ctx, code); user != nil {
// time limit code
prefix := code[:base.TimeLimitCodeLength]
data := fmt.Sprintf("%d%s%s%s%s", user.ID, email, user.LowerName, user.Passwd, user.Rands)
if base.VerifyTimeLimitCode(time.Now(), data, setting.Service.ActiveCodeLives, prefix) {
emailAddress := &EmailAddress{UID: user.ID, Email: email}
if has, _ := db.GetEngine(ctx).Get(emailAddress); has {
return emailAddress
}
}
}
return nil
}
// SearchEmailOrderBy is used to sort the results from SearchEmails()
type SearchEmailOrderBy string

View file

@ -160,34 +160,12 @@ func UpdateExternalUserByExternalID(ctx context.Context, external *ExternalLogin
return err
}
// EnsureLinkExternalToUser link the external user to the user
func EnsureLinkExternalToUser(ctx context.Context, external *ExternalLoginUser) error {
has, err := db.Exist[ExternalLoginUser](ctx, builder.Eq{
"external_id": external.ExternalID,
"login_source_id": external.LoginSourceID,
})
if err != nil {
return err
}
if has {
_, err = db.GetEngine(ctx).Where("external_id=? AND login_source_id=?", external.ExternalID, external.LoginSourceID).AllCols().Update(external)
return err
}
_, err = db.GetEngine(ctx).Insert(external)
return err
}
// FindExternalUserOptions represents an options to find external users
type FindExternalUserOptions struct {
db.ListOptions
Provider string
UserID int64
LoginSourceID int64
HasRefreshToken bool
Expired bool
OrderBy string
Provider string
UserID int64
OrderBy string
}
func (opts FindExternalUserOptions) ToConds() builder.Cond {
@ -198,22 +176,9 @@ func (opts FindExternalUserOptions) ToConds() builder.Cond {
if opts.UserID > 0 {
cond = cond.And(builder.Eq{"user_id": opts.UserID})
}
if opts.Expired {
cond = cond.And(builder.Lt{"expires_at": time.Now()})
}
if opts.HasRefreshToken {
cond = cond.And(builder.Neq{"refresh_token": ""})
}
if opts.LoginSourceID != 0 {
cond = cond.And(builder.Eq{"login_source_id": opts.LoginSourceID})
}
return cond
}
func (opts FindExternalUserOptions) ToOrders() string {
return opts.OrderBy
}
func IterateExternalLogin(ctx context.Context, opts FindExternalUserOptions, f func(ctx context.Context, u *ExternalLoginUser) error) error {
return db.Iterate(ctx, opts.ToConds(), f)
}

View file

@ -7,7 +7,9 @@ package user
import (
"context"
"crypto/subtle"
"encoding/hex"
"errors"
"fmt"
"net/mail"
"net/url"
@ -48,19 +50,19 @@ const (
UserTypeIndividual UserType = iota // Historic reason to make it starts at 0.
// UserTypeOrganization defines an organization
UserTypeOrganization
UserTypeOrganization // 1
// UserTypeUserReserved reserves a (non-existing) user, i.e. to prevent a spam user from re-registering after being deleted, or to reserve the name until the user is actually created later on
UserTypeUserReserved
UserTypeUserReserved // 2
// UserTypeOrganizationReserved reserves a (non-existing) organization, to be used in combination with UserTypeUserReserved
UserTypeOrganizationReserved
UserTypeOrganizationReserved // 3
// UserTypeBot defines a bot user
UserTypeBot
UserTypeBot // 4
// UserTypeRemoteUser defines a remote user for federated users
UserTypeRemoteUser
UserTypeRemoteUser // 5
)
const (
@ -318,15 +320,14 @@ func (u *User) OrganisationLink() string {
return setting.AppSubURL + "/org/" + url.PathEscape(u.Name)
}
// GenerateEmailActivateCode generates an activate code based on user information and given e-mail.
func (u *User) GenerateEmailActivateCode(email string) string {
code := base.CreateTimeLimitCode(
fmt.Sprintf("%d%s%s%s%s", u.ID, email, u.LowerName, u.Passwd, u.Rands),
setting.Service.ActiveCodeLives, time.Now(), nil)
// Add tail hex username
code += hex.EncodeToString([]byte(u.LowerName))
return code
// GenerateEmailAuthorizationCode generates an activation code based for the user for the specified purpose.
// The standard expiry is ActiveCodeLives minutes.
func (u *User) GenerateEmailAuthorizationCode(ctx context.Context, purpose auth.AuthorizationPurpose) (string, error) {
lookup, validator, err := auth.GenerateAuthToken(ctx, u.ID, timeutil.TimeStampNow().Add(int64(setting.Service.ActiveCodeLives)*60), purpose)
if err != nil {
return "", err
}
return lookup + ":" + validator, nil
}
// GetUserFollowers returns range of user's followers.
@ -421,6 +422,10 @@ func (u *User) IsIndividual() bool {
return u.Type == UserTypeIndividual
}
func (u *User) IsUser() bool {
return u.Type == UserTypeIndividual || u.Type == UserTypeBot
}
// IsBot returns whether or not the user is of type bot
func (u *User) IsBot() bool {
return u.Type == UserTypeBot
@ -832,35 +837,50 @@ func countUsers(ctx context.Context, opts *CountUserFilter) int64 {
return count
}
// GetVerifyUser get user by verify code
func GetVerifyUser(ctx context.Context, code string) (user *User) {
if len(code) <= base.TimeLimitCodeLength {
return nil
// VerifyUserActiveCode verifies that the code is valid for the given purpose for this user.
// If delete is specified, the token will be deleted.
func VerifyUserAuthorizationToken(ctx context.Context, code string, purpose auth.AuthorizationPurpose, delete bool) (*User, error) {
lookupKey, validator, found := strings.Cut(code, ":")
if !found {
return nil, nil
}
// use tail hex username query user
hexStr := code[base.TimeLimitCodeLength:]
if b, err := hex.DecodeString(hexStr); err == nil {
if user, err = GetUserByName(ctx, string(b)); user != nil {
return user
authToken, err := auth.FindAuthToken(ctx, lookupKey, purpose)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
return nil, nil
}
log.Error("user.getVerifyUser: %v", err)
return nil, err
}
return nil
}
if authToken.IsExpired() {
return nil, auth.DeleteAuthToken(ctx, authToken)
}
// VerifyUserActiveCode verifies active code when active account
func VerifyUserActiveCode(ctx context.Context, code string) (user *User) {
if user = GetVerifyUser(ctx, code); user != nil {
// time limit code
prefix := code[:base.TimeLimitCodeLength]
data := fmt.Sprintf("%d%s%s%s%s", user.ID, user.Email, user.LowerName, user.Passwd, user.Rands)
if base.VerifyTimeLimitCode(time.Now(), data, setting.Service.ActiveCodeLives, prefix) {
return user
rawValidator, err := hex.DecodeString(validator)
if err != nil {
return nil, err
}
if subtle.ConstantTimeCompare([]byte(authToken.HashedValidator), []byte(auth.HashValidator(rawValidator))) == 0 {
return nil, errors.New("validator doesn't match")
}
u, err := GetUserByID(ctx, authToken.UID)
if err != nil {
if IsErrUserNotExist(err) {
return nil, nil
}
return nil, err
}
if delete {
if err := auth.DeleteAuthToken(ctx, authToken); err != nil {
return nil, err
}
}
return nil
return u, nil
}
// ValidateUser check if user is valid to insert / update into database
@ -897,7 +917,13 @@ func UpdateUserCols(ctx context.Context, u *User, cols ...string) error {
// GetInactiveUsers gets all inactive users
func GetInactiveUsers(ctx context.Context, olderThan time.Duration) ([]*User, error) {
var cond builder.Cond = builder.Eq{"is_active": false}
cond := builder.And(
builder.Eq{"is_active": false},
builder.Or( // only plain user
builder.Eq{"`type`": UserTypeIndividual},
builder.Eq{"`type`": UserTypeUserReserved},
),
)
if olderThan > 0 {
cond = cond.And(builder.Lt{"created_unix": time.Now().Add(-olderThan).Unix()})

View file

@ -7,6 +7,7 @@ package user_test
import (
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"strings"
"testing"
@ -21,7 +22,9 @@ import (
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
@ -699,3 +702,80 @@ func TestDisabledUserFeatures(t *testing.T) {
assert.True(t, user_model.IsFeatureDisabledWithLoginType(user, f))
}
}
func TestGenerateEmailAuthorizationCode(t *testing.T) {
defer test.MockVariableValue(&setting.Service.ActiveCodeLives, 2)()
require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
code, err := user.GenerateEmailAuthorizationCode(db.DefaultContext, auth.UserActivation)
require.NoError(t, err)
lookupKey, validator, ok := strings.Cut(code, ":")
assert.True(t, ok)
rawValidator, err := hex.DecodeString(validator)
require.NoError(t, err)
authToken, err := auth.FindAuthToken(db.DefaultContext, lookupKey, auth.UserActivation)
require.NoError(t, err)
assert.False(t, authToken.IsExpired())
assert.EqualValues(t, authToken.HashedValidator, auth.HashValidator(rawValidator))
authToken.Expiry = authToken.Expiry.Add(-int64(setting.Service.ActiveCodeLives) * 60)
assert.True(t, authToken.IsExpired())
}
func TestVerifyUserAuthorizationToken(t *testing.T) {
defer test.MockVariableValue(&setting.Service.ActiveCodeLives, 2)()
require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
code, err := user.GenerateEmailAuthorizationCode(db.DefaultContext, auth.UserActivation)
require.NoError(t, err)
lookupKey, _, ok := strings.Cut(code, ":")
assert.True(t, ok)
t.Run("Wrong purpose", func(t *testing.T) {
u, err := user_model.VerifyUserAuthorizationToken(db.DefaultContext, code, auth.PasswordReset, false)
require.NoError(t, err)
assert.Nil(t, u)
})
t.Run("No delete", func(t *testing.T) {
u, err := user_model.VerifyUserAuthorizationToken(db.DefaultContext, code, auth.UserActivation, false)
require.NoError(t, err)
assert.EqualValues(t, user.ID, u.ID)
authToken, err := auth.FindAuthToken(db.DefaultContext, lookupKey, auth.UserActivation)
require.NoError(t, err)
assert.NotNil(t, authToken)
})
t.Run("Delete", func(t *testing.T) {
u, err := user_model.VerifyUserAuthorizationToken(db.DefaultContext, code, auth.UserActivation, true)
require.NoError(t, err)
assert.EqualValues(t, user.ID, u.ID)
authToken, err := auth.FindAuthToken(db.DefaultContext, lookupKey, auth.UserActivation)
require.ErrorIs(t, err, util.ErrNotExist)
assert.Nil(t, authToken)
})
}
func TestGetInactiveUsers(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
// all inactive users
// user1's createdunix is 1730468968
users, err := user_model.GetInactiveUsers(db.DefaultContext, 0)
require.NoError(t, err)
assert.Len(t, users, 1)
interval := time.Now().Unix() - 1730468968 + 3600*24
users, err = user_model.GetInactiveUsers(db.DefaultContext, time.Duration(interval*int64(time.Second)))
require.NoError(t, err)
require.Empty(t, users)
}

View file

@ -18,8 +18,32 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
return fullStepsOfEmptySteps(task)
}
firstStep := task.Steps[0]
// firstStep is the first step that has run or running, not include preStep.
// For example,
// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): firstStep is step1.
// 2. preStep(Success) -> step1(Skipped) -> step2(Success) -> postStep(Success): firstStep is step2.
// 3. preStep(Success) -> step1(Running) -> step2(Waiting) -> postStep(Waiting): firstStep is step1.
// 4. preStep(Success) -> step1(Skipped) -> step2(Skipped) -> postStep(Skipped): firstStep is nil.
// 5. preStep(Success) -> step1(Cancelled) -> step2(Cancelled) -> postStep(Cancelled): firstStep is nil.
var firstStep *actions_model.ActionTaskStep
// lastHasRunStep is the last step that has run.
// For example,
// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1.
// 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3.
// 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2.
// So its Stopped is the Started of postStep when there are no more steps to run.
var lastHasRunStep *actions_model.ActionTaskStep
var logIndex int64
for _, step := range task.Steps {
if firstStep == nil && (step.Status.HasRun() || step.Status.IsRunning()) {
firstStep = step
}
if step.Status.HasRun() {
lastHasRunStep = step
}
logIndex += step.LogLength
}
preStep := &actions_model.ActionTaskStep{
Name: preStepName,
@ -28,32 +52,17 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
Status: actions_model.StatusRunning,
}
if firstStep.Status.HasRun() || firstStep.Status.IsRunning() {
// No step has run or is running, so preStep is equal to the task
if firstStep == nil {
preStep.Stopped = task.Stopped
preStep.Status = task.Status
} else {
preStep.LogLength = firstStep.LogIndex
preStep.Stopped = firstStep.Started
preStep.Status = actions_model.StatusSuccess
} else if task.Status.IsDone() {
preStep.Stopped = task.Stopped
preStep.Status = actions_model.StatusFailure
if task.Status.IsSkipped() {
preStep.Status = actions_model.StatusSkipped
}
}
logIndex += preStep.LogLength
// lastHasRunStep is the last step that has run.
// For example,
// 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1.
// 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3.
// 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2.
// So its Stopped is the Started of postStep when there are no more steps to run.
var lastHasRunStep *actions_model.ActionTaskStep
for _, step := range task.Steps {
if step.Status.HasRun() {
lastHasRunStep = step
}
logIndex += step.LogLength
}
if lastHasRunStep == nil {
lastHasRunStep = preStep
}

View file

@ -137,6 +137,25 @@ func TestFullSteps(t *testing.T) {
{Name: postStepName, Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
},
},
{
name: "first step is skipped",
task: &actions_model.ActionTask{
Steps: []*actions_model.ActionTaskStep{
{Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
{Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090},
},
Status: actions_model.StatusSuccess,
Started: 10000,
Stopped: 10100,
LogLength: 100,
},
want: []*actions_model.ActionTaskStep{
{Name: preStepName, Status: actions_model.StatusSuccess, LogIndex: 0, LogLength: 10, Started: 10000, Stopped: 10010},
{Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
{Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090},
{Name: postStepName, Status: actions_model.StatusSuccess, LogIndex: 90, LogLength: 10, Started: 10090, Stopped: 10100},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

137
modules/annex/annex.go Normal file
View file

@ -0,0 +1,137 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
// Unlike modules/lfs, which operates mainly on git.Blobs, this operates on git.TreeEntrys.
// The motivation for this is that TreeEntrys have an easy pointer to the on-disk repo path,
// while blobs do not (in fact, if building with TAGS=gogit, blobs might exist only in a mock
// filesystem, living only in process RAM). We must have the on-disk path to do anything
// useful with git-annex because all of its interesting data is on-disk under .git/annex/.
package annex
import (
"errors"
"fmt"
"io/fs"
"os"
"path"
"path/filepath"
"regexp"
"strings"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
)
// ErrBlobIsNotAnnexed occurs if a blob does not contain a valid annex key
var ErrBlobIsNotAnnexed = errors.New("not a git-annex pointer")
func LookupKey(blob *git.Blob) (string, error) {
stdout, _, err := git.NewCommand(git.DefaultContext, "annex", "lookupkey", "--ref").AddDynamicArguments(blob.ID.String()).RunStdString(&git.RunOpts{Dir: blob.Repo().Path})
if err != nil {
return "", ErrBlobIsNotAnnexed
}
key := strings.TrimSpace(stdout)
return key, nil
}
func ContentLocationFromKey(repoPath, key string) (string, error) {
contentLocation, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "contentlocation").AddDynamicArguments(key).RunStdString(&git.RunOpts{Dir: repoPath})
if err != nil {
return "", fmt.Errorf("in %s: %s does not seem to be a valid annexed file: %w", repoPath, key, err)
}
contentLocation = strings.TrimSpace(contentLocation)
contentLocation = path.Clean("/" + contentLocation)[1:] // prevent directory traversals
contentLocation = path.Join(repoPath, contentLocation)
return contentLocation, nil
}
// return the absolute path of the content pointed to by the annex pointer stored in the git object
// errors if the content is not found in this repo
func ContentLocation(blob *git.Blob) (string, error) {
key, err := LookupKey(blob)
if err != nil {
return "", err
}
return ContentLocationFromKey(blob.Repo().Path, key)
}
// returns a stream open to the annex content
func Content(blob *git.Blob) (*os.File, error) {
contentLocation, err := ContentLocation(blob)
if err != nil {
return nil, err
}
return os.Open(contentLocation)
}
// whether the object appears to be a valid annex pointer
// does *not* verify if the content is actually in this repo;
// for that, use ContentLocation()
func IsAnnexed(blob *git.Blob) (bool, error) {
if !setting.Annex.Enabled {
return false, nil
}
// LookupKey is written to only return well-formed keys
// so the test is just to see if it errors
_, err := LookupKey(blob)
if err != nil {
if errors.Is(err, ErrBlobIsNotAnnexed) {
return false, nil
}
return false, err
}
return true, nil
}
// IsAnnexRepo determines if repo is a git-annex enabled repository
func IsAnnexRepo(repo *git.Repository) bool {
_, _, err := git.NewCommand(repo.Ctx, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: repo.Path})
return err == nil
}
var repoConfigFileRe = regexp.MustCompile("[^/]+/[^/]+.git/config$")
var (
uuid2repoPathCache = make(map[string]string)
repoPath2uuidCache = make(map[string]string)
)
func updateUUID2RepoPathCache() error {
return filepath.WalkDir(setting.RepoRootPath, func(path string, d fs.DirEntry, err error) error {
if err == nil && repoConfigFileRe.MatchString(path) {
thisRepoPath := strings.TrimSuffix(path, "/config")
_, ok := repoPath2uuidCache[thisRepoPath]
if ok {
return nil
}
stdout, _, err := git.NewCommand(git.DefaultContext, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: thisRepoPath})
if err != nil {
return nil
}
repoUUID := strings.TrimSpace(stdout)
if repoUUID != "" {
uuid2repoPathCache[repoUUID] = thisRepoPath
repoPath2uuidCache[thisRepoPath] = repoUUID
}
}
return nil
})
}
func UUID2RepoPath(uuid string) (string, error) {
if repoPath, ok := uuid2repoPathCache[uuid]; ok {
return repoPath, nil
}
// If the cache didn't contain an entry for the UUID then update the cache and try again
if err := updateUUID2RepoPathCache(); err != nil {
return "", err
}
if repoPath, ok := uuid2repoPathCache[uuid]; ok {
return repoPath, nil
}
return "", fmt.Errorf("no repository known for UUID '%s'", uuid)
}

View file

@ -4,26 +4,21 @@
package base
import (
"crypto/hmac"
"crypto/sha1"
"crypto/sha256"
"crypto/subtle"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"hash"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"time"
"unicode/utf8"
"code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/dustin/go-humanize"
)
@ -54,66 +49,6 @@ func BasicAuthDecode(encoded string) (string, string, error) {
return "", "", errors.New("invalid basic authentication")
}
// VerifyTimeLimitCode verify time limit code
func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) bool {
if len(code) <= 18 {
return false
}
startTimeStr := code[:12]
aliveTimeStr := code[12:18]
aliveTime, _ := strconv.Atoi(aliveTimeStr) // no need to check err, if anything wrong, the following code check will fail soon
// check code
retCode := CreateTimeLimitCode(data, aliveTime, startTimeStr, nil)
if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 {
retCode = CreateTimeLimitCode(data, aliveTime, startTimeStr, sha1.New()) // TODO: this is only for the support of legacy codes, remove this in/after 1.23
if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 {
return false
}
}
// check time is expired or not: startTime <= now && now < startTime + minutes
startTime, _ := time.ParseInLocation("200601021504", startTimeStr, time.Local)
return (startTime.Before(now) || startTime.Equal(now)) && now.Before(startTime.Add(time.Minute*time.Duration(minutes)))
}
// TimeLimitCodeLength default value for time limit code
const TimeLimitCodeLength = 12 + 6 + 40
// CreateTimeLimitCode create a time-limited code.
// Format: 12 length date time string + 6 minutes string (not used) + 40 hash string, some other code depends on this fixed length
// If h is nil, then use the default hmac hash.
func CreateTimeLimitCode[T time.Time | string](data string, minutes int, startTimeGeneric T, h hash.Hash) string {
const format = "200601021504"
var start time.Time
var startTimeAny any = startTimeGeneric
if t, ok := startTimeAny.(time.Time); ok {
start = t
} else {
var err error
start, err = time.ParseInLocation(format, startTimeAny.(string), time.Local)
if err != nil {
return "" // return an invalid code because the "parse" failed
}
}
startStr := start.Format(format)
end := start.Add(time.Minute * time.Duration(minutes))
if h == nil {
h = hmac.New(sha1.New, setting.GetGeneralTokenSigningSecret())
}
_, _ = fmt.Fprintf(h, "%s%s%s%s%d", data, hex.EncodeToString(setting.GetGeneralTokenSigningSecret()), startStr, end.Format(format), minutes)
encoded := hex.EncodeToString(h.Sum(nil))
code := fmt.Sprintf("%s%06d%s", startStr, minutes, encoded)
if len(code) != TimeLimitCodeLength {
panic("there is a hard requirement for the length of time-limited code") // it shouldn't happen
}
return code
}
// FileSize calculates the file size and generate user-friendly string.
func FileSize(s int64) string {
return humanize.IBytes(uint64(s))
@ -167,6 +102,12 @@ func Int64sToStrings(ints []int64) []string {
// EntryIcon returns the octicon class for displaying files/directories
func EntryIcon(entry *git.TreeEntry) string {
isAnnexed, _ := annex.IsAnnexed(entry.Blob())
if isAnnexed {
// Show git-annex files as binary files to differentiate them from non-annexed files
// TODO: find a more suitable icon, maybe something related to git-annex
return "file-binary"
}
switch {
case entry.IsLink():
te, _, err := entry.FollowLink()

View file

@ -4,13 +4,7 @@
package base
import (
"crypto/sha1"
"fmt"
"testing"
"time"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -46,57 +40,6 @@ func TestBasicAuthDecode(t *testing.T) {
require.Error(t, err)
}
func TestVerifyTimeLimitCode(t *testing.T) {
defer test.MockVariableValue(&setting.InstallLock, true)()
initGeneralSecret := func(secret string) {
setting.InstallLock = true
setting.CfgProvider, _ = setting.NewConfigProviderFromData(fmt.Sprintf(`
[oauth2]
JWT_SECRET = %s
`, secret))
setting.LoadCommonSettings()
}
initGeneralSecret("KZb_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko")
now := time.Now()
t.Run("TestGenericParameter", func(t *testing.T) {
time2000 := time.Date(2000, 1, 2, 3, 4, 5, 0, time.Local)
assert.Equal(t, "2000010203040000026fa5221b2731b7cf80b1b506f5e39e38c115fee5", CreateTimeLimitCode("test-sha1", 2, time2000, sha1.New()))
assert.Equal(t, "2000010203040000026fa5221b2731b7cf80b1b506f5e39e38c115fee5", CreateTimeLimitCode("test-sha1", 2, "200001020304", sha1.New()))
assert.Equal(t, "2000010203040000024842227a2f87041ff82025199c0187410a9297bf", CreateTimeLimitCode("test-hmac", 2, time2000, nil))
assert.Equal(t, "2000010203040000024842227a2f87041ff82025199c0187410a9297bf", CreateTimeLimitCode("test-hmac", 2, "200001020304", nil))
})
t.Run("TestInvalidCode", func(t *testing.T) {
assert.False(t, VerifyTimeLimitCode(now, "data", 2, ""))
assert.False(t, VerifyTimeLimitCode(now, "data", 2, "invalid code"))
})
t.Run("TestCreateAndVerify", func(t *testing.T) {
code := CreateTimeLimitCode("data", 2, now, nil)
assert.False(t, VerifyTimeLimitCode(now.Add(-time.Minute), "data", 2, code)) // not started yet
assert.True(t, VerifyTimeLimitCode(now, "data", 2, code))
assert.True(t, VerifyTimeLimitCode(now.Add(time.Minute), "data", 2, code))
assert.False(t, VerifyTimeLimitCode(now.Add(time.Minute), "DATA", 2, code)) // invalid data
assert.False(t, VerifyTimeLimitCode(now.Add(2*time.Minute), "data", 2, code)) // expired
})
t.Run("TestDifferentSecret", func(t *testing.T) {
// use another secret to ensure the code is invalid for different secret
verifyDataCode := func(c string) bool {
return VerifyTimeLimitCode(now, "data", 2, c)
}
code1 := CreateTimeLimitCode("data", 2, now, sha1.New())
code2 := CreateTimeLimitCode("data", 2, now, nil)
assert.True(t, verifyDataCode(code1))
assert.True(t, verifyDataCode(code2))
initGeneralSecret("000_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko")
assert.False(t, verifyDataCode(code1))
assert.False(t, verifyDataCode(code2))
})
}
func TestFileSize(t *testing.T) {
var size int64 = 512
assert.Equal(t, "512 B", FileSize(size))

View file

@ -90,8 +90,8 @@ loop:
return
}
for _, userStopwatches := range usersStopwatches {
apiSWs, err := convert.ToStopWatches(ctx, userStopwatches.StopWatches)
for uid, stopwatches := range usersStopwatches {
apiSWs, err := convert.ToStopWatches(ctx, stopwatches)
if err != nil {
if !issues_model.IsErrIssueNotExist(err) {
log.Error("Unable to APIFormat stopwatches: %v", err)
@ -103,7 +103,7 @@ loop:
log.Error("Unable to marshal stopwatches: %v", err)
continue
}
m.SendMessage(userStopwatches.UserID, &Event{
m.SendMessage(uid, &Event{
Name: "stopwatches",
Data: string(dataBs),
})

View file

@ -126,6 +126,10 @@ func (b *blobReader) Close() error {
return nil
}
func (b *Blob) Repo() *Repository {
return b.repo
}
// Name returns name of the tree entry this blob object was created from (or empty string)
func (b *Blob) Name() string {
return b.name

View file

@ -457,12 +457,13 @@ func (c *Command) RunStdBytes(opts *RunOpts) (stdout, stderr []byte, runErr RunS
}
// AllowLFSFiltersArgs return globalCommandArgs with lfs filter, it should only be used for tests
// It also re-enables git-credential(1), which is used to test git-annex's HTTP support
func AllowLFSFiltersArgs() TrustedCmdArgs {
// Now here we should explicitly allow lfs filters to run
filteredLFSGlobalArgs := make(TrustedCmdArgs, len(globalCommandArgs))
j := 0
for _, arg := range globalCommandArgs {
if strings.Contains(string(arg), "lfs") {
if strings.Contains(string(arg), "lfs") || strings.Contains(string(arg), "credential") {
j--
} else {
filteredLFSGlobalArgs[j] = arg

View file

@ -17,6 +17,8 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
"github.com/go-git/go-git/v5/config"
)
// Commit represents a git commit.
@ -365,53 +367,48 @@ func (c *Commit) GetSubModules() (*ObjectCache, error) {
return nil, err
}
rd, err := entry.Blob().DataAsync()
content, err := entry.Blob().GetBlobContent(10 * 1024)
if err != nil {
return nil, err
}
defer rd.Close()
scanner := bufio.NewScanner(rd)
c.submoduleCache = newObjectCache()
var ismodule bool
var path string
for scanner.Scan() {
if strings.HasPrefix(scanner.Text(), "[submodule") {
ismodule = true
continue
}
if ismodule {
fields := strings.Split(scanner.Text(), "=")
k := strings.TrimSpace(fields[0])
if k == "path" {
path = strings.TrimSpace(fields[1])
} else if k == "url" {
c.submoduleCache.Set(path, &SubModule{path, strings.TrimSpace(fields[1])})
ismodule = false
}
}
c.submoduleCache, err = parseSubmoduleContent([]byte(content))
if err != nil {
return nil, err
}
if err = scanner.Err(); err != nil {
return nil, fmt.Errorf("GetSubModules scan: %w", err)
}
return c.submoduleCache, nil
}
// GetSubModule get the sub module according entryname
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
func parseSubmoduleContent(bs []byte) (*ObjectCache, error) {
cfg := config.NewModules()
if err := cfg.Unmarshal(bs); err != nil {
return nil, err
}
submoduleCache := newObjectCache()
if len(cfg.Submodules) == 0 {
return nil, fmt.Errorf("no submodules found")
}
for _, subModule := range cfg.Submodules {
submoduleCache.Set(subModule.Path, subModule.URL)
}
return submoduleCache, nil
}
// GetSubModule returns the URL to the submodule according entryname
func (c *Commit) GetSubModule(entryname string) (string, error) {
modules, err := c.GetSubModules()
if err != nil {
return nil, err
return "", err
}
if modules != nil {
module, has := modules.Get(entryname)
if has {
return module.(*SubModule), nil
return module.(string), nil
}
}
return nil, nil
return "", nil
}
// GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only')

View file

@ -72,17 +72,15 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath
// If the entry if a submodule add a submodule file for this
if entry.IsSubModule() {
subModuleURL := ""
var fullPath string
if len(treePath) > 0 {
fullPath = treePath + "/" + entry.Name()
} else {
fullPath = entry.Name()
}
if subModule, err := commit.GetSubModule(fullPath); err != nil {
subModuleURL, err := commit.GetSubModule(fullPath)
if err != nil {
return nil, nil, err
} else if subModule != nil {
subModuleURL = subModule.URL
}
subModuleFile := NewSubModuleFile(commitsInfo[i].Commit, subModuleURL, entry.ID.String())
commitsInfo[i].SubModuleFile = subModuleFile

View file

@ -369,3 +369,33 @@ func TestParseCommitRenames(t *testing.T) {
assert.Equal(t, testcase.renames, renames)
}
}
func Test_parseSubmoduleContent(t *testing.T) {
submoduleFiles := []struct {
fileContent string
expectedPath string
expectedURL string
}{
{
fileContent: `[submodule "jakarta-servlet"]
url = ../../ALP-pool/jakarta-servlet
path = jakarta-servlet`,
expectedPath: "jakarta-servlet",
expectedURL: "../../ALP-pool/jakarta-servlet",
},
{
fileContent: `[submodule "jakarta-servlet"]
path = jakarta-servlet
url = ../../ALP-pool/jakarta-servlet`,
expectedPath: "jakarta-servlet",
expectedURL: "../../ALP-pool/jakarta-servlet",
},
}
for _, kase := range submoduleFiles {
submodule, err := parseSubmoduleContent([]byte(kase.fileContent))
require.NoError(t, err)
v, ok := submodule.Get(kase.expectedPath)
assert.True(t, ok)
assert.Equal(t, kase.expectedURL, v)
}
}

View file

@ -272,6 +272,17 @@ func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLi
// GetAffectedFiles returns the affected files between two commits
func GetAffectedFiles(repo *Repository, oldCommitID, newCommitID string, env []string) ([]string, error) {
objectFormat, err := repo.GetObjectFormat()
if err != nil {
return nil, err
}
// If the oldCommitID is empty, then we must assume its a new branch, so diff
// against the empty tree. So all changes of this new branch are included.
if oldCommitID == objectFormat.EmptyObjectID().String() {
oldCommitID = objectFormat.EmptyTree().String()
}
stdoutReader, stdoutWriter, err := os.Pipe()
if err != nil {
log.Error("Unable to create os.Pipe for %s", repo.Path)

View file

@ -97,12 +97,12 @@ func SetExecutablePath(path string) error {
}
if gitVersion.LessThan(versionRequired) {
moreHint := "get git: https://git-scm.com/download/"
moreHint := "get git: https://git-scm.com/downloads"
if runtime.GOOS == "linux" {
// there are a lot of CentOS/RHEL users using old git, so we add a special hint for them
if _, err = os.Stat("/etc/redhat-release"); err == nil {
// ius.io is the recommended official(git-scm.com) method to install git
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
moreHint = "get git: https://git-scm.com/downloads/linux and https://ius.io"
}
}
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", gitVersion.Original(), RequiredVersion, moreHint)

View file

@ -17,6 +17,7 @@ import (
"strings"
"time"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
@ -30,7 +31,7 @@ type GrepResult struct {
type GrepOptions struct {
RefName string
MaxResultLimit int
MatchesPerFile int
MatchesPerFile int // >= git 2.38
ContextLineNumber int
IsFuzzy bool
PathSpec []setting.Glob
@ -77,7 +78,14 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
"-I", "--null", "--break", "--heading", "--column",
"--fixed-strings", "--line-number", "--ignore-case", "--full-name")
cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber))
cmd.AddOptionValues("--max-count", fmt.Sprint(opts.MatchesPerFile))
// --max-count requires at least git 2.38
if CheckGitVersionAtLeast("2.38.0") == nil {
cmd.AddOptionValues("--max-count", fmt.Sprint(opts.MatchesPerFile))
} else {
log.Warn("git-grep: --max-count requires at least git 2.38")
}
words := []string{search}
if opts.IsFuzzy {
words = strings.Fields(search)

View file

@ -254,7 +254,7 @@ func TestGitAttributeCheckerError(t *testing.T) {
require.NoError(t, err)
_, err = ac.CheckPath("i-am-a-python.p")
require.ErrorIs(t, err, context.Canceled)
require.Error(t, err)
})
t.Run("Cancelled/DuringRun", func(t *testing.T) {

View file

@ -96,7 +96,7 @@ func Code(fileName, language, code string) (output template.HTML, lexerName stri
}
if lexer == nil {
lexer = lexers.Match(fileName)
lexer = lexers.Match(strings.ToLower(fileName))
if lexer == nil {
lexer = lexers.Fallback
}
@ -134,6 +134,12 @@ func CodeFromLexer(lexer chroma.Lexer, code string) template.HTML {
return template.HTML(strings.TrimSuffix(htmlbuf.String(), "\n"))
}
// For the case where Enry recognizes the language, but doesn't use the naming
// that Chroma expects.
var normalizeEnryToChroma = map[string]string{
"F#": "FSharp",
}
// File returns a slice of chroma syntax highlighted HTML lines of code and the matched lexer name
func File(fileName, language string, code []byte) ([]template.HTML, string, error) {
NewContext()
@ -162,10 +168,13 @@ func File(fileName, language string, code []byte) ([]template.HTML, string, erro
if lexer == nil {
guessLanguage := analyze.GetCodeLanguage(fileName, code)
if normalizedGuessLanguage, ok := normalizeEnryToChroma[guessLanguage]; ok {
guessLanguage = normalizedGuessLanguage
}
lexer = lexers.Get(guessLanguage)
if lexer == nil {
lexer = lexers.Match(fileName)
lexer = lexers.Match(strings.ToLower(fileName))
if lexer == nil {
lexer = lexers.Fallback
}

View file

@ -109,6 +109,18 @@ c=2
),
lexerName: "Python",
},
{
name: "DOS.PAS",
code: "",
want: lines(""),
lexerName: "ObjectPascal",
},
{
name: "test.fs",
code: "module Crypt = let generateCryptTable: array<uint32> =",
want: lines(`<span class="k">module</span> <span class="nn">Crypt</span> <span class="o">=</span> <span class="k">let</span> <span class="nv">generateCryptTable</span><span class="o">:</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">uint32</span><span class="o">&gt;</span> <span class="o">=</span>`),
lexerName: "FSharp",
},
}
for _, tt := range tests {

View file

@ -76,7 +76,8 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s
w.Header().Set("Etag", etag)
}
if lastModified != nil && !lastModified.IsZero() {
w.Header().Set("Last-Modified", lastModified.Format(http.TimeFormat))
// http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
w.Header().Set("Last-Modified", lastModified.UTC().Format(http.TimeFormat))
}
if len(etag) > 0 {

View file

@ -79,6 +79,7 @@ func ServeSetHeaders(w http.ResponseWriter, opts *ServeHeaderOptions) {
httpcache.SetCacheControlInHeader(header, duration)
if !opts.LastModified.IsZero() {
// http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat))
}
}

View file

@ -20,6 +20,7 @@ import (
indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
inner_elasticsearch "code.gitea.io/gitea/modules/indexer/internal/elasticsearch"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/typesniffer"
@ -197,8 +198,33 @@ func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha st
return nil
}
// Delete deletes indexes by ids
// Delete entries by repoId
func (b *Indexer) Delete(ctx context.Context, repoID int64) error {
if err := b.doDelete(ctx, repoID); err != nil {
// Maybe there is a conflict during the delete operation, so we should retry after a refresh
log.Warn("Deletion of entries of repo %v within index %v was erroneus. Trying to refresh index before trying again", repoID, b.inner.VersionedIndexName(), err)
if err := b.refreshIndex(ctx); err != nil {
return err
}
if err := b.doDelete(ctx, repoID); err != nil {
log.Error("Could not delete entries of repo %v within index %v", repoID, b.inner.VersionedIndexName())
return err
}
}
return nil
}
func (b *Indexer) refreshIndex(ctx context.Context) error {
if _, err := b.inner.Client.Refresh(b.inner.VersionedIndexName()).Do(ctx); err != nil {
log.Error("Error while trying to refresh index %v", b.inner.VersionedIndexName(), err)
return err
}
return nil
}
// Delete entries by repoId
func (b *Indexer) doDelete(ctx context.Context, repoID int64) error {
_, err := b.inner.Client.DeleteByQuery(b.inner.VersionedIndexName()).
Query(elastic.NewTermsQuery("repo_id", repoID)).
Do(ctx)

View file

@ -39,7 +39,7 @@ const (
// SanitizerRules implements markup.Renderer
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
return []setting.MarkupSanitizerRule{
{Element: "div", AllowAttr: "class", Regexp: regexp.MustCompile(playerClassName)},
{Element: "div", AllowAttr: "class", Regexp: regexp.MustCompile("^" + playerClassName + "$")},
{Element: "div", AllowAttr: playerSrcAttr},
}
}

View file

@ -38,7 +38,7 @@ func camoHandleLink(link string) string {
if setting.Camo.Enabled {
lnkURL, err := url.Parse(link)
if err == nil && lnkURL.IsAbs() && !strings.HasPrefix(link, setting.AppURL) &&
(setting.Camo.Allways || lnkURL.Scheme != "https") {
(setting.Camo.Always || lnkURL.Scheme != "https") {
return CamoEncode(link)
}
}

View file

@ -28,7 +28,7 @@ func TestCamoHandleLink(t *testing.T) {
"https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc",
camoHandleLink("http://testimages.org/img.jpg"))
setting.Camo.Allways = true
setting.Camo.Always = true
assert.Equal(t,
"https://gitea.com/img.jpg",
camoHandleLink("https://gitea.com/img.jpg"))

View file

@ -37,9 +37,9 @@ func (Renderer) Extensions() []string {
// SanitizerRules implements markup.Renderer
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
return []setting.MarkupSanitizerRule{
{Element: "table", AllowAttr: "class", Regexp: regexp.MustCompile(`data-table`)},
{Element: "th", AllowAttr: "class", Regexp: regexp.MustCompile(`line-num`)},
{Element: "td", AllowAttr: "class", Regexp: regexp.MustCompile(`line-num`)},
{Element: "table", AllowAttr: "class", Regexp: regexp.MustCompile(`^data-table$`)},
{Element: "th", AllowAttr: "class", Regexp: regexp.MustCompile(`^line-num$`)},
{Element: "td", AllowAttr: "class", Regexp: regexp.MustCompile(`^line-num$`)},
}
}

View file

@ -12,6 +12,7 @@ import (
"runtime"
"strings"
"code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
@ -86,8 +87,22 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
commands = strings.Fields(command)
args = commands[1:]
)
if p.IsInputFile {
isAnnexed, _ := annex.IsAnnexed(ctx.Blob)
// if a renderer wants to read a file, and we have annexed content, we can
// provide the annex key file location directly to the renderer. git-annex
// takes care of having that location be read-only, so no critical
// protection layer is needed. Moreover, the file readily exists, and
// expensive temporary files can be avoided, also allowing an operator
// to raise MAX_DISPLAY_FILE_SIZE without much negative impact.
if p.IsInputFile && isAnnexed {
// look for annexed content, will be empty, if there is none
annexContentLocation, _ := annex.ContentLocation(ctx.Blob)
// we call the renderer, even if there is no annex content present.
// showing the pointer file content is not much use, and a topical
// renderer might be able to produce something useful from the
// filename alone (present in ENV)
args = append(args, annexContentLocation)
} else if p.IsInputFile {
// write to temp file
f, err := os.CreateTemp("", "gitea_input")
if err != nil {
@ -130,6 +145,12 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
os.Environ(),
"GITEA_PREFIX_SRC="+ctx.Links.SrcLink(),
"GITEA_PREFIX_RAW="+ctx.Links.RawLink(),
// also communicate the relative path of the to-be-rendered item.
// this enables the renderer to make use of the original file name
// and path, e.g., to make rendering or dtype-detection decisions
// that go beyond the originally matched extension. Even if the
// content is directly streamed to STDIN
"GITEA_RELATIVE_PATH="+ctx.RelativePath,
)
if !p.IsInputFile {
cmd.Stdin = input

View file

@ -63,6 +63,14 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
attentionParagraph.AppendChild(attentionParagraph, calloutNode)
firstParagraph.Parent().InsertBefore(firstParagraph.Parent(), firstParagraph, attentionParagraph)
firstParagraph.RemoveChild(firstParagraph, calloutNode)
// Remove softbreak line if there's one.
if firstParagraph.ChildCount() >= 1 {
softBreakNode, ok := firstParagraph.FirstChild().(*ast.Text)
if ok && softBreakNode.SoftLineBreak() {
firstParagraph.RemoveChild(firstParagraph, softBreakNode)
}
}
}
return ast.WalkContinue, nil

View file

@ -1356,4 +1356,10 @@ func TestCallout(t *testing.T) {
}
test(">\n0", "<blockquote>\n</blockquote>\n<p>0</p>")
test("> **Warning**\n> Bad stuff is brewing here", `<blockquote class="attention-header attention-warning"><p class="attention-title"><strong class="attention-warning">Warning</strong></p>
<p>Bad stuff is brewing here</p>
</blockquote>`)
test("> [!WARNING]\n> Bad stuff is brewing here", `<blockquote class="attention-header attention-warning"><p class="attention-title"><strong class="attention-warning">Warning</strong></p>
<p>Bad stuff is brewing here</p>
</blockquote>`)
}

View file

@ -67,14 +67,18 @@ type Header struct {
// RenderContext represents a render context
type RenderContext struct {
Ctx context.Context
RelativePath string // relative path from tree root of the branch
Type string
IsWiki bool
Links Links
Metas map[string]string
DefaultLink string
GitRepo *git.Repository
Ctx context.Context
RelativePath string // relative path from tree root of the branch
Type string
IsWiki bool
Links Links
Metas map[string]string
DefaultLink string
GitRepo *git.Repository
// reporting the target blob that is to-be-rendered enables
// deeper inspection in the handler for external renderer
// (i.e., more targeted handling of annexed files)
Blob *git.Blob
ShaExistCache map[string]bool
cancelFn func()
SidebarTocNode ast.Node

View file

@ -94,10 +94,10 @@ func createDefaultPolicy() *bluemonday.Policy {
}
// Allow classes for anchors
policy.AllowAttrs("class").Matching(regexp.MustCompile(`ref-issue( ref-external-issue)?`)).OnElements("a")
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^ref-issue( ref-external-issue)?$`)).OnElements("a")
// Allow classes for task lists
policy.AllowAttrs("class").Matching(regexp.MustCompile(`task-list-item`)).OnElements("li")
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^task-list-item$`)).OnElements("li")
// Allow classes for org mode list item status.
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^(unchecked|checked|indeterminate)$`)).OnElements("li")
@ -106,7 +106,7 @@ func createDefaultPolicy() *bluemonday.Policy {
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^icon(\s+[\p{L}\p{N}_-]+)+$`)).OnElements("i")
// Allow classes for emojis
policy.AllowAttrs("class").Matching(regexp.MustCompile(`emoji`)).OnElements("img")
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^emoji$`)).OnElements("img")
// Allow icons, emojis, chroma syntax and keyword markup on span
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(emoji)|(language-math display)|(language-math inline))$|^([a-z][a-z0-9]{0,2})$|^` + keywordClass + `$`)).OnElements("span")
@ -122,13 +122,13 @@ func createDefaultPolicy() *bluemonday.Policy {
policy.AllowAttrs("class").Matching(regexp.MustCompile("^header$")).OnElements("div")
policy.AllowAttrs("data-line-number").Matching(regexp.MustCompile("^[0-9]+$")).OnElements("span")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^text small grey$")).OnElements("span")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^file-preview*")).OnElements("table")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^file-preview$")).OnElements("table")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^lines-escape$")).OnElements("td")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^toggle-escape-button btn interact-bg$")).OnElements("button")
policy.AllowAttrs("title").OnElements("button")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^ambiguous-code-point$")).OnElements("span")
policy.AllowAttrs("data-tooltip-content").OnElements("span")
policy.AllowAttrs("class").Matching(regexp.MustCompile("muted|(text black)")).OnElements("a")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^muted|(text black)$")).OnElements("a")
policy.AllowAttrs("class").Matching(regexp.MustCompile("^ui warning message tw-text-left$")).OnElements("div")
// Allow generally safe attributes

View file

@ -39,8 +39,8 @@ const (
var (
reName = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+$`)
reVer = regexp.MustCompile(`^[a-zA-Z0-9:_.+]+-+[0-9]+$`)
reOptDep = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?[a-zA-Z0-9@._+-]+)?(:.*)?$`)
rePkgVer = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?[a-zA-Z0-9@._+-]+)?$`)
reOptDep = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?([0-9]+:)?[a-zA-Z0-9@._+-]+)?(:.*)?$`)
rePkgVer = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?([0-9]+:)?[a-zA-Z0-9@._+-]+)?$`)
magicZSTD = []byte{0x28, 0xB5, 0x2F, 0xFD}
magicXZ = []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A}
@ -71,7 +71,7 @@ type VersionMetadata struct {
Conflicts []string `json:"conflicts,omitempty"`
Replaces []string `json:"replaces,omitempty"`
Backup []string `json:"backup,omitempty"`
Xdata []string `json:"xdata,omitempty"`
XData []string `json:"xdata,omitempty"`
}
// FileMetadata Metadata related to specific package file.
@ -125,7 +125,7 @@ func ParsePackage(r *packages.HashedBuffer) (*Package, error) {
defer tarball.Close()
var pkg *Package
var mtree bool
var mTree bool
for {
f, err := tarball.Read()
@ -135,24 +135,24 @@ func ParsePackage(r *packages.HashedBuffer) (*Package, error) {
if err != nil {
return nil, err
}
defer f.Close()
switch f.Name() {
case ".PKGINFO":
pkg, err = ParsePackageInfo(tarballType, f)
if err != nil {
_ = f.Close()
return nil, err
}
case ".MTREE":
mtree = true
mTree = true
}
_ = f.Close()
}
if pkg == nil {
return nil, util.NewInvalidArgumentErrorf(".PKGINFO file not found")
}
if !mtree {
if !mTree {
return nil, util.NewInvalidArgumentErrorf(".MTREE file not found")
}
@ -220,7 +220,7 @@ func ParsePackageInfo(compressType string, r io.Reader) (*Package, error) {
case "replaces":
p.VersionMetadata.Replaces = append(p.VersionMetadata.Replaces, value)
case "xdata":
p.VersionMetadata.Xdata = append(p.VersionMetadata.Xdata, value)
p.VersionMetadata.XData = append(p.VersionMetadata.XData, value)
case "builddate":
bd, err := strconv.ParseInt(value, 10, 64)
if err != nil {
@ -260,48 +260,43 @@ func ValidatePackageSpec(p *Package) error {
return util.NewInvalidArgumentErrorf("invalid project URL")
}
}
for _, cd := range p.VersionMetadata.CheckDepends {
if !rePkgVer.MatchString(cd) {
return util.NewInvalidArgumentErrorf("invalid check dependency: %s", cd)
for _, checkDepend := range p.VersionMetadata.CheckDepends {
if !rePkgVer.MatchString(checkDepend) {
return util.NewInvalidArgumentErrorf("invalid check dependency: %s", checkDepend)
}
}
for _, d := range p.VersionMetadata.Depends {
if !rePkgVer.MatchString(d) {
return util.NewInvalidArgumentErrorf("invalid dependency: %s", d)
for _, depend := range p.VersionMetadata.Depends {
if !rePkgVer.MatchString(depend) {
return util.NewInvalidArgumentErrorf("invalid dependency: %s", depend)
}
}
for _, md := range p.VersionMetadata.MakeDepends {
if !rePkgVer.MatchString(md) {
return util.NewInvalidArgumentErrorf("invalid make dependency: %s", md)
for _, makeDepend := range p.VersionMetadata.MakeDepends {
if !rePkgVer.MatchString(makeDepend) {
return util.NewInvalidArgumentErrorf("invalid make dependency: %s", makeDepend)
}
}
for _, p := range p.VersionMetadata.Provides {
if !rePkgVer.MatchString(p) {
return util.NewInvalidArgumentErrorf("invalid provides: %s", p)
for _, provide := range p.VersionMetadata.Provides {
if !rePkgVer.MatchString(provide) {
return util.NewInvalidArgumentErrorf("invalid provides: %s", provide)
}
}
for _, p := range p.VersionMetadata.Conflicts {
if !rePkgVer.MatchString(p) {
return util.NewInvalidArgumentErrorf("invalid conflicts: %s", p)
for _, conflict := range p.VersionMetadata.Conflicts {
if !rePkgVer.MatchString(conflict) {
return util.NewInvalidArgumentErrorf("invalid conflicts: %s", conflict)
}
}
for _, p := range p.VersionMetadata.Replaces {
if !rePkgVer.MatchString(p) {
return util.NewInvalidArgumentErrorf("invalid replaces: %s", p)
for _, replace := range p.VersionMetadata.Replaces {
if !rePkgVer.MatchString(replace) {
return util.NewInvalidArgumentErrorf("invalid replaces: %s", replace)
}
}
for _, p := range p.VersionMetadata.Replaces {
if !rePkgVer.MatchString(p) {
return util.NewInvalidArgumentErrorf("invalid xdata: %s", p)
for _, optDepend := range p.VersionMetadata.OptDepends {
if !reOptDep.MatchString(optDepend) {
return util.NewInvalidArgumentErrorf("invalid optional dependency: %s", optDepend)
}
}
for _, od := range p.VersionMetadata.OptDepends {
if !reOptDep.MatchString(od) {
return util.NewInvalidArgumentErrorf("invalid optional dependency: %s", od)
}
}
for _, bf := range p.VersionMetadata.Backup {
if strings.HasPrefix(bf, "/") {
for _, b := range p.VersionMetadata.Backup {
if strings.HasPrefix(b, "/") {
return util.NewInvalidArgumentErrorf("backup file contains leading forward slash")
}
}

View file

@ -96,7 +96,7 @@ func parsePackage(r io.Reader) (*Package, error) {
Target *string `json:"target"`
Kind string `json:"kind"`
Registry *string `json:"registry"`
ExplicitNameInToml string `json:"explicit_name_in_toml"`
ExplicitNameInToml *string `json:"explicit_name_in_toml"`
} `json:"deps"`
Features map[string][]string `json:"features"`
Authors []string `json:"authors"`
@ -136,8 +136,16 @@ func parsePackage(r io.Reader) (*Package, error) {
dependencies := make([]*Dependency, 0, len(meta.Deps))
for _, dep := range meta.Deps {
name := dep.Name
packageName := dep.ExplicitNameInToml
// If the explicit_name_in_toml field is set, the package is renamed and
// should be set accordingly.
if dep.ExplicitNameInToml != nil {
name = *dep.ExplicitNameInToml
packageName = &dep.Name
}
dependencies = append(dependencies, &Dependency{
Name: dep.Name,
Name: name,
Req: dep.VersionReq,
Features: dep.Features,
Optional: dep.Optional,
@ -145,6 +153,7 @@ func parsePackage(r io.Reader) (*Package, error) {
Target: dep.Target,
Kind: dep.Kind,
Registry: dep.Registry,
Package: packageName,
})
}

View file

@ -22,7 +22,7 @@ const (
)
func TestParsePackage(t *testing.T) {
createPackage := func(name, version string) io.Reader {
createPackage := func(name, version, dependency string) io.Reader {
metadata := `{
"name":"` + name + `",
"vers":"` + version + `",
@ -32,7 +32,7 @@ func TestParsePackage(t *testing.T) {
{
"name":"dep",
"version_req":"1.0"
}
}` + dependency + `
],
"homepage":"` + homepage + `",
"license":"` + license + `"
@ -48,7 +48,7 @@ func TestParsePackage(t *testing.T) {
t.Run("InvalidName", func(t *testing.T) {
for _, name := range []string{"", "0test", "-test", "_test", strings.Repeat("a", 65)} {
data := createPackage(name, "1.0.0")
data := createPackage(name, "1.0.0", "")
cp, err := ParsePackage(data)
assert.Nil(t, cp)
@ -58,7 +58,7 @@ func TestParsePackage(t *testing.T) {
t.Run("InvalidVersion", func(t *testing.T) {
for _, version := range []string{"", "1.", "-1.0", "1.0.0/1"} {
data := createPackage("test", version)
data := createPackage("test", version, "")
cp, err := ParsePackage(data)
assert.Nil(t, cp)
@ -67,7 +67,7 @@ func TestParsePackage(t *testing.T) {
})
t.Run("Valid", func(t *testing.T) {
data := createPackage("test", "1.0.0")
data := createPackage("test", "1.0.0", "")
cp, err := ParsePackage(data)
assert.NotNil(t, cp)
@ -84,4 +84,25 @@ func TestParsePackage(t *testing.T) {
content, _ := io.ReadAll(cp.Content)
assert.Equal(t, "test", string(content))
})
t.Run("Renamed dependency", func(t *testing.T) {
data := createPackage("test", "1.0.0", `, {"name":"v4l2-sys", "version":"0.3.0", "explicit_name_in_toml":"v4l2-sys-mit"}`)
cp, err := ParsePackage(data)
assert.NotNil(t, cp)
require.NoError(t, err)
assert.Equal(t, "test", cp.Name)
assert.Equal(t, "1.0.0", cp.Version)
assert.Equal(t, description, cp.Metadata.Description)
assert.Equal(t, []string{author}, cp.Metadata.Authors)
assert.Len(t, cp.Metadata.Dependencies, 2)
assert.Equal(t, "dep", cp.Metadata.Dependencies[0].Name)
assert.EqualValues(t, "v4l2-sys-mit", cp.Metadata.Dependencies[1].Name)
assert.EqualValues(t, "v4l2-sys", *cp.Metadata.Dependencies[1].Package)
assert.Equal(t, homepage, cp.Metadata.ProjectURL)
assert.Equal(t, license, cp.Metadata.License)
content, _ := io.ReadAll(cp.Content)
assert.Equal(t, "test", string(content))
})
}

View file

@ -48,6 +48,7 @@ type Metadata struct {
Homepage string `json:"homepage,omitempty"`
License Licenses `json:"license,omitempty"`
Authors []Author `json:"authors,omitempty"`
Bin []string `json:"bin,omitempty"`
Autoload map[string]any `json:"autoload,omitempty"`
AutoloadDev map[string]any `json:"autoload-dev,omitempty"`
Extra map[string]any `json:"extra,omitempty"`

View file

@ -40,6 +40,7 @@ type ServCommandResults struct {
UserName string
UserEmail string
UserID int64
UserMode perm.AccessMode
OwnerName string
RepoName string
RepoID int64

25
modules/setting/annex.go Normal file
View file

@ -0,0 +1,25 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package setting
import (
"code.gitea.io/gitea/modules/log"
)
// Annex represents the configuration for git-annex
var Annex = struct {
Enabled bool `ini:"ENABLED"`
DisableP2PHTTP bool `ini:"DISABLE_P2PHTTP"`
}{}
func loadAnnexFrom(rootCfg ConfigProvider) {
sec := rootCfg.Section("annex")
if err := sec.MapTo(&Annex); err != nil {
log.Fatal("Failed to map Annex settings: %v", err)
}
if !sec.HasKey("DISABLE_P2PHTTP") {
// If DisableP2PHTTP is not explicitly set then use DisableHTTPGit as its default
Annex.DisableP2PHTTP = Repository.DisableHTTPGit
}
}

View file

@ -3,18 +3,28 @@
package setting
import "code.gitea.io/gitea/modules/log"
import (
"strconv"
"code.gitea.io/gitea/modules/log"
)
var Camo = struct {
Enabled bool
ServerURL string `ini:"SERVER_URL"`
HMACKey string `ini:"HMAC_KEY"`
Allways bool
Always bool
}{}
func loadCamoFrom(rootCfg ConfigProvider) {
mustMapSetting(rootCfg, "camo", &Camo)
if Camo.Enabled {
oldValue := rootCfg.Section("camo").Key("ALLWAYS").MustString("")
if oldValue != "" {
log.Warn("camo.ALLWAYS is deprecated, use camo.ALWAYS instead")
Camo.Always, _ = strconv.ParseBool(oldValue)
}
if Camo.ServerURL == "" || Camo.HMACKey == "" {
log.Fatal(`Camo settings require "SERVER_URL" and HMAC_KEY`)
}

Some files were not shown because too many files have changed in this diff Show more