Compare commits

...

39 commits

Author SHA1 Message Date
Beowulf cd54f1b027
Show repo activities also when repo has no git files
If the repo has no git files, the activity tab in now also displayed.
The activity tab is then limited to the Pulse page and the navigation on
the left-hand side is hidden.
2024-04-27 14:56:49 +02:00
Beowulf c9ba62b005
Also show repo activities when only code active
When all repository units are deactivated except for the code unit,
the activity tab will not be shown.
Since the activities tab also shows contributing stats,
it would be good to show the activities tab also when only code is
active.
This commit changes the behavior when the activities tab is shown.
Previous it would only be shown when Issues, Pull-Requests or Releases
are activated. Now it would additionally be shown when the code unit is
activated.

Refs: #3429
2024-04-27 14:56:49 +02:00
Earl Warren 8da64860e7 Merge pull request 'Update module gitea.com/gitea/act to v0.261.1' (#3492) from renovate/gitea.com-gitea-act-0.x into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3492
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-04-27 11:01:59 +00:00
Earl Warren d90b1e2c00
fix(renovate): gitea.com/gitea/act requires dashboard approval 2024-04-27 10:31:13 +02:00
Renovate Bot 004fe91d37 Update module gitea.com/gitea/act to v0.261.1 2024-04-27 02:04:59 +00:00
Baptiste Daroussin 08f5a25d3b ldap: default domain name (#3414)
When the ldap synchronizer is look for an email address and fails at
finding one, it falls back at creating one using "localhost.local"
domain.

This new field makes this domain name configurable.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3414
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Baptiste Daroussin <bapt@FreeBSD.org>
Co-committed-by: Baptiste Daroussin <bapt@FreeBSD.org>
2024-04-26 22:38:58 +00:00
Earl Warren 4da76d0e5f Merge pull request 'fix(Dockerfile.rootless): revert to default path for app.ini' (#3363) from gmask/forgejo:fix/container-app-ini-variable into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3363
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-04-26 22:36:33 +00:00
Earl Warren c4db84ad0e Merge pull request 'docs(release-notes): 7.0.1' (#3484) from earl-warren/forgejo:wip-release-notes-v7.0 into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3484
Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org>
Reviewed-by: crystal <crystal@noreply.codeberg.org>
2024-04-26 22:34:25 +00:00
Earl Warren a5df622099
docs(release-notes): 7.0.1 2024-04-27 00:31:22 +02:00
Gerard Salvatella dad16cd589 fix(Dockerfile.rootless): revert to default path for app.ini
The current path of the `$GITEA_APP_INI` configuration file makes the
forgejo application reset every time the container is restarted, unless
a specific volume for this file is created. Consider the following:

* This quirk is not documented
* All configuration data resides in `/var/lib/gitea`
* The custom configuration path defaults to `/var/lib/gitea/custom/conf`
  (see `forgejo -h`)
* Containers mounting the volume `-v /foo/bar:/var/lib/gitea` already
  have this file available to modify. Another volume shouldn't be
  required
* Containers using named volumes can use `docker cp` to modify the file
  inside the volume, if desired

For these reasons, it makes more sense to use the default path for
`$GITEA_APP_INI` rather than require users to create a dedicated volume
for the file. Revert it back to its default while maintaining backwards
compatibility (users can update by simply moving the file to the new
path).
2024-04-26 21:30:10 +02:00
Earl Warren d6c36ec406 Merge pull request 'Drop Gitea-specific columns from two tables' (#3475) from algernon/forgejo:wiki-branch-wars-episode-iii-a-new-migration into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3475
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-04-26 10:21:28 +00:00
oliverpool 20350846fc Merge pull request 'fix: git.ComputeHash did not write the content' (#3466) from oliverpool/forgejo:fix_compute_hash into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3466
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-04-26 10:15:23 +00:00
Earl Warren c31ae1a651 fix(lfs): gogit /settings/lfs/find 500 error (#3472)
Refs: https://codeberg.org/forgejo/forgejo/pulls/3448
Refs: https://codeberg.org/forgejo/forgejo/issues/3438
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3472
Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2024-04-26 09:22:09 +00:00
Earl Warren 0819ed2053 Merge pull request 'Update dependency vitest to v1.5.2' (#3468) from renovate/vitest-monorepo into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3468
2024-04-26 08:37:20 +00:00
Earl Warren 51a610d46c Merge pull request 'Update dependency swagger-ui-dist to v5.17.2' (#3467) from renovate/swagger-ui-dist-5.17.x into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3467
2024-04-26 08:36:47 +00:00
Gergely Nagy 2bc226eb57
Drop Gitea-specific columns from two tables
Gitea and Forgejo chose to implement wiki branch naming differently, but
Forgejo picked the Gitea migration anyway, resulting in an unused column
in the database, which wasn't part of the `Repository` struct either -
something warned about during startup, too.

Similarly, Forgejo chose not to implement User badges at all - but kept
the existing code for it -, and the `badge` table ended up with an
unused `slug` column due to a Gitea migration, and resulted in another
warning at startup.

To keep the database consistent with the code, and to get rid of these
warnings, lets introduce a new migration, which simply drops these
Gitea-specific columns from the database.

Fixes #3463.

Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
2024-04-26 10:34:06 +02:00
Earl Warren 801554f708 Merge pull request 'Limit database max connections by default' (#3383) from fnetx/Limit database max connections by default into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3383
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-04-26 08:31:15 +00:00
Earl Warren c864448dc9 Merge pull request 'services/convert: Convert a Repository's ObjectFormatName too' (#3464) from algernon/forgejo:i-object-exclamationmark-format-name into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3464
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-04-26 08:27:41 +00:00
Earl Warren 127eff49ee docs(release-notes): split items in files to avoid conflicts (#3452)
I thought there would be conflicts but that they would not be so difficult to manage. Worst idea I had this week. Change to @oliverpool idea instead.

> Instead of documenting the release notes in the issue, why not in the codebase?
>
> For instance in [go](https://cs.opensource.google/go/go/+/master:doc/README.md) there is a `doc/next` folder where you add `<pr-number>.md` files which document each pr.
>
> Before the release, a script takes all those files to generate the changelog.
>
> Having them as a file tracked by git, makes them easy to review and to programmatically handle.

Refs: https://codeberg.org/forgejo/discussions/issues/155#issuecomment-1787013
Co-authored-by: Shiny Nematoda <snematoda.751k2@aleeas.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3452
Reviewed-by: Gergely Nagy <algernon@noreply.codeberg.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2024-04-26 08:26:33 +00:00
oliverpool 5247fd50db fix: git.ComputeHash did not write the content 2024-04-26 10:16:59 +02:00
oliverpool 3dfa5ba43a test: LFS gc should not delete all metadata objects
and ComputeBlobHash should depend on the blob content (not only the
length)
2024-04-26 10:16:59 +02:00
Renovate Bot 90c56a9d66 Update dependency vitest to v1.5.2 2024-04-26 08:10:29 +00:00
Renovate Bot aa2af10f67 Update dependency swagger-ui-dist to v5.17.2 2024-04-26 08:10:19 +00:00
Shiny Nematoda a641ebf221 [FIX] Set max fuzziness to 2 for bleve (#3444)
closes #3443

regression from ab5f0b7558

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3444
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: Shiny Nematoda <snematoda.751k2@aleeas.com>
Co-committed-by: Shiny Nematoda <snematoda.751k2@aleeas.com>
2024-04-26 08:08:47 +00:00
Earl Warren 40d0f50838 Merge pull request 'docs(release-notes): 7.0.0 LFS garbage collection and workaround' (#3473) from earl-warren/forgejo:wip-release-notes-v7.0 into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3473
Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org>
2024-04-26 08:05:12 +00:00
Gergely Nagy 2385f3c9db
services/convert: Convert a Repository's ObjectFormatName too
When converting a `repo_model.Repository` to `api.Repository`, copy the
`ObjectFormatName` field too.

Fixes #3458.

Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
2024-04-26 09:25:30 +02:00
Earl Warren b51c608d3f
docs(release-notes): 7.0.0 LFS garbage collection and workaround
Refs: https://codeberg.org/forgejo/forgejo/issues/3438
(cherry picked from commit a37836f228)
2024-04-26 09:16:50 +02:00
Renovate Bot a3be70f0a5 Update ghcr.io/visualon/renovate Docker tag to v37.323.3 2024-04-26 04:02:40 +00:00
Earl Warren 7f187f9857 Merge pull request 'fix(ui): /settings/lfs/find 500 error (take 2)' (#3465) from earl-warren/forgejo:wip-lfs-template into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3465
Reviewed-by: Otto <otto@codeberg.org>
2024-04-25 21:39:14 +00:00
Earl Warren 4036448c02
fix(ui): /settings/lfs/find 500 error (take 2)
Make the test actually fails on error and not just report failure on
the output and succeed.
2024-04-25 23:00:11 +02:00
Earl Warren 94d7523f83 Merge pull request '[BUG] save empty comments' (#3442) from oliverpool/forgejo:empty_comments into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3442
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-04-25 19:32:28 +00:00
Earl Warren f7786e207e Merge pull request 'Change the default SSH clone url to the ssh:// style' (#3285) from algernon/forgejo:cloning-in-sshtyle into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3285
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: twenty-panda <twenty-panda@noreply.codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-04-25 19:24:54 +00:00
Earl Warren 9e212c515e Merge pull request 'chore(eslint): avoid lint the build' (#3446) from kecrily/forgejo:chore/eslint into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3446
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-04-25 19:20:06 +00:00
Nicolas CARPi ad9872d884 docs: contributing: avoid information duplication (#3454)
The file CONTRIBUTING.md contains a list of links that points to
different parts of the developer documentation.

Unfortunately, this list is now incomplete and contains a dead link for the
Developer Workflow.

Given that a more complete similar list is present at:
https://forgejo.org/docs/latest/developer/, this patch removes the
duplication of information, which leads to dead links and
maintenance burden, and replaces the list with simply a link to the page
that has all the current links.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3454
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Nicolas CARPi <nico-git@deltablot.email>
Co-committed-by: Nicolas CARPi <nico-git@deltablot.email>
2024-04-25 19:10:43 +00:00
Percy Ma 44a1f90308
chore(eslint): avoid lint the build 2024-04-25 21:49:18 +08:00
oliverpool ea9051624d comment: save empty comments 2024-04-25 11:21:39 +02:00
oliverpool 0d37f3a79b test: empty existing comment 2024-04-25 11:20:04 +02:00
Otto Richter f23fd221e4 Limit database max connections by default
Our default of unlimited database connections is not sane, because every database has a limit, and our default should just follow this. Otherwise it will lead to issues every time a small instance gets a high traffic peak.

Part of https://codeberg.org/forgejo/forgejo/issues/3381

The value of 100 is the lowest value from:

- 100 Postgres https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-MAX-CONNECTIONS
- 151 MySQL https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_connections
- 151 MariaDB https://mariadb.com/docs/server/ref/mdb/system-variables/max_connections/
2024-04-23 00:47:50 +02:00
Gergely Nagy dc39043cd6
Change the default SSH clone url to the ssh:// style
Rather than using an scp-style URI, use the same URL style for SSH
clones as for HTTP(S) ones. This is not only more consistent, but the
URL style allows one to specify a port, and makes it clear that it is an
SSH clone URL.

git itself favours the URL style, and mentions the scp-style in passing
only. Said style is prominently used by GitHub, and might be more
familiar for a lot of people, but other than familiarity, it has no
advantage over the URL style.

For the benefit of consistency, and flexibility, lets flip the default,
and make it the URL style. Instance admins who prefer to use the
scp-style, and are running SSH on its standard port, can change the
setting back to false.

This addresses #3193.

Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
2024-04-17 11:04:48 +02:00
50 changed files with 392 additions and 206 deletions

View file

@ -4,6 +4,7 @@ reportUnusedDisableDirectives: true
ignorePatterns:
- /web_src/js/vendor
- /web_src/fomantic
- /public/assets/js
parserOptions:
sourceType: module

View file

@ -22,7 +22,7 @@ jobs:
runs-on: docker
container:
image: ghcr.io/visualon/renovate:37.316.2
image: ghcr.io/visualon/renovate:37.323.3
steps:
- name: Load renovate repo cache

View file

@ -4,21 +4,4 @@ The Forgejo project is run by a community of people who are expected to follow t
Sensitive security-related issues should be reported to [security@forgejo.org](mailto:security@forgejo.org) using [encryption](https://keyoxide.org/security@forgejo.org).
## For everyone involved
- [Documentation](https://forgejo.org/docs/next/)
- [Code of Conduct](https://forgejo.org/docs/latest/developer/coc/)
- [Bugs, features, security and others discussions](https://forgejo.org/docs/latest/developer/discussions/)
- [Governance](https://forgejo.org/docs/latest/developer/governance/)
- [Sustainability and funding](https://codeberg.org/forgejo/sustainability/src/branch/main/README.md)
## For contributors
- [Developer Certificate of Origin (DCO)](https://forgejo.org/docs/latest/developer/dco/)
- [Development workflow](https://forgejo.org/docs/latest/developer/workflow/)
- [Compiling from source](https://forgejo.org/docs/latest/developer/from-source/)
## For maintainers
- [Release management](https://forgejo.org/docs/latest/developer/release/)
- [Secrets](https://forgejo.org/docs/latest/developer/secrets/)
You can find links to the different aspects of Developer documentation on this page: [Forgejo developer guide](https://forgejo.org/docs/next/developer/).

View file

@ -100,8 +100,11 @@ ENV GITEA_CUSTOM /var/lib/gitea/custom
ENV GITEA_TEMP /tmp/gitea
ENV TMPDIR /tmp/gitea
#TODO add to docs the ability to define the ini to load (useful to test and revert a config)
ENV GITEA_APP_INI /etc/gitea/app.ini
# Legacy config file for backwards compatibility
# TODO: remove on next major version release
ENV GITEA_APP_INI_LEGACY /etc/gitea/app.ini
ENV GITEA_APP_INI ${GITEA_CUSTOM}/conf/app.ini
ENV HOME "/var/lib/gitea/git"
VOLUME ["/var/lib/gitea", "/etc/gitea"]
WORKDIR /var/lib/gitea

View file

@ -4,19 +4,9 @@ A minor or major Forgejo release is published every [three months](https://forge
A [patch or minor release](https://semver.org/spec/v2.0.0.html) (e.g. upgrading from v7.0.0 to v7.0.1 or v7.1.0) does not require manual intervention. But [major releases](https://semver.org/spec/v2.0.0.html#spec-item-8) where the first version number changes (e.g. upgrading from v1.21 to v7.0) contain breaking changes and the release notes explain how to deal with them.
## 8.0.0
## Upcoming releases (not available yet)
This is a major release. It contains breaking changes that may require manual intervention. See the documentation for more information on the [upgrade procedure](https://forgejo.org/docs/v7.0/admin/upgrade/).
* **Breaking changes:**
In addition to the following notable bug fixes, you can browse the [full list of commits](https://codeberg.org/forgejo/forgejo/compare/v8.0.0...v7.0.0) included in this release.
If you have any feedback or suggestions for Forgejo do not hold back, it is also your project.
Open an issue in [the issue tracker](https://codeberg.org/forgejo/forgejo/issues)
for feature requests or bug reports, reach out [on the Fediverse](https://floss.social/@forgejo),
or drop into [the Matrix space](https://matrix.to/#/#forgejo:matrix.org)
([main chat room](https://matrix.to/#/#forgejo-chat:matrix.org)) and say hi!
- [8.0.0](/release-notes/8.0.0/)
## 7.0.1
@ -25,9 +15,11 @@ This is a bug fix release. See the documentation for more information on the [up
In addition to the following notable bug fixes, you can browse the [full list of commits](https://codeberg.org/forgejo/forgejo/compare/v7.0.0...v7.0.1) included in this release.
* **Bug fixes:**
* The regression in the [`fogejo admin user create`](https://forgejo.org/docs/v7.0/admin/command-line/#admin-user-create) CLI command [is fixed](https://codeberg.org/forgejo/forgejo/issues/3399) and it is backward compatible.
* Fixed a bug where the `/api/v1/repos/{owner}/{repo}/wiki` API endpoints were using a hardcoded "master" branch for the wiki, rather than the branch they really use. ([#3430](https://codeberg.org/forgejo/forgejo/pulls/3430))
* Fixed an error 500 when visiting [the LFS settings]() at `/{owner}/{repo}/settings/lfs/find?oid=...`.
* [PR](https://codeberg.org/forgejo/forgejo/pulls/3466): LFS data corruption when running the [`forgejo doctor check --fix`](https://forgejo.org/docs/v7.0/admin/command-line/#doctor-check) CLI command or setting [`[cron.gc_lfs].ENABLED=true`](https://forgejo.org/docs/v7.0/admin/config-cheat-sheet/#cron---garbage-collect-lfs-pointers-in-repositories-crongc_lfs) (the default is `false`).
* [PR](https://codeberg.org/forgejo/forgejo/pulls/3412): [non backward compatible change](https://codeberg.org/forgejo/forgejo/issues/3399) in the [`forgejo admin user create`](https://forgejo.org/docs/v7.0/admin/command-line/#admin-user-create) CLI command.
* [PR](https://codeberg.org/forgejo/forgejo/pulls/3448): error 500 because of an incorrect evaluation of the template when visiting the LFS settings of a repository.
* [PR](https://codeberg.org/forgejo/forgejo/pulls/3464): `GET /repos/{owner}/{name}` API endpoint [always returns an empty string for the `object_format_name` field](https://codeberg.org/forgejo/forgejo/issues/3458).
* [PR](https://codeberg.org/forgejo/forgejo/pulls/3444): fuzzy search [may fail with bleve](https://codeberg.org/forgejo/forgejo/issues/3443).
## 7.0.0
@ -38,8 +30,9 @@ $ git clone https://codeberg.org/forgejo/forgejo/
$ git -C forgejo log --oneline --no-merges origin/v1.21/forgejo..origin/v7.0/forgejo
```
* **Regression and workaround:**
* The [`fogejo admin user create`](https://forgejo.org/docs/v7.0/admin/command-line/#admin-user-create) CLI command [requires a password](https://codeberg.org/forgejo/forgejo/commit/b122c6ef8b9254120432aed373cbe075331132ac) change by default when creating the first user and the `--admin` flag is not specified. The `--must-change-password=false` argument must be given to not require a password change. This regression will be [fixed in 7.0.1](https://codeberg.org/forgejo/forgejo/issues/3399).
* **Regressions and workarounds:**
* Running the [`forgejo doctor check --fix`](https://forgejo.org/docs/v7.0/admin/command-line/#doctor-check) CLI command or setting [`[cron.gc_lfs].ENABLED=true`](https://forgejo.org/docs/v7.0/admin/config-cheat-sheet/#cron---garbage-collect-lfs-pointers-in-repositories-crongc_lfs) (the default is `false`) will corrupt the LFS storage. The workaround is to not run the doctor CLI command and disable the `cron.gc_lfs`. This regression will be [fixed in 7.0.1](https://codeberg.org/forgejo/forgejo/issues/3438).
* The [`forgejo admin user create`](https://forgejo.org/docs/v7.0/admin/command-line/#admin-user-create) CLI command [requires a password](https://codeberg.org/forgejo/forgejo/commit/b122c6ef8b9254120432aed373cbe075331132ac) change by default when creating the first user and the `--admin` flag is not specified. The `--must-change-password=false` argument must be given to not require a password change. This regression will be [fixed in 7.0.1](https://codeberg.org/forgejo/forgejo/issues/3399).
* **Breaking changes requiring manual intervention:**
* [MySQL 8.0 or PostgreSQL 12](https://codeberg.org/forgejo/forgejo/commit/e94f9fcafdcf284561e7fb33f60156a69c4ad6a5) are the minimum supported versions. The database must be migrated before upgrading. The requirements regarding SQLite did not change.
* The `per_page` parameter is [no longer a synonym for `limit`](https://codeberg.org/forgejo/forgejo/commit/0aab2d38a7d91bc8caff332e452364468ce52d9a) in the [/repos/{owner}/{repo}/releases](https://code.forgejo.org/api/swagger/#/repository/repoListReleases) API endpoint.

View file

@ -407,8 +407,8 @@ USER = root
;; Database connection max life time, default is 0 or 3s mysql (See #6804 & #7071 for reasoning)
;CONN_MAX_LIFETIME = 3s
;;
;; Database maximum number of open connections, default is 0 meaning no maximum
;MAX_OPEN_CONNS = 0
;; Database maximum number of open connections, default is 100 which is the lowest default from Postgres (MariaDB + MySQL default to 151). Ensure you only increase the value if you configured your database server accordingly.
;MAX_OPEN_CONNS = 100
;;
;; Whether execute database models migrations automatically
;AUTO_MIGRATION = true

View file

@ -13,5 +13,10 @@ fi
if [ $# -gt 0 ]; then
exec "$@"
else
# TODO: remove on next major version release
# Honour legacy config file if existing
if [ -f ${GITEA_APP_INI_LEGACY} ]; then
GITEA_APP_INI=${GITEA_APP_INI_LEGACY}
fi
exec /usr/local/bin/gitea -c ${GITEA_APP_INI} web
fi

View file

@ -11,6 +11,18 @@ mkdir -p ${GITEA_CUSTOM} && chmod 0700 ${GITEA_CUSTOM}
mkdir -p ${GITEA_TEMP} && chmod 0700 ${GITEA_TEMP}
if [ ! -w ${GITEA_TEMP} ]; then echo "${GITEA_TEMP} is not writable"; exit 1; fi
# TODO: remove on next major version release
# Honour legacy config file if existing, but inform the user
if [ -f ${GITEA_APP_INI_LEGACY} ] && [ ${GITEA_APP_INI} != ${GITEA_APP_INI_LEGACY} ]; then
GITEA_APP_INI_DEFAULT=/var/lib/gitea/custom/conf/app.ini
echo -e \
"\033[33mWARNING\033[0m: detected configuration file in deprecated default path ${GITEA_APP_INI_LEGACY}." \
"The new default is ${GITEA_APP_INI_DEFAULT}. To remove this warning, choose one of the options:\n" \
"* Move ${GITEA_APP_INI_LEGACY} to ${GITEA_APP_INI_DEFAULT} (or to \$GITEA_APP_INI if you want to override this variable)\n" \
"* Explicitly override GITEA_APP_INI=${GITEA_APP_INI_LEGACY} in the container environment"
GITEA_APP_INI=${GITEA_APP_INI_LEGACY}
fi
#Prepare config file
if [ ! -f ${GITEA_APP_INI} ]; then

12
go.mod
View file

@ -89,13 +89,13 @@ require (
github.com/sassoftware/go-rpmutils v0.2.1-0.20240124161140-277b154961dd
github.com/sergi/go-diff v1.3.1
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
github.com/syndtr/goleveldb v1.0.0
github.com/ulikunitz/xz v0.5.11
github.com/urfave/cli/v2 v2.27.1
github.com/xanzy/go-gitlab v0.96.0
github.com/yohcop/openid-go v1.0.1
github.com/yuin/goldmark v1.6.0
github.com/yuin/goldmark v1.7.0
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
github.com/yuin/goldmark-meta v1.1.0
golang.org/x/crypto v0.21.0
@ -243,8 +243,8 @@ require (
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.46.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rhysd/actionlint v1.6.26 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
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/russross/blackfriday/v2 v2.1.0 // indirect
@ -272,7 +272,7 @@ require (
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.etcd.io/bbolt v1.3.8 // indirect
go.etcd.io/bbolt v1.3.9 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
go.opentelemetry.io/otel v1.22.0 // indirect
go.opentelemetry.io/otel/trace v1.22.0 // indirect
@ -294,7 +294,7 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0
replace github.com/nektos/act => gitea.com/gitea/act v0.259.1
replace github.com/nektos/act => gitea.com/gitea/act v0.261.1
replace github.com/gorilla/feeds => github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5

23
go.sum
View file

@ -52,8 +52,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
gitea.com/gitea/act v0.259.1 h1:8GG1o/xtUHl3qjn5f0h/2FXrT5ubBn05TJOM5ry+FBw=
gitea.com/gitea/act v0.259.1/go.mod h1:UxZWRYqQG2Yj4+4OqfGWW5a3HELwejyWFQyU7F1jUD8=
gitea.com/gitea/act v0.261.1 h1:iACWLc/k8wct9fCF2WdYKqn2Hxx6NjW9zbOP79HF4H4=
gitea.com/gitea/act v0.261.1/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
gitea.com/go-chi/binding v0.0.0-20230415142243-04b515c6d669 h1:RUBX+MK/TsDxpHmymaOaydfigEbbzqUnG1OTZU/HAeo=
gitea.com/go-chi/binding v0.0.0-20230415142243-04b515c6d669/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
gitea.com/go-chi/cache v0.2.0 h1:E0npuTfDW6CT1yD8NMDVc1SK6IeRjfmRL2zlEsCEd7w=
@ -708,11 +708,11 @@ github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwy
github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rhysd/actionlint v1.6.26 h1:zi7jPZf3Ks14gCXYAAL47uBziyFlX7+Xwilqhexct9g=
github.com/rhysd/actionlint v1.6.26/go.mod h1:TIj1DlCgtYLOv5CH9wCK+WJTOr1qAdnFzkGi0IgSCO4=
github.com/rhysd/actionlint v1.6.27 h1:xxwe8YmveBcC8lydW6GoHMGmB6H/MTqUU60F2p10wjw=
github.com/rhysd/actionlint v1.6.27/go.mod h1:m2nFUjAnOrxCMXuOMz9evYBRCLUsMnKY2IJl/N5umbk=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -785,8 +785,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
@ -837,8 +838,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA=
github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
@ -849,8 +850,8 @@ github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=

View file

@ -9,7 +9,7 @@
-
id: 2
id: 2 # this is an LFS orphan object
oid: 2eccdb43825d2a49d99d542daa20075cff1d97d9d2349a8977efe9c03661737c
size: 107
repository_id: 54

View file

@ -64,6 +64,8 @@ var migrations = []*Migration{
NewMigration("Add repo_archive_download_count table", forgejo_v1_22.AddRepoArchiveDownloadCount),
// v13 -> v14
NewMigration("Add `hide_archive_links` column to `release` table", AddHideArchiveLinksToRelease),
// v14 -> v15
NewMigration("Remove Gitea-specific columns from the repository and badge tables", RemoveGiteaSpecificColumnsFromRepositoryAndBadge),
}
// GetCurrentDBVersion returns the current Forgejo database version.

View file

@ -0,0 +1,43 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forgejo_migrations //nolint:revive
import (
"code.gitea.io/gitea/models/migrations/base"
"xorm.io/xorm"
)
func RemoveGiteaSpecificColumnsFromRepositoryAndBadge(x *xorm.Engine) error {
// Make sure the columns exist before dropping them
type Repository struct {
ID int64
DefaultWikiBranch string
}
if err := x.Sync(&Repository{}); err != nil {
return err
}
type Badge struct {
ID int64 `xorm:"pk autoincr"`
Slug string
}
err := x.Sync(new(Badge))
if err != nil {
return err
}
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
if err := base.DropTableColumns(sess, "repository", "default_wiki_branch"); err != nil {
return err
}
if err := base.DropTableColumns(sess, "badge", "slug"); err != nil {
return err
}
return sess.Commit()
}

View file

@ -6,6 +6,7 @@ package git
import (
"crypto/sha1"
"crypto/sha256"
"hash"
"regexp"
"strconv"
)
@ -33,6 +34,15 @@ type ObjectFormat interface {
ComputeHash(t ObjectType, content []byte) ObjectID
}
func computeHash(dst []byte, hasher hash.Hash, t ObjectType, content []byte) []byte {
_, _ = hasher.Write(t.Bytes())
_, _ = hasher.Write([]byte(" "))
_, _ = hasher.Write([]byte(strconv.Itoa(len(content))))
_, _ = hasher.Write([]byte{0})
_, _ = hasher.Write(content)
return hasher.Sum(dst)
}
/* SHA1 Type */
type Sha1ObjectFormatImpl struct{}
@ -65,16 +75,9 @@ func (Sha1ObjectFormatImpl) MustID(b []byte) ObjectID {
// ComputeHash compute the hash for a given ObjectType and content
func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
hasher := sha1.New()
_, _ = hasher.Write(t.Bytes())
_, _ = hasher.Write([]byte(" "))
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
_, _ = hasher.Write([]byte{0})
// HashSum generates a SHA1 for the provided hash
var sha1 Sha1Hash
copy(sha1[:], hasher.Sum(nil))
return &sha1
var obj Sha1Hash
computeHash(obj[:0], sha1.New(), t, content)
return &obj
}
/* SHA256 Type */
@ -111,16 +114,9 @@ func (Sha256ObjectFormatImpl) MustID(b []byte) ObjectID {
// ComputeHash compute the hash for a given ObjectType and content
func (h Sha256ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
hasher := sha256.New()
_, _ = hasher.Write(t.Bytes())
_, _ = hasher.Write([]byte(" "))
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
_, _ = hasher.Write([]byte{0})
// HashSum generates a SHA256 for the provided hash
var sha256 Sha1Hash
copy(sha256[:], hasher.Sum(nil))
return &sha256
var obj Sha256Hash
computeHash(obj[:0], sha256.New(), t, content)
return &obj
}
var (

View file

@ -18,4 +18,8 @@ func TestIsValidSHAPattern(t *testing.T) {
assert.False(t, h.IsValid("abc"))
assert.False(t, h.IsValid("123g"))
assert.False(t, h.IsValid("some random text"))
assert.Equal(t, "79ee38a6416c1ede423ec7ee0a8639ceea4aad22", ComputeBlobHash(Sha1ObjectFormat, []byte("some random blob")).String())
assert.Equal(t, "d5c6407415d85df49592672aa421aed39b9db5e3", ComputeBlobHash(Sha1ObjectFormat, []byte("same length blob")).String())
assert.Equal(t, "df0b5174ed06ae65aea40d43316bcbc21d82c9e3158ce2661df2ad28d7931dd6", ComputeBlobHash(Sha256ObjectFormat, []byte("some random blob")).String())
}

View file

@ -0,0 +1,32 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package pipeline
import (
"fmt"
"time"
"code.gitea.io/gitea/modules/git"
)
// LFSResult represents commits found using a provided pointer file hash
type LFSResult struct {
Name string
SHA string
Summary string
When time.Time
ParentHashes []git.ObjectID
BranchName string
FullCommitName string
}
type lfsResultSlice []*LFSResult
func (a lfsResultSlice) Len() int { return len(a) }
func (a lfsResultSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a lfsResultSlice) Less(i, j int) bool { return a[j].When.After(a[i].When) }
func lfsError(msg string, err error) error {
return fmt.Errorf("LFS error occurred, %s: err: %w", msg, err)
}

View file

@ -7,12 +7,10 @@ package pipeline
import (
"bufio"
"fmt"
"io"
"sort"
"strings"
"sync"
"time"
"code.gitea.io/gitea/modules/git"
@ -21,23 +19,6 @@ import (
"github.com/go-git/go-git/v5/plumbing/object"
)
// LFSResult represents commits found using a provided pointer file hash
type LFSResult struct {
Name string
SHA string
Summary string
When time.Time
ParentHashes []git.ObjectID
BranchName string
FullCommitName string
}
type lfsResultSlice []*LFSResult
func (a lfsResultSlice) Len() int { return len(a) }
func (a lfsResultSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a lfsResultSlice) Less(i, j int) bool { return a[j].When.After(a[i].When) }
// FindLFSFile finds commits that contain a provided pointer file hash
func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, error) {
resultsMap := map[string]*LFSResult{}
@ -51,7 +32,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
All: true,
})
if err != nil {
return nil, fmt.Errorf("Failed to get GoGit CommitsIter. Error: %w", err)
return nil, lfsError("failed to get GoGit CommitsIter", err)
}
err = commitsIter.ForEach(func(gitCommit *object.Commit) error {
@ -85,7 +66,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
return nil
})
if err != nil && err != io.EOF {
return nil, fmt.Errorf("Failure in CommitIter.ForEach: %w", err)
return nil, lfsError("failure in CommitIter.ForEach", err)
}
for _, result := range resultsMap {
@ -156,7 +137,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
select {
case err, has := <-errChan:
if has {
return nil, fmt.Errorf("Unable to obtain name for LFS files. Error: %w", err)
return nil, lfsError("unable to obtain name for LFS files", err)
}
default:
}

View file

@ -8,33 +8,14 @@ package pipeline
import (
"bufio"
"bytes"
"fmt"
"io"
"sort"
"strings"
"sync"
"time"
"code.gitea.io/gitea/modules/git"
)
// LFSResult represents commits found using a provided pointer file hash
type LFSResult struct {
Name string
SHA string
Summary string
When time.Time
ParentIDs []git.ObjectID
BranchName string
FullCommitName string
}
type lfsResultSlice []*LFSResult
func (a lfsResultSlice) Len() int { return len(a) }
func (a lfsResultSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a lfsResultSlice) Less(i, j int) bool { return a[j].When.After(a[i].When) }
// FindLFSFile finds commits that contain a provided pointer file hash
func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, error) {
resultsMap := map[string]*LFSResult{}
@ -137,11 +118,11 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
n += int64(count)
if bytes.Equal(binObjectID, objectID.RawValue()) {
result := LFSResult{
Name: curPath + string(fname),
SHA: curCommit.ID.String(),
Summary: strings.Split(strings.TrimSpace(curCommit.CommitMessage), "\n")[0],
When: curCommit.Author.When,
ParentIDs: curCommit.Parents,
Name: curPath + string(fname),
SHA: curCommit.ID.String(),
Summary: strings.Split(strings.TrimSpace(curCommit.CommitMessage), "\n")[0],
When: curCommit.Author.When,
ParentHashes: curCommit.Parents,
}
resultsMap[curCommit.ID.String()+":"+curPath+string(fname)] = &result
} else if string(mode) == git.EntryModeTree.String() {
@ -183,7 +164,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
for _, result := range resultsMap {
hasParent := false
for _, parentID := range result.ParentIDs {
for _, parentID := range result.ParentHashes {
if _, hasParent = resultsMap[parentID.String()+":"+result.Name]; hasParent {
break
}
@ -241,7 +222,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
select {
case err, has := <-errChan:
if has {
return nil, fmt.Errorf("Unable to obtain name for LFS files. Error: %w", err)
return nil, lfsError("unable to obtain name for LFS files", err)
}
default:
}

View file

@ -41,6 +41,8 @@ const (
maxBatchSize = 16
// fuzzyDenominator determines the levenshtein distance per each character of a keyword
fuzzyDenominator = 4
// see https://github.com/blevesearch/bleve/issues/1563#issuecomment-786822311
maxFuzziness = 2
)
func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
@ -246,7 +248,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
phraseQuery.Analyzer = repoIndexerAnalyzer
keywordQuery = phraseQuery
if opts.IsKeywordFuzzy {
phraseQuery.Fuzziness = len(opts.Keyword) / fuzzyDenominator
phraseQuery.Fuzziness = min(maxFuzziness, len(opts.Keyword)/fuzzyDenominator)
}
if len(opts.RepoIDs) > 0 {

View file

@ -49,6 +49,12 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
IDs: []int64{},
Langs: 0,
},
{
RepoIDs: nil,
Keyword: "Description for",
IDs: []int64{repoID},
Langs: 1,
},
{
RepoIDs: nil,
Keyword: "repo1",

View file

@ -39,6 +39,8 @@ const (
maxBatchSize = 16
// fuzzyDenominator determines the levenshtein distance per each character of a keyword
fuzzyDenominator = 4
// see https://github.com/blevesearch/bleve/issues/1563#issuecomment-786822311
maxFuzziness = 2
)
// IndexerData an update to the issue indexer
@ -162,7 +164,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
if options.Keyword != "" {
fuzziness := 0
if options.IsFuzzyKeyword {
fuzziness = len(options.Keyword) / fuzzyDenominator
fuzziness = min(maxFuzziness, len(options.Keyword)/fuzzyDenominator)
}
queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{

View file

@ -130,6 +130,20 @@ var cases = []*testIndexerCase{
ExpectedIDs: []int64{1002, 1001, 1000},
ExpectedTotal: 3,
},
{
Name: "Keyword Fuzzy",
ExtraData: []*internal.IndexerData{
{ID: 1000, Title: "hi hello world"},
{ID: 1001, Content: "hi hello world"},
{ID: 1002, Comments: []string{"hi", "hello world"}},
},
SearchOptions: &internal.SearchOptions{
Keyword: "hello wrold",
IsFuzzyKeyword: true,
},
ExpectedIDs: []int64{1002, 1001, 1000},
ExpectedTotal: 3,
},
{
Name: "RepoIDs",
ExtraData: []*internal.IndexerData{

View file

@ -83,7 +83,7 @@ func loadDBSetting(rootCfg ConfigProvider) {
Database.ConnMaxLifetime = sec.Key("CONN_MAX_LIFETIME").MustDuration(0)
}
Database.ConnMaxIdleTime = sec.Key("CONN_MAX_IDLETIME").MustDuration(0)
Database.MaxOpenConns = sec.Key("MAX_OPEN_CONNS").MustInt(0)
Database.MaxOpenConns = sec.Key("MAX_OPEN_CONNS").MustInt(100)
Database.IterateBufferSize = sec.Key("ITERATE_BUFFER_SIZE").MustInt(50)
Database.LogSQL = sec.Key("LOG_SQL").MustBool(false)

View file

@ -162,7 +162,7 @@ var (
PreferredLicenses: []string{"Apache-2.0", "MIT"},
DisableHTTPGit: false,
AccessControlAllowOrigin: "",
UseCompatSSHURI: false,
UseCompatSSHURI: true,
DefaultCloseIssuesViaCommitsInAnyBranch: false,
EnablePushCreateUser: false,
EnablePushCreateOrg: false,

View file

@ -3100,6 +3100,7 @@ auths.attribute_mail = Email attribute
auths.attribute_ssh_public_key = Public SSH key attribute
auths.attribute_avatar = Avatar attribute
auths.attributes_in_bind = Fetch attributes in bind DN context
auths.default_domain_name = Default domain name used for the email address
auths.allow_deactivate_all = Allow an empty search result to deactivate all users
auths.use_paged_search = Use paged search
auths.search_page_size = Page size

74
package-lock.json generated
View file

@ -44,7 +44,7 @@
"postcss-nesting": "12.1.2",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
"swagger-ui-dist": "5.17.1",
"swagger-ui-dist": "5.17.2",
"tailwindcss": "3.4.3",
"temporal-polyfill": "0.2.4",
"throttle-debounce": "5.0.0",
@ -96,7 +96,7 @@
"svgo": "3.2.0",
"updates": "16.0.1",
"vite-string-plugin": "1.2.0",
"vitest": "1.5.1"
"vitest": "1.5.2"
},
"engines": {
"node": ">= 18.0.0"
@ -2545,13 +2545,13 @@
}
},
"node_modules/@vitest/expect": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.1.tgz",
"integrity": "sha512-w3Bn+VUMqku+oWmxvPhTE86uMTbfmBl35aGaIPlwVW7Q89ZREC/icfo2HBsEZ3AAW6YR9lObfZKPEzstw9tJOQ==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.2.tgz",
"integrity": "sha512-rf7MTD1WCoDlN3FfYJ9Llfp0PbdtOMZ3FIF0AVkDnKbp3oiMW1c8AmvRZBcqbAhDUAvF52e9zx4WQM1r3oraVA==",
"dev": true,
"dependencies": {
"@vitest/spy": "1.5.1",
"@vitest/utils": "1.5.1",
"@vitest/spy": "1.5.2",
"@vitest/utils": "1.5.2",
"chai": "^4.3.10"
},
"funding": {
@ -2559,12 +2559,12 @@
}
},
"node_modules/@vitest/runner": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.1.tgz",
"integrity": "sha512-mt372zsz0vFR7L1xF/ert4t+teD66oSuXoTyaZbl0eJgilvyzCKP1tJ21gVa8cDklkBOM3DLnkE1ljj/BskyEw==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.2.tgz",
"integrity": "sha512-7IJ7sJhMZrqx7HIEpv3WrMYcq8ZNz9L6alo81Y6f8hV5mIE6yVZsFoivLZmr0D777klm1ReqonE9LyChdcmw6g==",
"dev": true,
"dependencies": {
"@vitest/utils": "1.5.1",
"@vitest/utils": "1.5.2",
"p-limit": "^5.0.0",
"pathe": "^1.1.1"
},
@ -2600,9 +2600,9 @@
}
},
"node_modules/@vitest/snapshot": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.1.tgz",
"integrity": "sha512-h/1SGaZYXmjn6hULRBOlqam2z4oTlEe6WwARRzLErAPBqljAs6eX7tfdyN0K+MpipIwSZ5sZsubDWkCPAiVXZQ==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.2.tgz",
"integrity": "sha512-CTEp/lTYos8fuCc9+Z55Ga5NVPKUgExritjF5VY7heRFUfheoAqBneUlvXSUJHUZPjnPmyZA96yLRJDP1QATFQ==",
"dev": true,
"dependencies": {
"magic-string": "^0.30.5",
@ -2626,9 +2626,9 @@
}
},
"node_modules/@vitest/spy": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.1.tgz",
"integrity": "sha512-vsqczk6uPJjmPLy6AEtqfbFqgLYcGBe9BTY+XL8L6y8vrGOhyE23CJN9P/hPimKXnScbqiZ/r/UtUSOQ2jIDGg==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.2.tgz",
"integrity": "sha512-xCcPvI8JpCtgikT9nLpHPL1/81AYqZy1GCy4+MCHBE7xi8jgsYkULpW5hrx5PGLgOQjUpb6fd15lqcriJ40tfQ==",
"dev": true,
"dependencies": {
"tinyspy": "^2.2.0"
@ -2638,9 +2638,9 @@
}
},
"node_modules/@vitest/utils": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.1.tgz",
"integrity": "sha512-92pE17bBXUxA0Y7goPcvnATMCuq4NQLOmqsG0e2BtzRi7KLwZB5jpiELi/8ybY8IQNWemKjSD5rMoO7xTdv8ug==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.2.tgz",
"integrity": "sha512-sWOmyofuXLJ85VvXNsroZur7mOJGiQeM0JN3/0D1uU8U9bGFM69X1iqHaRXl6R8BwaLY6yPCogP257zxTzkUdA==",
"dev": true,
"dependencies": {
"diff-sequences": "^29.6.3",
@ -11495,9 +11495,9 @@
}
},
"node_modules/swagger-ui-dist": {
"version": "5.17.1",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.1.tgz",
"integrity": "sha512-6MNu1MYNALLFvcPpo2MJVJFIxz2rFkH+XoX+J72LBLdj4JLjVaP4lHmNHtJ/tXZUXHdsb2Iw9JhPlqspjkomQg=="
"version": "5.17.2",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.2.tgz",
"integrity": "sha512-V/NqUw6QoTrjSpctp2oLQvxrl3vW29UsUtZyq7B1CF0v870KOFbYGDQw8rpKaKm0JxTwHpWnW1SN9YuKZdiCyw=="
},
"node_modules/sync-fetch": {
"version": "0.4.5",
@ -12257,9 +12257,9 @@
}
},
"node_modules/vite-node": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.1.tgz",
"integrity": "sha512-HNpfV7BrAsjkYVNWIcPleJwvJmydJqqJRrRbpoQ/U7QDwJKyEzNa4g5aYg8MjXJyKsk29IUCcMLFRcsEvqUIsA==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.2.tgz",
"integrity": "sha512-Y8p91kz9zU+bWtF7HGt6DVw2JbhyuB2RlZix3FPYAYmUyZ3n7iTp8eSyLyY6sxtPegvxQtmlTMhfPhUfCUF93A==",
"dev": true,
"dependencies": {
"cac": "^6.7.14",
@ -12339,16 +12339,16 @@
}
},
"node_modules/vitest": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.1.tgz",
"integrity": "sha512-3GvBMpoRnUNbZRX1L3mJCv3Ou3NAobb4dM48y8k9ZGwDofePpclTOyO+lqJFKSQpubH1V8tEcAEw/Y3mJKGJQQ==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.2.tgz",
"integrity": "sha512-l9gwIkq16ug3xY7BxHwcBQovLZG75zZL0PlsiYQbf76Rz6QGs54416UWMtC0jXeihvHvcHrf2ROEjkQRVpoZYw==",
"dev": true,
"dependencies": {
"@vitest/expect": "1.5.1",
"@vitest/runner": "1.5.1",
"@vitest/snapshot": "1.5.1",
"@vitest/spy": "1.5.1",
"@vitest/utils": "1.5.1",
"@vitest/expect": "1.5.2",
"@vitest/runner": "1.5.2",
"@vitest/snapshot": "1.5.2",
"@vitest/spy": "1.5.2",
"@vitest/utils": "1.5.2",
"acorn-walk": "^8.3.2",
"chai": "^4.3.10",
"debug": "^4.3.4",
@ -12362,7 +12362,7 @@
"tinybench": "^2.5.1",
"tinypool": "^0.8.3",
"vite": "^5.0.0",
"vite-node": "1.5.1",
"vite-node": "1.5.2",
"why-is-node-running": "^2.2.2"
},
"bin": {
@ -12377,8 +12377,8 @@
"peerDependencies": {
"@edge-runtime/vm": "*",
"@types/node": "^18.0.0 || >=20.0.0",
"@vitest/browser": "1.5.1",
"@vitest/ui": "1.5.1",
"@vitest/browser": "1.5.2",
"@vitest/ui": "1.5.2",
"happy-dom": "*",
"jsdom": "*"
},

View file

@ -43,7 +43,7 @@
"postcss-nesting": "12.1.2",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
"swagger-ui-dist": "5.17.1",
"swagger-ui-dist": "5.17.2",
"tailwindcss": "3.4.3",
"temporal-polyfill": "0.2.4",
"throttle-debounce": "5.0.0",
@ -95,7 +95,7 @@
"svgo": "3.2.0",
"updates": "16.0.1",
"vite-string-plugin": "1.2.0",
"vitest": "1.5.1"
"vitest": "1.5.2"
},
"browserslist": ["defaults"]
}

View file

@ -0,0 +1 @@
Allow to customize the domain name used as a fallback when synchronizing sources from ldap [`ldap: default domain name`](https://codeberg.org/forgejo/forgejo/pulls/3414)

View file

@ -0,0 +1,6 @@
Reverted the rootless container image path in `GITEA_APP_INI` from
`/etc/gitea/app.ini` to its default value of
`/var/lib/gitea/custom/conf/app.ini`. This allows container users to not have
to mount two separate volumes (one for the configuration data and one for the
configuration `.ini` file). A warning is issued for users with the legacy
configuration on how to update to the new path.

View file

@ -0,0 +1 @@
Fixed a bug where the `/api/v1/repos/{owner}/{repo}/wiki` API endpoints were using a hardcoded "master" branch for the wiki, rather than the branch they really use.

View file

@ -0,0 +1 @@
Save updated empty comments instead of skipping the update silently, [which prevented the removal of attachments of such comments](https://codeberg.org/forgejo/forgejo/issues/3424).

View file

@ -37,7 +37,8 @@
"matchDepNames": [
"bitnami/minio",
"github.com/go-ap/activitypub",
"github.com/nektos/act"
"github.com/nektos/act",
"gitea.com/gitea/act"
],
"dependencyDashboardApproval": true
},

View file

@ -129,6 +129,7 @@ func parseLDAPConfig(form forms.AuthenticationForm) *ldap.Source {
UserDN: form.UserDN,
BindPassword: form.BindPassword,
UserBase: form.UserBase,
DefaultDomainName: form.DefaultDomainName,
AttributeUsername: form.AttributeUsername,
AttributeName: form.AttributeName,
AttributeSurname: form.AttributeSurname,

View file

@ -57,7 +57,7 @@ func Activity(ctx *context.Context) {
ctx.Repo.CanRead(unit.TypeReleases),
ctx.Repo.CanRead(unit.TypeIssues),
ctx.Repo.CanRead(unit.TypePullRequests),
ctx.Repo.CanRead(unit.TypeCode)); err != nil {
ctx.Repo.CanRead(unit.TypeCode) && !ctx.Repo.Repository.IsEmpty); err != nil {
ctx.ServerError("GetActivityStats", err)
return
}

View file

@ -3160,12 +3160,6 @@ func UpdateCommentContent(ctx *context.Context) {
oldContent := comment.Content
comment.Content = ctx.FormString("content")
if len(comment.Content) == 0 {
ctx.JSON(http.StatusOK, map[string]any{
"content": "",
})
return
}
if err = issue_service.UpdateComment(ctx, comment, ctx.Doer, oldContent); err != nil {
ctx.ServerError("UpdateComment", err)
return

View file

@ -1423,16 +1423,16 @@ func registerRoutes(m *web.Route) {
m.Group("/contributors", func() {
m.Get("", repo.Contributors)
m.Get("/data", repo.ContributorsData)
})
}, repo.MustBeNotEmpty)
m.Group("/code-frequency", func() {
m.Get("", repo.CodeFrequency)
m.Get("/data", repo.CodeFrequencyData)
})
}, repo.MustBeNotEmpty)
m.Group("/recent-commits", func() {
m.Get("", repo.RecentCommits)
m.Get("/data", repo.RecentCommitsData)
})
}, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
}, repo.MustBeNotEmpty)
}, context.RepoRef(), context.RequireRepoReaderOr(unit.TypeCode, unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
m.Group("/activity_author_data", func() {
m.Get("", repo.ActivityAuthors)

View file

@ -34,6 +34,7 @@ type Source struct {
BindPassword string // Bind DN password
UserBase string // Base search path for users
UserDN string // Template for the DN of the user for simple auth
DefaultDomainName string // DomainName used if none are in the field, default "localhost.local"
AttributeUsername string // Username attribute
AttributeName string // First name attribute
AttributeSurname string // Surname attribute

View file

@ -105,7 +105,11 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
}
if len(su.Mail) == 0 {
su.Mail = fmt.Sprintf("%s@localhost.local", su.Username)
domainName := source.DefaultDomainName
if len(domainName) == 0 {
domainName = "localhost.local"
}
su.Mail = fmt.Sprintf("%s@%s", su.Username, domainName)
}
fullName := composeFullName(su.Name, su.Surname, su.Username)

View file

@ -237,6 +237,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
MirrorInterval: mirrorInterval,
MirrorUpdated: mirrorUpdated,
RepoTransfer: transfer,
ObjectFormatName: repo.ObjectFormatName,
}
}

View file

@ -26,6 +26,7 @@ type AuthenticationForm struct {
AttributeUsername string
AttributeName string
AttributeSurname string
DefaultDomainName string
AttributeMail string
AttributeSSHPublicKey string
AttributeAvatar string

View file

@ -28,9 +28,13 @@ func TestGarbageCollectLFSMetaObjects(t *testing.T) {
err := storage.Init()
assert.NoError(t, err)
repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "repo1")
repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "lfs")
assert.NoError(t, err)
validLFSObjects, err := db.GetEngine(db.DefaultContext).Count(git_model.LFSMetaObject{RepositoryID: repo.ID})
assert.NoError(t, err)
assert.Greater(t, validLFSObjects, int64(1))
// add lfs object
lfsContent := []byte("gitea1")
lfsOid := storeObjectInRepo(t, repo.ID, &lfsContent)
@ -39,13 +43,18 @@ func TestGarbageCollectLFSMetaObjects(t *testing.T) {
err = repo_service.GarbageCollectLFSMetaObjects(context.Background(), repo_service.GarbageCollectLFSMetaObjectsOptions{
AutoFix: true,
OlderThan: time.Now().Add(7 * 24 * time.Hour).Add(5 * 24 * time.Hour),
UpdatedLessRecentlyThan: time.Now().Add(7 * 24 * time.Hour).Add(3 * 24 * time.Hour),
UpdatedLessRecentlyThan: time.Time{}, // ensure that the models/fixtures/lfs_meta_object.yml objects are considered as well
LogDetail: t.Logf,
})
assert.NoError(t, err)
// lfs meta has been deleted
_, err = git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, lfsOid)
assert.ErrorIs(t, err, git_model.ErrLFSObjectNotExist)
remainingLFSObjects, err := db.GetEngine(db.DefaultContext).Count(git_model.LFSMetaObject{RepositoryID: repo.ID})
assert.NoError(t, err)
assert.Equal(t, validLFSObjects-1, remainingLFSObjects)
}
func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string {

View file

@ -97,6 +97,10 @@
<label for="attribute_mail">{{ctx.Locale.Tr "admin.auths.attribute_mail"}}</label>
<input id="attribute_mail" name="attribute_mail" value="{{$cfg.AttributeMail}}" placeholder="mail" required>
</div>
<div class="field">
<label for="default_domain_name">{{ctx.Locale.Tr "admin.auths.default_domain_name"}}</label>
<input id="default_domain_name" name="default_domain_name" value="{{$cfg.DefaultDomainName}}" placeholder="localhost.local" >
</div>
<div class="field">
<label for="attribute_ssh_public_key">{{ctx.Locale.Tr "admin.auths.attribute_ssh_public_key"}}</label>
<input id="attribute_ssh_public_key" name="attribute_ssh_public_key" value="{{$cfg.AttributeSSHPublicKey}}" placeholder="SshPublicKey">

View file

@ -71,6 +71,10 @@
<label for="attribute_mail">{{ctx.Locale.Tr "admin.auths.attribute_mail"}}</label>
<input id="attribute_mail" name="attribute_mail" value="{{.attribute_mail}}" placeholder="mail">
</div>
<div class="field">
<label for="default_domain_name">{{ctx.Locale.Tr "admin.auths.default_domain_name"}}</label>
<input id="default_domain_name" name="default_domain_name" value="{{.default_domain_name}}" placeholder="localhost.local">
</div>
<div class="field">
<label for="attribute_ssh_public_key">{{ctx.Locale.Tr "admin.auths.attribute_ssh_public_key"}}</label>
<input id="attribute_ssh_public_key" name="attribute_ssh_public_key" value="{{.attribute_ssh_public_key}}" placeholder="SshPublicKey">

View file

@ -2,9 +2,11 @@
<div role="main" aria-label="{{.Title}}" class="page-content repository commits">
{{template "repo/header" .}}
<div class="ui container flex-container">
<div class="flex-container-nav">
{{template "repo/navbar" .}}
</div>
{{if and (not .IsEmptyRepo) (.Permission.CanRead $.UnitTypeCode)}}
<div class="flex-container-nav">
{{template "repo/navbar" .}}
</div>
{{end}}
<div class="flex-container-main">
{{if .PageIsPulse}}{{template "repo/pulse" .}}{{end}}
{{if .PageIsContributors}}{{template "repo/contributors" .}}{{end}}

View file

@ -159,7 +159,7 @@
</a>
{{end}}
{{if and (.Permission.CanReadAny $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases) (not .IsEmptyRepo)}}
{{if and (.Permission.CanReadAny $.UnitTypeCode $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases)}}
<a class="{{if .PageIsActivity}}active {{end}}item" href="{{.RepoLink}}/activity">
{{svg "octicon-pulse"}} {{ctx.Locale.Tr "repo.activity"}}
</a>

View file

@ -23,9 +23,9 @@
<span class="text grey">{{svg "octicon-git-branch"}}{{.BranchName}}</span>
</td>
<td>
{{if .ParentIDs}}
{{if .ParentHashes}}
{{ctx.Locale.Tr "repo.diff.parent"}}
{{range .ParentIDs}}
{{range .ParentHashes}}
<a class="ui primary sha label" href="{{$.RepoLink}}/commit/{{.String}}">{{ShortSha .String}}</a>
{{end}}
{{end}}

View file

@ -701,3 +701,14 @@ func TestAPIRepoGetAssignees(t *testing.T) {
DecodeJSON(t, resp, &assignees)
assert.Len(t, assignees, 1)
}
func TestAPIViewRepoObjectFormat(t *testing.T) {
defer tests.PrepareTestEnv(t)()
var repo api.Repository
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1")
resp := MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &repo)
assert.EqualValues(t, "sha1", repo.ObjectFormatName)
}

View file

@ -112,13 +112,17 @@ func getLDAPServerPort() string {
return port
}
func buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, groupFilter, groupTeamMap, groupTeamMapRemoval string) map[string]string {
func buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, mailKeyAttribute, defaultDomainName, groupFilter, groupTeamMap, groupTeamMapRemoval string) map[string]string {
// Modify user filter to test group filter explicitly
userFilter := "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))"
if groupFilter != "" {
userFilter = "(&(objectClass=inetOrgPerson)(uid=%s))"
}
if len(mailKeyAttribute) == 0 {
mailKeyAttribute = "mail"
}
return map[string]string{
"_csrf": csrf,
"type": "2",
@ -134,8 +138,9 @@ func buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, groupFilter, groupTeamMap
"attribute_username": "uid",
"attribute_name": "givenName",
"attribute_surname": "sn",
"attribute_mail": "mail",
"attribute_mail": mailKeyAttribute,
"attribute_ssh_public_key": sshKeyAttribute,
"default_domain_name": defaultDomainName,
"is_sync_enabled": "on",
"is_active": "on",
"groups_enabled": "on",
@ -148,7 +153,7 @@ func buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, groupFilter, groupTeamMap
}
}
func addAuthSourceLDAP(t *testing.T, sshKeyAttribute, groupFilter string, groupMapParams ...string) {
func addAuthSourceLDAP(t *testing.T, sshKeyAttribute, mailKeyAttribute, defaultDomainName, groupFilter string, groupMapParams ...string) {
groupTeamMapRemoval := "off"
groupTeamMap := ""
if len(groupMapParams) == 2 {
@ -157,7 +162,7 @@ func addAuthSourceLDAP(t *testing.T, sshKeyAttribute, groupFilter string, groupM
}
session := loginUser(t, "user1")
csrf := GetCSRF(t, session, "/admin/auths/new")
req := NewRequestWithValues(t, "POST", "/admin/auths/new", buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, groupFilter, groupTeamMap, groupTeamMapRemoval))
req := NewRequestWithValues(t, "POST", "/admin/auths/new", buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, mailKeyAttribute, defaultDomainName, groupFilter, groupTeamMap, groupTeamMapRemoval))
session.MakeRequest(t, req, http.StatusSeeOther)
}
@ -167,7 +172,7 @@ func TestLDAPUserSignin(t *testing.T) {
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "")
addAuthSourceLDAP(t, "", "", "", "")
u := gitLDAPUsers[0]
@ -184,7 +189,7 @@ func TestLDAPUserSignin(t *testing.T) {
func TestLDAPAuthChange(t *testing.T) {
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "")
addAuthSourceLDAP(t, "", "", "", "")
session := loginUser(t, "user1")
req := NewRequest(t, "GET", "/admin/auths")
@ -205,7 +210,7 @@ func TestLDAPAuthChange(t *testing.T) {
binddn, _ := doc.Find(`input[name="bind_dn"]`).Attr("value")
assert.Equal(t, "uid=gitea,ou=service,dc=planetexpress,dc=com", binddn)
req = NewRequestWithValues(t, "POST", href, buildAuthSourceLDAPPayload(csrf, "", "", "", "off"))
req = NewRequestWithValues(t, "POST", href, buildAuthSourceLDAPPayload(csrf, "", "", "", "", "", "off"))
session.MakeRequest(t, req, http.StatusSeeOther)
req = NewRequest(t, "GET", href)
@ -215,6 +220,21 @@ func TestLDAPAuthChange(t *testing.T) {
assert.Equal(t, host, getLDAPServerHost())
binddn, _ = doc.Find(`input[name="bind_dn"]`).Attr("value")
assert.Equal(t, "uid=gitea,ou=service,dc=planetexpress,dc=com", binddn)
domainname, _ := doc.Find(`input[name="default_domain_name"]`).Attr("value")
assert.Equal(t, "", domainname)
req = NewRequestWithValues(t, "POST", href, buildAuthSourceLDAPPayload(csrf, "", "", "test.org", "", "", "off"))
session.MakeRequest(t, req, http.StatusSeeOther)
req = NewRequest(t, "GET", href)
resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body)
host, _ = doc.Find(`input[name="host"]`).Attr("value")
assert.Equal(t, host, getLDAPServerHost())
binddn, _ = doc.Find(`input[name="bind_dn"]`).Attr("value")
assert.Equal(t, "uid=gitea,ou=service,dc=planetexpress,dc=com", binddn)
domainname, _ = doc.Find(`input[name="default_domain_name"]`).Attr("value")
assert.Equal(t, "test.org", domainname)
}
func TestLDAPUserSync(t *testing.T) {
@ -223,7 +243,7 @@ func TestLDAPUserSync(t *testing.T) {
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "")
addAuthSourceLDAP(t, "", "", "", "")
auth.SyncExternalUsers(context.Background(), true)
// Check if users exists
@ -252,7 +272,7 @@ func TestLDAPUserSyncWithEmptyUsernameAttribute(t *testing.T) {
session := loginUser(t, "user1")
csrf := GetCSRF(t, session, "/admin/auths/new")
payload := buildAuthSourceLDAPPayload(csrf, "", "", "", "")
payload := buildAuthSourceLDAPPayload(csrf, "", "", "", "", "", "")
payload["attribute_username"] = ""
req := NewRequestWithValues(t, "POST", "/admin/auths/new", payload)
session.MakeRequest(t, req, http.StatusSeeOther)
@ -300,7 +320,7 @@ func TestLDAPUserSyncWithGroupFilter(t *testing.T) {
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "(cn=git)")
addAuthSourceLDAP(t, "", "", "", "(cn=git)")
// Assert a user not a member of the LDAP group "cn=git" cannot login
// This test may look like TestLDAPUserSigninFailed but it is not.
@ -359,7 +379,7 @@ func TestLDAPUserSigninFailed(t *testing.T) {
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "")
addAuthSourceLDAP(t, "", "", "", "")
u := otherLDAPUsers[0]
testLoginFailed(t, u.UserName, u.Password, translation.NewLocale("en-US").TrString("form.username_password_incorrect"))
@ -371,7 +391,7 @@ func TestLDAPUserSSHKeySync(t *testing.T) {
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "sshPublicKey", "")
addAuthSourceLDAP(t, "sshPublicKey", "", "", "")
auth.SyncExternalUsers(context.Background(), true)
@ -404,7 +424,7 @@ func TestLDAPGroupTeamSyncAddMember(t *testing.T) {
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "", "on", `{"cn=ship_crew,ou=people,dc=planetexpress,dc=com":{"org26": ["team11"]},"cn=admin_staff,ou=people,dc=planetexpress,dc=com": {"non-existent": ["non-existent"]}}`)
addAuthSourceLDAP(t, "", "", "", "", "on", `{"cn=ship_crew,ou=people,dc=planetexpress,dc=com":{"org26": ["team11"]},"cn=admin_staff,ou=people,dc=planetexpress,dc=com": {"non-existent": ["non-existent"]}}`)
org, err := organization.GetOrgByName(db.DefaultContext, "org26")
assert.NoError(t, err)
team, err := organization.GetTeam(db.DefaultContext, org.ID, "team11")
@ -449,7 +469,7 @@ func TestLDAPGroupTeamSyncRemoveMember(t *testing.T) {
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "", "on", `{"cn=dispatch,ou=people,dc=planetexpress,dc=com": {"org26": ["team11"]}}`)
addAuthSourceLDAP(t, "", "", "", "", "on", `{"cn=dispatch,ou=people,dc=planetexpress,dc=com": {"org26": ["team11"]}}`)
org, err := organization.GetOrgByName(db.DefaultContext, "org26")
assert.NoError(t, err)
team, err := organization.GetTeam(db.DefaultContext, org.ID, "team11")
@ -487,6 +507,58 @@ func TestLDAPPreventInvalidGroupTeamMap(t *testing.T) {
session := loginUser(t, "user1")
csrf := GetCSRF(t, session, "/admin/auths/new")
req := NewRequestWithValues(t, "POST", "/admin/auths/new", buildAuthSourceLDAPPayload(csrf, "", "", `{"NOT_A_VALID_JSON"["MISSING_DOUBLE_POINT"]}`, "off"))
req := NewRequestWithValues(t, "POST", "/admin/auths/new", buildAuthSourceLDAPPayload(csrf, "", "", "", "", `{"NOT_A_VALID_JSON"["MISSING_DOUBLE_POINT"]}`, "off"))
session.MakeRequest(t, req, http.StatusOK) // StatusOK = failed, StatusSeeOther = ok
}
func TestLDAPUserSyncInvalidMail(t *testing.T) {
if skipLDAPTests() {
t.Skip()
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "nonexisting", "", "")
auth.SyncExternalUsers(context.Background(), true)
// Check if users exists
for _, gitLDAPUser := range gitLDAPUsers {
dbUser, err := user_model.GetUserByName(db.DefaultContext, gitLDAPUser.UserName)
assert.NoError(t, err)
assert.Equal(t, gitLDAPUser.UserName, dbUser.Name)
assert.Equal(t, gitLDAPUser.UserName+"@localhost.local", dbUser.Email)
assert.Equal(t, gitLDAPUser.IsAdmin, dbUser.IsAdmin)
assert.Equal(t, gitLDAPUser.IsRestricted, dbUser.IsRestricted)
}
// Check if no users exist
for _, otherLDAPUser := range otherLDAPUsers {
_, err := user_model.GetUserByName(db.DefaultContext, otherLDAPUser.UserName)
assert.True(t, user_model.IsErrUserNotExist(err))
}
}
func TestLDAPUserSyncInvalidMailDefaultDomain(t *testing.T) {
if skipLDAPTests() {
t.Skip()
return
}
defer tests.PrepareTestEnv(t)()
addAuthSourceLDAP(t, "", "nonexisting", "test.org", "")
auth.SyncExternalUsers(context.Background(), true)
// Check if users exists
for _, gitLDAPUser := range gitLDAPUsers {
dbUser, err := user_model.GetUserByName(db.DefaultContext, gitLDAPUser.UserName)
assert.NoError(t, err)
assert.Equal(t, gitLDAPUser.UserName, dbUser.Name)
assert.Equal(t, gitLDAPUser.UserName+"@test.org", dbUser.Email)
assert.Equal(t, gitLDAPUser.IsAdmin, dbUser.IsAdmin)
assert.Equal(t, gitLDAPUser.IsRestricted, dbUser.IsRestricted)
}
// Check if no users exist
for _, otherLDAPUser := range otherLDAPUsers {
_, err := user_model.GetUserByName(db.DefaultContext, otherLDAPUser.UserName)
assert.True(t, user_model.IsErrUserNotExist(err))
}
}

View file

@ -307,6 +307,16 @@ func TestIssueCommentUpdate(t *testing.T) {
comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: commentID})
assert.Equal(t, modifiedContent, comment.Content)
// make the comment empty
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{
"_csrf": GetCSRF(t, session, issueURL),
"content": "",
})
session.MakeRequest(t, req, http.StatusOK)
comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: commentID})
assert.Equal(t, "", comment.Content)
}
func TestIssueReaction(t *testing.T) {

View file

@ -100,6 +100,6 @@ func TestLFSRender(t *testing.T) {
req = NewRequest(t, "GET", lfsFindPath)
resp = session.MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body).doc
assert.Contains(t, doc.Text(), "README.md")
assert.Equal(t, 1, doc.Find(`.sha.label[href="/user2/lfs/commit/73cf03db6ece34e12bf91e8853dc58f678f2f82d"]`).Length(), "could not find link to commit")
})
}