Merged with gitea-master

This commit is contained in:
kolaente 2018-06-06 14:23:30 +02:00
commit 8c1f627c75
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
406 changed files with 14439 additions and 33453 deletions

View File

@ -197,6 +197,7 @@ pipeline:
environment:
TAGS: bindata sqlite
commands:
- export PATH=$PATH:$GOPATH/bin
- make release
when:
event: [ push, tag ]

View File

@ -4,6 +4,21 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.4.2](https://github.com/go-gitea/gitea/releases/tag/v1.4.2) - 2018-06-04
* BUGFIXES
* Adjust z-index for floating labels (#3939) (#3950)
* Add missing token validation on application settings page (#3976) #3978
* Webhook and hook_task clean up (#4006)
* Fix webhook bug of response info is not displayed in UI (#4023)
* Fix writer cannot read bare repo guide (#4033) (#4039)
* Don't force due date to current time (#3830) (#4057)
* Fix wiki redirects (#3919) (#4065)
* Fix attachment ENABLED (#4064) (#4066)
* Added deletion of an empty line at the end of file (#4054) (#4074)
* Use ResolveReference instead of path.Join (#4073)
* Fix #4081 Check for leading / in base before removing it (#4083)
* Respository's home page not updated after first push (#4075)
## [1.4.1](https://github.com/go-gitea/gitea/releases/tag/v1.4.1) - 2018-05-03
* BREAKING
* Add "error" as reserved username (#3882) (#3886)

View File

@ -69,14 +69,14 @@ and keep the compatibility on upgrade. To make sure you are
running the test suite exactly like we do, you should install
the CLI for [Drone CI](https://github.com/drone/drone), as
we are using the server for continous testing, following [these
instructions](http://readme.drone.io/usage/getting-started-cli). After that,
you can simply call `drone exec` within your working directory and it will try
to run the test suite locally.
instructions](http://docs.drone.io/cli-installation/). After that,
you can simply call `drone exec --local --build-event "pull_request"` within
your working directory and it will try to run the test suite locally.
## Vendoring
We keep a cached copy of dependencies within the `vendor/` directory,
managing updates via [govendor](http://github.com/kardianos/govendor).
managing updates via [dep](https://github.com/golang/dep).
Pull requests should only include `vendor/` updates if they are part of
the same change, be it a bugfix or a feature addition.
@ -85,6 +85,8 @@ The `vendor/` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference
an existing upstream commit.
You can find more information on how to get started with it on the [dep project website](https://golang.github.io/dep/docs/introduction.html).
## Translation
We do all translation work inside [Crowdin](https://crowdin.com/project/gitea).
@ -112,7 +114,7 @@ pull request workflow to do that. And, we also use [LGTM](http://lgtm.co)
to ensure every PR is reviewed by at least 2 maintainers.
Please try to make your pull request easy to review for us. And, please read
the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/pull-requests.md#best-practices-for-faster-reviews)* guide;
the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob/261cb0fd089b64002c91e8eddceebf032462ccd6/contributors/guide/pull-requests.md#best-practices-for-faster-reviews)* guide;
it has lots of useful tips for any project you may want to contribute.
Some of the key points:

878
Gopkg.lock generated Normal file
View File

@ -0,0 +1,878 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
name = "code.gitea.io/git"
packages = ["."]
revision = "31f4b8e8c805438ac6d8914b38accb1d8aaf695e"
[[projects]]
branch = "master"
name = "code.gitea.io/sdk"
packages = ["gitea"]
revision = "b2308e3f700875a3642a78bd3f6e5db8ef6f974d"
[[projects]]
name = "github.com/PuerkitoBio/goquery"
packages = ["."]
revision = "ed7d758e9a34ba1f55e8084e0d731448b46921a8"
[[projects]]
name = "github.com/RoaringBitmap/roaring"
packages = ["."]
revision = "1a28a7fa985680f9f4e1644c0a857ec359a444b0"
version = "v0.4.7"
[[projects]]
branch = "master"
name = "github.com/Smerity/govarint"
packages = ["."]
revision = "7265e41f48f15fd61751e16da866af3c704bb3ab"
[[projects]]
branch = "master"
name = "github.com/Unknwon/cae"
packages = [
".",
"zip"
]
revision = "c6aac99ea2cae2ebaf23f26f76b04fe3fcfc9f8c"
[[projects]]
branch = "master"
name = "github.com/Unknwon/com"
packages = ["."]
revision = "7677a1d7c1137cd3dd5ba7a076d0c898a1ef4520"
[[projects]]
branch = "master"
name = "github.com/Unknwon/i18n"
packages = ["."]
revision = "b64d336589669d317928070e70ba0ae558f16633"
[[projects]]
name = "github.com/Unknwon/paginater"
packages = ["."]
revision = "7748a72e01415173a27d79866b984328e7b0c12b"
[[projects]]
name = "github.com/andybalholm/cascadia"
packages = ["."]
revision = "349dd0209470eabd9514242c688c403c0926d266"
[[projects]]
name = "github.com/blevesearch/bleve"
packages = [
".",
"analysis",
"analysis/analyzer/custom",
"analysis/analyzer/standard",
"analysis/datetime/flexible",
"analysis/datetime/optional",
"analysis/lang/en",
"analysis/token/camelcase",
"analysis/token/lowercase",
"analysis/token/porter",
"analysis/token/stop",
"analysis/token/unicodenorm",
"analysis/token/unique",
"analysis/tokenizer/unicode",
"document",
"geo",
"index",
"index/scorch",
"index/scorch/mergeplan",
"index/scorch/segment",
"index/scorch/segment/mem",
"index/scorch/segment/zap",
"index/store",
"index/store/boltdb",
"index/store/gtreap",
"index/upsidedown",
"mapping",
"numeric",
"registry",
"search",
"search/collector",
"search/facet",
"search/highlight",
"search/highlight/format/html",
"search/highlight/fragmenter/simple",
"search/highlight/highlighter/html",
"search/highlight/highlighter/simple",
"search/query",
"search/scorer",
"search/searcher"
]
revision = "ff210fbc6d348ad67aa5754eaea11a463fcddafd"
[[projects]]
branch = "master"
name = "github.com/blevesearch/go-porterstemmer"
packages = ["."]
revision = "23a2c8e5cf1f380f27722c6d2ae8896431dc7d0e"
[[projects]]
name = "github.com/blevesearch/segment"
packages = ["."]
revision = "db70c57796cc8c310613541dfade3dce627d09c7"
[[projects]]
name = "github.com/boltdb/bolt"
packages = ["."]
revision = "ccd680d8c1a0179ac3d68f692b01e1a1589cbfc7"
source = "github.com/go-gitea/bolt"
[[projects]]
name = "github.com/boombuler/barcode"
packages = [
".",
"qr",
"utils"
]
revision = "fe0f26ff6d26693948ee8189aa064ee8c54141fa"
[[projects]]
name = "github.com/bradfitz/gomemcache"
packages = ["memcache"]
revision = "fb1f79c6b65acda83063cbc69f6bba1522558bfc"
[[projects]]
name = "github.com/chaseadamsio/goorgeous"
packages = ["."]
revision = "098da33fde5f9220736531b3cb26a2dec86a8367"
[[projects]]
name = "github.com/coreos/etcd"
packages = ["error"]
revision = "01c303113d0a3d5a8075864321c3aedb72035bdd"
[[projects]]
branch = "master"
name = "github.com/coreos/go-etcd"
packages = ["etcd"]
revision = "003851be7bb0694fe3cc457a49529a19388ee7cf"
[[projects]]
branch = "master"
name = "github.com/couchbase/vellum"
packages = [
".",
"regexp",
"utf8"
]
revision = "eb6ae3743b3f300f2136f83ca78c08cc071edbd4"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
name = "github.com/denisenkom/go-mssqldb"
packages = ["."]
revision = "e32ca5036449b7ea12c62ed761ea1ad7fc88a4e2"
[[projects]]
name = "github.com/dgrijalva/jwt-go"
packages = ["."]
revision = "9ed569b5d1ac936e6494082958d63a6aa4fff99a"
[[projects]]
branch = "master"
name = "github.com/edsrzf/mmap-go"
packages = ["."]
revision = "0bce6a6887123b67a60366d2c9fe2dfb74289d2e"
[[projects]]
name = "github.com/elazarl/go-bindata-assetfs"
packages = ["."]
revision = "57eb5e1fc594ad4b0b1dbea7b286d299e0cb43c2"
[[projects]]
name = "github.com/ethantkoenig/rupture"
packages = ["."]
revision = "0a76f03a811abcca2e6357329b673e9bb8ef9643"
[[projects]]
branch = "master"
name = "github.com/facebookgo/clock"
packages = ["."]
revision = "600d898af40aa09a7a93ecb9265d87b0504b6f03"
[[projects]]
name = "github.com/facebookgo/grace"
packages = [
"gracehttp",
"gracenet"
]
revision = "5729e484473f52048578af1b80d0008c7024089b"
[[projects]]
branch = "master"
name = "github.com/facebookgo/httpdown"
packages = ["."]
revision = "a3b1354551a26449fbe05f5d855937f6e7acbd71"
[[projects]]
branch = "master"
name = "github.com/facebookgo/stats"
packages = ["."]
revision = "1b76add642e42c6ffba7211ad7b3939ce654526e"
[[projects]]
branch = "master"
name = "github.com/glycerine/go-unsnap-stream"
packages = ["."]
revision = "9f0cb55181dd3a0a4c168d3dbc72d4aca4853126"
[[projects]]
branch = "master"
name = "github.com/go-macaron/bindata"
packages = ["."]
revision = "85786f57eee3e5544a9cc24fa2afe425b97a8652"
[[projects]]
name = "github.com/go-macaron/binding"
packages = ["."]
revision = "9440f336b443056c90d7d448a0a55ad8c7599880"
[[projects]]
branch = "master"
name = "github.com/go-macaron/cache"
packages = [
".",
"memcache",
"redis"
]
revision = "56173531277692bc2925924d51fda1cd0a6b8178"
[[projects]]
name = "github.com/go-macaron/captcha"
packages = ["."]
revision = "8aa5919789ab301e865595eb4b1114d6b9847deb"
[[projects]]
branch = "master"
name = "github.com/go-macaron/csrf"
packages = ["."]
revision = "503617c6b37257a55dff6293ec28556506c3a9a8"
[[projects]]
branch = "master"
name = "github.com/go-macaron/gzip"
packages = ["."]
revision = "cad1c6580a07c56f5f6bc52d66002a05985c5854"
[[projects]]
branch = "master"
name = "github.com/go-macaron/i18n"
packages = ["."]
revision = "ef57533c3b0fc2d8581deda14937e52f11a203ab"
[[projects]]
branch = "master"
name = "github.com/go-macaron/inject"
packages = ["."]
revision = "d8a0b8677191f4380287cfebd08e462217bac7ad"
[[projects]]
name = "github.com/go-macaron/session"
packages = [
".",
"redis"
]
revision = "66031fcb37a0fff002a1f028eb0b3a815c78306b"
[[projects]]
name = "github.com/go-macaron/toolbox"
packages = ["."]
revision = "99a42f20e9e88daec5c0d7beb4e7eac134680ab0"
[[projects]]
name = "github.com/go-sql-driver/mysql"
packages = ["."]
revision = "ce924a41eea897745442daaa1739089b0f3f561d"
[[projects]]
name = "github.com/go-xorm/builder"
packages = ["."]
revision = "488224409dd8aa2ce7a5baf8d10d55764a913738"
[[projects]]
name = "github.com/go-xorm/core"
packages = ["."]
revision = "cb1d0ca71f42d3ee1bf4aba7daa16099bc31a7e9"
[[projects]]
name = "github.com/go-xorm/tidb"
packages = ["."]
revision = "21e49190ce47a766fa741cf7edc831a30c12c6ac"
[[projects]]
name = "github.com/go-xorm/xorm"
packages = ["."]
revision = "d4149d1eee0c2c488a74a5863fd9caf13d60fd03"
[[projects]]
branch = "master"
name = "github.com/gogits/chardet"
packages = ["."]
revision = "2404f777256163ea3eadb273dada5dcb037993c0"
[[projects]]
name = "github.com/gogits/cron"
packages = ["."]
revision = "7f3990acf1833faa5ebd0e86f0a4c72a4b5eba3c"
[[projects]]
name = "github.com/golang/protobuf"
packages = ["proto"]
revision = "99511271042a09d1e01baea8781caa5210fec66e"
[[projects]]
name = "github.com/golang/snappy"
packages = ["."]
revision = "5f1c01d9f64b941dd9582c638279d046eda6ca31"
[[projects]]
name = "github.com/gorilla/context"
packages = ["."]
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
version = "v1.1.1"
[[projects]]
name = "github.com/gorilla/mux"
packages = ["."]
revision = "757bef944d0f21880861c2dd9c871ca543023cba"
[[projects]]
name = "github.com/gorilla/securecookie"
packages = ["."]
revision = "e59506cc896acb7f7bf732d4fdf5e25f7ccd8983"
version = "v1.1.1"
[[projects]]
name = "github.com/gorilla/sessions"
packages = ["."]
revision = "ca9ada44574153444b00d3fd9c8559e4cc95f896"
version = "v1.1"
[[projects]]
name = "github.com/issue9/identicon"
packages = ["."]
revision = "d36b54562f4cf70c83653e13dc95c220c79ef521"
[[projects]]
name = "github.com/jaytaylor/html2text"
packages = ["."]
revision = "8fb95d837f7d6db1913fecfd7bcc5333e6499596"
[[projects]]
name = "github.com/juju/errors"
packages = ["."]
revision = "b2c7a7da5b2995941048f60146e67702a292e468"
[[projects]]
name = "github.com/kballard/go-shellquote"
packages = ["."]
revision = "cd60e84ee657ff3dc51de0b4f55dd299a3e136f2"
[[projects]]
name = "github.com/keybase/go-crypto"
packages = [
"brainpool",
"cast5",
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"openpgp",
"openpgp/armor",
"openpgp/ecdh",
"openpgp/elgamal",
"openpgp/errors",
"openpgp/packet",
"openpgp/s2k",
"rsa"
]
revision = "00ac4db533f63ef97576cbc7b07939ff7daf7329"
[[projects]]
name = "github.com/klauspost/compress"
packages = [
"flate",
"gzip"
]
revision = "8df558b6cb6f9b445f9586446cfe7223e7d8bd6b"
version = "v1.1"
[[projects]]
name = "github.com/klauspost/cpuid"
packages = ["."]
revision = "09cded8978dc9e80714c4d85b0322337b0a1e5e0"
version = "v1.0"
[[projects]]
name = "github.com/klauspost/crc32"
packages = ["."]
revision = "cb6bfca970f6908083f26f39a79009d608efd5cd"
version = "v1.1"
[[projects]]
name = "github.com/lafriks/xormstore"
packages = [
".",
"util"
]
revision = "9cab149ea91875cf056211bd6ef82379fce9cb67"
version = "v1.0.0"
[[projects]]
name = "github.com/lib/pq"
packages = [
".",
"oid"
]
revision = "456514e2defec52e0cd37f90ccf17ec8b28295e2"
[[projects]]
branch = "master"
name = "github.com/lunny/dingtalk_webhook"
packages = ["."]
revision = "e3534c89ef969912856dfa39e56b09e58c5f5daf"
[[projects]]
name = "github.com/markbates/goth"
packages = [
".",
"gothic",
"providers/bitbucket",
"providers/dropbox",
"providers/facebook",
"providers/github",
"providers/gitlab",
"providers/gplus",
"providers/openidConnect",
"providers/twitter"
]
revision = "4933f155d89c3c52ab4ca545c6602cf4a1e87913"
version = "1.45.5"
[[projects]]
name = "github.com/mattn/go-sqlite3"
packages = ["."]
revision = "acfa60124032040b9f5a9406f5a772ee16fe845e"
[[projects]]
branch = "master"
name = "github.com/mcuadros/go-version"
packages = ["."]
revision = "88e56e02bea1c203c99222c365fa52a69996ccac"
[[projects]]
name = "github.com/microcosm-cc/bluemonday"
packages = ["."]
revision = "f77f16ffc87a6a58814e64ae72d55f9c41374e6d"
[[projects]]
name = "github.com/mrjones/oauth"
packages = ["."]
revision = "3f67d9c274355678b2f9844b08d643e2f9213340"
[[projects]]
branch = "master"
name = "github.com/mschoch/smat"
packages = ["."]
revision = "90eadee771aeab36e8bf796039b8c261bebebe4f"
[[projects]]
name = "github.com/msteinert/pam"
packages = ["."]
revision = "02ccfbfaf0cc627aa3aec8ef7ed5cfeec5b43f63"
[[projects]]
name = "github.com/nfnt/resize"
packages = ["."]
revision = "891127d8d1b52734debe1b3c3d7e747502b6c366"
[[projects]]
name = "github.com/ngaut/deadline"
packages = ["."]
revision = "fae8f9dfd7048de16575b9d4c255278e38c28a4f"
[[projects]]
branch = "master"
name = "github.com/ngaut/go-zookeeper"
packages = ["zk"]
revision = "9c3719e318c7cfd072e41eb48cb71fcaa49d5e05"
[[projects]]
name = "github.com/ngaut/log"
packages = ["."]
revision = "d2af3a61f64d093457fb23b25d20f4ce3cd551ce"
[[projects]]
branch = "master"
name = "github.com/ngaut/pools"
packages = ["."]
revision = "b7bc8c42aac787667ba45adea78233f53f548443"
[[projects]]
branch = "master"
name = "github.com/ngaut/sync2"
packages = ["."]
revision = "7a24ed77b2efb460c1468b7dc917821c66e80e55"
[[projects]]
branch = "master"
name = "github.com/ngaut/tso"
packages = [
"client",
"proto",
"util"
]
revision = "118f6c141d58f1e72577ff61f43f649bf39355ee"
[[projects]]
branch = "master"
name = "github.com/ngaut/zkhelper"
packages = ["."]
revision = "6738bdc138d469112c6687fbfcfe049ccabd6a0a"
[[projects]]
branch = "master"
name = "github.com/petar/GoLLRB"
packages = ["llrb"]
revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4"
[[projects]]
name = "github.com/philhofer/fwd"
packages = ["."]
revision = "bb6d471dc95d4fe11e432687f8b70ff496cf3136"
version = "v1.0.0"
[[projects]]
name = "github.com/pingcap/go-hbase"
packages = [
".",
"iohelper",
"proto"
]
revision = "7a98d1fe4e9e115de8c77ae0e158c0d08732c550"
[[projects]]
branch = "master"
name = "github.com/pingcap/go-themis"
packages = [
".",
"oracle",
"oracle/oracles"
]
revision = "dbb996606c1d1fe8571fd9ac6da2254c76d2c5c9"
[[projects]]
name = "github.com/pingcap/tidb"
packages = [
".",
"ast",
"column",
"context",
"ddl",
"domain",
"evaluator",
"executor",
"infoschema",
"inspectkv",
"kv",
"kv/memkv",
"meta",
"meta/autoid",
"model",
"mysql",
"optimizer",
"optimizer/plan",
"parser",
"parser/opcode",
"perfschema",
"privilege",
"privilege/privileges",
"sessionctx",
"sessionctx/autocommit",
"sessionctx/db",
"sessionctx/forupdate",
"sessionctx/variable",
"store/hbase",
"store/localstore",
"store/localstore/boltdb",
"store/localstore/engine",
"store/localstore/goleveldb",
"structure",
"table",
"table/tables",
"terror",
"util",
"util/bytes",
"util/charset",
"util/codec",
"util/distinct",
"util/hack",
"util/segmentmap",
"util/sqlexec",
"util/stringutil",
"util/types"
]
revision = "33197485abe227dcb254644cf5081c9a3c281669"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/pquerna/otp"
packages = [
".",
"hotp",
"totp"
]
revision = "54653902c20e47f3417541d35435cb6d6162e28a"
[[projects]]
branch = "master"
name = "github.com/russross/blackfriday"
packages = ["."]
revision = "11635eb403ff09dbc3a6b5a007ab5ab09151c229"
[[projects]]
name = "github.com/satori/go.uuid"
packages = ["."]
revision = "b061729afc07e77a8aa4fad0a2fd840958f1942a"
[[projects]]
name = "github.com/sergi/go-diff"
packages = ["diffmatchpatch"]
revision = "552b4e9bbdca9e5adafd95ee98c822fdd11b330b"
[[projects]]
name = "github.com/shurcooL/sanitized_anchor_name"
packages = ["."]
revision = "1dba4b3954bc059efc3991ec364f9f9a35f597d2"
[[projects]]
branch = "master"
name = "github.com/steveyen/gtreap"
packages = ["."]
revision = "0abe01ef9be25c4aedc174758ec2d917314d6d70"
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert"]
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
[[projects]]
name = "github.com/syndtr/goleveldb"
packages = [
"leveldb",
"leveldb/cache",
"leveldb/comparer",
"leveldb/errors",
"leveldb/filter",
"leveldb/iterator",
"leveldb/journal",
"leveldb/memdb",
"leveldb/opt",
"leveldb/storage",
"leveldb/table",
"leveldb/util"
]
revision = "917f41c560270110ceb73c5b38be2a9127387071"
[[projects]]
branch = "master"
name = "github.com/tinylib/msgp"
packages = ["msgp"]
revision = "c8cf64dff2009d53fa8f8a16df54d1cdfc64c4a7"
[[projects]]
branch = "master"
name = "github.com/tstranex/u2f"
packages = ["."]
revision = "d21a03e0b1d9fc1df59ff54e7a513655c1748b0c"
[[projects]]
name = "github.com/twinj/uuid"
packages = ["."]
revision = "89173bcdda19db0eb88aef1e1cb1cb2505561d31"
version = "0.10.0"
[[projects]]
name = "github.com/ugorji/go"
packages = ["codec"]
revision = "c062049c1793b01a3cc3fe786108edabbaf7756b"
[[projects]]
name = "github.com/urfave/cli"
packages = ["."]
revision = "d86a009f5e13f83df65d0d6cee9a2e3f1445f0da"
[[projects]]
branch = "master"
name = "github.com/willf/bitset"
packages = ["."]
revision = "8ce1146b8621c95164efd9c8b1124cfa9b8afb4e"
[[projects]]
name = "github.com/yohcop/openid-go"
packages = ["."]
revision = "2c050d2dae5345c417db301f11fda6fbf5ad0f0a"
[[projects]]
name = "golang.org/x/crypto"
packages = [
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"md4",
"pbkdf2",
"ssh"
]
revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
[[projects]]
name = "golang.org/x/net"
packages = [
"context",
"html",
"html/atom",
"html/charset"
]
revision = "f2499483f923065a842d38eb4c7f1927e6fc6e6d"
[[projects]]
name = "golang.org/x/oauth2"
packages = [
".",
"internal"
]
revision = "c10ba270aa0bf8b8c1c986e103859c67a9103061"
[[projects]]
name = "golang.org/x/sync"
packages = ["syncmap"]
revision = "5a06fca2c336a4b2b2fcb45702e8c47621b2aa2c"
[[projects]]
name = "golang.org/x/sys"
packages = [
"unix",
"windows",
"windows/svc"
]
revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8"
[[projects]]
name = "golang.org/x/text"
packages = [
"encoding",
"encoding/charmap",
"encoding/htmlindex",
"encoding/internal",
"encoding/internal/identifier",
"encoding/japanese",
"encoding/korean",
"encoding/simplifiedchinese",
"encoding/traditionalchinese",
"encoding/unicode",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"internal/utf8internal",
"language",
"runes",
"transform",
"unicode/cldr",
"unicode/norm"
]
revision = "2bf8f2a19ec09c670e931282edfe6567f6be21c9"
[[projects]]
branch = "v3"
name = "gopkg.in/alexcesaro/quotedprintable.v3"
packages = ["."]
revision = "2caba252f4dc53eaf6b553000885530023f54623"
[[projects]]
name = "gopkg.in/asn1-ber.v1"
packages = ["."]
revision = "4e86f4367175e39f69d9358a5f17b4dda270378d"
version = "v1.1"
[[projects]]
name = "gopkg.in/bufio.v1"
packages = ["."]
revision = "567b2bfa514e796916c4747494d6ff5132a1dfce"
version = "v1"
[[projects]]
name = "gopkg.in/editorconfig/editorconfig-core-go.v1"
packages = ["."]
revision = "a872f05c2e34b37b567401384d202aff11ba06d4"
version = "v1.2.0"
[[projects]]
branch = "v2"
name = "gopkg.in/gomail.v2"
packages = ["."]
revision = "81ebce5c23dfd25c6c67194b37d3dd3f338c98b1"
[[projects]]
name = "gopkg.in/ini.v1"
packages = ["."]
revision = "7e7da451323b6766da368f8a1e8ec9a88a16b4a0"
version = "v1.31.1"
[[projects]]
name = "gopkg.in/ldap.v2"
packages = ["."]
revision = "d0a5ced67b4dc310b9158d63a2c6f9c5ec13f105"
version = "v2.4.1"
[[projects]]
name = "gopkg.in/macaron.v1"
packages = ["."]
revision = "75f2e9b42e99652f0d82b28ccb73648f44615faa"
version = "v1.2.4"
[[projects]]
name = "gopkg.in/redis.v2"
packages = ["."]
revision = "e6179049628164864e6e84e973cfb56335748dea"
version = "v2.3.2"
[[projects]]
name = "gopkg.in/testfixtures.v2"
packages = ["."]
revision = "b9ef14dc461bf934d8df2dfc6f1f456be5664cca"
version = "v2.0.0"
[[projects]]
name = "gopkg.in/yaml.v2"
packages = ["."]
revision = "a5b47d31c556af34a302ce5d659e6fea44d90de0"
[[projects]]
name = "strk.kbt.io/projects/go/libravatar"
packages = ["."]
revision = "5eed7bff870ae19ef51c5773dbc8f3e9fcbd0982"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "036b8c882671cf8d2c5e2fdbe53b1bdfbd39f7ebd7765bd50276c7c4ecf16687"
solver-name = "gps-cdcl"
solver-version = 1

106
Gopkg.toml Normal file
View File

@ -0,0 +1,106 @@
ignored = ["google.golang.org/appengine*"]
[prune]
go-tests = true
unused-packages = true
non-go = true
[[constraint]]
branch = "master"
name = "code.gitea.io/git"
[[constraint]]
branch = "master"
name = "code.gitea.io/sdk"
[[constraint]]
revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
name = "golang.org/x/crypto"
[[constraint]]
revision = "a646d33e2ee3172a661fc09bca23bb4889a41bc8"
name = "golang.org/x/sys"
[[constraint]]
revision = "2bf8f2a19ec09c670e931282edfe6567f6be21c9"
name = "golang.org/x/text"
[[constraint]]
revision = "f2499483f923065a842d38eb4c7f1927e6fc6e6d"
name = "golang.org/x/net"
[[constraint]]
#version = "v1.0.0"
revision = "33197485abe227dcb254644cf5081c9a3c281669"
name = "github.com/pingcap/tidb"
[[override]]
name = "github.com/go-xorm/xorm"
#version = "0.6.5"
revision = "d4149d1eee0c2c488a74a5863fd9caf13d60fd03"
[[override]]
name = "github.com/gorilla/mux"
revision = "757bef944d0f21880861c2dd9c871ca543023cba"
[[constraint]]
name = "github.com/gorilla/context"
version = "1.1.1"
[[constraint]]
name = "github.com/lafriks/xormstore"
version = "1.0.0"
[[constraint]]
branch = "master"
name = "github.com/lunny/dingtalk_webhook"
[[constraint]]
name = "github.com/markbates/goth"
version = "1.45.5"
[[constraint]]
branch = "master"
name = "github.com/mcuadros/go-version"
[[constraint]]
branch = "master"
name = "github.com/russross/blackfriday"
[[constraint]]
branch = "master"
name = "github.com/tstranex/u2f"
[[constraint]]
name = "gopkg.in/editorconfig/editorconfig-core-go.v1"
version = "1.2.0"
[[constraint]]
branch = "v2"
name = "gopkg.in/gomail.v2"
[[constraint]]
name = "gopkg.in/ini.v1"
version = "1.31.1"
[[constraint]]
name = "gopkg.in/ldap.v2"
version = "2.4.1"
[[constraint]]
name = "gopkg.in/macaron.v1"
version = "1.2.4"
[[constraint]]
name = "gopkg.in/testfixtures.v2"
version = "2.0.0"
[[override]]
name = "github.com/boltdb/bolt"
revision = "ccd680d8c1a0179ac3d68f692b01e1a1589cbfc7"
source = "github.com/go-gitea/bolt"
[[override]]
revision = "c10ba270aa0bf8b8c1c986e103859c67a9103061"
name = "golang.org/x/oauth2"

View File

@ -100,6 +100,13 @@ swagger-check: generate-swagger
exit 1; \
fi;
.PHONY: swagger-validate
swagger-validate:
@hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \
fi
swagger validate ./public/swagger.v1.json
.PHONY: errcheck
errcheck:
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
@ -153,18 +160,22 @@ coverage:
unit-test-coverage:
for PKG in $(PACKAGES); do $(GO) test -tags=sqlite -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done;
.PHONY: test-vendor
test-vendor:
@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/kardianos/govendor; \
.PHONY: vendor
vendor:
@hash dep > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/golang/dep/cmd/dep; \
fi
govendor list +unused | tee "$(TMPDIR)/wc-gitea-unused"
[ $$(cat "$(TMPDIR)/wc-gitea-unused" | wc -l) -eq 0 ] || echo "Warning: /!\\ Some vendor are not used /!\\"
dep ensure -vendor-only
govendor list +outside | tee "$(TMPDIR)/wc-gitea-outside"
[ $$(cat "$(TMPDIR)/wc-gitea-outside" | wc -l) -eq 0 ] || exit 1
govendor status || exit 1
.PHONY: test-vendor
test-vendor: vendor
@diff=$$(git diff vendor/); \
if [ -n "$$diff" ]; then \
echo "Please run 'make vendor' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;
#TODO add dep status -missing when implemented
.PHONY: test-sqlite
test-sqlite: integrations.sqlite.test
@ -230,7 +241,7 @@ $(EXECUTABLE): $(SOURCES)
$(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
.PHONY: release
release: release-dirs release-windows release-linux release-darwin release-copy release-check
release: release-dirs release-windows release-linux release-darwin release-copy release-compress release-check
.PHONY: release-dirs
release-dirs:
@ -274,6 +285,13 @@ release-copy:
release-check:
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
.PHONY: release-compress
release-compress:
@hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/ulikunitz/xz/cmd/gxz; \
fi
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),gxz -k -9 $(notdir $(file));)
.PHONY: javascripts
javascripts: public/js/index.js

View File

@ -91,6 +91,12 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
## FAQ
**How do you pronounce Gitea?**
Gitea is pronounced [/ɡɪti:/](https://youtu.be/EM71-2uDAoY) as in "gi-tea" with a hard g.
## License
This project is licensed under the MIT License.

View File

@ -268,7 +268,7 @@ func runServ(c *cli.Context) error {
claims := jwt.MapClaims{
"repo": repo.ID,
"op": lfsVerb,
"exp": now.Add(5 * time.Minute).Unix(),
"exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
"nbf": now.Unix(),
}
if user != nil {

View File

@ -24,8 +24,8 @@
# Default values
NAME=gitea
GITEA_HOME=/home/git/gitea
GITEA_PATH=${GITEA_HOME}/$NAME
GITEA_HOME=/var/lib/${NAME}
GITEA_PATH=/usr/local/bin/${NAME}
GITEA_USER=git
SERVICENAME="Gitea - Git with a cup of tea"
LOCKFILE=/var/lock/subsys/gitea
@ -49,11 +49,11 @@ DAEMON_OPTS="--check $NAME"
start() {
cd ${GITEA_HOME}
echo -n "Starting ${SERVICENAME}: "
daemon $DAEMON_OPTS "${GITEA_PATH} web > ${LOGFILE} 2>&1 &"
daemon $DAEMON_OPTS "${GITEA_PATH} web -c /etc/${NAME}/app.ini > ${LOGFILE} 2>&1 &"
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${LOCKFILE}
return $RETVAL
}
@ -63,7 +63,7 @@ stop() {
killproc ${NAME}
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${LOCKFILE}
[ $RETVAL = 0 ] && rm -f ${LOCKFILE}
}
case "$1" in

View File

@ -14,17 +14,20 @@
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Git with a cup of tea"
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="Gitea - Git with a cup of tea"
NAME=gitea
SERVICEVERBOSE=yes
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
WORKINGDIR=/home/git/gitea
DAEMON=$WORKINGDIR/$NAME
DAEMON_ARGS="web"
WORKINGDIR=/var/lib/$NAME
DAEMON=/usr/local/bin/$NAME
DAEMON_ARGS="web -c /etc/$NAME/app.ini"
USER=git
USERBIND="setcap cap_net_bind_service=+ep"
USERBIND=""
# If you want to bind Gitea to a port below 1024 uncomment
# the line below
#USERBIND="setcap cap_net_bind_service=+ep"
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"
# Read configuration variable file if it is present
@ -36,7 +39,7 @@ STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"
do_start()
{
$USERBIND $DAEMON
sh -c "USER=$USER start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
sh -c "USER=$USER HOME=/home/$USER GITEA_WORK_DIR=$WORKINGDIR start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
--background --chdir $WORKINGDIR --chuid $USER \\
--exec $DAEMON -- $DAEMON_ARGS"
}

View File

@ -19,9 +19,9 @@ load_rc_config $name
: ${gitea_user:="git"}
: ${gitea_enable:="NO"}
: ${gitea_directory:="/home/git"}
: ${gitea_directory:="/var/lib/gitea"}
command="${gitea_directory}/gitea web"
command="/usr/local/bin/gitea web -c /etc/gitea/app.ini"
procname="$(echo $command |cut -d' ' -f1)"
pidfile="${gitea_directory}/${name}.pid"
@ -33,6 +33,7 @@ gitea_start() {
cd ${gitea_directory}
export USER=${gitea_user}
export HOME=/usr/home/${gitea_user}
export GITEA_WORK_DIR=${gitea_directory}
/usr/sbin/daemon -f -u ${gitea_user} -p ${pidfile} $command
}

View File

@ -1,11 +1,11 @@
#!/sbin/openrc-run
DIR=/home/git/gitea
DIR=/var/lib/gitea
USER=git
start_stop_daemon_args="--user ${USER} --chdir ${DIR}"
command="${DIR}/gitea"
command_args="web"
command="/usr/local/bin/gitea"
command_args="web -c /etc/gitea/app.ini"
command_background=yes
pidfile=/var/run/gitea.pid

View File

@ -2,11 +2,11 @@
#
# $OpenBSD$
daemon="/home/git/gitea/gitea"
daemon="/usr/local/bin/gitea"
daemon_user="git"
daemon_flags="web"
daemon_flags="web -c /etc/gitea/app.ini"
gitea_directory="/home/git/gitea"
gitea_directory="/var/lib/gitea"
rc_bg=YES

View File

@ -18,10 +18,10 @@
# Default values
NAME=gitea
GITEA_HOME=/home/git/gitea
GITEA_PATH=${GITEA_HOME}/$NAME
GITEA_HOME=/var/lib/$NAME
GITEA_PATH=/usr/local/bin/$NAME
GITEA_USER=git
SERVICENAME="Git - with a cup of tea"
SERVICENAME="Gitea - Git with a cup of tea"
LOCKFILE=/var/lock/subsys/gitea
LOGPATH=${GITEA_HOME}/log
LOGFILE=${LOGPATH}/error.log
@ -58,7 +58,7 @@ case "$1" in
# return skipped as service is already running
(exit 5)
else
su - ${GITEA_USER} -c "USER=${GITEA_USER} ${GITEA_PATH} web 2>&1 >>${LOGFILE} &"
su - ${GITEA_USER} -c "USER=${GITEA_USER} GITEA_WORK_DIR=${GITEA_HOME} ${GITEA_PATH} web -c /etc/${NAME}/app.ini 2>&1 >>${LOGFILE} &"
fi
# Remember status and be verbose

View File

@ -18,10 +18,10 @@ RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/home/git/gitea
ExecStart=/home/git/gitea/gitea web
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
# If you want to bind Gitea to a port below 1024 uncomment
# the two values below
###

View File

@ -124,6 +124,7 @@ UNIX_SOCKET_PERMISSION = 666
; Local (DMZ) URL for Gitea workers (such as SSH update) accessing web service.
; In most cases you do not need to change the default value.
; Alter it only if your SSH server node is not the same as HTTP node.
; Do not set this variable if PROTOCOL is set to 'unix'.
LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
; Disable SSH feature when not available
DISABLE_SSH = false
@ -188,6 +189,8 @@ LFS_START_SERVER = false
LFS_CONTENT_PATH = data/lfs
; LFS authentication secret, change this yourself
LFS_JWT_SECRET =
; LFS authentication validity period (in time.Duration), pushes taking longer than this may fail.
LFS_HTTP_AUTH_EXPIRY = 20m
; Define allowed algorithms and their minimum key length (use -1 to disable a type)
[ssh.minimum_key_sizes]
@ -414,7 +417,7 @@ ENABLE_FEDERATED_AVATAR = false
[attachment]
; Whether attachments are enabled. Defaults to `true`
ENABLE = true
ENABLED = true
; Path for attachments. Defaults to `data/attachments`
PATH = data/attachments
; One or more allowed types, e.g. image/jpeg|image/png
@ -570,28 +573,21 @@ ENABLE_SWAGGER_ENDPOINT = true
MAX_RESPONSE_ITEMS = 50
[i18n]
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
[U2F]
; Two Factor authentication with security keys
; https://developers.yubico.com/U2F/App_ID.html
APP_ID = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
; Comma seperated list of truisted facets
TRUSTED_FACETS = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
; Used for datetimepicker
[i18n.datelang]
en-US = en
zh-CN = zh
zh-HK = zh-TW
zh-HK = zh-HK
zh-TW = zh-TW
de-DE = de
fr-FR = fr
nl-NL = nl
lv-LV = lv
ru-RU = ru
uk-UA = uk
ja-JP = ja
es-ES = es
pt-BR = pt-BR
@ -605,6 +601,13 @@ sr-SP = sr
sv-SE = sv
ko-KR = ko
[U2F]
; Two Factor authentication with security keys
; https://developers.yubico.com/U2F/App_ID.html
APP_ID = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
; Comma seperated list of truisted facets
TRUSTED_FACETS = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s
; Extension mapping to highlight class
; e.g. .toml=ini
[highlight.mapping]

View File

@ -35,6 +35,8 @@ if [ ! -f /data/gitea/conf/app.ini ]; then
DB_USER=${DB_USER:-"root"} \
DB_PASSWD=${DB_PASSWD:-""} \
INSTALL_LOCK=${INSTALL_LOCK:-"false"} \
DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-"false"} \
REQUIRE_SIGNIN_VIEW=${REQUIRE_SIGNIN_VIEW:-"false"} \
SECRET_KEY=${SECRET_KEY:-""} \
envsubst < /etc/templates/app.ini > /data/gitea/conf/app.ini
fi

View File

@ -38,3 +38,7 @@ ROOT_PATH = /data/gitea/log
[security]
INSTALL_LOCK = $INSTALL_LOCK
SECRET_KEY = $SECRET_KEY
[service]
DISABLE_REGISTRATION = $DISABLE_REGISTRATION
REQUIRE_SIGNIN_VIEW = $REQUIRE_SIGNIN_VIEW

View File

@ -95,6 +95,11 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
- `UNIX_SOCKET_PERMISSION`: **666**: Permissions for the Unix socket.
- `LOCAL_ROOT_URL`: **%(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/**: Local
(DMZ) URL for Gitea workers (such as SSH update) accessing web service. In
most cases you do not need to change the default value. Alter it only if
your SSH server node is not the same as HTTP node. Do not set this variable
if `PROTOCOL` is set to `unix`.
- `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
- `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server.
- `SSH_DOMAIN`: **%(DOMAIN)s**: Domain name of this server, used for displayed clone URL.
@ -110,6 +115,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `LFS_START_SERVER`: **false**: Enables git-lfs support.
- `LFS_CONTENT_PATH`: **./data/lfs**: Where to store LFS files.
- `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string.
- `LFS_HTTP_AUTH_EXPIRY`: **20m**: LFS authentication validity period in time.Duration, pushes taking longer than this may fail.
- `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, redirects http requests
on another (https) port.
- `PORT_TO_REDIRECT`: **80**: Port used when `REDIRECT_OTHER_PORT` is true.
@ -145,6 +151,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
authentication.
- `DISABLE_GIT_HOOKS`: **false**: Prevent all users (including admin) from creating custom
git hooks.
- `IMPORT_LOCAL_PATHS`: **false**: Prevent all users (including admin) from importing local path on server.
## OpenID (`openid`)
@ -273,6 +280,41 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
- `MAX_GIT_DIFF_FILES`: **100**: Max number of files shown in diff view.
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`.
## API (`api`)
- `ENABLE_SWAGGER_ENDPOINT`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true.
- `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page
## i18n (`i18n`)
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
### i18n - Datepicker Language (`i18n.datelang`)
Maps locales to the languages used by the datepicker plugin
- `en-US`: **en**
- `zh-CN`: **zh**
- `zh-HK`: **zh-HK**
- `zh-TW`: **zh-TW**
- `de-DE`: **de**
- `fr-FR`: **fr**
- `nl-NL`: **nl**
- `lv-LV`: **lv**
- `ru-RU`: **ru**
- `ja-JP`: **ja**
- `es-ES`: **es**
- `pt-BR`: **pt-BR**
- `pl-PL`: **pl**
- `bg-BG`: **bg**
- `it-IT`: **it**
- `fi-FI`: **fi**
- `tr-TR`: **tr**
- `cs-CZ`: **cs-CZ**
- `sr-SP`: **sr**
- `sv-SE`: **sv**
- `ko-KR`: **ko**
## U2F (`U2F`)
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application. Requires HTTPS.
- `TRUSTED_FACETS`: List of additional facets which are trusted. This is not support by all browsers.

View File

@ -37,6 +37,7 @@ _Symbols used in table:_
<td>GitLab CE</td>
<td>GitLab EE</td>
<td>BitBucket</td>
<td>RhodeCode CE</td>
</tr>
</thead>
<tbody>
@ -48,6 +49,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Issue tracker</td>
@ -57,6 +59,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Pull/Merge requests</td>
@ -66,6 +69,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Squash merging</td>
@ -75,6 +79,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Rebase merging</td>
@ -84,6 +89,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Pull/Merge request inline comments</td>
@ -93,6 +99,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Pull/Merge request approval</td>
@ -102,6 +109,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Merge conflict resolution</td>
@ -111,6 +119,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Restrict push and merge access to certain users</td>
@ -120,6 +129,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Markdown support</td>
@ -129,6 +139,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Issues and pull/merge requests templates</td>
@ -138,6 +149,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Revert specific commits or a merge request</td>
@ -147,6 +159,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Labels</td>
@ -156,6 +169,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Time tracking</td>
@ -165,6 +179,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Multiple assignees for issues</td>
@ -174,6 +189,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Related issues</td>
@ -183,6 +199,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Confidential issues</td>
@ -192,6 +209,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Comment reactions</td>
@ -201,6 +219,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Lock Discussion</td>
@ -210,6 +229,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Batch issue handling</td>
@ -219,6 +239,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Issue Boards</td>
@ -228,6 +249,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Create new branches from issues</td>
@ -237,6 +259,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Commit graph</td>
@ -246,6 +269,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Web code editor</td>
@ -255,6 +279,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Branch manager</td>
@ -264,6 +289,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Create new branches</td>
@ -273,6 +299,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Repository topics</td>
@ -282,6 +309,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Repository code search</td>
@ -291,6 +319,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Global code search</td>
@ -300,6 +329,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Issue search</td>
@ -309,6 +339,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Global issue search</td>
@ -318,6 +349,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Git LFS 2.0</td>
@ -327,6 +359,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Integrated Git-powered wiki</td>
@ -336,6 +369,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Static Git-powered pages</td>
@ -345,6 +379,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Group Milestones</td>
@ -354,6 +389,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Granular user roles (Code, Issues, Wiki etc)</td>
@ -363,6 +399,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Cherry-picking changes</td>
@ -372,6 +409,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>GPG Signed Commits</td>
@ -381,6 +419,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Reject unsigned commits</td>
@ -390,6 +429,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Verified Committer</td>
@ -399,6 +439,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Subgroups: groups within groups</td>
@ -408,6 +449,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Custom Git Hooks</td>
@ -417,6 +459,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Repository Activity page</td>
@ -426,6 +469,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Deploy Tokens</td>
@ -435,6 +479,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Repository Tokens with write rights</td>
@ -444,6 +489,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Easy upgrade process</td>
@ -453,6 +499,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Built-in Container Registry</td>
@ -462,6 +509,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>External git mirroring</td>
@ -471,6 +519,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>AD / LDAP integration</td>
@ -480,6 +529,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Multiple LDAP / AD server support</td>
@ -489,6 +539,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>LDAP user synchronization</td>
@ -498,6 +549,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>OpenId Connect support</td>
@ -507,6 +559,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td>?</td>
<td></td>
</tr>
<tr>
<td>OAuth 2.0 integration (external authorization)</td>
@ -516,6 +569,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td>?</td>
<td></td>
</tr>
<tr>
<td>Act as OAuth 2.0 provider</td>
@ -525,6 +579,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Two factor authentication (2FA)</td>
@ -534,6 +589,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>FIDO U2F (2FA)</td>
@ -543,6 +599,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Webhook support</td>
@ -552,6 +609,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Mattermost/Slack integration</td>
@ -561,6 +619,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Discord integration</td>
@ -570,6 +629,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Built-in CI/CD</td>
@ -579,6 +639,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>External CI/CD status display</td>
@ -588,6 +649,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Multiple database support</td>
@ -597,6 +659,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Multiple OS support</td>
@ -606,6 +669,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Low resource usage (RAM/CPU)</td>
@ -615,6 +679,7 @@ _Symbols used in table:_
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>

View File

@ -1,5 +1,5 @@
---
date: "2017-01-20T15:00:00+08:00"
date: "2018-05-21T15:00:00+00:00"
title: "Support Options"
slug: "seek-help"
weight: 10
@ -16,8 +16,7 @@ menu:
# Support Options
- [Discord](https://discord.gg/NsatcWJ)
- [#gitea on Freenode](http://webchat.freenode.net?nick=giteachat....&channels=%23gitea&prompt=1)
- [Matrix](https://matrix.to/#/#gitea-dev:matrix.org)
- [Discourse Forum](https://discourse.gitea.io/)
## Bugs

View File

@ -20,8 +20,8 @@ embedded assets. This can be different for older releases. Choose the file match
the destination platform from the [downloads page](https://dl.gitea.io/gitea), copy
the URL and replace the URL within the commands below:
```
wget -O gitea https://dl.gitea.io/gitea/1.3.2/gitea-1.3.2-linux-amd64
```sh
wget -O gitea https://dl.gitea.io/gitea/1.4.2/gitea-1.4.2-linux-amd64
chmod +x gitea
```
@ -34,6 +34,54 @@ location. When launched manually, Gitea can be killed using `Ctrl+C`.
./gitea web
```
## Recommended server configuration
### Prepare environment
Check that git is installed on the server, if it is not install it first.
```sh
git --version
```
Create user to run gitea (ex. `git`)
```sh
adduser \
--system \
--shell /bin/bash \
--gecos 'Git Version Control' \
--group \
--disabled-password \
--home /home/git \
git
```
### Create required directory structure
```sh
mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
chown git:git /var/lib/gitea/{data,indexers,log}
chmod 750 /var/lib/gitea/{data,indexers,log}
mkdir /etc/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea
```
**NOTE:** `/etc/gitea` is temporary set with write rights for user `git` so that Web installer could write configuration file. After installation is done it is recommended to set rights to read-only using:
```
chmod 750 /etc/gitea
chmod 644 /etc/gitea/app.ini
```
### Copy gitea binary to global location
```
cp gitea /usr/local/bin/gitea
```
### Create service file to start gitea automatically
See how to create [Linux service]({{< relref "run-as-service-in-ubuntu.en-us.md" >}})
## Troubleshooting
### Old glibc versions

View File

@ -17,16 +17,13 @@ menu:
## Debian
The only distribution that has any "official" package of Gitea is Debian. This is currently
in Debian's [contrib](https://wiki.debian.org/SourcesList). This is (currently) only available
in Debian testing and unstable (but should be installable/functional on stable).
Although there is a package of Gitea in Debian's [contrib](https://wiki.debian.org/SourcesList),
it is not supported directly by us.
- Edit /etc/apt/sourced.list
- Add "contrib" to "deb http://deb.debian.org/debian unstable main contrib"
- apt-get update
- apt-get install gitea
Unfortunately the package is not maintained anymore and broken because of missing sources.
Please follow the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide instead.
For other distributions, see the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide.
Should the packages get updated and fixed, we will provide up-to-date installation instructions here.
## Windows

View File

@ -231,7 +231,7 @@ You can configure some of Gitea's settings via environment variables:
* `APP_NAME`: **"Gitea: Git with a cup of tea"**: Application name, used in the page title.
* `RUN_MODE`: **dev**: For performance and other purposes, change this to `prod` when deployed to a production environment.
* `SSH_DOMAIN`: **localhost**: Domain name of this server, used for displayed clone UR in Gitea's UI.
* `SSH_DOMAIN`: **localhost**: Domain name of this server, used for the displayed clone URL in Gitea's UI.
* `SSH_PORT`: **22**: SSH port displayed in clone URL.
* `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
* `HTTP_PORT`: **3000**: HTTP listen port.
@ -243,6 +243,8 @@ You can configure some of Gitea's settings via environment variables:
* `DB_PASSWD`: **"<empty>"**: Database user password. Use \`your password\` for quoting if you use special characters in the password.
* `INSTALL_LOCK`: **false**: Disallow access to the install page.
* `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`.
* `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create accounts for users.
* `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page.
# Customization

View File

@ -0,0 +1,46 @@
---
date: "2018-06-02T11:00:00+02:00"
title: "Usage: HTTPS setup"
slug: "https-setup"
weight: 12
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "HTTPS setup"
weight: 12
identifier: "https-setup"
---
# HTTPS setup to encrypt connections to Gitea
## Using built-in server
Before you enable HTTPS make sure that you have valid SSL/TLS certificates.
You could use self-generated certificates for evaluation and testing. Please run `gitea cert --host [HOST]` to generate a self signed certificate.
To use Gitea's built-in HTTPS support you must change your `app.ini` file:
```ini
[server]
PROTOCOL=https
ROOT_URL = `https://git.example.com:3000/`
HTTP_PORT = 3000
CERT_FILE = cert.pem
KEY_FILE = key.pem
```
To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).
## Using reverse proxy
Setup up your reverse proxy like shown in the [reverse proxy guide](../reverse-proxies).
After that, enable HTTPS by following one of these guides:
* [nginx](https://nginx.org/en/docs/http/configuring_https_servers.html)
* [apache2/httpd](https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html)
* [caddy](https://caddyserver.com/docs/tls)
Note: You connection between your reverse proxy and gitea might be unencrypted. To encrypt it too follow the [built-in server guide](#using-built-in-server) and change
the proxy url to `https://[URL]`.

View File

@ -0,0 +1,104 @@
---
date: "2018-05-22T11:00:00+00:00"
title: "Usage: Reverse Proxies"
slug: "reverse-proxies"
weight: 17
toc: true
draft: false
menu:
sidebar:
parent: "usage"
name: "Reverse Proxies"
weight: 16
identifier: "reverse-proxies"
---
## Using Nginx as a reverse proxy
If you want Nginx to serve your Gitea instance you can the following `server` section inside the `http` section of `nginx.conf`:
```
server {
listen 80;
server_name git.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
```
## Using Nginx with a Sub-path as a reverse proxy
In case you already have a site, and you want Gitea to share the domain name, you can setup Nginx to serve Gitea under a sub-path by adding the following `server` section inside the `http` section of `nginx.conf`:
```
server {
listen 80;
server_name git.example.com;
location /git/ { # Note: Trailing slash
proxy_pass http://localhost:3000/; # Note: Trailing slash
}
}
```
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.
## Using Apache HTTPD as a reverse proxy
If you want Apache HTTPD to serve your Gitea instance you can add the following to you Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):
```
<VirtualHost *:80>
...
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</VirtualHost>
```
Note: The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`
## Using Apache HTTPD with a Sub-path as a reverse proxy
In case you already have a site, and you want Gitea to share the domain name, you can setup Apache HTTPD to serve Gitea under a sub-path by adding the following to you Apache HTTPD configuration (usually located at `/etc/apache2/httpd.conf` in Ubuntu):
```
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /git http://localhost:3000 # Note: no trailing slash after either /git or port
ProxyPassReverse /git http://localhost:3000 # Note: no trailing slash after either /git or port
</VirtualHost>
```
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.
Note: The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`
## Using Caddy with a Sub-path as a reverse proxy
If you want Caddy to serve your Gitea instance you can add the following server block to your Caddyfile:
```
git.example.com {
proxy / http://localhost:3000
}
```
## Using Caddy with a Sub-path as a reverse proxy
In case you already have a site, and you want Gitea to share the domain name, you can setup Caddy to serve Gitea under a sub-path by adding the following to you server block in your Caddyfile:
```
git.example.com {
proxy /git/ http://localhost:3000 # Note: Trailing Slash after /git/
}
```
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.

View File

@ -40,7 +40,11 @@ var gitLDAPUsers = []ldapUser{
Password: "hermes",
FullName: "Conrad Hermes",
Email: "hermes@planetexpress.com",
IsAdmin: true,
SSHKeys: []string{
"SHA256:qLY06smKfHoW/92yXySpnxFR10QFrLdRjf/GNPvwcW8",
"SHA256:QlVTuM5OssDatqidn2ffY+Lc4YA5Fs78U+0KOHI51jQ",
},
IsAdmin: true,
},
{
UserName: "fry",
@ -89,26 +93,27 @@ func getLDAPServerHost() string {
return host
}
func addAuthSourceLDAP(t *testing.T) {
func addAuthSourceLDAP(t *testing.T, sshKeyAttribute string) {
session := loginUser(t, "user1")
csrf := GetCSRF(t, session, "/admin/auths/new")
req := NewRequestWithValues(t, "POST", "/admin/auths/new", map[string]string{
"_csrf": csrf,
"type": "2",
"name": "ldap",
"host": getLDAPServerHost(),
"port": "389",
"bind_dn": "uid=gitea,ou=service,dc=planetexpress,dc=com",
"bind_password": "password",
"user_base": "ou=people,dc=planetexpress,dc=com",
"filter": "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))",
"admin_filter": "(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)",
"attribute_username": "uid",
"attribute_name": "givenName",
"attribute_surname": "sn",
"attribute_mail": "mail",
"is_sync_enabled": "on",
"is_active": "on",
"_csrf": csrf,
"type": "2",
"name": "ldap",
"host": getLDAPServerHost(),
"port": "389",
"bind_dn": "uid=gitea,ou=service,dc=planetexpress,dc=com",
"bind_password": "password",
"user_base": "ou=people,dc=planetexpress,dc=com",
"filter": "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))",
"admin_filter": "(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)",
"attribute_username": "uid",
"attribute_name": "givenName",
"attribute_surname": "sn",
"attribute_mail": "mail",
"attribute_ssh_public_key": sshKeyAttribute,
"is_sync_enabled": "on",
"is_active": "on",
})
session.MakeRequest(t, req, http.StatusFound)
}
@ -119,7 +124,7 @@ func TestLDAPUserSignin(t *testing.T) {
return
}
prepareTestEnv(t)
addAuthSourceLDAP(t)
addAuthSourceLDAP(t, "")
u := gitLDAPUsers[0]
@ -140,7 +145,7 @@ func TestLDAPUserSync(t *testing.T) {
return
}
prepareTestEnv(t)
addAuthSourceLDAP(t)
addAuthSourceLDAP(t, "")
models.SyncExternalUsers()
session := loginUser(t, "user1")
@ -186,9 +191,41 @@ func TestLDAPUserSigninFailed(t *testing.T) {
return
}
prepareTestEnv(t)
addAuthSourceLDAP(t)
addAuthSourceLDAP(t, "")
u := otherLDAPUsers[0]
testLoginFailed(t, u.UserName, u.Password, i18n.Tr("en", "form.username_password_incorrect"))
}
func TestLDAPUserSSHKeySync(t *testing.T) {
if skipLDAPTests() {
t.Skip()
return
}
prepareTestEnv(t)
addAuthSourceLDAP(t, "sshPublicKey")
models.SyncExternalUsers()
// Check if users has SSH keys synced
for _, u := range gitLDAPUsers {
if len(u.SSHKeys) == 0 {
continue
}
session := loginUserWithPassword(t, u.UserName, u.Password)
req := NewRequest(t, "GET", "/user/settings/keys")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
divs := htmlDoc.doc.Find(".key.list .print.meta")
syncedKeys := make([]string, divs.Length())
for i := 0; i < divs.Length(); i++ {
syncedKeys[i] = strings.TrimSpace(divs.Eq(i).Text())
}
assert.ElementsMatch(t, u.SSHKeys, syncedKeys)
}
}

View File

@ -370,11 +370,19 @@ func (issue *Issue) HasLabel(labelID int64) bool {
func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
var err error
if err = issue.loadRepo(x); err != nil {
log.Error(4, "loadRepo: %v", err)
return
}
if err = issue.loadPoster(x); err != nil {
log.Error(4, "loadPoster: %v", err)
return
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull {
if err = issue.loadRepo(x); err != nil {
log.Error(4, "loadRepo: %v", err)
return
}
if err = issue.loadPullRequest(x); err != nil {
log.Error(4, "loadPullRequest: %v", err)
return
@ -390,6 +398,14 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueLabelUpdated,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
}
if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
@ -505,6 +521,11 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
return fmt.Errorf("Commit: %v", err)
}
if err = issue.loadPoster(x); err != nil {
return fmt.Errorf("loadPoster: %v", err)
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull {
err = issue.PullRequest.LoadIssue()
if err != nil {
@ -515,9 +536,17 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
Action: api.HookIssueLabelCleared,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueLabelCleared,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
}
if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
@ -689,13 +718,14 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
return fmt.Errorf("Commit: %v", err)
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull {
// Merge pull request calls issue.changeStatus so we need to handle separately.
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: repo.APIFormat(AccessModeNone),
Repository: repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if isClosed {
@ -704,6 +734,19 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
apiPullRequest.Action = api.HookIssueReOpened
}
err = PrepareWebhooks(repo, HookEventPullRequest, apiPullRequest)
} else {
apiIssue := &api.IssuePayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if isClosed {
apiIssue.Action = api.HookIssueClosed
} else {
apiIssue.Action = api.HookIssueReOpened
}
err = PrepareWebhooks(repo, HookEventIssues, apiIssue)
}
if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
@ -737,6 +780,7 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
return err
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull {
issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
@ -748,10 +792,24 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
},
},
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Title: &api.ChangesFromPayload{
From: oldTitle,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: issue.Poster.APIFormat(),
})
}
if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else {
@ -788,6 +846,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return fmt.Errorf("UpdateIssueCols: %v", err)
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if issue.IsPull {
issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
@ -799,9 +858,22 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
},
},
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited,
Index: issue.Index,
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
From: oldContent,
},
},
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
})
}
if err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
@ -994,6 +1066,19 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []in
log.Error(4, "MailParticipants: %v", err)
}
mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
if err = PrepareWebhooks(repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueOpened,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormat(mode),
Sender: issue.Poster.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(issue.RepoID)
}
return nil
}

View File

@ -159,12 +159,16 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
return fmt.Errorf("createAssigneeComment: %v", err)
}
mode, _ := accessLevel(sess, doer.ID, issue.Repo)
if issue.IsPull {
issue.PullRequest = &PullRequest{Issue: issue}
if err = issue.loadPullRequest(sess); err != nil {
return fmt.Errorf("loadPullRequest: %v", err)
}
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if removed {
@ -172,7 +176,23 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
} else {
apiPullRequest.Action = api.HookIssueAssigned
}
if err := PrepareWebhooks(issue.Repo, HookEventPullRequest, apiPullRequest); err != nil {
if err := prepareWebhooks(sess, issue.Repo, HookEventPullRequest, apiPullRequest); err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return nil
}
} else {
apiIssue := &api.IssuePayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
}
if removed {
apiIssue.Action = api.HookIssueUnassigned
} else {
apiIssue.Action = api.HookIssueAssigned
}
if err := prepareWebhooks(sess, issue.Repo, HookEventIssues, apiIssue); err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return nil
}

View File

@ -669,6 +669,8 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
Sender: doer.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go HookQueue.Add(repo.ID)
}
return comment, nil
}
@ -811,6 +813,8 @@ func UpdateComment(doer *User, c *Comment, oldContent string) error {
Sender: doer.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err)
} else {
go HookQueue.Add(c.Issue.Repo.ID)
}
return nil
@ -862,6 +866,8 @@ func DeleteComment(doer *User, comment *Comment) error {
Sender: doer.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} else {
go HookQueue.Add(comment.Issue.Repo.ID)
}
return nil

View File

@ -402,6 +402,8 @@ func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err
}
if err != nil {
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
} else {
go HookQueue.Add(issue.RepoID)
}
return nil
}

View File

@ -54,28 +54,30 @@ func newIssueUsers(e Engine, repo *Repository, issue *Issue) error {
func updateIssueAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) {
// Check if the user exists
_, err = GetUserByID(assigneeID)
assignee, err := GetUserByID(assigneeID)
if err != nil {
return false, err
}
// Check if the submitted user is already assigne, if yes delete him otherwise add him
var toBeDeleted bool
for _, assignee := range issue.Assignees {
if assignee.ID == assigneeID {
toBeDeleted = true
var i int
for i = 0; i < len(issue.Assignees); i++ {
if issue.Assignees[i].ID == assigneeID {
break
}
}
assigneeIn := IssueAssignees{AssigneeID: assigneeID, IssueID: issue.ID}
toBeDeleted := i < len(issue.Assignees)
if toBeDeleted {
issue.Assignees = append(issue.Assignees[:i], issue.Assignees[i:]...)
_, err = e.Delete(assigneeIn)
if err != nil {
return toBeDeleted, err
}
} else {
issue.Assignees = append(issue.Assignees, assignee)
_, err = e.Insert(assigneeIn)
if err != nil {
return toBeDeleted, err

View File

@ -185,6 +185,8 @@ var migrations = []Migration{
// v65 -> v66
NewMigration("add u2f", addU2FReg),
// v66 -> v67
NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
// v66 -> v67
NewMigration("add issue_dependencies", addIssueDependencies),
}

View File

@ -1,4 +1,4 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
@ -6,95 +6,17 @@ package migrations
import (
"fmt"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func addIssueDependencies(x *xorm.Engine) (err error) {
type IssueDependency struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL"`
IssueID int64 `xorm:"NOT NULL"`
DependencyID int64 `xorm:"NOT NULL"`
Created time.Time `xorm:"-"`
CreatedUnix int64 `xorm:"INDEX created"`
Updated time.Time `xorm:"-"`
UpdatedUnix int64 `xorm:"updated"`
func addLoginSourceIDToPublicKeyTable(x *xorm.Engine) error {
type PublicKey struct {
LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"`
}
if err = x.Sync(new(IssueDependency)); err != nil {
return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err)
if err := x.Sync2(new(PublicKey)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
// Update Comment definition
// This (copied) struct does only contain fields used by xorm as the only use here is to update the database
// CommentType defines the comment type
type CommentType int
// TimeStamp defines a timestamp
type TimeStamp int64
type Comment struct {
ID int64 `xorm:"pk autoincr"`
Type CommentType
PosterID int64 `xorm:"INDEX"`
IssueID int64 `xorm:"INDEX"`
LabelID int64
OldMilestoneID int64
MilestoneID int64
OldAssigneeID int64
AssigneeID int64
OldTitle string
NewTitle string
DependentIssueID int64
CommitID int64
Line int64
Content string `xorm:"TEXT"`
CreatedUnix TimeStamp `xorm:"INDEX created"`
UpdatedUnix TimeStamp `xorm:"INDEX updated"`
// Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"`
}
if err = x.Sync(new(Comment)); err != nil {
return fmt.Errorf("Error updating issue_comment table column definition: %v", err)
}
// RepoUnit describes all units of a repository
type RepoUnit struct {
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"`
Config map[string]interface{} `xorm:"JSON"`
CreatedUnix int64 `xorm:"INDEX CREATED"`
Created time.Time `xorm:"-"`
}
//Updating existing issue units
units := make([]*RepoUnit, 0, 100)
err = x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
if err != nil {
return fmt.Errorf("Query repo units: %v", err)
}
for _, unit := range units {
if unit.Config == nil {
unit.Config = make(map[string]interface{})
}
if _, ok := unit.Config["EnableDependencies"]; !ok {
unit.Config["EnableDependencies"] = setting.Service.DefaultEnableDependencies
}
if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
return err
}
}
return err
return nil
}

1
models/migrations/v67.go Normal file
View File

@ -0,0 +1 @@
package migrations

View File

@ -457,15 +457,18 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
log.Error(4, "LoadAttributes: %v", err)
return nil
}
mode, _ := AccessLevel(doer.ID, pr.Issue.Repo)
if err = PrepareWebhooks(pr.Issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueClosed,
Index: pr.Index,
PullRequest: pr.APIFormat(),
Repository: pr.Issue.Repo.APIFormat(AccessModeNone),
Repository: pr.Issue.Repo.APIFormat(mode),
Sender: doer.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks: %v", err)
return nil
} else {
go HookQueue.Add(pr.Issue.Repo.ID)
}
l, err := baseGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase)
@ -492,12 +495,14 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
After: mergeCommit.ID.String(),
CompareURL: setting.AppURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID),
Commits: ListToPushCommits(l).ToAPIPayloadCommits(pr.BaseRepo.HTMLURL()),
Repo: pr.BaseRepo.APIFormat(AccessModeNone),
Repo: pr.BaseRepo.APIFormat(mode),
Pusher: pr.HeadRepo.MustOwner().APIFormat(),
Sender: doer.APIFormat(),
}
if err = PrepareWebhooks(pr.BaseRepo, HookEventPush, p); err != nil {
return fmt.Errorf("PrepareWebhooks: %v", err)
log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(pr.BaseRepo.ID)
}
return nil
}
@ -782,16 +787,18 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
pr.Issue = pull
pull.PullRequest = pr
mode, _ := AccessLevel(pull.Poster.ID, repo)
if err = PrepareWebhooks(repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueOpened,
Index: pull.Index,
PullRequest: pr.APIFormat(),
Repository: repo.APIFormat(AccessModeNone),
Repository: repo.APIFormat(mode),
Sender: pull.Poster.APIFormat(),
}); err != nil {
log.Error(4, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(repo.ID)
}
go HookQueue.Add(repo.ID)
return nil
}

View File

@ -207,6 +207,8 @@ func CreateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
Sender: rel.Publisher.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
}
}
@ -371,7 +373,7 @@ func SortReleases(rels []*Release) {
}
// UpdateRelease updates information of a release.
func UpdateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) (err error) {
func UpdateRelease(doer *User, gitRepo *git.Repository, rel *Release, attachmentUUIDs []string) (err error) {
if err = createTag(gitRepo, rel); err != nil {
return err
}
@ -382,8 +384,25 @@ func UpdateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
return err
}
err = rel.loadAttributes(x)
if err != nil {
return err
}
err = addReleaseAttachments(rel.ID, attachmentUUIDs)
mode, _ := accessLevel(x, doer.ID, rel.Repo)
if err1 := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseUpdated,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err1 != nil {
log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
return err
}
@ -429,6 +448,18 @@ func DeleteReleaseByID(id int64, u *User, delTag bool) error {
}
}
mode, _ := accessLevel(x, u.ID, rel.Repo)
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseDeleted,
Release: rel.APIFormat(),
Repository: rel.Repo.APIFormat(mode),
Sender: rel.Publisher.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks: %v", err)
} else {
go HookQueue.Add(rel.Repo.ID)
}
return nil
}

View File

@ -1828,6 +1828,8 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
&PullRequest{BaseRepoID: repoID},
&RepoUnit{RepoID: repoID},
&RepoRedirect{RedirectRepoID: repoID},
&Webhook{RepoID: repoID},
&HookTask{RepoID: repoID},
); err != nil {
return fmt.Errorf("deleteBeans: %v", err)
}
@ -2464,11 +2466,13 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
mode, _ := AccessLevel(doer.ID, repo)
if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{
Forkee: repo.APIFormat(mode),
Repo: oldRepo.APIFormat(oldMode),
Forkee: oldRepo.APIFormat(oldMode),
Repo: repo.APIFormat(mode),
Sender: doer.APIFormat(),
}); err != nil {
log.Error(2, "PrepareWebhooks [repo_id: %d]: %v", oldRepo.ID, err)
} else {
go HookQueue.Add(oldRepo.ID)
}
if err = repo.UpdateSize(); err != nil {

View File

@ -152,6 +152,10 @@ const (
SearchOrderBySizeReverse = "size DESC"
SearchOrderByID = "id ASC"
SearchOrderByIDReverse = "id DESC"
SearchOrderByStars = "num_stars ASC"
SearchOrderByStarsReverse = "num_stars DESC"
SearchOrderByForks = "num_forks ASC"
SearchOrderByForksReverse = "num_forks DESC"
)
// SearchRepositoryByName takes keyword and part of repository name to search,

View File

@ -47,13 +47,14 @@ const (
// PublicKey represents a user or deploy SSH public key.
type PublicKey struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"NOT NULL"`
Content string `xorm:"TEXT NOT NULL"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 2"`
Type KeyType `xorm:"NOT NULL DEFAULT 1"`
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"NOT NULL"`
Content string `xorm:"TEXT NOT NULL"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 2"`
Type KeyType `xorm:"NOT NULL DEFAULT 1"`
LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"`
UpdatedUnix util.TimeStamp `xorm:"updated"`
@ -391,7 +392,7 @@ func addKey(e Engine, key *PublicKey) (err error) {
}
// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(ownerID int64, name, content string) (*PublicKey, error) {
func AddPublicKey(ownerID int64, name, content string, LoginSourceID int64) (*PublicKey, error) {
log.Trace(content)
fingerprint, err := calcFingerprint(content)
@ -420,12 +421,13 @@ func AddPublicKey(ownerID int64, name, content string) (*PublicKey, error) {
}
key := &PublicKey{
OwnerID: ownerID,
Name: name,
Fingerprint: fingerprint,
Content: content,
Mode: AccessModeWrite,
Type: KeyTypeUser,
OwnerID: ownerID,
Name: name,
Fingerprint: fingerprint,
Content: content,
Mode: AccessModeWrite,
Type: KeyTypeUser,
LoginSourceID: LoginSourceID,
}
if err = addKey(sess, key); err != nil {
return nil, fmt.Errorf("addKey: %v", err)
@ -471,6 +473,14 @@ func ListPublicKeys(uid int64) ([]*PublicKey, error) {
Find(&keys)
}
// ListPublicLdapSSHKeys returns a list of synchronized public ldap ssh keys belongs to given user and login source.
func ListPublicLdapSSHKeys(uid int64, LoginSourceID int64) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 5)
return keys, x.
Where("owner_id = ? AND login_source_id = ?", uid, LoginSourceID).
Find(&keys)
}
// UpdatePublicKeyUpdated updates public key use time.
func UpdatePublicKeyUpdated(id int64) error {
// Check if key exists before update as affected rows count is unreliable

View File

@ -1272,7 +1272,7 @@ func GetUser(user *User) (bool, error) {
type SearchUserOptions struct {
Keyword string
Type UserType
OrderBy string
OrderBy SearchOrderBy
Page int
PageSize int // Can be smaller than or equal to setting.UI.ExplorePagingNum
IsActive util.OptionalBool
@ -1322,7 +1322,7 @@ func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) {
users = make([]*User, 0, opts.PageSize)
return users, count, x.Where(cond).
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
OrderBy(opts.OrderBy).
OrderBy(opts.OrderBy.String()).
Find(&users)
}
@ -1356,6 +1356,119 @@ func GetWatchedRepos(userID int64, private bool) ([]*Repository, error) {
return repos, nil
}
// deleteKeysMarkedForDeletion returns true if ssh keys needs update
func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
// Start session
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return false, err
}
// Delete keys marked for deletion
var sshKeysNeedUpdate bool
for _, KeyToDelete := range keys {
key, err := SearchPublicKeyByContent(KeyToDelete)
if err != nil {
log.Error(4, "SearchPublicKeyByContent: %v", err)
continue
}
if err = deletePublicKeys(sess, key.ID); err != nil {
log.Error(4, "deletePublicKeys: %v", err)
continue
}
sshKeysNeedUpdate = true
}
if err := sess.Commit(); err != nil {
return false, err
}
return sshKeysNeedUpdate, nil
}
func addLdapSSHPublicKeys(s *LoginSource, usr *User, SSHPublicKeys []string) bool {
var sshKeysNeedUpdate bool
for _, sshKey := range SSHPublicKeys {
if strings.HasPrefix(strings.ToLower(sshKey), "ssh") {
sshKeyName := fmt.Sprintf("%s-%s", s.Name, sshKey[0:40])
if _, err := AddPublicKey(usr.ID, sshKeyName, sshKey, s.ID); err != nil {
log.Error(4, "addLdapSSHPublicKeys[%s]: Error adding LDAP Public SSH Key for user %s: %v", s.Name, usr.Name, err)
} else {
log.Trace("addLdapSSHPublicKeys[%s]: Added LDAP Public SSH Key for user %s", s.Name, usr.Name)
sshKeysNeedUpdate = true
}
} else {
log.Warn("addLdapSSHPublicKeys[%s]: Skipping invalid LDAP Public SSH Key for user %s: %v", s.Name, usr.Name, sshKey)
}
}
return sshKeysNeedUpdate
}
func synchronizeLdapSSHPublicKeys(s *LoginSource, SSHPublicKeys []string, usr *User) bool {
var sshKeysNeedUpdate bool
log.Trace("synchronizeLdapSSHPublicKeys[%s]: Handling LDAP Public SSH Key synchronization for user %s", s.Name, usr.Name)
// Get Public Keys from DB with current LDAP source
var giteaKeys []string
keys, err := ListPublicLdapSSHKeys(usr.ID, s.ID)
if err != nil {
log.Error(4, "synchronizeLdapSSHPublicKeys[%s]: Error listing LDAP Public SSH Keys for user %s: %v", s.Name, usr.Name, err)
}
for _, v := range keys {
giteaKeys = append(giteaKeys, v.OmitEmail())
}
// Get Public Keys from LDAP and skip duplicate keys
var ldapKeys []string
for _, v := range SSHPublicKeys {
ldapKey := strings.Join(strings.Split(v, " ")[:2], " ")
if !util.ExistsInSlice(ldapKey, ldapKeys) {
ldapKeys = append(ldapKeys, ldapKey)
}
}
// Check if Public Key sync is needed
if util.IsEqualSlice(giteaKeys, ldapKeys) {
log.Trace("synchronizeLdapSSHPublicKeys[%s]: LDAP Public Keys are already in sync for %s (LDAP:%v/DB:%v)", s.Name, usr.Name, len(ldapKeys), len(giteaKeys))
return false
}
log.Trace("synchronizeLdapSSHPublicKeys[%s]: LDAP Public Key needs update for user %s (LDAP:%v/DB:%v)", s.Name, usr.Name, len(ldapKeys), len(giteaKeys))
// Add LDAP Public SSH Keys that doesn't already exist in DB
var newLdapSSHKeys []string
for _, LDAPPublicSSHKey := range ldapKeys {
if !util.ExistsInSlice(LDAPPublicSSHKey, giteaKeys) {
newLdapSSHKeys = append(newLdapSSHKeys, LDAPPublicSSHKey)
}
}
if addLdapSSHPublicKeys(s, usr, newLdapSSHKeys) {
sshKeysNeedUpdate = true
}
// Mark LDAP keys from DB that doesn't exist in LDAP for deletion
var giteaKeysToDelete []string
for _, giteaKey := range giteaKeys {
if !util.ExistsInSlice(giteaKey, ldapKeys) {
log.Trace("synchronizeLdapSSHPublicKeys[%s]: Marking LDAP Public SSH Key for deletion for user %s: %v", s.Name, usr.Name, giteaKey)
giteaKeysToDelete = append(giteaKeysToDelete, giteaKey)
}
}
// Delete LDAP keys from DB that doesn't exist in LDAP
needUpd, err := deleteKeysMarkedForDeletion(giteaKeysToDelete)
if err != nil {
log.Error(4, "synchronizeLdapSSHPublicKeys[%s]: Error deleting LDAP Public SSH Keys marked for deletion for user %s: %v", s.Name, usr.Name, err)
}
if needUpd {
sshKeysNeedUpdate = true
}
return sshKeysNeedUpdate
}
// SyncExternalUsers is used to synchronize users with external authorization source
func SyncExternalUsers() {
if !taskStatusTable.StartIfNotRunning(syncExternalUsers) {
@ -1377,10 +1490,13 @@ func SyncExternalUsers() {
if !s.IsActived || !s.IsSyncEnabled {
continue
}
if s.IsLDAP() {
log.Trace("Doing: SyncExternalUsers[%s]", s.Name)
var existingUsers []int64
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(s.LDAP().AttributeSSHPublicKey)) > 0
var sshKeysNeedUpdate bool
// Find all users with this login type
var users []User
@ -1389,7 +1505,6 @@ func SyncExternalUsers() {
Find(&users)
sr := s.LDAP().SearchEntries()
for _, su := range sr {
if len(su.Username) == 0 {
continue
@ -1426,11 +1541,23 @@ func SyncExternalUsers() {
}
err = CreateUser(usr)
if err != nil {
log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err)
} else if isAttributeSSHPublicKeySet {
log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", s.Name, usr.Name)
if addLdapSSHPublicKeys(s, usr, su.SSHPublicKey) {
sshKeysNeedUpdate = true
}
}
} else if updateExisting {
existingUsers = append(existingUsers, usr.ID)
// Synchronize SSH Public Key if that attribute is set
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(s, su.SSHPublicKey, usr) {
sshKeysNeedUpdate = true
}
// Check if user data has changed
if (len(s.LDAP().AdminFilter) > 0 && usr.IsAdmin != su.IsAdmin) ||
strings.ToLower(usr.Email) != strings.ToLower(su.Mail) ||
@ -1455,6 +1582,11 @@ func SyncExternalUsers() {
}
}
// Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed
if sshKeysNeedUpdate {
RewriteAllPublicKeys()
}
// Deactivate users not present in LDAP
if updateExisting {
for _, usr := range users {

View File

@ -494,7 +494,14 @@ func (t *HookTask) AfterLoad() {
t.RequestInfo = &HookRequest{}
if err := json.Unmarshal([]byte(t.RequestContent), t.RequestInfo); err != nil {
log.Error(3, "Unmarshal[%d]: %v", t.ID, err)
log.Error(3, "Unmarshal RequestContent[%d]: %v", t.ID, err)
}
if len(t.ResponseContent) > 0 {
t.ResponseInfo = &HookResponse{}
if err := json.Unmarshal([]byte(t.ResponseContent), t.ResponseInfo); err != nil {
log.Error(3, "Unmarshal ResponseContent[%d]: %v", t.ID, err)
}
}
}
@ -665,6 +672,10 @@ func (t *HookTask) deliver() {
log.Trace("Hook delivery failed: %s", t.UUID)
}
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err)
}
// Update webhook last delivery status.
w, err := GetWebhookByID(t.HookID)
if err != nil {
@ -717,10 +728,6 @@ func DeliverHooks() {
// Update hook task status.
for _, t := range tasks {
t.deliver()
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err)
}
}
// Start listening on new hook requests.
@ -741,10 +748,6 @@ func DeliverHooks() {
}
for _, t := range tasks {
t.deliver()
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err)
continue
}
}
}
}

View File

@ -43,7 +43,7 @@ func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) {
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: fmt.Sprintf("view branch %s", refName),
SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName,
},
}, nil
@ -60,7 +60,7 @@ func getDingtalkDeletePayload(p *api.DeletePayload) (*DingtalkPayload, error) {
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: fmt.Sprintf("view branch %s", refName),
SingleTitle: fmt.Sprintf("view ref %s", refName),
SingleURL: p.Repo.HTMLURL + "/src/" + refName,
},
}, nil
@ -153,23 +153,30 @@ func getDingtalkIssuesPayload(p *api.IssuePayload) (*DingtalkPayload, error) {
title = fmt.Sprintf("[%s] Issue unassigned: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueLabelUpdated:
title = fmt.Sprintf("[%s] Pull request labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
title = fmt.Sprintf("[%s] Issue labels updated: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueLabelCleared:
title = fmt.Sprintf("[%s] Pull request labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
title = fmt.Sprintf("[%s] Issue labels cleared: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueSynchronized:
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
}
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: text,
Text: title + "\r\n\r\n" + text,
//Markdown: "# " + title + "\n" + text,
Title: title,
HideAvatar: "0",
SingleTitle: "view pull request",
SingleTitle: "view issue",
SingleURL: p.Issue.URL,
},
}, nil
@ -195,10 +202,10 @@ func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) (*DingtalkPayloa
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: content,
Text: title + "\r\n\r\n" + content,
Title: title,
HideAvatar: "0",
SingleTitle: "view pull request",
SingleTitle: "view issue comment",
SingleURL: url,
},
}, nil
@ -243,12 +250,19 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload,
case api.HookIssueSynchronized:
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Pull request clear milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
}
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: text,
Text: title + "\r\n\r\n" + text,
//Markdown: "# " + title + "\n" + text,
Title: title,
HideAvatar: "0",
SingleTitle: "view pull request",
@ -300,7 +314,34 @@ func getDingtalkReleasePayload(p *api.ReleasePayload) (*DingtalkPayload, error)
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view repository",
SingleTitle: "view release",
SingleURL: url,
},
}, nil
case api.HookReleaseUpdated:
title = fmt.Sprintf("[%s] Release updated", p.Release.TagName)
url = p.Release.URL
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view release",
SingleURL: url,
},
}, nil
case api.HookReleaseDeleted:
title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName)
url = p.Release.URL
return &DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: title,
Title: title,
HideAvatar: "0",
SingleTitle: "view release",
SingleURL: url,
},
}, nil

View File

@ -251,6 +251,14 @@ func getDiscordIssuesPayload(p *api.IssuePayload, meta *DiscordMeta) (*DiscordPa
title = fmt.Sprintf("[%s] Issue synchronized: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
color = warnColor
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Issue milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
color = warnColor
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Issue clear milestone: #%d %s", p.Repository.FullName, p.Index, p.Issue.Title)
text = p.Issue.Body
color = warnColor
}
return &DiscordPayload{
@ -362,6 +370,14 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta)
title = fmt.Sprintf("[%s] Pull request synchronized: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
color = warnColor
case api.HookIssueMilestoned:
title = fmt.Sprintf("[%s] Pull request milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
color = warnColor
case api.HookIssueDemilestoned:
title = fmt.Sprintf("[%s] Pull request clear milestone: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
text = p.PullRequest.Body
color = warnColor
}
return &DiscordPayload{
@ -422,6 +438,14 @@ func getDiscordReleasePayload(p *api.ReleasePayload, meta *DiscordMeta) (*Discor
title = fmt.Sprintf("[%s] Release created", p.Release.TagName)
url = p.Release.URL
color = successColor
case api.HookReleaseUpdated:
title = fmt.Sprintf("[%s] Release updated", p.Release.TagName)
url = p.Release.URL
color = successColor
case api.HookReleaseDeleted:
title = fmt.Sprintf("[%s] Release deleted", p.Release.TagName)
url = p.Release.URL
color = successColor
}
return &DiscordPayload{

View File

@ -213,7 +213,17 @@ func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (
func getSlackReleasePayload(p *api.ReleasePayload, slack *SlackMeta) (*SlackPayload, error) {
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
refLink := SlackLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName)
text := fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName)
var text string
switch p.Action {
case api.HookReleasePublished:
text = fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName)
case api.HookReleaseUpdated:
text = fmt.Sprintf("[%s] new release %s updated by %s", repoLink, refLink, p.Sender.UserName)
case api.HookReleaseDeleted:
text = fmt.Sprintf("[%s] new release %s deleted by %s", repoLink, refLink, p.Sender.UserName)
}
return &SlackPayload{
Channel: slack.Channel,
Text: text,

View File

@ -24,6 +24,7 @@ type AuthenticationForm struct {
AttributeName string
AttributeSurname string
AttributeMail string
AttributeSSHPublicKey string
AttributesInBind bool
UsePagedSearch bool
SearchPageSize int

View File

@ -28,33 +28,35 @@ const (
// Source Basic LDAP authentication service
type Source struct {
Name string // canonical name (ie. corporate.ad)
Host string // LDAP host
Port int // port number
SecurityProtocol SecurityProtocol
SkipVerify bool
BindDN string // DN to bind with
BindPassword string // Bind DN password
UserBase string // Base search path for users
UserDN string // Template for the DN of the user for simple auth
AttributeUsername string // Username attribute
AttributeName string // First name attribute
AttributeSurname string // Surname attribute
AttributeMail string // E-mail attribute
AttributesInBind bool // fetch attributes in bind context (not user)
SearchPageSize uint32 // Search with paging page size
Filter string // Query filter to validate entry
AdminFilter string // Query filter to check if user is admin
Enabled bool // if this source is disabled
Name string // canonical name (ie. corporate.ad)
Host string // LDAP host
Port int // port number
SecurityProtocol SecurityProtocol
SkipVerify bool
BindDN string // DN to bind with
BindPassword string // Bind DN password
UserBase string // Base search path for users
UserDN string // Template for the DN of the user for simple auth
AttributeUsername string // Username attribute
AttributeName string // First name attribute
AttributeSurname string // Surname attribute
AttributeMail string // E-mail attribute
AttributesInBind bool // fetch attributes in bind context (not user)
AttributeSSHPublicKey string // LDAP SSH Public Key attribute
SearchPageSize uint32 // Search with paging page size
Filter string // Query filter to validate entry
AdminFilter string // Query filter to check if user is admin
Enabled bool // if this source is disabled
}
// SearchResult : user data
type SearchResult struct {
Username string // Username
Name string // Name
Surname string // Surname
Mail string // E-mail address
IsAdmin bool // if user is administrator
Username string // Username
Name string // Name
Surname string // Surname
Mail string // E-mail address
SSHPublicKey []string // SSH Public Key
IsAdmin bool // if user is administrator
}
func (ls *Source) sanitizedUserQuery(username string) (string, bool) {
@ -298,10 +300,10 @@ func (ls *Source) SearchEntries() []*SearchResult {
userFilter := fmt.Sprintf(ls.Filter, "*")
log.Trace("Fetching attributes '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, userFilter, ls.UserBase)
log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, userFilter, ls.UserBase)
search := ldap.NewSearchRequest(
ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
[]string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail},
[]string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey},
nil)
var sr *ldap.SearchResult
@ -319,11 +321,12 @@ func (ls *Source) SearchEntries() []*SearchResult {
for i, v := range sr.Entries {
result[i] = &SearchResult{
Username: v.GetAttributeValue(ls.AttributeUsername),
Name: v.GetAttributeValue(ls.AttributeName),
Surname: v.GetAttributeValue(ls.AttributeSurname),
Mail: v.GetAttributeValue(ls.AttributeMail),
IsAdmin: checkAdmin(l, ls, v.DN),
Username: v.GetAttributeValue(ls.AttributeUsername),
Name: v.GetAttributeValue(ls.AttributeName),
Surname: v.GetAttributeValue(ls.AttributeSurname),
Mail: v.GetAttributeValue(ls.AttributeMail),
SSHPublicKey: v.GetAttributeValues(ls.AttributeSSHPublicKey),
IsAdmin: checkAdmin(l, ls, v.DN),
}
}

View File

@ -372,7 +372,7 @@ func (f *MergePullRequestForm) Validate(ctx *macaron.Context, errs binding.Error
// NewReleaseForm form for creating release
type NewReleaseForm struct {
TagName string `binding:"Required"`
TagName string `binding:"Required;GitRefName"`
Target string `form:"tag_target" binding:"Required"`
Title string `binding:"Required"`
Content string

View File

@ -5,6 +5,6 @@ import (
)
var (
defaultLangs = strings.Split("en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR", ",")
defaultLangNames = strings.Split("English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어", ",")
defaultLangs = strings.Split("en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR", ",")
defaultLangNames = strings.Split("English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어", ",")
)

View File

@ -136,10 +136,11 @@ var (
}
LFS struct {
StartServer bool `ini:"LFS_START_SERVER"`
ContentPath string `ini:"LFS_CONTENT_PATH"`
JWTSecretBase64 string `ini:"LFS_JWT_SECRET"`
JWTSecretBytes []byte `ini:"-"`
StartServer bool `ini:"LFS_START_SERVER"`
ContentPath string `ini:"LFS_CONTENT_PATH"`
JWTSecretBase64 string `ini:"LFS_JWT_SECRET"`
JWTSecretBytes []byte `ini:"-"`
HTTPAuthExpiry time.Duration `ini:"LFS_HTTP_AUTH_EXPIRY"`
}
// Security settings
@ -828,6 +829,8 @@ func NewContext() {
LFS.ContentPath = filepath.Join(AppWorkPath, LFS.ContentPath)
}
LFS.HTTPAuthExpiry = sec.Key("LFS_HTTP_AUTH_EXPIRY").MustDuration(20 * time.Minute)
if LFS.StartServer {
if err := os.MkdirAll(LFS.ContentPath, 0700); err != nil {
@ -947,7 +950,7 @@ func NewContext() {
AttachmentAllowedTypes = strings.Replace(sec.Key("ALLOWED_TYPES").MustString("image/jpeg,image/png,application/zip,application/gzip"), "|", ",", -1)
AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(4)
AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5)
AttachmentEnabled = sec.Key("ENABLE").MustBool(true)
AttachmentEnabled = sec.Key("ENABLED").MustBool(true)
TimeFormatKey := Cfg.Section("time").Key("FORMAT").MustString("RFC1123")
TimeFormat = map[string]string{

View File

@ -27,3 +27,32 @@ func IsSliceInt64Eq(a, b []int64) bool {
}
return true
}
// ExistsInSlice returns true if string exists in slice.
func ExistsInSlice(target string, slice []string) bool {
i := sort.Search(len(slice),
func(i int) bool { return slice[i] == target })
return i < len(slice)
}
// IsEqualSlice returns true if slices are equal.
func IsEqualSlice(target []string, source []string) bool {
if len(target) != len(source) {
return false
}
if (target == nil) != (source == nil) {
return false
}
sort.Strings(target)
sort.Strings(source)
for i, v := range target {
if v != source[i] {
return false
}
}
return true
}

View File

@ -7,6 +7,7 @@ package util
import (
"net/url"
"path"
"strings"
"code.gitea.io/gitea/modules/log"
)
@ -56,16 +57,25 @@ func Max(a, b int) int {
// URLJoin joins url components, like path.Join, but preserving contents
func URLJoin(base string, elems ...string) string {
u, err := url.Parse(base)
if !strings.HasSuffix(base, "/") {
base += "/"
}
baseURL, err := url.Parse(base)
if err != nil {
log.Error(4, "URLJoin: Invalid base URL %s", base)
return ""
}
joinArgs := make([]string, 0, len(elems)+1)
joinArgs = append(joinArgs, u.Path)
joinArgs = append(joinArgs, elems...)
u.Path = path.Join(joinArgs...)
return u.String()
joinedPath := path.Join(elems...)
argURL, err := url.Parse(joinedPath)
if err != nil {
log.Error(4, "URLJoin: Invalid arg %s", joinedPath)
return ""
}
joinedURL := baseURL.ResolveReference(argURL).String()
if !baseURL.IsAbs() && !strings.HasPrefix(base, "/") {
return joinedURL[1:] // Removing leading '/' if needed
}
return joinedURL
}
// Min min of two ints

View File

@ -30,6 +30,14 @@ func TestURLJoin(t *testing.T) {
"a", "b/c/"),
newTest("a/b/d",
"a/", "b/c/", "/../d/"),
newTest("https://try.gitea.io/a/b/c#d",
"https://try.gitea.io", "a/b", "c#d"),
newTest("/a/b/d",
"/a/", "b/c/", "/../d/"),
newTest("/a/b/c",
"/a", "b/c/"),
newTest("/a/b/c#hash",
"/a", "b/c#hash"),
} {
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
}

View File

@ -19,7 +19,7 @@ const (
)
var (
// GitRefNamePattern is regular expression wirh unallowed characters in git reference name
// GitRefNamePattern is regular expression with unallowed characters in git reference name
GitRefNamePattern = regexp.MustCompile("[^\\d\\w-_\\./]")
)

View File

@ -59,7 +59,6 @@ test_git_failed=Неуспешно тестването на "git" команд
[home]
password_holder=Парола
switch_dashboard_context=Превключи контекст на таблото
my_repos=Моите хранилища
collaborative_repos=Съвместни хранилища
my_orgs=Моите организации
my_mirrors=Моите огледала

View File

@ -59,7 +59,6 @@ test_git_failed=Chyba při testu příkazu 'git': %v
[home]
password_holder=Heslo
switch_dashboard_context=Přepnout kontext přehledu
my_repos=Mé repositáře
collaborative_repos=Společné repositáře
my_orgs=Mé organizace
my_mirrors=Má zrcadla

View File

@ -31,6 +31,18 @@ twofa=Zwei-Faktor-Authentifizierung
twofa_scratch=Zwei-Faktor-Einmalpasswort
passcode=PIN
u2f_insert_key=Hardware-Sicherheitsschlüssel einstecken
u2f_sign_in=Drücke den Knopf auf deinem Sicherheitsschlüssel. Wenn deiner keinen Knopf hat, stecke ihn erneut ein.
u2f_press_button=Drücke den Knopf auf deinem Sicherheitsschlüssel…
u2f_use_twofa=Zwei-Faktor-Authentifizierung via Handy verwenden
u2f_error=Wir können deinen Hardware-Sicherheitsschlüssel nicht lesen!
u2f_unsupported_browser=Dein Browser unterstützt keine U2F-Geräte. Bitte benutze einen anderen Browser.
u2f_error_1=Ein unbekannter Fehler ist aufgetreten. Bitte versuche es erneut.
u2f_error_2=Stelle sicher, dass du einen verschlüsselte Verbindung (https://) benutzt und die richtige URL eingeben hast.
u2f_error_3=Der Server kann deine Anfrage nicht bearbeiten.
u2f_error_4=Dieser Sicherheitsschlüssel ist nicht berechtigt. Wenn du versuchst, einen neuen Sicherheitsschlüssel zu registrieren, stelle bitte sicher, dass du ihn nicht bereits registriert hast.
u2f_error_5=Das Zeitlimit wurde erreicht bevor dein Schlüssel gelesen werden konnte. Bitte lade die Seite neu.
u2f_reload=Neu laden
repository=Repository
organization=Organisation
@ -156,7 +168,7 @@ no_reply_address_helper=Domain-Namen für Benutzer mit einer versteckten Emailad
uname_holder=E-Mail-Adresse oder Benutzername
password_holder=Passwort
switch_dashboard_context=Kontext der Übersichtsseite wechseln
my_repos=Meine Repositories
my_repos=Repositories
show_more_repos=Zeige mehr Repositories…
collaborative_repos=Gemeinschaftliche Repositories
my_orgs=Meine Organisationen
@ -321,6 +333,7 @@ twofa=Zwei-Faktor-Authentifizierung
account_link=Verknüpfte Benutzerkonten
organization=Organisationen
uid=Uid
u2f=Hardware-Sicherheitsschlüssel
public_profile=Öffentliches Profil
profile_desc=Deine E-Mail-Adresse wird für Benachrichtigungen und anderes verwendet.
@ -450,6 +463,13 @@ then_enter_passcode=Und gebe dann die angezeigte PIN der Anwendung ein:
passcode_invalid=Die PIN ist falsch. Probiere es erneut.
twofa_enrolled=Die Zwei-Faktor-Authentifizierung wurde für dein Konto aktiviert. Bewahre dein Einmalpasswort (%s) an einem sicheren Ort auf, da es nicht wieder angezeigt werden wird.
u2f_desc=Hardware-Sicherheitsschlüssel sind Geräte, die kryptografische Schlüssel beinhalten. Diese können für die Zwei-Faktor-Authentifizierung verwendet werden. Der Sicherheitsschlüssel muss den <a href="https://fidoalliance.org/">FIDO U2F</a>-Standard unterstützen.
u2f_require_twofa=Du musst die Zwei-Faktor-Authentifizierung aktivieren, um Hardware-Sicherheitsschlüssel nutzen zu können.
u2f_register_key=Sicherheitsschlüssel hinzufügen
u2f_nickname=Nickname
u2f_press_button=Drücke den Knopf auf deinem Sicherheitsschlüssel, um diesen zu registrieren.
u2f_delete_key=Sicherheitsschlüssel entfernen
u2f_delete_key_desc=Wenn du den Sicherheitsschlüssel entfernst, kannst du dich nicht mehr mit diesem einloggen. Bist du sicher?
manage_account_links=Verknüpfte Accounts verwalten
manage_account_links_desc=Diese externen Accounts sind mit deinem Gitea-Account verknüpft.
@ -673,6 +693,8 @@ issues.filter_sort.recentupdate=Kürzlich aktualisiert
issues.filter_sort.leastupdate=Am Längsten nicht aktualisiert
issues.filter_sort.mostcomment=Am meisten kommentiert
issues.filter_sort.leastcomment=Am wenigsten kommentiert
issues.filter_sort.mostforks=Meiste Forks
issues.filter_sort.fewestforks=Wenigste Forks
issues.action_open=Öffnen
issues.action_close=Schließen
issues.action_label=Label
@ -753,7 +775,7 @@ issues.due_date_form_update=Fälligkeitsdatum ändern
issues.due_date_form_remove=Fälligkeitsdatum löschen
issues.due_date_not_writer=Du musst Schreibrechte in diesem Repository haben, um das Fälligkeitsdatum zu ändern.
issues.due_date_not_set=Kein Fälligkeitsdatum gesetzt.
issues.due_date_added=hat %s$2 das Fälligkeitsdatum %s$1 hinzugefügt
issues.due_date_added=hat %[2]s das Fälligkeitsdatum %[1]s hinzugefügt
issues.due_date_modified=hat %[3]s das Fälligkeitsdatum von %[2]s zu %[1]s geändert
issues.due_date_remove=hat %[2]s das Fälligkeitsdatum %[1]s entfernt
issues.due_date_overdue=Überfällig
@ -1011,7 +1033,7 @@ settings.event_issues_desc=Issue geöffnet, geschlossen, wieder geöffnet, bearb
settings.event_issue_comment=Issue-Kommentar
settings.event_issue_comment_desc=Issue-Kommentar angelegt, geändert oder gelöscht.
settings.event_release=Release
settings.event_release_desc=Release in Repository veröffentlicht.
settings.event_release_desc=Release in einem Repository veröffentlicht, aktualisiert oder gelöscht.
settings.event_pull_request=Pull-Request
settings.event_pull_request_desc=Pull-Request geöffnet, geschlossen, wieder geöffnet, bearbeitet, zugewiesen, nicht zugewiesen, Label aktualisiert, Label gelöscht oder synchronisiert.
settings.event_push=Push
@ -1339,6 +1361,7 @@ repos.name=Name
repos.private=Privat
repos.watches=Beobachtungen
repos.stars=Favoriten
repos.forks=Forks
repos.issues=Issues
repos.size=Größe

View File

@ -168,7 +168,7 @@ no_reply_address_helper = Domain name for users with a hidden email address. For
uname_holder = Username or Email Address
password_holder = Password
switch_dashboard_context = Switch Dashboard Context
my_repos = My Repositories
my_repos = Repositories
show_more_repos = Show more repositories…
collaborative_repos = Collaborative Repositories
my_orgs = My Organizations
@ -463,7 +463,7 @@ then_enter_passcode = And enter the passcode shown in the application:
passcode_invalid = The passcode is incorrect. Try again.
twofa_enrolled = Your account has been enrolled into two-factor authentication. Store your scratch token (%s) in a safe place as it is only shown once!
u2f_desc = Security keys are hardware devices containing cryptograhic keys. They could be used for two factor authentication. The security key must support the <a href="https://fidoalliance.org/">FIDO U2F</a> standard.
u2f_desc = Security keys are hardware devices containing cryptographic keys. They could be used for two factor authentication. The security key must support the <a href="https://fidoalliance.org/">FIDO U2F</a> standard.
u2f_require_twofa = Two-Factor-Authentication must be enrolled in order to use security keys.
u2f_register_key = Add Security Key
u2f_nickname = Nickname
@ -693,6 +693,10 @@ issues.filter_sort.recentupdate = Recently updated
issues.filter_sort.leastupdate = Least recently updated
issues.filter_sort.mostcomment = Most commented
issues.filter_sort.leastcomment = Least commented
issues.filter_sort.moststars = Most stars
issues.filter_sort.feweststars = Fewest stars
issues.filter_sort.mostforks = Most forks
issues.filter_sort.fewestforks = Fewest forks
issues.action_open = Open
issues.action_close = Close
issues.action_label = Label
@ -1058,7 +1062,7 @@ settings.event_issues_desc = Issue opened, closed, reopened, edited, assigned, u
settings.event_issue_comment = Issue Comment
settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
settings.event_release = Release
settings.event_release_desc = Release published in a repository.
settings.event_release_desc = Release published, updated or deleted in a repository.
settings.event_pull_request = Pull Request
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared or synchronized.
settings.event_push = Push
@ -1386,6 +1390,7 @@ repos.name = Name
repos.private = Private
repos.watches = Watches
repos.stars = Stars
repos.forks = Forks
repos.issues = Issues
repos.size = Size
@ -1412,6 +1417,7 @@ auths.attribute_username_placeholder = Leave empty to use the username entered i
auths.attribute_name = First Name Attribute
auths.attribute_surname = Surname Attribute
auths.attribute_mail = Email Attribute
auths.attribute_ssh_public_key = Public SSH Key Attribute
auths.attributes_in_bind = Fetch Attributes in Bind DN Context
auths.use_paged_search = Use Paged Search
auths.search_page_size = Page Size

View File

@ -69,7 +69,6 @@ save_config_failed=Error al guardar la configuración: %v
[home]
password_holder=Contraseña
switch_dashboard_context=Cambiar el contexto del Dashboard
my_repos=Mis repositorios
collaborative_repos=Repositorios colaborativos
my_orgs=Mis organizaciones
my_mirrors=Mis réplicas

View File

@ -61,7 +61,6 @@ test_git_failed=Epäonnistui testata 'git' komentoa: %v
[home]
password_holder=Salasana
switch_dashboard_context=Vaihda kojelaudan kontekstia
my_repos=Reponi
collaborative_repos=Yhteistyö repot
my_orgs=Organisaationi
my_mirrors=Peilini

View File

@ -70,7 +70,6 @@ save_config_failed=L'enregistrement de la configuration %v a échoué
[home]
password_holder=Mot de passe
switch_dashboard_context=Basculer le contexte du tableau de bord
my_repos=Mes dépôts
collaborative_repos=Dépôts collaboratifs
my_orgs=Mes organisations
my_mirrors=Mes miroirs

View File

@ -71,7 +71,6 @@ save_config_failed=Hiba történt a konfiguráció mentése közben: %v
[home]
password_holder=Jelszó
switch_dashboard_context=Műszerfal nézőpont váltás
my_repos=Tárolóim
show_more_repos=Több tároló mutatása…
collaborative_repos=Együttműködési tárolók
my_orgs=Szervezeteim

View File

@ -70,7 +70,6 @@ save_config_failed=Gagal menyimpan konfigurasi: %v
[home]
password_holder=Kata Sandi
switch_dashboard_context=Alihkan Dasbor Konteks
my_repos=Repositori Saya
collaborative_repos=Repositori Kolaboratif
my_orgs=Organisasi Saya
my_mirrors=Duplikat Saya

View File

@ -70,7 +70,6 @@ save_config_failed=Salvataggio della configurazione non riuscito: %v
[home]
password_holder=Password
switch_dashboard_context=Cambia Dashboard Context
my_repos=I miei Repository
collaborative_repos=Repository Condivisi
my_orgs=Le mie Organizzazioni
my_mirrors=I miei Mirror

View File

@ -71,7 +71,6 @@ save_config_failed=設定ファイルの保存に失敗しました: %v
[home]
password_holder=パスワード
switch_dashboard_context=ダッシュ ボードのコンテキストを切替
my_repos=自分のリポジトリ
show_more_repos=リポジトリをさらに表示…
collaborative_repos=共同リポジトリ
my_orgs=自分の組織

View File

@ -70,7 +70,6 @@ save_config_failed=설정을 저장할 수 없습니다: %v
[home]
password_holder=비밀번호
switch_dashboard_context=대시보드 컨텍스트 바꾸기
my_repos=내 저장소
collaborative_repos=협업 저장소
my_orgs=내 조직
my_mirrors=내 미러 저장소들

View File

@ -56,7 +56,6 @@ confirm_password=Patvirtinkite slaptažodį
[home]
password_holder=Slaptažodis
my_repos=Mano saugyklos
my_orgs=Mano organizacijos
my_mirrors=Mano veidrodžiai
view_home=Rodyti %s

View File

@ -71,7 +71,6 @@ save_config_failed=Neizdevās saglabāt konfigurāciju: %v
[home]
password_holder=Parole
switch_dashboard_context=Mainīt infopaneļa kontekstu
my_repos=Mani repozitoriji
show_more_repos=Parādīt vairāk repozitorijus…
collaborative_repos=Sadarbības repozitoriji
my_orgs=Manas organizācijas

View File

@ -71,7 +71,6 @@ save_config_failed=Kan de configuratie niet opslaan: %v
[home]
password_holder=Wachtwoord
switch_dashboard_context=Wissel voorpaginacontext
my_repos=Mijn repositories
show_more_repos=Toon meer repositories…
collaborative_repos=Gedeelde repositories
my_orgs=Mijn organisaties

View File

@ -70,7 +70,6 @@ save_config_failed=Nie udało się zapisać konfiguracji: %v
[home]
password_holder=Hasło
switch_dashboard_context=Przełącz kontekst pulpitu
my_repos=Moje repozytoria
collaborative_repos=Wspólne repozytoria
my_orgs=Moje organizacje
my_mirrors=Moje kopie lustrzane

View File

@ -31,6 +31,18 @@ twofa=Autenticação de dois fatores
twofa_scratch=Código de backup da autenticação de dois fatores
passcode=Senha
u2f_insert_key=Insira sua chave de segurança
u2f_sign_in=Pressione o botão na sua chave de segurança. Se você não encontrar um botão, insira-o novamente.
u2f_press_button=Por favor, pressione o botão na sua chave de segurança...
u2f_use_twofa=Use um código de dois fatores no seu telefone
u2f_error=Não conseguimos ler sua chave de segurança!
u2f_unsupported_browser=Seu navegador não suporta chaves U2F. Por favor, tente outro navegador.
u2f_error_1=Ocorreu um erro desconhecido. Por favor, tente novamente.
u2f_error_2=Por favor, certifique-se de que você está usando uma conexão criptografada (https://) e visite a URL correta.
u2f_error_3=O servidor não pôde prosseguir com sua solicitação.
u2f_error_4=A chave apresentada não é elegível para esta solicitação. Se você tentar registrá-la, certifique-se de que a chave já não é registrada.
u2f_error_5=Tempo limite atingido antes de sua chave poder ser lida. Por favor, recarregue para tentar novamente.
u2f_reload=Recarregar
repository=Repositório
organization=Organização
@ -156,7 +168,7 @@ no_reply_address_helper=Nome de domínio para usuários com um endereço de e-ma
uname_holder=Usuário ou e-mail
password_holder=Senha
switch_dashboard_context=Trocar contexto do painel de controle
my_repos=Meus repositórios
my_repos=Repositórios
show_more_repos=Mostrar mais repositórios…
collaborative_repos=Repositórios colaborativos
my_orgs=Minhas organizações
@ -321,6 +333,7 @@ twofa=Autenticação de dois fatores
account_link=Contas vinculadas
organization=Organizações
uid=Uid
u2f=Chaves de segurança
public_profile=Perfil público
profile_desc=Seu endereço de e-mail será usado para notificações e outras operações.
@ -450,6 +463,13 @@ then_enter_passcode=E insira a senha mostrada no aplicativo:
passcode_invalid=Esse código de acesso é inválido. Tente novamente.
twofa_enrolled=Sua conta foi inscrita na autenticação de dois fatores. Armazene seu token de backup (%s) em um local seguro, pois ele é exibido apenas uma vez!
u2f_desc=Chaves de segurança são dispositivos de hardware que contém chaves de criptografia. Elas podem ser usadas para autenticação de dois fatores. A chave de segurança deve suportar o padrão <a href="https://fidoalliance.org/">FIDO U2F</a>.
u2f_require_twofa=Autenticação de dois fatores deve estar inscrita para usar chaves de segurança.
u2f_register_key=Adicionar chave de segurança
u2f_nickname=Apelido
u2f_press_button=Pressione o botão na sua chave de segurança para registrá-la.
u2f_delete_key=Remover chave de segurança
u2f_delete_key_desc=Se você remover uma chave de segurança você não poderá mais acessar com ela. Tem certeza?
manage_account_links=Gerenciar contas vinculadas
manage_account_links_desc=Estas contas externas estão vinculadas a sua conta de Gitea.
@ -673,6 +693,10 @@ issues.filter_sort.recentupdate=Mais recentemente atualizados
issues.filter_sort.leastupdate=Menos recentemente atualizados
issues.filter_sort.mostcomment=Mais comentados
issues.filter_sort.leastcomment=Menos comentados
issues.filter_sort.moststars=Mais estrelas
issues.filter_sort.feweststars=Menos estrelas
issues.filter_sort.mostforks=Mais forks
issues.filter_sort.fewestforks=Menos forks
issues.action_open=Abrir
issues.action_close=Fechar
issues.action_label=Etiqueta
@ -753,9 +777,9 @@ issues.due_date_form_update=Modificar data limite
issues.due_date_form_remove=Remover data limite
issues.due_date_not_writer=Você deve ter permissão de escrita no repositório para atualizar a data limite de uma issue.
issues.due_date_not_set=Data limite não informada.
issues.due_date_added=adicionou a data limite %s à %s
issues.due_date_modified=modificou a data limite para %s ao invés de %s à %s
issues.due_date_remove=removeu a data limite %s à %s
issues.due_date_added=adicionou a data limite %s %s
issues.due_date_modified=modificou a data limite para %s ao invés de %s %s
issues.due_date_remove=removeu a data limite %s %s
issues.due_date_overdue=Em atraso
pulls.desc=Habilitar solicitações de merge e revisões de código.
@ -1011,7 +1035,7 @@ settings.event_issues_desc=Issue aberta, fechada, reaberta, editada, atribuída,
settings.event_issue_comment=Comentário da issue
settings.event_issue_comment_desc=Comentário da issue criado, editado ou excluído.
settings.event_release=Versão
settings.event_release_desc=Versão publicada em um repositório.
settings.event_release_desc=Versão publicada, atualizada ou excluída em um repositório.
settings.event_pull_request=Pull request
settings.event_pull_request_desc=Pull request aberto, fechado, reaberto, atribuído, desatribuído, teve etiqueta atualizada ou limpada ou foi sincronizado.
settings.event_push=Push
@ -1339,6 +1363,7 @@ repos.name=Nome
repos.private=Privado
repos.watches=Observadores
repos.stars=Favoritos
repos.forks=Forks
repos.issues=Issues
repos.size=Tamanho
@ -1365,6 +1390,7 @@ auths.attribute_username_placeholder=Deixe em branco para usar o nome de usuári
auths.attribute_name=Atributo primeiro nome
auths.attribute_surname=Atributo sobrenome
auths.attribute_mail=Atributo e-mail
auths.attribute_ssh_public_key=Atributo de chave SSH pública
auths.attributes_in_bind=Buscar os atributos no contexto de Bind DN
auths.use_paged_search=Use a pesquisa paginada
auths.search_page_size=Tamanho da página

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,6 @@ test_git_failed=Команда 'git' није успела: %v
[home]
password_holder=Лозинка
switch_dashboard_context=Пребаците контекст контролној панели
my_repos=Моја спремишта
collaborative_repos=Заједничка спремишта
my_orgs=Моје организације
my_mirrors=Моја огледала

View File

@ -70,7 +70,6 @@ save_config_failed=Misslyckades att spara konfigurationen: %v
[home]
password_holder=Lösenord
switch_dashboard_context=Växla Visad Instrumentpanel
my_repos=Mina utvecklingskataloger
collaborative_repos=Kollaborativa Utvecklingskataloger
my_orgs=Mina organisationer
my_mirrors=Mina speglar

View File

@ -70,7 +70,6 @@ save_config_failed=%v Yapılandırması kaydedilirken hata oluştu
[home]
password_holder=Parola
switch_dashboard_context=Panoya Geçiş Yap
my_repos=Depolarım
collaborative_repos=Katkıya Açık Depolar
my_orgs=Organizasyonlarım
my_mirrors=Yansılarım

View File

@ -31,6 +31,8 @@ twofa=Двофакторна авторизація
twofa_scratch=Двофакторний одноразовий пароль
passcode=Код доступу
u2f_insert_key=Вставте ключ безпеки
u2f_reload=Оновити
repository=Репозиторій
organization=Організація
@ -71,6 +73,7 @@ host=Хост
user=Ім'я кристувача
password=Пароль
db_name=Ім'я бази даних
db_helper=Примітка для користувачів MySQL: будь ласка, використовуйте InnoDB механізм зберігання і набір символів 'utf8_general_ci'.
ssl_mode=SSL
path=Шлях
sqlite_helper=Шлях до файлу для бази даних SQLite3 або TiDB. <br> Введіть абсолютний шлях, якщо ви запускаєте Gitea як сервіс.
@ -105,8 +108,11 @@ mailer_user=SMTP Ім'я кристувача
mailer_password=SMTP Пароль
register_confirm=Потрібно підтвердити електронну пошту для реєстрації
mail_notify=Увімкнути сповіщення електронною поштою
server_service_title=Сервер і налаштування зовнішніх служб
offline_mode=Увімкнути локальний режим
offline_mode_popup=Відключити сторонні мережі доставки контенту і обслуговувати всі ресурси локально.
disable_gravatar=Вимкнути Gravatar
disable_gravatar_popup=Відключити Gravatar і сторонні джерела аватарів. Якщо користувач не завантажить аватар локально то за замовчуванням буде використовуватися стандартний аватар.
federated_avatar_lookup=Увімкнути федеративні аватари
federated_avatar_lookup_popup=Увімкнути зовнішний Аватар за допомогою Libravatar.
disable_registration=Вимкнути самостійну реєстрацію
@ -116,6 +122,9 @@ openid_signin_popup=Увімкнути вхід за допомогою OpenID.
openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID
enable_captcha=Увімкнути CAPTCHA
enable_captcha_popup=Вимагати перевірку CAPTCHA при самостійній реєстрації користувача.
require_sign_in_view=Вимагати авторизації для перегляду сторінок
require_sign_in_view_popup=Обмеження доступу до сторінки для користувачів, які виконали вхід. Відвідувачі побачать тільки сторінки входу і реєстрації.
admin_setting_desc=Створення облікового запису адміністратора необов'язково. Перший зареєстрований користувач автоматично стає адміністратором.
admin_title=Налаштування облікового запису адміністратора
admin_name=Ім'я кристувача Адміністратора
admin_password=Пароль
@ -124,10 +133,13 @@ admin_email=Адреса електронної пошти
install_btn_confirm=Встановлення Gitea
test_git_failed=Не в змозі перевірити 'git' команду: %v
save_config_failed=Не в змозі зберегти конфігурацію: %v
invalid_admin_setting=Неприпустимі налаштування облікового запису адміністратора: %v
install_success=Ласкаво просимо! Дякуємо вам за вибір Gitea. Розважайтеся, і будьте обережні!
invalid_log_root_path=Неприпустимий шлях для логів: %v
default_keep_email_private=Приховати адресу електронної пошти за замовчуванням
default_keep_email_private_popup=Приховати адресу електронної пошти нових облікових записів за замовчуванням.
default_allow_create_organization=Дозволити створення організацій за замовчуванням
default_allow_create_organization_popup=Дозволити новим обліковим записам користувачів створювати організації за замовчуванням.
default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
default_enable_timetracking_popup=Включити відстеження часу для нових репозиторіїв за замовчуванням.
no_reply_address=Прихований поштовий домен
@ -135,8 +147,8 @@ no_reply_address=Прихований поштовий домен
[home]
uname_holder=Ім'я користувача або Ел. пошта
password_holder=Пароль
switch_dashboard_context=Змінити дошку
my_repos=Мої репозиторії
switch_dashboard_context=Переключити контекст панелі управління
my_repos=Репозиторії
show_more_repos=Показати більше репозиторіїв…
collaborative_repos=Спільні репозиторії
my_orgs=Мої організації
@ -281,28 +293,34 @@ twofa=Двофакторна авторизація
account_link=Прив'язані облікові записи
organization=Організації
uid=Ідентифікатор Uid
u2f=Ключі безпеки
public_profile=Загальнодоступний профіль
profile_desc=Ваша адреса електронної пошти використовуватиметься для сповіщення та інших операцій.
full_name=Повне ім'я
website=Веб-сайт
location=Місцезнаходження
update_profile=Оновити профіль
update_profile_success=Профіль успішно оновлено.
change_username=Ваше Ім'я кристувача було змінено.
continue=Продовжити
cancel=Відміна
language=Мова
lookup_avatar_by_mail=Знайти Аватар за адресою електронної пошти
federated_avatar_lookup=Знайти зовнішній аватар
enable_custom_avatar=Увімкнути користувацькі аватари
choose_new_avatar=Оберіть новий аватар
update_avatar=Оновити аватар
delete_current_avatar=Видалити поточний аватар
uploaded_avatar_not_a_image=Завантажений файл не є зображенням.
update_avatar_success=Ваш аватар був змінений.
change_password=Оновити пароль
old_password=Поточний пароль
new_password=Новий пароль
retype_new_password=Введіть новий пароль ще раз
password_incorrect=Поточний пароль неправильний.
change_password_success=Ваш пароль був оновлений. Тепер увійдіть в систему, використовуючи новий пароль.
password_change_disabled=Нелокальні акаунти не можуть змінити пароль через Gitea.
@ -312,8 +330,10 @@ email_desc=Ваша основна адреса електронної пошт
primary=Основний
primary_email=Зробити основним
delete_email=Видалити
email_deletion=Видалити адресу електронної пошти
add_new_email=Додати нову адресу електронної пошти
add_email=Додати адресу електронної пошти
add_email_confirmation_sent=Електронний лист із підтвердженням було відправлено на '%s', будь ласка, перевірте вашу поштову скриньку протягом наступних %s, щоб підтвердити адресу.
keep_email_private=Приховати адресу електронної пошти
keep_email_private_popup=Вашу адресу електронної пошти буде приховано від інших користувачів.
@ -324,6 +344,7 @@ ssh_helper=<strong>Потрібна допомога?</strong> Дивіться
gpg_helper=<strong> Потрібна допомога? </strong> Перегляньте посібник GitHub <a href="%s"> про GPG </a>.
add_new_key=Додати SSH ключ
add_new_gpg_key=Додати GPG ключ
subkeys=Підключі
key_id=ID ключа
key_name=Ім'я ключа
key_content=Зміст
@ -331,6 +352,8 @@ delete_key=Видалити
ssh_key_deletion=Видалити SSH ключ
gpg_key_deletion=Видалити GPG ключ
gpg_key_deletion_desc=Видалення GPG ключа скасовує перевірку підписаних ним комітів. Продовжити?
ssh_key_deletion_success=SSH було видалено.
gpg_key_deletion_success=GPG було видалено.
add_on=Додано
valid_until=Дійсний до
valid_forever=Дійсний завжди
@ -350,17 +373,21 @@ unbind=Від'єднати
manage_access_token=Керування токенами доступу
generate_new_token=Згенерувати новий токен
tokens_desc=Ці токени надають доступ до вашого облікового запису за допомогою Gitea API.
new_token_desc=Додатки, що використовують токен, мають повний доступ до вашого облікового запису.
token_name=Ім'я токену
generate_token=Згенерувати токен
delete_token=Видалити
access_token_deletion=Видалити токен доступу
twofa_disable=Вимкнути двофакторну автентифікацію
or_enter_secret=Або введіть секрет: %s
u2f_nickname=Псевдонім
manage_account_links=Керування обліковими записами
remove_account_link=Видалити облікові записи
orgs_none=Ви не є учасником будь-якої організації.
delete_account=Видалити ваш обліковий запис
confirm_delete_account=Підтвердження видалення
@ -374,6 +401,7 @@ visiblity_helper=Зробити репозиторій приватним
clone_helper=Потрібна допомога у клонуванні? Відвідайте <a target="_blank" rel="noopener" href="%s">Допомогу</a>.
fork_repo=Форкнути репозиторій
fork_from=Форк з
fork_visiblity_helper=Видимість форкнутого репозиторію змінити не можна.
repo_desc=Опис
repo_lang=Мова
repo_gitignore_helper=Виберіть шаблон .gitignore.
@ -388,22 +416,27 @@ mirror_interval=Інтервал дзеркалювання (доступні з
mirror_address=Клонування з URL-адреси
mirror_last_synced=Остання синхронізація
watchers=Спостерігачі
stargazers=Зацікавлені
forks=Форки
pick_reaction=Залиште свою оцінку
reactions_more=додати %d більше
form.reach_limit_of_creation=Ви досягли максимальної кількості %d створених репозиторіїв.
need_auth=Клонування авторизації
need_auth=Клонувати з авторизацією
migrate_type=Тип міграції
migrate_type_helper=Даний репозиторій буде <span class="text blue">дзеркалом</span>
migrate_repo=Перенесення репозиторія
migrate_repo=Перенести репозиторій
migrate.clone_address=Міграція / клонувати з URL-адреси
migrate.clone_address_desc=URL-адреса HTTP(S) або Git "clone" існуючого репозиторія
migrate.clone_local_path=або шлях до локального серверу
migrate.permission_denied=Вам не дозволено імпортувати локальні репозиторії.
migrate.failed=Міграція не вдалася: %v
migrate.lfs_mirror_unsupported=Дзеркалювання LFS об'єктів не підтримується - використовуйте 'git lfs fetch --all' і 'git lfs push --all' вручну.
mirror_from=дзеркало
forked_from=форк від
fork_from_self=Ви не можете форкнути репозиторій, так як ви його власник.
copy_link=Копіювати
copy_link_error=Натисніть ⌘-C або Ctrl-C, щоб скопіювати
copied=Скопійовано
@ -432,7 +465,7 @@ pulls=Запити на злиття
labels=Мітки
milestones=Етап
commits=Коміти
commit=Змина
commit=Коміт
releases=Релізи
file_raw=Неформатований
file_history=Історія
@ -447,8 +480,10 @@ editor.edit_file=Редагування файлу
editor.preview_changes=Попередній перегляд змін
editor.edit_this_file=Редагувати файл
editor.must_be_on_a_branch=Ви повинні бути у гілці щоб зробити, або запропонувати зміни до цього файлу.
editor.fork_before_edit=Необхідно зробити форк цього репозиторій, щоб внести або запропонувати зміни в цей файл.
editor.delete_this_file=Видалити файл
editor.must_have_write_access=Ви повинні мати доступ на запис щоб запропонувати зміни до цього файлу.
editor.file_delete_success=Файл '%s' видалено.
editor.name_your_file=Дайте назву файлу…
editor.or=або
editor.cancel_lower=Скасувати
@ -463,7 +498,9 @@ editor.create_new_branch=Створити <strong>нову гілку</strong>
editor.new_branch_name_desc=Ім'я нової гілки…
editor.cancel=Відміна
editor.branch_already_exists=Гілка '%s' вже присутня в репозиторії.
editor.no_changes_to_show=Нема змін для показу.
editor.fail_to_update_file=Не вдалося оновити/створити файл '%s' через помилку: %v
editor.add_subdir=Додати каталог…
editor.unable_to_upload_files=Не вдалося завантажити файли до '%s' через помилку: %v
editor.upload_files_to_dir=Завантажувати файли до '%s'
@ -497,6 +534,7 @@ issues.new_label=Нова мітка
issues.new_label_placeholder=Назва мітки
issues.new_label_desc_placeholder=Опис
issues.create_label=Створити мітку
issues.label_templates.title=Завантажити визначений набір міток
issues.label_templates.helper=Оберіть набір міток
issues.label_templates.fail_to_load_file=Не вдалося завантажити файл шаблона мітки '%s': %v
issues.add_label_at=додав(ла) мітку <div class="ui label" style="color: %s\; background-color: %s">%s</div> %s
@ -525,6 +563,7 @@ issues.filter_sort.recentupdate=Нещодавно оновлено
issues.filter_sort.leastupdate=Найдавніше оновлені
issues.filter_sort.mostcomment=Найбільш коментовані
issues.filter_sort.leastcomment=Найменш коментовані
issues.filter_sort.mostforks=Найбільше форків
issues.action_open=Відкрити
issues.action_close=Закрити
issues.action_label=Мітка
@ -536,7 +575,7 @@ issues.opened_by=%[1]s відкрито <a href="%[2]s">%[3]s</a>
issues.opened_by_fake=%[1]s відкрито %[2]s
issues.previous=Попередній
issues.next=Далі
issues.open_title=Відкрити
issues.open_title=Відкрито
issues.closed_title=Закрито
issues.num_comments=%d коментарів
issues.commented_at=`прокоментував(ла) <a href="#%s">%s</a>`
@ -550,6 +589,7 @@ issues.create_comment=Коментар
issues.closed_at=`закрито <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.reopened_at=`повторно відкрито <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.commit_ref_at=`згадано цю проблему в коміті <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Автор
issues.collaborator=Співавтор
issues.owner=Власник
issues.sign_in_require_desc=<a href="%s">Підпишіться</a> щоб приєднатися до обговорення.
@ -571,6 +611,7 @@ issues.label.filter_sort.by_size=Розмір
issues.label.filter_sort.reverse_by_size=Зворотний розмір
issues.num_participants=%d учасників
issues.attachment.open_tab=`Натисніть щоб побачити "%s" у новій вкладці`
issues.attachment.download=`Натисніть щоб завантажити "%s"`
issues.subscribe=Підписатися
issues.unsubscribe=Відписатися
issues.tracker=Відстеження часу
@ -586,12 +627,17 @@ issues.add_time_hours=Години
issues.add_time_minutes=Хвилини
issues.add_time_sum_to_small=Час не введено.
issues.cancel_tracking=Відміна
issues.cancel_tracking_history=`скасував відстеження часу %s`
issues.time_spent_total=Загальний витрачений час
issues.time_spent_from_all_authors=`Загальний витрачений час: %s`
issues.due_date=Дата завершення
issues.due_date_form=рррр-мм-дд
issues.due_date_form_add=Додати дату завершення
issues.due_date_form_update=Оновити дату завершення
issues.due_date_form_remove=Видалити дату завершення
issues.due_date_not_set=Термін виконання не встановлений.
issues.due_date_added=додав(ла) дату завершення %s %s
issues.due_date_overdue=Прострочено
pulls.new=Новий запит на злиття
pulls.compare_changes=Новий запит на злиття
@ -610,8 +656,11 @@ pulls.reopen_to_merge=Будь ласка перевідкрийте цей за
pulls.merged=Злито
pulls.has_merged=Запит на злиття було об'єднано.
pulls.can_auto_merge_desc=Цей запит можна об'єднати автоматично.
pulls.cannot_auto_merge_desc=Цей запит на злиття не може бути злитий автоматично через конфлікти.
pulls.cannot_auto_merge_helper=Злийте вручну для вирішення конфліктів.
pulls.merge_pull_request=Об'єднати запит на злиття
pulls.squash_merge_pull_request=Об'єднати і злити
pulls.rebase_merge_pull_request=Зробити Rebase і злити
pulls.squash_merge_pull_request=Об'єднати (Squash) і злити
milestones.new=Новий етап
milestones.open_tab=%d відкрито
@ -629,6 +678,8 @@ milestones.edit=Редагувати етап
milestones.cancel=Відміна
milestones.modify=Оновити етап
milestones.deletion=Видалити етап
milestones.filter_sort.most_issues=Найбільш проблем
milestones.filter_sort.least_issues=Найменш проблем
ext_wiki=Зов. Вікі
@ -691,7 +742,7 @@ search.search_repo=Пошук репозиторію
settings=Налаштування
settings.options=Репозиторій
settings.collaboration=Співробітники
settings.collaboration=Співавтори
settings.collaboration.admin=Адміністратор
settings.collaboration.write=Запис
settings.collaboration.read=Читати
@ -709,11 +760,15 @@ settings.use_internal_wiki=Використовувати вбудовані В
settings.use_external_wiki=Використовувати зовнішні Вікі
settings.external_wiki_url=URL зовнішньої вікі
settings.issues_desc=Увімкнути відстеження проблем в репозиторію
settings.use_internal_issue_tracker=Використовувати вбудовану систему відстеження проблем
settings.external_tracker_url=URL зовнішньої системи відстеження проблем
settings.tracker_url_format=Формат URL зовнішнього трекера задач
settings.tracker_issue_style.numeric=Цифровий
settings.tracker_issue_style.alphanumeric=Буквено-цифровий
settings.enable_timetracker=Увімкнути відстеження часу
settings.pulls_desc=Увімкнути запити на злиття в репозиторій
settings.pulls.ignore_whitespace=Ігнорувати пробіл у конфліктах
settings.pulls.allow_rebase_merge=Увімкнути Rebasing коміти перед злиттям
settings.pulls.allow_squash_commits=Увімкнути об'єднувати коміти перед злиттям
settings.admin_settings=Налаштування адміністратора
settings.admin_enable_health_check=Включити перевірки працездатності репозиторію (git fsck)
@ -721,16 +776,22 @@ settings.danger_zone=Небезпечна зона
settings.new_owner_has_same_repo=Новий власник вже має репозиторій з такою назвою. Будь ласка, виберіть інше ім'я.
settings.convert=Перетворити на звичайний репозиторій
settings.convert_desc=Ви можете сконвертувати це дзеркало у звичайний репозиторій. Це не може бути скасовано.
settings.convert_confirm=Перетворити репозиторій
settings.transfer=Передати новому власнику
settings.transfer_form_title=Введіть ім'я репозиторія як підтвердження:
settings.wiki_delete=Видалити вікі-дані
settings.confirm_wiki_delete=Видалити Вікі-дані
settings.delete=Видалити цей репозиторій
settings.delete_notices_1=- Цю операцію <strong>НЕ МОЖНА</strong> відмінити.
settings.deletion_success=Репозиторій успішно видалено.
settings.update_settings_success=Налаштування репозиторію було оновлено.
settings.transfer_owner=Новий власник
settings.make_transfer=Здіснити перенесення
settings.confirm_delete=Видалити репозиторій
settings.add_collaborator=Додати співавтора
settings.add_collaborator_success=Додано співавтора.
settings.delete_collaborator=Видалити
settings.collaborator_deletion=Видалити співавтора
settings.search_user_placeholder=Пошук користувача…
settings.add_webhook=Додати веб-хук
settings.webhook_deletion=Видалити веб-хук
@ -744,12 +805,14 @@ settings.webhook.body=Тіло
settings.githook_name=Ім'я хуку
settings.githook_content=Зміст хука
settings.update_githook=Оновити хук
settings.payload_url=Цільова URL-адреса
settings.secret=Секрет
settings.slack_username=Ім'я кристувача
settings.slack_icon_url=URL іконки
settings.discord_username=Ім'я кристувача
settings.discord_icon_url=URL іконки
settings.slack_color=Колір
settings.event_desc=Тригер:
settings.event_push_only=Push події
settings.event_send_everything=Всі події
settings.event_choose=Власні події…
@ -758,19 +821,31 @@ settings.event_create_desc=Гілку або тег створено.
settings.event_delete=Видалити
settings.event_delete_desc=Гілку або мітку було видалено
settings.event_fork=Форк
settings.event_fork_desc=Репозиторій було форкнуто
settings.event_issues=Проблеми
settings.event_issues_desc=Проблему відкрито, закрито, перевідкрито, відредаговано, призначено, відкріплено, змінено мітку, очищено мітку, створено етап, очищено етап.
settings.event_issue_comment=Коментар проблеми
settings.event_issue_comment_desc=Коментар проблеми створено, видалено чи відредаговано.
settings.event_release=Реліз
settings.event_pull_request=Запити до злиття
settings.event_pull_request_desc=Запит до злиття відкрито, закрито, перевідкрито, змінено, призначено, знято, мітку оновлено, мітку прибрано або синхронізовано.
settings.event_push=Push
settings.event_push_desc=Git push до репозиторію.
settings.event_repository=Репозиторій
settings.event_repository_desc=Репозиторій створений або видалено.
settings.active=Додавати інформацію про події
settings.add_hook_success=Веб-хук було додано.
settings.update_webhook=Оновити веб-хук
settings.update_hook_success=Веб-хук було оновлено.
settings.delete_webhook=Видалити веб-хук
settings.recent_deliveries=Недавні розсилки
settings.hook_type=Тип хука
settings.add_slack_hook_desc=Інтеграція <a href="%s">Slack</a> у ваш репозиторії.
settings.slack_token=Токен
settings.slack_domain=Домен
settings.slack_channel=Канал
settings.add_discord_hook_desc=Інтеграція <a href="%s">Discord</a> у ваш репозиторії.
settings.add_dingtalk_hook_desc=Інтеграція <a href="%s">Dingtalk</a> у ваш репозиторії.
settings.deploy_keys=Ключі для розгортування
settings.add_deploy_key=Додати ключ для розгортування
settings.is_writable=Увімкнути доступ для запису
@ -782,9 +857,11 @@ settings.protected_branch_can_push=Дозволити push?
settings.protected_branch_can_push_yes=Ви можете виконувати push
settings.protected_branch_can_push_no=Ви не можете виконувати push
settings.protect_whitelist_search_users=Пошук користувачів…
settings.protect_whitelist_search_teams=Пошук команд…
settings.add_protected_branch=Увімкнути захист
settings.delete_protected_branch=Вимкнути захист
settings.choose_branch=Оберіть гілку…
settings.no_protected_branch=Немає захищених гілок.
diff.browse_source=Переглянути джерело
diff.parent=джерело
@ -793,7 +870,9 @@ diff.show_diff_stats=Показати статистику Diff
diff.show_split_view=Розділений перегляд
diff.show_unified_view=Об'єднаний перегляд
diff.stats_desc=<strong> %d змінених файлів</strong> з <strong>%d додано</strong> та <strong>%d видалено</strong>
diff.bin=BIN
diff.view_file=Переглянути файл
diff.file_suppressed=Різницю між файлами не показано, бо вона завелика
diff.too_many_files=Деякі файли не було показано, через те що забагато файлів було змінено
release.releases=Релізи
@ -803,6 +882,7 @@ release.prerelease=Пре-реліз
release.stable=Стабільний
release.edit=редагувати
release.ahead=<strong>%d</strong> комітів %s після цього релізу
release.source_code=Код
release.tag_name=Назва тегу
release.target=Ціль
release.tag_helper=Виберіть існуючий тег або створіть новий.
@ -821,10 +901,13 @@ release.delete_release=Видалити реліз
release.deletion=Видалити реліз
release.downloads=Завантажити
branch.name=Ім'я гілки
branch.search=Пошук гілок
branch.delete_head=Видалити
branch.delete=Видалити гілку '%s'
branch.delete_html=Видалити гілку
branch.create_from=з '%s'
branch.branch_already_exists=Гілка '%s' вже присутня в репозиторії.
branch.deleted_by=Видалено %s
topic.manage_topics=Керувати тематичними мітками
@ -844,6 +927,7 @@ create_team=Створити команду
org_desc=Опис
team_name=Назва команди
team_desc=Опис
team_name_helper=Назва команди має бути простою та зрозумілою.
team_permission_desc=Права доступу
team_unit_desc=Дозволити доступ до розділів репозиторію
@ -857,8 +941,10 @@ settings.update_settings=Оновити налаштування
settings.delete=Видалити організацію
settings.delete_account=Видалити цю організацію
settings.confirm_delete_account=Підтвердіть видалення
settings.delete_org_title=Видалити організацію
members.membership_visibility=Видимість учасника:
members.public=Показувати
members.public_helper=зробити прихованим
members.private=Прихований
members.private_helper=зробити видимим
@ -875,13 +961,22 @@ teams.leave=Покинути
teams.read_access=Доступ для читання
teams.write_access=Доступ на запис
teams.admin_access=Доступ адміністратора
teams.no_desc=Ця команда не має опису
teams.settings=Налаштування
teams.owners_permission_desc=Власник має повний доступ до <strong>усіх репозиторіїв</strong> та має <strong>права адміністратора</strong> організації.
teams.members=Учасники команди
teams.update_settings=Оновити налаштування
teams.delete_team=Видалити команду
teams.add_team_member=Додати учасника команди
teams.delete_team_title=Видалити команду
teams.read_permission_desc=Ця команда має доступ для <strong>читання</strong>: учасники можуть переглядати та клонувати репозиторії.
teams.write_permission_desc=Ця команда надає доступ на <strong>запис</strong>: учасники можуть отримувати й виконувати push команди до репозитрію.
teams.admin_permission_desc=Ця команда надає <strong>адміністраторський</strong> доступ: учасники можуть читати, виконувати push команди та додавати співробітників до репозиторію.
teams.repositories=Репозиторії команди
teams.search_repo_placeholder=Пошук репозиторію…
teams.add_team_repository=Додати репозиторій команди
teams.remove_repo=Видалити
teams.add_nonexistent_repo=Ви намагаєтеся додати у репозиторій якого не існує. Будь ласка, спочатку створіть його.
[admin]
dashboard=Панель управління
@ -897,17 +992,25 @@ last_page=Остання
total=Разом: %d
dashboard.statistic=Підсумок
dashboard.operations=Технічне обслуговування
dashboard.system_status=Статус системи
dashboard.operation_name=Назва операції
dashboard.operation_switch=Перемкнути
dashboard.operation_run=Запустити
dashboard.delete_inactivate_accounts=Видалити всі неактивні облікові записи
dashboard.delete_inactivate_accounts_success=Усі неактивні облікові записи успішно видалено.
dashboard.delete_repo_archives=Видалити всі архіви репозиторіїв
dashboard.git_gc_repos_success=Всі репозиторії завершили збирання сміття.
dashboard.server_uptime=Uptime серверу
dashboard.current_memory_usage=Поточне використання пам'яті
dashboard.total_memory_allocated=Виділено пам'яті загалом
dashboard.memory_obtained=Отримано пам'яті
dashboard.current_heap_usage=Поточне використання динамічної пам'яті
dashboard.heap_memory_obtained=Отримано динамічної пам'яті
dashboard.heap_memory_idle=Не використовується динамічною пам'яттю
dashboard.heap_memory_in_use=Використовується динамічною пам'яттю
dashboard.heap_memory_released=Звільнено динамічної пам'яті
dashboard.heap_objects=Об'єктів динамічної пам'яті
dashboard.stack_memory_obtained=Зайнято пам'яті стеком
dashboard.mspan_structures_usage=Використання структур MSpan
dashboard.mspan_structures_obtained=Отримано структур MSpan
@ -953,11 +1056,13 @@ orgs.teams=Команди
orgs.members=Учасники
orgs.new_orga=Нова організація
repos.repo_manage_panel=Керування організаціями
repos.repo_manage_panel=Керування репозиторіями
repos.owner=Власник
repos.name=Назва
repos.private=Приватний
repos.watches=Стежать
repos.stars=В обраному
repos.forks=Форки
repos.issues=Проблеми
repos.size=Розмір
@ -973,6 +1078,10 @@ auths.security_protocol=Протокол безпеки
auths.domain=Домен
auths.host=Хост
auths.port=Порт
auths.user_base=База пошуку користувачів
auths.user_dn=DN користувача
auths.search_page_size=Розмір сторінки
auths.filter=Користувацький фільтр
auths.admin_filter=Фільтр адміністратора
auths.smtp_auth=Тип автентифікації SMTP
auths.smtphost=SMTP хост
@ -980,6 +1089,8 @@ auths.smtpport=SMTP порт
auths.allowed_domains=Дозволені домени
auths.enable_tls=Увімкнути TLS-шифрування
auths.skip_tls_verify=Пропустити перевірку TLS
auths.pam_service_name=Ім'я служби PAM
auths.oauth2_provider=Постачальник OAuth2
auths.oauth2_clientSecret=Ключ клієнта
auths.oauth2_tokenURL=URL токену
auths.oauth2_authURL=URL авторизації
@ -1006,6 +1117,7 @@ config.app_ver=Версія Gitea
config.app_url=Базова URL-адреса Gitea
config.custom_conf=Шлях до файлу конфігурації
config.domain=Домен SSH сервера
config.offline_mode=Локальний режим
config.disable_router_log=Вимкнути логування роутеру
config.run_user=Запуск від імені Користувача
config.run_mode=Режим виконання
@ -1043,6 +1155,7 @@ config.disable_register=Вимкнути самостійну реєстраці
config.enable_openid_signup=Увімкнути самостійну реєстрацію за допомогою OpenID
config.enable_openid_signin=Увімкнути реєстрацію за допомогою OpenID
config.show_registration_button=Показувати кнопку "Реєстрація
config.require_sign_in_view=Вимагати авторизації для перегляду сторінок
config.mail_notify=Увімкнути сповіщення електронною поштою
config.disable_key_size_check=Вимкнути перевірку мінімального розміру ключа
config.enable_captcha=Увімкнути CAPTCHA
@ -1065,6 +1178,7 @@ config.mailer_user=Користувач
config.mailer_use_sendmail=Використовувати Sendmail
config.mailer_sendmail_path=Шлях до Sendmail
config.send_test_mail=Відправити тестового листа
config.test_mail_sent=Тестового листа було відправлено до '%s'.
config.oauth_config=Конфігурація OAuth
config.oauth_enabled=Увімкнено
@ -1124,19 +1238,20 @@ notices.type=Тип
notices.type_1=Репозиторій
notices.desc=Опис
notices.op=Оп.
notices.delete_success=Сповіщення системи були видалені.
[action]
create_repo=створено репозиторій <a href="%s">%s</a>
create_repo=створив(ла) репозиторій <a href="%s">%s</a>
rename_repo=репозиторій перейменовано з <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
commit_repo=виконав(ла) push в <a href="%[1]s/src/%[2]s">%[3]s</a> у <a href="%[1]s">%[4]s</a>
create_issue=`відкрив(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`закрито проблему <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`повторно відкрив(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`створено запити на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`закрито запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
create_pull_request=`створив(ла) запити на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`закрив(ла) запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`повторно відкрито запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`прокоментував(ла) проблему <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=апит на злиття злито <a href="%s/pulls/%s">%s#%[2]s</a>`
merge_pull_request=лив(ла) запит на злиття <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=перенесено репозиторій <code>%s</code> у <a href="%s">%s</a>
push_tag=створив(ла) тег <a href="%s/src/%s">%[2]s</a> в <a href="%[1]s">%[3]s</a>
delete_tag=видалено мітку %[2]s з <a href="%[1]s">%[3]s</a>

View File

@ -1,7 +1,7 @@
app_desc=一款极易搭建的自助 Git 服务
home=首页
dashboard=控制面板
dashboard=首页
explore=探索
help=帮助
sign_in=登录
@ -31,15 +31,27 @@ twofa=两步验证
twofa_scratch=两步验证口令
passcode=验证码
u2f_insert_key=插入安全密钥
u2f_sign_in=按下安全密钥上的按钮。如果找不到按钮, 请重新插入。
u2f_press_button=请按下安全密钥上的按钮。
u2f_use_twofa=使用来自你手机中的两步验证码
u2f_error=没有找到你的安全密钥!
u2f_unsupported_browser=您的浏览器不支持 U2F 密钥。请尝试其他浏览器。
u2f_error_1=发生未知错误。请重试。
u2f_error_2=请确保您使用的是加密连接 (https://) 并访问正确的 URL。
u2f_error_3=服务器无法执行您的请求。
u2f_error_4=所提交的密钥不符合此请求。如果您尝试注册它, 请确保该密钥尚未注册。
u2f_error_5=在读取到密钥之前超时。请重新加载以重试。
u2f_reload=重新加载
repository=仓库
organization=组织
mirror=镜像
new_repo=创建新的仓库
new_repo=创建仓库
new_migrate=迁移外部仓库
new_mirror=创建新的镜像
new_fork=新的仓库Fork
new_org=创建新的组织
new_org=创建组织
manage_org=管理我的组织
admin_panel=管理后台
account_settings=帐户设置
@ -156,7 +168,7 @@ no_reply_address_helper=具有隐藏电子邮件地址的用户的域名。例
uname_holder=登录名或电子邮箱地址
password_holder=密码
switch_dashboard_context=切换控制面板用户
my_repos=我的仓库
my_repos=仓库列表
show_more_repos=显示更多仓库…
collaborative_repos=参与协作的仓库
my_orgs=我的组织
@ -321,6 +333,7 @@ twofa=两步验证
account_link=已绑定帐户
organization=组织
uid=用户 ID
u2f=安全密钥
public_profile=公开信息
profile_desc=您的电子邮件地址将用于通知和其他操作。
@ -450,6 +463,13 @@ then_enter_passcode=并输入应用程序中显示的密码:
passcode_invalid=密码不正确。再试一次。
twofa_enrolled=你的账号已经启用了两步验证。请保存初始令牌(%s到一个安全的地方此令牌仅当前显示一次。
u2f_desc=安全密钥是包含加密算法的硬件设备。它们可以用于两步验证。安全密钥必须支持 <a href="https://fidoalliance.org/">FIDO U2F</a> 标准。
u2f_require_twofa=必须开启两步验证才能使用安全密钥。
u2f_register_key=添加安全密钥
u2f_nickname=昵称
u2f_press_button=按安全密钥上的按钮进行注册。
u2f_delete_key=移除安全密钥
u2f_delete_key_desc=如果移除安全密钥, 则无法再使用它登录。是否确定?
manage_account_links=管理绑定过的账号
manage_account_links_desc=这些外部帐户已经绑定到您的 Gitea 帐户。
@ -673,6 +693,10 @@ issues.filter_sort.recentupdate=最近更新
issues.filter_sort.leastupdate=最少更新
issues.filter_sort.mostcomment=最多评论
issues.filter_sort.leastcomment=最少评论
issues.filter_sort.moststars=点赞由多到少
issues.filter_sort.feweststars=点赞由少到多
issues.filter_sort.mostforks=派生由多到少
issues.filter_sort.fewestforks=派生由少到多
issues.action_open=开启
issues.action_close=关闭
issues.action_label=标签
@ -718,7 +742,7 @@ issues.label_deletion_desc=删除标签会将其从所有问题中删除。继
issues.label_deletion_success=该标签已被删除。
issues.label.filter_sort.alphabetically=按字母顺序排序
issues.label.filter_sort.reverse_alphabetically=按字母逆序排序
issues.label.filter_sort.by_size=大小
issues.label.filter_sort.by_size=从小到大
issues.label.filter_sort.reverse_by_size=从大到小
issues.num_participants=%d 名参与者
issues.attachment.open_tab=`在新的标签页中查看 '%s'`
@ -1011,7 +1035,7 @@ settings.event_issues_desc=工单被开启、关闭、重新开启、编辑、
settings.event_issue_comment=工单评论
settings.event_issue_comment_desc=工单评论被创建、编辑或删除
settings.event_release=版本发布
settings.event_release_desc=仓库发布新的版本
settings.event_release_desc=发布、更新或删除版本时
settings.event_pull_request=合并请求
settings.event_pull_request_desc=开启、关闭、重新开启、编辑、指派、取消指派、更新标签、清除标签或同步合并请求
settings.event_push=推送
@ -1226,14 +1250,14 @@ teams.remove_repo=移除仓库
teams.add_nonexistent_repo=您尝试添加到团队的仓库不存在,请先创建仓库!
[admin]
dashboard=控制面板
dashboard=管理面板
users=帐户管理
organizations=组织管理
repositories=仓库管理
authentication=认证源
config=应用配置
notices=系统提示
monitor=应用监控面板
monitor=监控面板
first_page=首页
last_page=末页
total=总计:%d
@ -1339,8 +1363,9 @@ repos.name=名称
repos.private=私有库
repos.watches=关注数
repos.stars=点赞数
repos.forks=派生数
repos.issues=工单数
repos.size=从小到
repos.size=
auths.auth_manage_panel=认证源管理
auths.new=添加认证源
@ -1365,6 +1390,7 @@ auths.attribute_username_placeholder=置空将使用Gitea的用户名。
auths.attribute_name=名字属性
auths.attribute_surname=姓氏属性
auths.attribute_mail=电子邮箱属性
auths.attribute_ssh_public_key=SSH公钥属性
auths.attributes_in_bind=从 Bind DN 中拉取属性信息
auths.use_paged_search=使用分页搜索
auths.search_page_size=分页大小
@ -1534,11 +1560,11 @@ monitor.name=任务名称
monitor.schedule=任务安排
monitor.next=下次执行时间
monitor.previous=上次执行时间
monitor.execute_times=执行时
monitor.execute_times=执行时
monitor.process=运行中进程
monitor.desc=进程描述
monitor.start=开始时间
monitor.execute_time=执行时
monitor.execute_time=执行时
notices.system_notice_list=系统提示管理
notices.view_detail_header=查看提示详情
@ -1550,7 +1576,7 @@ notices.delete_selected=删除选中项
notices.delete_all=删除所有提示
notices.type=提示类型
notices.type_1=仓库
notices.desc=进程描述
notices.desc=提示描述
notices.op=操作
notices.delete_success=系统通知已被删除。

View File

@ -67,7 +67,6 @@ save_config_failed=儲存設定失敗:%v
[home]
password_holder=密碼
switch_dashboard_context=切換控制面版用戶
my_repos=我的儲存庫
collaborative_repos=參與協作的儲存庫
my_orgs=我的組織
my_mirrors=我的鏡像

View File

@ -70,7 +70,6 @@ save_config_failed=儲存設定失敗:%v
[home]
password_holder=密碼
switch_dashboard_context=切換控制面版用戶
my_repos=我的儲存庫
collaborative_repos=參與協作的儲存庫
my_orgs=我的組織
my_mirrors=我的鏡像

View File

@ -1028,7 +1028,9 @@
}
],
"responses": {
"200": {}
"200": {
"description": "success"
}
}
}
},
@ -1338,7 +1340,9 @@
}
],
"responses": {
"200": {}
"200": {
"description": "success"
}
}
}
},
@ -3261,7 +3265,9 @@
}
],
"responses": {
"200": {}
"200": {
"description": "success"
}
}
}
},
@ -4999,7 +5005,8 @@
"type": "string",
"description": "username of user",
"name": "username",
"in": "path"
"in": "path",
"required": true
}
],
"responses": {
@ -5273,7 +5280,8 @@
"type": "string",
"description": "username of the user",
"name": "username",
"in": "path"
"in": "path",
"required": true
}
],
"responses": {
@ -7376,11 +7384,13 @@
"description": "AccessTokenList represents a list of API access token."
},
"Attachment": {
"description": "Attachment",
"schema": {
"$ref": "#/definitions/Attachment"
}
},
"AttachmentList": {
"description": "AttachmentList",
"schema": {
"type": "array",
"items": {
@ -7389,11 +7399,13 @@
}
},
"Branch": {
"description": "Branch",
"schema": {
"$ref": "#/definitions/Branch"
}
},
"BranchList": {
"description": "BranchList",
"schema": {
"type": "array",
"items": {
@ -7402,11 +7414,13 @@
}
},
"Comment": {
"description": "Comment",
"schema": {
"$ref": "#/definitions/Comment"
}
},
"CommentList": {
"description": "CommentList",
"schema": {
"type": "array",
"items": {
@ -7415,11 +7429,13 @@
}
},
"DeployKey": {
"description": "DeployKey",
"schema": {
"$ref": "#/definitions/DeployKey"
}
},
"DeployKeyList": {
"description": "DeployKeyList",
"schema": {
"type": "array",
"items": {
@ -7428,6 +7444,7 @@
}
},
"EmailList": {
"description": "EmailList",
"schema": {
"type": "array",
"items": {
@ -7436,11 +7453,13 @@
}
},
"GPGKey": {
"description": "GPGKey",
"schema": {
"$ref": "#/definitions/GPGKey"
}
},
"GPGKeyList": {
"description": "GPGKeyList",
"schema": {
"type": "array",
"items": {
@ -7449,6 +7468,7 @@
}
},
"Hook": {
"description": "Hook",
"schema": {
"type": "array",
"items": {
@ -7457,6 +7477,7 @@
}
},
"HookList": {
"description": "HookList",
"schema": {
"type": "array",
"items": {
@ -7465,11 +7486,13 @@
}
},
"Issue": {
"description": "Issue",
"schema": {
"$ref": "#/definitions/Issue"
}
},
"IssueList": {
"description": "IssueList",
"schema": {
"type": "array",
"items": {
@ -7478,11 +7501,13 @@
}
},
"Label": {
"description": "Label",
"schema": {
"$ref": "#/definitions/Label"
}
},
"LabelList": {
"description": "LabelList",
"schema": {
"type": "array",
"items": {
@ -7494,11 +7519,13 @@
"description": "MarkdownRender is a rendered markdown document"
},
"Milestone": {
"description": "Milestone",
"schema": {
"$ref": "#/definitions/Milestone"
}
},
"MilestoneList": {
"description": "MilestoneList",
"schema": {
"type": "array",
"items": {
@ -7507,11 +7534,13 @@
}
},
"Organization": {
"description": "Organization",
"schema": {
"$ref": "#/definitions/Organization"
}
},
"OrganizationList": {
"description": "OrganizationList",
"schema": {
"type": "array",
"items": {
@ -7520,11 +7549,13 @@
}
},
"PublicKey": {
"description": "PublicKey",
"schema": {
"$ref": "#/definitions/PublicKey"
}
},
"PublicKeyList": {
"description": "PublicKeyList",
"schema": {
"type": "array",
"items": {
@ -7533,11 +7564,13 @@
}
},
"PullRequest": {
"description": "PullRequest",
"schema": {
"$ref": "#/definitions/PullRequest"
}
},
"PullRequestList": {
"description": "PullRequestList",
"schema": {
"type": "array",
"items": {
@ -7546,11 +7579,13 @@
}
},
"Release": {
"description": "Release",
"schema": {
"$ref": "#/definitions/Release"
}
},
"ReleaseList": {
"description": "ReleaseList",
"schema": {
"type": "array",
"items": {
@ -7559,11 +7594,13 @@
}
},
"Repository": {
"description": "Repository",
"schema": {
"$ref": "#/definitions/Repository"
}
},
"RepositoryList": {
"description": "RepositoryList",
"schema": {
"type": "array",
"items": {
@ -7572,6 +7609,7 @@
}
},
"SearchResults": {
"description": "SearchResults",
"schema": {
"$ref": "#/definitions/SearchResults"
},
@ -7580,16 +7618,19 @@
}
},
"ServerVersion": {
"description": "ServerVersion",
"schema": {
"$ref": "#/definitions/ServerVersion"
}
},
"Status": {
"description": "Status",
"schema": {
"$ref": "#/definitions/Status"
}
},
"StatusList": {
"description": "StatusList",
"schema": {
"type": "array",
"items": {
@ -7598,11 +7639,13 @@
}
},
"Team": {
"description": "Team",
"schema": {
"$ref": "#/definitions/Team"
}
},
"TeamList": {
"description": "TeamList",
"schema": {
"type": "array",
"items": {
@ -7611,11 +7654,13 @@
}
},
"TrackedTime": {
"description": "TrackedTime",
"schema": {
"$ref": "#/definitions/TrackedTime"
}
},
"TrackedTimeList": {
"description": "TrackedTimeList",
"schema": {
"type": "array",
"items": {
@ -7624,11 +7669,13 @@
}
},
"User": {
"description": "User",
"schema": {
"$ref": "#/definitions/User"
}
},
"UserList": {
"description": "UserList",
"schema": {
"type": "array",
"items": {
@ -7637,6 +7684,7 @@
}
},
"WatchInfo": {
"description": "WatchInfo",
"schema": {
"$ref": "#/definitions/WatchInfo"
}
@ -7670,6 +7718,7 @@
"description": "APINotFound is a not found empty response"
},
"parameterBodies": {
"description": "parameterBodies",
"schema": {
"$ref": "#/definitions/EditAttachmentOptions"
},

View File

@ -15,10 +15,7 @@ File(s): /vendor/plugins/clipboard/clipboard.min.js
Version: 1.5.9
File(s): /vendor/plugins/gitgraph/gitgraph.js
Version: 9b492e8bf1ddf7908a4997b8f83fa38a809a9da3
File(s): /vendor/plugins/autolink/autolink.js
Version: 741f66f
Version: 745f604212e2abfe2f0a59169ea530857b46625c
File(s): /vendor/plugins/vue/vue.min.js
Version: 2.1.10
@ -50,6 +47,9 @@ Version: 1.10.1
File(s): /vendor/plugins/pdfjs/
Version: 1.4.20
File(s): /vendor/plugins/u2f/
Version: 1.0.8
File(s): /vendor/assets/font-awesome/fonts/
Version: 4.6.0

View File

@ -45,11 +45,6 @@
<td><a href="https://github.com/bluef/gitgraph.js/blob/master/LICENSE">BSD 3-Clause</a></td>
<td><a href="https://github.com/bluef/gitgraph.js">gitgraph.js-latest</a></td>
</tr>
<tr>
<td><a href="/vendor/plugins/autolink/autolink.js">autolink.min.js</a></td>
<td><a href="https://github.com/egoist/autolink.js/blob/master/LICENSE">Expat</a></td>
<td><a href="https://github.com/egoist/autolink.js">autolink.js-latest</a></td>
</tr>
<tr>
<td><a href="/vendor/plugins/vue/vue.min.js">vue.min.js</a></td>
<td><a href="https://github.com/vuejs/vue/blob/dev/LICENSE">Expat</a></td>

View File

@ -126,7 +126,20 @@ var gitGraph = function (canvas, rawGraphList, config) {
!(row[i - 2] && row[i] === "_" && row[i - 2] === "|")) {}
return i;
}
};
var findLineBreak = function (row) {
if (!row) {
return -1
}
var i = row.length;
while (i-- &&
!(row[i - 1] && row[i - 2] && row[i] === " " && row[i - 1] === "|" && row[i - 2] === "_")) {}
return i;
};
var genNewFlow = function () {
var newId;
@ -138,21 +151,21 @@ var gitGraph = function (canvas, rawGraphList, config) {
return {id:newId, color:"#" + newId};
};
//draw method
var drawLineRight = function (x, y, color) {
//Draw methods
var drawLine = function (moveX, moveY, lineX, lineY, color) {
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(x, y + config.unitSize / 2);
ctx.lineTo(x + config.unitSize, y + config.unitSize / 2);
ctx.moveTo(moveX, moveY);
ctx.lineTo(lineX, lineY);
ctx.stroke();
};
var drawLineRight = function (x, y, color) {
drawLine(x, y + config.unitSize / 2, x + config.unitSize, y + config.unitSize / 2, color);
};
var drawLineUp = function (x, y, color) {
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(x, y + config.unitSize / 2);
ctx.lineTo(x, y - config.unitSize / 2);
ctx.stroke();
drawLine(x, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
};
var drawNode = function (x, y, color) {
@ -166,37 +179,28 @@ var gitGraph = function (canvas, rawGraphList, config) {
};
var drawLineIn = function (x, y, color) {
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(x + config.unitSize, y + config.unitSize / 2);
ctx.lineTo(x, y - config.unitSize / 2);
ctx.stroke();
drawLine(x + config.unitSize, y + config.unitSize / 2, x, y - config.unitSize / 2, color);
};
var drawLineOut = function (x, y, color) {
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(x, y + config.unitSize / 2);
ctx.lineTo(x + config.unitSize, y - config.unitSize / 2);
ctx.stroke();
drawLine(x, y + config.unitSize / 2, x + config.unitSize, y - config.unitSize / 2, color);
};
var draw = function (graphList) {
var colomn, colomnIndex, prevColomn, condenseIndex;
var colomn, colomnIndex, prevColomn, condenseIndex, breakIndex = -1;
var x, y;
var color;
var nodePos, outPos;
var nodePos;
var tempFlow;
var prevRowLength = 0;
var flowSwapPos = -1;
var lastLinePos;
var i, k, l;
var i, l;
var condenseCurrentLength, condensePrevLength = 0, condenseNextLength = 0;
var inlineIntersect = false;
//initiate for first row
//initiate color array for first row
for (i = 0, l = graphList[0].length; i < l; i++) {
if (graphList[0][i] !== "_" && graphList[0][i] !== " ") {
flows.push(genNewFlow());
@ -275,6 +279,7 @@ var gitGraph = function (canvas, rawGraphList, config) {
colomnIndex = 0; //reset index
condenseIndex = 0;
condensePrevLength = 0;
breakIndex = -1; //reset break index
while (colomnIndex < currentRow.length) {
colomn = currentRow[colomnIndex];
@ -282,6 +287,18 @@ var gitGraph = function (canvas, rawGraphList, config) {
++condensePrevLength;
}
//check and fix line break in next row
if (colomn === "/" && currentRow[colomnIndex - 1] && currentRow[colomnIndex - 1] === "|") {
if ((breakIndex = findLineBreak(nextRow)) !== -1) {
nextRow.splice(breakIndex, 1);
}
}
//if line break found replace all '/' with '|' after breakIndex in previous row
if (breakIndex !== - 1 && colomn === "/" && colomnIndex > breakIndex) {
currentRow[colomnIndex] = "|";
colomn = "|";
}
if (colomn === " " &&
currentRow[colomnIndex + 1] &&
currentRow[colomnIndex + 1] === "_" &&
@ -294,7 +311,7 @@ var gitGraph = function (canvas, rawGraphList, config) {
colomn = "/";
}
//create new flow only when no intersetc happened
//create new flow only when no intersect happened
if (flowSwapPos === -1 &&
colomn === "/" &&
currentRow[colomnIndex - 1] &&
@ -415,4 +432,4 @@ var gitGraph = function (canvas, rawGraphList, config) {
init();
draw(graphList);
};
// @end-license
// @end-license

View File

@ -97,24 +97,25 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig {
}
return &models.LDAPConfig{
Source: &ldap.Source{
Name: form.Name,
Host: form.Host,
Port: form.Port,
SecurityProtocol: ldap.SecurityProtocol(form.SecurityProtocol),
SkipVerify: form.SkipVerify,
BindDN: form.BindDN,
UserDN: form.UserDN,
BindPassword: form.BindPassword,
UserBase: form.UserBase,
AttributeUsername: form.AttributeUsername,
AttributeName: form.AttributeName,
AttributeSurname: form.AttributeSurname,
AttributeMail: form.AttributeMail,
AttributesInBind: form.AttributesInBind,
SearchPageSize: pageSize,
Filter: form.Filter,
AdminFilter: form.AdminFilter,
Enabled: true,
Name: form.Name,
Host: form.Host,
Port: form.Port,
SecurityProtocol: ldap.SecurityProtocol(form.SecurityProtocol),
SkipVerify: form.SkipVerify,
BindDN: form.BindDN,
UserDN: form.UserDN,
BindPassword: form.BindPassword,
UserBase: form.UserBase,
AttributeUsername: form.AttributeUsername,
AttributeName: form.AttributeName,
AttributeSurname: form.AttributeSurname,
AttributeMail: form.AttributeMail,
AttributesInBind: form.AttributesInBind,
AttributeSSHPublicKey: form.AttributeSSHPublicKey,
SearchPageSize: pageSize,
Filter: form.Filter,
AdminFilter: form.AdminFilter,
Enabled: true,
},
}
}

View File

@ -51,6 +51,7 @@ func ListUserOrgs(ctx *context.APIContext) {
// in: path
// description: username of user
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/OrganizationList"

View File

@ -36,7 +36,8 @@ func GetRawFile(ctx *context.APIContext) {
// type: string
// required: true
// responses:
// 200:
// 200:
// description: success
if !ctx.Repo.HasAccess() {
ctx.Status(404)
return
@ -85,7 +86,8 @@ func GetArchive(ctx *context.APIContext) {
// type: string
// required: true
// responses:
// 200:
// 200:
// description: success
repoPath := models.RepoPath(ctx.Params(":username"), ctx.Params(":reponame"))
gitRepo, err := git.OpenRepository(repoPath)
if err != nil {
@ -121,7 +123,8 @@ func GetEditorconfig(ctx *context.APIContext) {
// type: string
// required: true
// responses:
// 200:
// 200:
// description: success
ec, err := ctx.Repo.GetEditorconfig()
if err != nil {
if git.IsErrNotExist(err) {

View File

@ -171,7 +171,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
rel.Repo = ctx.Repo.Repository
rel.Publisher = ctx.User
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.ServerError("UpdateRelease", err)
return
}
@ -245,7 +245,7 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
if form.IsPrerelease != nil {
rel.IsPrerelease = *form.IsPrerelease
}
if err := models.UpdateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
if err := models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.Error(500, "UpdateRelease", err)
return
}

View File

@ -8,60 +8,70 @@ import (
api "code.gitea.io/sdk/gitea"
)
// Issue
// swagger:response Issue
type swaggerResponseIssue struct {
// in:body
Body api.Issue `json:"body"`
}
// IssueList
// swagger:response IssueList
type swaggerResponseIssueList struct {
// in:body
Body []api.Issue `json:"body"`
}
// Comment
// swagger:response Comment
type swaggerResponseComment struct {
// in:body
Body api.Comment `json:"body"`
}
// CommentList
// swagger:response CommentList
type swaggerResponseCommentList struct {
// in:body
Body []api.Comment `json:"body"`
}
// Label
// swagger:response Label
type swaggerResponseLabel struct {
// in:body
Body api.Label `json:"body"`
}
// LabelList
// swagger:response LabelList
type swaggerResponseLabelList struct {
// in:body
Body []api.Label `json:"body"`
}
// Milestone
// swagger:response Milestone
type swaggerResponseMilestone struct {
// in:body
Body api.Milestone `json:"body"`
}
// MilestoneList
// swagger:response MilestoneList
type swaggerResponseMilestoneList struct {
// in:body
Body []api.Milestone `json:"body"`
}
// TrackedTime
// swagger:response TrackedTime
type swaggerResponseTrackedTime struct {
// in:body
Body api.TrackedTime `json:"body"`
}
// TrackedTimeList
// swagger:response TrackedTimeList
type swaggerResponseTrackedTimeList struct {
// in:body

View File

@ -8,36 +8,42 @@ import (
api "code.gitea.io/sdk/gitea"
)
// PublicKey
// swagger:response PublicKey
type swaggerResponsePublicKey struct {
// in:body
Body api.PublicKey `json:"body"`
}
// PublicKeyList
// swagger:response PublicKeyList
type swaggerResponsePublicKeyList struct {
// in:body
Body []api.PublicKey `json:"body"`
}
// GPGKey
// swagger:response GPGKey
type swaggerResponseGPGKey struct {
// in:body
Body api.GPGKey `json:"body"`
}
// GPGKeyList
// swagger:response GPGKeyList
type swaggerResponseGPGKeyList struct {
// in:body
Body []api.GPGKey `json:"body"`
}
// DeployKey
// swagger:response DeployKey
type swaggerResponseDeployKey struct {
// in:body
Body api.DeployKey `json:"body"`
}
// DeployKeyList
// swagger:response DeployKeyList
type swaggerResponseDeployKeyList struct {
// in:body

View File

@ -8,6 +8,7 @@ import (
api "code.gitea.io/sdk/gitea"
)
// ServerVersion
// swagger:response ServerVersion
type swaggerResponseServerVersion struct {
// in:body

View File

@ -12,6 +12,7 @@ import (
// not actually a response, just a hack to get go-swagger to include definitions
// of the various XYZOption structs
// parameterBodies
// swagger:response parameterBodies
type swaggerParameterBodies struct {
AddCollaboratorOption api.AddCollaboratorOption

View File

@ -8,24 +8,28 @@ import (
api "code.gitea.io/sdk/gitea"
)
// Organization
// swagger:response Organization
type swaggerResponseOrganization struct {
// in:body
Body api.Organization `json:"body"`
}
// OrganizationList
// swagger:response OrganizationList
type swaggerResponseOrganizationList struct {
// in:body
Body []api.Organization `json:"body"`
}
// Team
// swagger:response Team
type swaggerResponseTeam struct {
// in:body
Body api.Team `json:"body"`
}
// TeamList
// swagger:response TeamList
type swaggerResponseTeamList struct {
// in:body

View File

@ -8,95 +8,111 @@ import (
api "code.gitea.io/sdk/gitea"
)
// Repository
// swagger:response Repository
type swaggerResponseRepository struct {
// in:body
Body api.Repository `json:"body"`
}
// RepositoryList
// swagger:response RepositoryList
type swaggerResponseRepositoryList struct {
// in:body
Body []api.Repository `json:"body"`
}
// Branch
// swagger:response Branch
type swaggerResponseBranch struct {
// in:body
Body api.Branch `json:"body"`
}
// BranchList
// swagger:response BranchList
type swaggerResponseBranchList struct {
// in:body
Body []api.Branch `json:"body"`
}
// Hook
// swagger:response Hook
type swaggerResponseHook struct {
// in:body
Body []api.Branch `json:"body"`
}
// HookList
// swagger:response HookList
type swaggerResponseHookList struct {
// in:body
Body []api.Branch `json:"body"`
}
// Release
// swagger:response Release
type swaggerResponseRelease struct {
// in:body
Body api.Release `json:"body"`
}
// ReleaseList
// swagger:response ReleaseList
type swaggerResponseReleaseList struct {
// in:body
Body []api.Release `json:"body"`
}
// PullRequest
// swagger:response PullRequest
type swaggerResponsePullRequest struct {
// in:body
Body api.PullRequest `json:"body"`
}
// PullRequestList
// swagger:response PullRequestList
type swaggerResponsePullRequestList struct {
// in:body
Body []api.PullRequest `json:"body"`
}
// Status
// swagger:response Status
type swaggerResponseStatus struct {
// in:body
Body api.Status `json:"body"`
}
// StatusList
// swagger:response StatusList
type swaggerResponseStatusList struct {
// in:body
Body []api.Status `json:"body"`
}
// WatchInfo
// swagger:response WatchInfo
type swaggerResponseWatchInfo struct {
// in:body
Body api.WatchInfo `json:"body"`
}
// SearchResults
// swagger:response SearchResults
type swaggerResponseSearchResults struct {
Body api.SearchResults `json:"body"`
}
// AttachmentList
// swagger:response AttachmentList
type swaggerResponseAttachmentList struct {
//in: body
Body []api.Attachment `json:"body"`
}
// Attachment
// swagger:response Attachment
type swaggerResponseAttachment struct {
//in: body

View File

@ -8,18 +8,21 @@ import (
api "code.gitea.io/sdk/gitea"
)
// User
// swagger:response User
type swaggerResponseUser struct {
// in:body
Body api.User `json:"body"`
}
// UserList
// swagger:response UserList
type swaggerResponseUserList struct {
// in:body
Body []api.User `json:"body"`
}
// EmailList
// swagger:response EmailList
type swaggerResponseEmailList struct {
// in:body

View File

@ -129,7 +129,7 @@ func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid
return
}
key, err := models.AddPublicKey(uid, form.Title, content)
key, err := models.AddPublicKey(uid, form.Title, content, 0)
if err != nil {
repo.HandleAddKeyError(ctx, err)
return

View File

@ -43,6 +43,7 @@ func GetWatchedRepos(ctx *context.APIContext) {
// type: string
// in: path
// description: username of the user
// required: true
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"

View File

@ -104,6 +104,14 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
orderBy = models.SearchOrderBySizeReverse
case "size":
orderBy = models.SearchOrderBySize
case "moststars":
orderBy = models.SearchOrderByStarsReverse
case "feweststars":
orderBy = models.SearchOrderByStars
case "mostforks":
orderBy = models.SearchOrderByForksReverse
case "fewestforks":
orderBy = models.SearchOrderByForks
default:
ctx.Data["SortType"] = "recentupdate"
orderBy = models.SearchOrderByRecentUpdated
@ -164,26 +172,26 @@ func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplN
users []*models.User
count int64
err error
orderBy string
orderBy models.SearchOrderBy
)
ctx.Data["SortType"] = ctx.Query("sort")
switch ctx.Query("sort") {
case "newest":
orderBy = "id DESC"
orderBy = models.SearchOrderByIDReverse
case "oldest":
orderBy = "id ASC"
orderBy = models.SearchOrderByID
case "recentupdate":
orderBy = "updated_unix DESC"
orderBy = models.SearchOrderByRecentUpdated
case "leastupdate":
orderBy = "updated_unix ASC"
orderBy = models.SearchOrderByLeastUpdated
case "reversealphabetically":
orderBy = "name DESC"
orderBy = models.SearchOrderByAlphabeticallyReverse
case "alphabetically":
orderBy = "name ASC"
orderBy = models.SearchOrderByAlphabetically
default:
ctx.Data["SortType"] = "alphabetically"
orderBy = "name ASC"
orderBy = models.SearchOrderByAlphabetically
}
opts.Keyword = strings.Trim(ctx.Query("q"), " ")

View File

@ -197,7 +197,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
rel.PublisherID = ctx.User.ID
rel.IsTag = false
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.Data["Err_TagName"] = true
ctx.ServerError("UpdateRelease", err)
return
@ -276,7 +276,7 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
rel.Note = form.Content
rel.IsDraft = len(form.Draft) > 0
rel.IsPrerelease = form.Prerelease
if err = models.UpdateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
ctx.ServerError("UpdateRelease", err)
return
}

View File

@ -223,6 +223,10 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
var output bytes.Buffer
lines := strings.Split(fileContent, "\n")
//Remove blank line at the end of file
if len(lines) > 0 && lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
for index, line := range lines {
line = gotemplate.HTMLEscapeString(line)
if index != len(lines)-1 {

View File

@ -25,7 +25,7 @@ import (
const (
tplHooks base.TplName = "repo/settings/webhook/base"
tplHookNew base.TplName = "repo/settings/webhook/new"
tplOrgHookNew base.TplName = "org/settings/webhook/new"
tplOrgHookNew base.TplName = "org/settings/hook_new"
)
// Webhooks render web hooks list page

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