You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

repository.go 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package setting
  4. import (
  5. "os/exec"
  6. "path"
  7. "path/filepath"
  8. "strings"
  9. "code.gitea.io/gitea/modules/log"
  10. )
  11. // enumerates all the policy repository creating
  12. const (
  13. RepoCreatingLastUserVisibility = "last"
  14. RepoCreatingPrivate = "private"
  15. RepoCreatingPublic = "public"
  16. )
  17. // ItemsPerPage maximum items per page in forks, watchers and stars of a repo
  18. const ItemsPerPage = 40
  19. // Repository settings
  20. var (
  21. Repository = struct {
  22. DetectedCharsetsOrder []string
  23. DetectedCharsetScore map[string]int `ini:"-"`
  24. AnsiCharset string
  25. ForcePrivate bool
  26. DefaultPrivate string
  27. DefaultPushCreatePrivate bool
  28. MaxCreationLimit int
  29. PreferredLicenses []string
  30. DisableHTTPGit bool
  31. AccessControlAllowOrigin string
  32. UseCompatSSHURI bool
  33. DefaultCloseIssuesViaCommitsInAnyBranch bool
  34. EnablePushCreateUser bool
  35. EnablePushCreateOrg bool
  36. DisabledRepoUnits []string
  37. DefaultRepoUnits []string
  38. PrefixArchiveFiles bool
  39. DisableMigrations bool
  40. DisableStars bool `ini:"DISABLE_STARS"`
  41. DefaultBranch string
  42. AllowAdoptionOfUnadoptedRepositories bool
  43. AllowDeleteOfUnadoptedRepositories bool
  44. DisableDownloadSourceArchives bool
  45. AllowForkWithoutMaximumLimit bool
  46. // Repository editor settings
  47. Editor struct {
  48. LineWrapExtensions []string
  49. PreviewableFileModes []string
  50. } `ini:"-"`
  51. // Repository upload settings
  52. Upload struct {
  53. Enabled bool
  54. TempPath string
  55. AllowedTypes string
  56. FileMaxSize int64
  57. MaxFiles int
  58. } `ini:"-"`
  59. // Repository local settings
  60. Local struct {
  61. LocalCopyPath string
  62. } `ini:"-"`
  63. // Pull request settings
  64. PullRequest struct {
  65. WorkInProgressPrefixes []string
  66. CloseKeywords []string
  67. ReopenKeywords []string
  68. DefaultMergeStyle string
  69. DefaultMergeMessageCommitsLimit int
  70. DefaultMergeMessageSize int
  71. DefaultMergeMessageAllAuthors bool
  72. DefaultMergeMessageMaxApprovers int
  73. DefaultMergeMessageOfficialApproversOnly bool
  74. PopulateSquashCommentWithCommitMessages bool
  75. AddCoCommitterTrailers bool
  76. TestConflictingPatchesWithGitApply bool
  77. } `ini:"repository.pull-request"`
  78. // Issue Setting
  79. Issue struct {
  80. LockReasons []string
  81. } `ini:"repository.issue"`
  82. Release struct {
  83. AllowedTypes string
  84. DefaultPagingNum int
  85. } `ini:"repository.release"`
  86. Signing struct {
  87. SigningKey string
  88. SigningName string
  89. SigningEmail string
  90. InitialCommit []string
  91. CRUDActions []string `ini:"CRUD_ACTIONS"`
  92. Merges []string
  93. Wiki []string
  94. DefaultTrustModel string
  95. } `ini:"repository.signing"`
  96. }{
  97. DetectedCharsetsOrder: []string{
  98. "UTF-8",
  99. "UTF-16BE",
  100. "UTF-16LE",
  101. "UTF-32BE",
  102. "UTF-32LE",
  103. "ISO-8859-1",
  104. "windows-1252",
  105. "ISO-8859-2",
  106. "windows-1250",
  107. "ISO-8859-5",
  108. "ISO-8859-6",
  109. "ISO-8859-7",
  110. "windows-1253",
  111. "ISO-8859-8-I",
  112. "windows-1255",
  113. "ISO-8859-8",
  114. "windows-1251",
  115. "windows-1256",
  116. "KOI8-R",
  117. "ISO-8859-9",
  118. "windows-1254",
  119. "Shift_JIS",
  120. "GB18030",
  121. "EUC-JP",
  122. "EUC-KR",
  123. "Big5",
  124. "ISO-2022-JP",
  125. "ISO-2022-KR",
  126. "ISO-2022-CN",
  127. "IBM424_rtl",
  128. "IBM424_ltr",
  129. "IBM420_rtl",
  130. "IBM420_ltr",
  131. },
  132. DetectedCharsetScore: map[string]int{},
  133. AnsiCharset: "",
  134. ForcePrivate: false,
  135. DefaultPrivate: RepoCreatingLastUserVisibility,
  136. DefaultPushCreatePrivate: true,
  137. MaxCreationLimit: -1,
  138. PreferredLicenses: []string{"Apache License 2.0", "MIT License"},
  139. DisableHTTPGit: false,
  140. AccessControlAllowOrigin: "",
  141. UseCompatSSHURI: false,
  142. DefaultCloseIssuesViaCommitsInAnyBranch: false,
  143. EnablePushCreateUser: false,
  144. EnablePushCreateOrg: false,
  145. DisabledRepoUnits: []string{},
  146. DefaultRepoUnits: []string{},
  147. PrefixArchiveFiles: true,
  148. DisableMigrations: false,
  149. DisableStars: false,
  150. DefaultBranch: "main",
  151. AllowForkWithoutMaximumLimit: true,
  152. // Repository editor settings
  153. Editor: struct {
  154. LineWrapExtensions []string
  155. PreviewableFileModes []string
  156. }{
  157. LineWrapExtensions: strings.Split(".txt,.md,.markdown,.mdown,.mkd,", ","),
  158. PreviewableFileModes: []string{"markdown"},
  159. },
  160. // Repository upload settings
  161. Upload: struct {
  162. Enabled bool
  163. TempPath string
  164. AllowedTypes string
  165. FileMaxSize int64
  166. MaxFiles int
  167. }{
  168. Enabled: true,
  169. TempPath: "data/tmp/uploads",
  170. AllowedTypes: "",
  171. FileMaxSize: 3,
  172. MaxFiles: 5,
  173. },
  174. // Repository local settings
  175. Local: struct {
  176. LocalCopyPath string
  177. }{
  178. LocalCopyPath: "tmp/local-repo",
  179. },
  180. // Pull request settings
  181. PullRequest: struct {
  182. WorkInProgressPrefixes []string
  183. CloseKeywords []string
  184. ReopenKeywords []string
  185. DefaultMergeStyle string
  186. DefaultMergeMessageCommitsLimit int
  187. DefaultMergeMessageSize int
  188. DefaultMergeMessageAllAuthors bool
  189. DefaultMergeMessageMaxApprovers int
  190. DefaultMergeMessageOfficialApproversOnly bool
  191. PopulateSquashCommentWithCommitMessages bool
  192. AddCoCommitterTrailers bool
  193. TestConflictingPatchesWithGitApply bool
  194. }{
  195. WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
  196. // Same as GitHub. See
  197. // https://help.github.com/articles/closing-issues-via-commit-messages
  198. CloseKeywords: strings.Split("close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved", ","),
  199. ReopenKeywords: strings.Split("reopen,reopens,reopened", ","),
  200. DefaultMergeStyle: "merge",
  201. DefaultMergeMessageCommitsLimit: 50,
  202. DefaultMergeMessageSize: 5 * 1024,
  203. DefaultMergeMessageAllAuthors: false,
  204. DefaultMergeMessageMaxApprovers: 10,
  205. DefaultMergeMessageOfficialApproversOnly: true,
  206. PopulateSquashCommentWithCommitMessages: false,
  207. AddCoCommitterTrailers: true,
  208. },
  209. // Issue settings
  210. Issue: struct {
  211. LockReasons []string
  212. }{
  213. LockReasons: strings.Split("Too heated,Off-topic,Spam,Resolved", ","),
  214. },
  215. Release: struct {
  216. AllowedTypes string
  217. DefaultPagingNum int
  218. }{
  219. AllowedTypes: "",
  220. DefaultPagingNum: 10,
  221. },
  222. // Signing settings
  223. Signing: struct {
  224. SigningKey string
  225. SigningName string
  226. SigningEmail string
  227. InitialCommit []string
  228. CRUDActions []string `ini:"CRUD_ACTIONS"`
  229. Merges []string
  230. Wiki []string
  231. DefaultTrustModel string
  232. }{
  233. SigningKey: "default",
  234. SigningName: "",
  235. SigningEmail: "",
  236. InitialCommit: []string{"always"},
  237. CRUDActions: []string{"pubkey", "twofa", "parentsigned"},
  238. Merges: []string{"pubkey", "twofa", "basesigned", "commitssigned"},
  239. Wiki: []string{"never"},
  240. DefaultTrustModel: "collaborator",
  241. },
  242. }
  243. RepoRootPath string
  244. ScriptType = "bash"
  245. RepoArchive = struct {
  246. Storage
  247. }{}
  248. )
  249. func newRepository() {
  250. var err error
  251. // Determine and create root git repository path.
  252. sec := Cfg.Section("repository")
  253. Repository.DisableHTTPGit = sec.Key("DISABLE_HTTP_GIT").MustBool()
  254. Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool()
  255. Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
  256. Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString(Repository.DefaultBranch)
  257. RepoRootPath = sec.Key("ROOT").MustString(path.Join(AppDataPath, "gitea-repositories"))
  258. forcePathSeparator(RepoRootPath)
  259. if !filepath.IsAbs(RepoRootPath) {
  260. RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath)
  261. } else {
  262. RepoRootPath = filepath.Clean(RepoRootPath)
  263. }
  264. defaultDetectedCharsetsOrder := make([]string, 0, len(Repository.DetectedCharsetsOrder))
  265. for _, charset := range Repository.DetectedCharsetsOrder {
  266. defaultDetectedCharsetsOrder = append(defaultDetectedCharsetsOrder, strings.ToLower(strings.TrimSpace(charset)))
  267. }
  268. ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
  269. if _, err := exec.LookPath(ScriptType); err != nil {
  270. log.Warn("SCRIPT_TYPE %q is not on the current PATH. Are you sure that this is the correct SCRIPT_TYPE?", ScriptType)
  271. }
  272. if err = Cfg.Section("repository").MapTo(&Repository); err != nil {
  273. log.Fatal("Failed to map Repository settings: %v", err)
  274. } else if err = Cfg.Section("repository.editor").MapTo(&Repository.Editor); err != nil {
  275. log.Fatal("Failed to map Repository.Editor settings: %v", err)
  276. } else if err = Cfg.Section("repository.upload").MapTo(&Repository.Upload); err != nil {
  277. log.Fatal("Failed to map Repository.Upload settings: %v", err)
  278. } else if err = Cfg.Section("repository.local").MapTo(&Repository.Local); err != nil {
  279. log.Fatal("Failed to map Repository.Local settings: %v", err)
  280. } else if err = Cfg.Section("repository.pull-request").MapTo(&Repository.PullRequest); err != nil {
  281. log.Fatal("Failed to map Repository.PullRequest settings: %v", err)
  282. }
  283. if !Cfg.Section("packages").Key("ENABLED").MustBool(true) {
  284. Repository.DisabledRepoUnits = append(Repository.DisabledRepoUnits, "repo.packages")
  285. }
  286. // Handle default trustmodel settings
  287. Repository.Signing.DefaultTrustModel = strings.ToLower(strings.TrimSpace(Repository.Signing.DefaultTrustModel))
  288. if Repository.Signing.DefaultTrustModel == "default" {
  289. Repository.Signing.DefaultTrustModel = "collaborator"
  290. }
  291. // Handle preferred charset orders
  292. preferred := make([]string, 0, len(Repository.DetectedCharsetsOrder))
  293. for _, charset := range Repository.DetectedCharsetsOrder {
  294. canonicalCharset := strings.ToLower(strings.TrimSpace(charset))
  295. preferred = append(preferred, canonicalCharset)
  296. // remove it from the defaults
  297. for i, charset := range defaultDetectedCharsetsOrder {
  298. if charset == canonicalCharset {
  299. defaultDetectedCharsetsOrder = append(defaultDetectedCharsetsOrder[:i], defaultDetectedCharsetsOrder[i+1:]...)
  300. break
  301. }
  302. }
  303. }
  304. i := 0
  305. for _, charset := range preferred {
  306. // Add the defaults
  307. if charset == "defaults" {
  308. for _, charset := range defaultDetectedCharsetsOrder {
  309. canonicalCharset := strings.ToLower(strings.TrimSpace(charset))
  310. if _, has := Repository.DetectedCharsetScore[canonicalCharset]; !has {
  311. Repository.DetectedCharsetScore[canonicalCharset] = i
  312. i++
  313. }
  314. }
  315. continue
  316. }
  317. if _, has := Repository.DetectedCharsetScore[charset]; !has {
  318. Repository.DetectedCharsetScore[charset] = i
  319. i++
  320. }
  321. }
  322. if !filepath.IsAbs(Repository.Upload.TempPath) {
  323. Repository.Upload.TempPath = path.Join(AppWorkPath, Repository.Upload.TempPath)
  324. }
  325. RepoArchive.Storage = getStorage("repo-archive", "", nil)
  326. }