Compare commits

..

696 Commits

Author SHA1 Message Date
无闻
4f74b4e657 Merge pull request #483 from pkgr/dev
Add new distributions on https://packager.io/gh/pkgr/gogs
2014-09-18 12:21:00 -04:00
Cyril Rohr
31d763bc1f Add new distributions on https://packager.io/gh/pkgr/gogs
* ubuntu 12.04
* debian 7
2014-09-18 13:56:44 +00:00
Unknwon
a596388ebf Add success message after transfer repository #481 2014-09-17 14:52:46 -04:00
Unknwon
8a09256941 Mirror fix and fix #481 2014-09-17 14:22:51 -04:00
无闻
c03f5a2c7c Merge pull request #480 from compressed/correct_push_user
clarify name/username/owner/pusher for webhook
2014-09-17 14:13:54 -04:00
Christopher Brickley
f94d7c3f51 clarify name/username/owner/pusher for webhook 2014-09-17 09:20:14 -04:00
lunnyxiao
061a879cea Merge branch 'dev' of github.com:gogits/gogs into dev
Conflicts:
	conf/app.ini
2014-09-17 12:04:18 +08:00
lunnyxiao
ed84adb679 toutf8 improved & add max git diff lines 2014-09-17 12:03:03 +08:00
无闻
9f015b4c73 Merge pull request #479 from quux/dev
French translation
2014-09-16 21:25:57 -04:00
Philippe Barsalou
bc3abb397f typos 2014-09-16 20:58:17 -04:00
Philippe Barsalou
9e10304ab2 started french localization 2014-09-16 20:58:17 -04:00
Unknwon
ae3639868e Quick fix on #476 2014-09-16 20:58:06 -04:00
无闻
d082e821a0 Merge pull request #477 from fanningert/dev
Intial commit for systemd support
2014-09-16 14:21:37 -04:00
Thomas Fanninger
78bd144c1c Intial commit for systemd support 2014-09-16 20:10:21 +02:00
Unknown
ebb4f1b78c Work #475 and #458 2014-09-16 13:34:09 -04:00
Unknwon
62f21ff3ed Work on #476 2014-09-16 11:29:53 -04:00
Unknwon
0d9c41be7d Work on #476 2014-09-16 10:10:33 -04:00
Unknwon
c1ceec45da Fix mirror UI style and work on #475 2014-09-16 08:32:13 -04:00
Unknwon
b162e565b3 Merge branch 'master' of github.com:gogits/gogs into dev 2014-09-16 08:04:29 -04:00
无闻
6516ecaa51 Merge pull request #473 from j100002ben/master
Fix TimeSince arguments error.
2014-09-16 07:35:33 -04:00
无闻
5163d368e3 Merge pull request #474 from tobyzxj/dev
fix user's actions on domain/org/name-of-organization/dashboard
2014-09-16 07:29:03 -04:00
tobyzxj
ad041167f7 fix user's actions on domain/org/name-of-organization/dashboard 2014-09-16 16:20:32 +08:00
Benjamin Peng
cff3ca23a5 Fix TimeSince arguments error. 2014-09-16 15:55:41 +08:00
Unknwon
41386fa91a Fix UI 2014-09-15 22:35:05 -04:00
Unknwon
ea309acdb2 Fix #468 2014-09-15 17:23:58 -04:00
Unknwon
0f037b430a Fix #464 2014-09-15 10:09:17 -04:00
Unknwon
632b1b694d Fix #465 2014-09-15 09:56:12 -04:00
Unknwon
efb68a0a96 Fix UI issue 2014-09-14 19:22:52 -04:00
Unknwon
7027ac9308 Fix #461 2014-09-14 16:43:22 -04:00
Unknwon
b9560374cd UI fix 2014-09-13 22:12:11 -04:00
Unknwon
a5926f2689 add missing style 2014-09-13 15:07:09 -04:00
无闻
f1304bde34 Merge pull request #460 from 4d47/rm-app-logo
Remove APP_LOGO setting
2014-09-13 14:08:19 -04:00
Mathieu Gagnon
3549fb0ea8 Remove APP_LOGO setting 2014-09-13 03:52:51 -04:00
Unknwon
a2cac952a4 Prepare 0.5 release 2014-09-12 21:36:26 -04:00
Unknwon
bba401a5dc Prepare 0.5 release 2014-09-12 19:42:11 -04:00
Unknwon
1b7adf57e9 fix https://github.com/go-xorm/xorm/issues/161 2014-09-12 18:58:24 -04:00
Unknwon
cfed11f092 Bug: Transfer repository doesn't update the count 2014-09-12 18:29:58 -04:00
lunnyxiao
f67c59135f build script fixed 2014-09-12 14:45:38 +08:00
Unknwon
fdc8c34258 Fix clone panel z-index 2014-09-10 11:32:14 -04:00
无闻
18a80b291b Merge pull request #456 from compressed/send_hook_immediately
Deliver hooks immediately after commit
2014-09-10 09:36:12 -04:00
Christopher Brickley
52d15ddec8 deliver hooks immediately after commit 2014-09-10 08:57:11 -04:00
Unknwon
2a3660dae3 Fix #453 2014-09-09 18:19:57 -04:00
无闻
09ca5d125a Merge pull request #455 from pkgr/pkgr-dev
Make Gogs packageable with https://packager.io
2014-09-09 16:53:31 -04:00
Cyril Rohr
27cb01cd5f Move into packager folder 2014-09-09 20:29:39 +00:00
Cyril Rohr
7fe61558f6 Make Gogs packageable with https://packager.io 2014-09-09 18:31:32 +00:00
Unknwon
33659ed9a5 Fix #452 2014-09-09 10:17:35 -04:00
无闻
e004ec08e9 Merge pull request #451 from compressed/hook_task_upd
update specific hook_task, not all
2014-09-09 09:09:22 -04:00
Christopher Brickley
132590fab8 update specific hook_task, not all 2014-09-09 08:37:34 -04:00
lunnyxiao
e21d8a7d35 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-09-08 12:11:48 +08:00
lunnyxiao
d84d6dfdae add showinfo for xorm 2014-09-08 12:11:25 +08:00
无闻
b92384020c Merge pull request #435 from tstorch/translation-update
Small German update
2014-09-07 23:53:59 -04:00
Unknwon
d89e630bc0 Fix test cases 2014-09-07 20:11:13 -04:00
Unknwon
59a7c7c5a5 Remove ldap dep 2014-09-07 20:04:47 -04:00
Unknwon
25d6ae69d1 Remove hg dep 2014-09-07 19:58:01 -04:00
Unknwon
f8977f4847 Organization level webhooks 2014-09-07 19:39:26 -04:00
无闻
e79e4b1580 Merge pull request #442 from compressed/org_hook
Organization-level Webhooks
2014-09-07 19:30:51 -04:00
无闻
40bc130b19 Merge pull request #447 from m0sth8/fix-milestone-render-markdown
Render milestone content as markdown
2014-09-07 19:19:10 -04:00
Unknwon
0ddb1eb769 Finish new install page, almost ready for 0.5 release 2014-09-07 19:02:58 -04:00
Unknwon
ab7206d6b7 Fix #348 2014-09-05 17:28:09 -04:00
Christopher Brickley
f7be61c819 getOrgRepoCtx returns values directly & err 2014-09-05 07:19:34 -04:00
Christopher Brickley
85c35a6b8b add organization-level webhooks 2014-09-05 07:19:34 -04:00
Christopher Brickley
7269b06fd5 HookType is case-sensitive
Update webhook wasn’t showing up because of the wrong case
2014-09-05 07:19:34 -04:00
Christopher Brickley
8d2fe064c5 modify grammar undo -> undone 2014-09-05 07:19:33 -04:00
Vyacheslav Bakhmutov
6498fce04b Render milestone content as markdown 2014-09-05 09:10:58 +07:00
无闻
033a7f0224 Merge pull request #446 from m0sth8/fix-milestone-content-size
Set milestone content field to TEXT orm type
2014-09-04 21:55:17 -04:00
Vyacheslav Bakhmutov
31d8011843 Set milestone content field to TEXT orm type 2014-09-05 08:10:41 +07:00
无闻
d8290c9bac Merge pull request #444 from tstorch/database-cleanup
Code dedoublication in models/models.go
2014-09-04 11:38:35 -04:00
Tristan Storch
bdfdf3cacb Code dedoublication in models/models.go
Just some code dedoublication in models/models.go
2014-09-04 17:19:26 +02:00
Lunny Xiao
8db8771be7 Merge pull request #441 from tstorch/git-setup
Standard git user.name and user.email if not set
2014-09-04 22:55:05 +08:00
Tristan Storch
9fc4ded369 Standard git user.name and user.email if not set
Git user.name and user.email will now be set to the standard values

  - Gogs
  - gogitservice@gmail.com

if user.name is not set or empty.

If user.name is set and user.email not, it will leave it this way.
2014-09-04 12:07:09 +02:00
无闻
881ee6a4df Merge pull request #440 from deringer/dev
Correct loading of font-awesome styles from CDN
2014-09-03 21:40:33 -04:00
Michael Dyrynda
aee46bac01 add rel attribute such that font-awesome icons load correctly 2014-09-04 09:12:51 +09:30
无闻
714de0a3af Merge pull request #437 from tstorch/docker-update
Use variables, when the're there
2014-09-03 14:11:45 -04:00
Tristan Storch
863a4d5bc4 Use variables, when the're there
Why not use the environment variables, when they are there...
2014-09-03 18:44:15 +02:00
无闻
f36f9e07b7 Merge pull request #436 from tstorch/docker-update
docker dev block update
2014-09-03 11:35:59 -04:00
Tristan Storch
7df0794e14 docker dev block update
The dev Dockerfile now works without superfluous go get calls.
At this point the -u option is really not what we want.
2014-09-03 17:12:38 +02:00
Tristan Storch
000b906259 Small German update
Cleaning up a misunderstanding I had.
2014-09-03 16:58:23 +02:00
无闻
87b442433c Merge pull request #432 from deringer/dev
Add handling to branch switcher label to make label more consistent with
2014-09-03 10:33:08 -04:00
无闻
097f1b5759 Merge pull request #426 from m0sth8/fix-milestone-assignee
Take params for milestone and assignee from query instead of path args
2014-09-03 09:02:47 -04:00
Michael Dyrynda
dcb10a41d4 Add handling to branch switcher label to make label more consistent with
GitHub behaviour

Addresses #431
2014-09-03 10:01:32 +09:30
Vyacheslav Bakhmutov
2a7a03e5b3 take params for milestone and assignee from query instead of path args 2014-09-03 00:04:22 +07:00
Unknwon
05a33107c9 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-09-02 13:01:09 -04:00
Unknwon
8b0e815d98 Fix #425 2014-09-02 13:01:02 -04:00
无闻
f19fc230d4 Merge pull request #423 from m0sth8/fix-xcsrf-token
Set headers in js and go files to X-Csrf-Token
2014-09-02 12:30:44 -04:00
Vyacheslav Bakhmutov
9476e58de9 Set headers in js and go files to X-Csrf-Token 2014-09-02 22:48:40 +07:00
无闻
9ddd545473 Merge pull request #421 from arpemedia/dev
Fix grammar error in German translation
2014-09-02 10:49:53 -04:00
Arpemedia
0730ec4087 Fix grammar error in German translation 2014-09-02 13:46:18 +02:00
Unknwon
8826186c30 Merge branch 'master' of github.com:gogits/gogs into dev 2014-09-02 07:18:01 -04:00
无闻
565974f8f7 Merge pull request #420 from gogits/revert-419-master
Revert "Fix a gramma error and translate two additional strings (German ...
2014-09-02 07:15:35 -04:00
无闻
399887cc0e Revert "Fix a gramma error and translate two additional strings (German translation)" 2014-09-02 07:13:13 -04:00
无闻
fd5ea4b79e Merge pull request #419 from arpemedia/master
Fix a gramma error and translate two additional strings (German translation)
2014-09-02 07:13:09 -04:00
Unknwon
830efc90da update docs and mirror bug fix 2014-09-02 07:11:39 -04:00
Arpemedia
8e0aeb4ad5 Fix a gramma error and translate two additional strings 2014-09-02 09:20:39 +02:00
lunnyxiao
c80f0232f1 Merge branch 'master' into dev 2014-09-02 11:59:39 +08:00
lunnyxiao
1240fef0ca bug fixed for migrate and fixed #141 2014-09-02 11:57:06 +08:00
无闻
85f375433d Merge pull request #416 from compressed/compare_commits
Add commit compare functionality
2014-09-01 20:02:34 -07:00
Christopher Brickley
af0741da07 handle initial commit for compareUrl 2014-09-01 19:19:56 -04:00
Christopher Brickley
00a864e693 add commit compare functionality 2014-09-01 14:56:19 -04:00
无闻
d55c5b9e28 Merge pull request #410 from tstorch/docker_mix_match
Docker mix and match setup
2014-09-01 10:53:51 +08:00
无闻
bc67c34bea Merge pull request #409 from tstorch/translation-03
German laguage update
2014-09-01 10:53:18 +08:00
Tristan Storch
d1a2228f1c Docker mix and match setup
Rewrite of the docker setup. Now uses fig to manage containers and container
linkage. The base is a block based mix and match, which will give you the
possibility to easily test all configurations.
2014-08-31 21:00:19 +02:00
Tristan Storch
7b310b1abb German laguage update
What has been done:

  - standardized expressions
  - shorter and clearer
  - minor corrections (orthography)
2014-08-31 19:29:03 +02:00
无闻
2886eb76b6 Merge pull request #408 from fanningert/patch-1
Add new translation keys
2014-09-01 00:50:52 +08:00
fanningert
1858d2066b Add new translation keys 2014-08-31 18:48:24 +02:00
无闻
3e740278bd Merge pull request #407 from fanningert/patch-3
Update locale_de-DE.ini and correct a wrong translation
2014-09-01 00:36:23 +08:00
无闻
9611f29966 Merge pull request #402 from fanningert/patch-2
Add missing dependencies
2014-09-01 00:34:06 +08:00
Unknwon
c5ce33047e Mirror fix and hide missing pages for 0.5 release 2014-09-01 00:33:40 +08:00
fanningert
da8dba53a7 Removed not needed deps
Removed
* github.com/gogits/cache
* github.com/gogits/session
2014-08-31 18:28:59 +02:00
Unknwon
bf5595f9a0 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-09-01 00:16:14 +08:00
无闻
1ed67798ac Merge pull request #379 from compressed/slack
Slack Support
2014-09-01 00:12:58 +08:00
Unknwon
36661f53e6 Update deps 2014-09-01 00:12:37 +08:00
fanningert
801fc536f2 Update locale_de-DE.ini 2014-08-31 18:05:26 +02:00
fanningert
99e009665c Update locale_de-DE.ini 2014-08-31 18:04:15 +02:00
fanningert
72ec3e8da0 Update locale_de-DE.ini 2014-08-31 18:03:28 +02:00
Christopher Brickley
2bce24068d add Slack API webhook support 2014-08-31 12:01:59 -04:00
fanningert
9554ad514e Change "Repositories" to "Repositorys" 2014-08-31 17:59:22 +02:00
fanningert
df3621e050 Update locale_de-DE.ini and correct a wrong translation 2014-08-31 17:30:53 +02:00
无闻
5e6091a30a Merge pull request #405 from fanningert/patch-1
Update german translation with PR #404
2014-08-31 22:10:54 +08:00
fanningert
80447f1168 Update german translation with PR #404 2014-08-31 16:10:02 +02:00
无闻
bc1a578914 Merge pull request #401 from fanningert/patch-1
Update locale_de-DE.ini
2014-08-31 22:06:05 +08:00
fanningert
cc9a84b83a Add missing dependencies 2014-08-31 15:21:56 +02:00
fanningert
c30063eefb Update locale_de-DE.ini 2014-08-31 15:18:29 +02:00
无闻
ae2f4866d0 Merge pull request #400 from deringer/dev
Add missing 'new migration' link
2014-08-31 21:07:14 +08:00
Unknwon
676bd764fa UI: SSH/HTTPS address switch and copy 2014-08-31 21:03:16 +08:00
Michael Dyrynda
1bbf4c9768 Add missing 'new migration' link
Addresses issue #399
2014-08-31 21:06:50 +09:30
Unknwon
7e36bf448d Merge branch 'master' of github.com:gogits/gogs into dev
Conflicts:
	dockerfiles/README.md
2014-08-31 15:11:55 +08:00
无闻
d78008b546 Merge pull request #396 from fanningert/patch-1
Update locale_zh-CN.ini
2014-08-31 11:30:13 +08:00
无闻
1d6df04ecb Merge pull request #397 from fanningert/patch-2
Update locale_en-US.ini
2014-08-31 11:30:02 +08:00
无闻
084dce53ac Merge pull request #398 from fanningert/patch-3
Update locale_de-DE.ini
2014-08-31 11:28:13 +08:00
fanningert
5cdecd74c7 Update locale_de-DE.ini 2014-08-30 22:29:23 +02:00
fanningert
85e01bfe01 Update locale_en-US.ini
Double entry of "config.log_config"
2014-08-30 22:28:43 +02:00
fanningert
73ddf401ee Update locale_zh-CN.ini
Double entry of "config.log_config"
2014-08-30 22:28:03 +02:00
无闻
4c8ef90157 Merge pull request #394 from tstorch/trailing_white_spaces
Removed trailing white spaces
2014-08-30 06:37:04 -07:00
Tristan Storch
69e332f432 Removed trailing white spaces
Removed trailing whitespaces with

```sh
for file in `grep -r " $" * | cut -d : -f 1 | sort | uniq | grep -v " "`; do sed -i 's/[ \t]*$//' $file; done
```

and some handwork.
2014-08-30 15:12:53 +02:00
Unknwon
9bc63bda7d Finish all new admin pages. 2014-08-30 20:49:51 +08:00
无闻
66d51804c9 Merge pull request #391 from fanningert/patch-1
Update locale_en-US.ini
2014-08-30 04:30:35 -07:00
无闻
444032664b Merge pull request #392 from fanningert/patch-2
Update locale_de-DE.ini
2014-08-30 04:30:20 -07:00
fanningert
272d387c0c Update locale_de-DE.ini 2014-08-30 12:48:14 +02:00
fanningert
32760ba49d Update locale_en-US.ini 2014-08-30 12:47:51 +02:00
无闻
08dbf08d39 Merge pull request #386 from fanningert/patch-2
Update locale_de-DE.ini
2014-08-29 05:53:48 -07:00
Unknwon
d2aff9a46a Continue working on new admin pages 2014-08-29 20:50:43 +08:00
fanningert
56b735f67b Update locale_de-DE.ini
Add missing translation keys and add some german translations
2014-08-29 14:25:29 +02:00
Unknwon
904bf1a50b Add migrate repo API 2014-08-29 17:31:53 +08:00
Unknwon
8829174574 Finish new admin users pages 2014-08-29 15:32:52 +08:00
无闻
6558990e3a Merge pull request #384 from fanningert/patch-1
Update locale_de-DE.ini
2014-08-28 20:56:42 -07:00
lunnyxiao
a6ec6def8d Merge branch 'dev' of github.com:gogits/gogs into dev 2014-08-29 11:25:03 +08:00
lunnyxiao
c40e815763 add migrate api 2014-08-29 11:24:37 +08:00
fanningert
c4a33892d3 Update locale_de-DE.ini
Add missing translation of "locale_en-US.ini"
2014-08-28 19:12:30 +02:00
Unknwon
1aec1a2dda Finish new admin dashboard 2014-08-28 22:29:00 +08:00
Unknwon
81287ba022 Mirror issue fix 2014-08-27 22:40:45 +08:00
Unknwon
9baf2b38d0 Bug fix on organization 2014-08-27 16:39:36 +08:00
Unknwon
50de06056b Merge branch 'dev' of github.com:gogits/gogs into dev 2014-08-26 18:11:27 +08:00
Unknwon
74b31566cf Finsih add/remove repo in organization 2014-08-26 18:11:15 +08:00
无闻
66c9c86219 Merge pull request #371 from m0sth8/bufix_migrate_all_branches
Migrate all branches and tags
2014-08-25 19:38:41 -07:00
无闻
ce55807542 Merge pull request #372 from andmarios/dev
Remove newline characters from ssh key before processing it.
2014-08-25 19:13:58 -07:00
Marios Andreopoulos
510d5a5d74 import strings 2014-08-25 21:07:08 +03:00
Marios Andreopoulos
cd0ddcfa01 fix typo 2014-08-25 20:35:23 +03:00
Marios Andreopoulos
3d79f59671 fix wrong variable name 2014-08-25 20:20:44 +03:00
Marios Andreopoulos
b40922f4d4 remove extra comma 2014-08-25 20:07:47 +03:00
Marios Andreopoulos
12639c577f Remove newline characters from ssh key before processing it.
Fixes issue #370: https://github.com/gogits/gogs/issues/370
2014-08-25 18:54:50 +03:00
Vyacheslav Bakhmutov
95a594d75a Migrate all branches and tags 2014-08-25 20:28:14 +07:00
Unknwon
f2c263c54f fix #367 2014-08-25 09:45:39 +08:00
Unknwon
21a1b8e5a3 Finish new edit team page, add member to team 2014-08-24 21:09:05 +08:00
Lunny Xiao
03c6a395aa Merge pull request #365 from choas/patch-1
update dockerfiles README.md
2014-08-24 20:42:50 +08:00
Lars Gregori
1661421a65 update dockerfiles README.md
typo
2014-08-24 12:39:01 +02:00
Unknwon
e325c8499a Fix and set git config 2014-08-23 23:58:56 +08:00
Unknwon
97a373f5e7 Fix #362, update code with upstream 2014-08-23 21:13:55 +08:00
Unknwon
b765229a6d Fix code style 2014-08-23 20:30:29 +08:00
Unknwon
e0a2d23baf Merge branch 'dev' of github.com:gogits/gogs into dev 2014-08-23 20:24:31 +08:00
Unknwon
fa60502a70 Working on organization pages 2014-08-23 20:24:02 +08:00
lunnyxiao
97fb62f51e auto detect text file encode and convert to utf8 2014-08-20 16:34:48 +08:00
Unknwon
a60edbe88c Add/remove member need add/remove access to repositories as well 2014-08-16 16:58:32 +08:00
Unknwon
bba707de36 Finish team list, create new team, join/leave team page 2014-08-16 16:21:17 +08:00
Unknwon
78add502d7 Finish new organization members and invitation page 2014-08-15 23:37:33 +08:00
Unknwon
36b4c57ff1 Finish new organization members and invitation page 2014-08-15 18:29:41 +08:00
无闻
3e32b14ad4 Merge pull request #359 from fanningert/dev
Correct some type issues in the English translation and update the German translation
2014-08-14 15:56:25 -07:00
fanningert
202a29a475 Correct type issue in locale_en-US.ini 2014-08-14 21:56:56 +02:00
fanningert
352d8943e4 German translation updated 2014-08-14 21:54:11 +02:00
fanningert
ccc20f7c70 Correct type issue in locale_en-US.ini 2014-08-14 21:52:01 +02:00
无闻
5fbf27bb07 Merge pull request #358 from fanningert/dev
Correct some type issues in the english locale file
2014-08-14 06:36:31 -07:00
fanningert
d0dd90958a Initial release of german translation 2014-08-14 10:55:07 +02:00
fanningert
ba8b6f5d78 Correct some type issues 2014-08-14 10:53:08 +02:00
fanningert
872cd0d3bd Correct some type issues 2014-08-14 10:51:55 +02:00
Unknwon
5acc948562 Page: /org/:orgname/settings 2014-08-14 14:12:21 +08:00
无闻
2935ee440c Merge pull request #357 from rojaro/patch-1
Update locale_en-US.ini
2014-08-14 09:17:47 +08:00
rojaro
371372d65d Update locale_en-US.ini
Fixed typo
2014-08-13 11:24:24 +02:00
Unknwon
5fbf8531e6 Finish new home page of organization 2014-08-10 20:11:18 -07:00
Unknwon
7af7584d25 Finish new reset password, etc. 2014-08-09 21:02:00 -07:00
Unknwon
5605af973b Feature: Social sign in 2014-08-09 18:01:29 -07:00
Unknwon
78defd238c Page: Manage social accounts 2014-08-09 17:25:02 -07:00
Unknwon
08c6d07aad UI: Bare repository does not have visual link to settings page 2014-08-09 15:50:06 -07:00
Unknwon
9a1d5d2489 Finish new web hook pages 2014-08-09 15:40:10 -07:00
Unknwon
9820b8e134 Finish new hooks list page 2014-08-09 10:29:51 -07:00
lunnyxiao
7c7014262b Merge branch 'dev' of github.com:gogits/gogs into dev 2014-08-08 13:51:43 +08:00
lunnyxiao
57f6ec672a bug fixed 2014-08-08 13:51:02 +08:00
Unknwon
9d5c0c80a4 Mirror fix on #352 2014-08-07 06:45:29 -04:00
无闻
e527c9b330 Merge pull request #352 from DerDackel/ssh-permissions
Ensure correct permissions on .ssh and authorized_keys file
2014-08-07 06:43:58 -04:00
Unknwon
e8c9bb2c66 Finish new collaboration page 2014-08-07 06:40:05 -04:00
Sebastian Jackel
0bfbefc38a Moved defer f.Close() up so there is no chance of returning without closing and handled an error on f.Chmod 2014-08-07 11:06:42 +02:00
Sebastian Jackel
51abaf788c Corrected log message 2014-08-07 10:34:37 +02:00
Sebastian Jackel
be7ce72ebe Make sure, .ssh directory and authorized_keys file are kept at correct permissions 2014-08-07 10:00:57 +02:00
Unknwon
99eeb08419 nowarp fix 2014-08-07 00:15:39 -04:00
Unknwon
a8e05fdf1b Use toolbox 2014-08-06 17:21:24 -04:00
Unknwon
6fc2107529 Add missing less files 2014-08-05 21:18:29 -04:00
Unknwon
fa0a389dc4 Fix bare repo bug 2014-08-05 19:40:01 -04:00
无闻
6f6fda1481 Merge pull request #347 from nuss-justin/dev
Fix wrong selector for AJAX issue creation.
2014-08-04 13:47:43 -04:00
无闻
5f84e8f4ff Merge pull request #346 from nuss-justin/vet
Fix invalid struct tags and remove unreachable code.
2014-08-04 13:46:23 -04:00
Justin Nuß
2cb754b5af Fix wrong selector for AJAX issue creation. 2014-08-04 11:02:29 +02:00
Justin Nuß
8023494a94 Fix invalid struct tags and remove unreachable code. 2014-08-04 10:37:57 +02:00
Unknwon
755eec745f Finish new repo settings page 2014-08-02 13:47:33 -04:00
Unknwon
669552e255 Fix #340 2014-08-01 06:12:14 -04:00
Unknwon
17d2675dd2 Fix #258 2014-08-01 05:20:33 -04:00
Unknwon
b95e78f7e6 Mirro fix on PR #311 2014-08-01 00:24:29 -04:00
无闻
568c9b353e Merge pull request #311 from nuss-justin/issue/281
Fix #281. Add mouse-over precise time and on-click switch listener.
2014-08-01 00:15:06 -04:00
Unknwon
dabf5b057c Finish new migrate page 2014-08-01 00:06:19 -04:00
Unknwon
7bbf644dd5 Convert captcha, cache, csrf as middlewares 2014-07-31 17:25:34 -04:00
Unknwon
3428baa3b5 Mirror fix on template 2014-07-30 10:02:31 -04:00
无闻
78672b9227 Merge pull request #338 from gogits/revert-335-patch-1
Revert "actually use SshPort variable"
2014-07-28 11:23:02 -04:00
无闻
8453ffb7ed Revert "actually use SshPort variable" 2014-07-28 11:22:53 -04:00
无闻
645c194a00 Merge pull request #336 from adelq/responsive-layouts
Avoid using fixed width in CSS for layouts
2014-07-28 06:27:33 -04:00
Adel Qalieh
d4cbbc864a Avoid using fixed width in CSS for layouts 2014-07-27 20:06:43 -04:00
无闻
b1185e121f Merge pull request #335 from taziden/patch-1
actually use SshPort variable
2014-07-27 18:38:07 -04:00
taziden
febaddfd1d actually use SshPort variable
SshPort is defined (SSH_PORT) but the value is not actually used (just compared to default port 22).
2014-07-27 20:32:41 +02:00
Unknwon
9813161411 Reser repo owner to organization when error occurs in repo create page, dashboard news feed page, create organization page 2014-07-26 23:53:16 -04:00
Unknwon
5e81383413 Git installation check, show image in single file view, show short SHA1 instead of 40-length string, complete log module 2014-07-26 18:37:18 -04:00
无闻
02a81ddb62 Merge pull request #332 from acusti/dev
Styling plus a couple small fixes for issue attachments (& misc cleanup)
2014-07-26 13:55:32 -04:00
无闻
27a51f5bcc Merge pull request #331 from nuss-justin/dev
Use :index instead of :issue in UpdateIssueMilestone
2014-07-26 13:54:05 -04:00
Justin Nuß
91480f3791 Merge branch 'dev' of https://github.com/gogits/Gogs into issue/281
Conflicts:
	modules/base/tool.go
2014-07-26 11:23:58 +02:00
Justin Nuß
7de3dd01de Use :index instead of :issue in UpdateIssueMilestone 2014-07-26 11:10:49 +02:00
Unknwon
35c75f06a0 Fix test case 2014-07-26 03:05:56 -04:00
Unknwon
545d320648 Docs fix 2014-07-26 03:02:46 -04:00
Unknwon
5c4bc3c848 Huge updates!!!!! Be careful to merge!!!! 2014-07-26 02:28:04 -04:00
Unknwon
3f38ff6c09 Merge branch 'dev' of github.com:gogits/gogs into dev
Conflicts:
	templates/status/500.tmpl
2014-07-26 00:25:43 -04:00
Unknwon
8dd07c0ddd New UI merge in progress 2014-07-26 00:24:27 -04:00
无闻
76f7ad45e6 Merge pull request #329 from ciarand/feature/update-docs
Update the Docker instructions in the README
2014-07-26 00:21:28 -04:00
无闻
872590d8b5 Merge pull request #330 from ciarand/reword-language-on-error-pages
Reword the language on the error page templates
2014-07-26 00:21:07 -04:00
Ciaran Downey
7921e60f30 Change "an error is occurred" to "has occurred" 2014-07-25 20:51:05 -07:00
Ciaran Downey
0db84e4f63 Update the Docker instructions in the README 2014-07-25 20:13:17 -07:00
无闻
0a739cf9ac Merge pull request #325 from nuss-justin/dev
Remove 'None yet' message when adding first label to issue.
2014-07-25 20:58:31 -04:00
无闻
3e23241f58 Merge pull request #327 from ciarand/dev
Update the Docker build's Go source and version
2014-07-25 19:13:05 -04:00
Andrew Patton
6407caa761 Semicolons for consistency ;); 2014-07-25 17:51:41 -04:00
Andrew Patton
ef8eef7519 Trivial cleanup
using `event.preventDefault` instead of `return false` for being more
explicit
2014-07-25 17:51:18 -04:00
Andrew Patton
71cefc95ab Use console.log instead of breakpoint 2014-07-25 17:50:25 -04:00
Andrew Patton
957361d755 Fix typos 2014-07-25 17:50:03 -04:00
Andrew Patton
cd369b667f Fix “Submitting” state of Close issue input
If .btn-default isn’t removed, .btn-default and .btn-warning styles
conflict
2014-07-25 17:49:51 -04:00
Andrew Patton
ef430ae7ab Small whitespace cleanup 2014-07-25 17:48:26 -04:00
Andrew Patton
a447aecd95 Fix for erroneous Submitting mode on button
Click handler was also attaching to “Select Attachments” button, so
modified selector to grab #issue-reply-btn by ID and submit button
2014-07-25 17:47:01 -04:00
Ciaran Downey
aea2b54c99 Use the official Go source, follow redirects 2014-07-25 12:59:10 -07:00
Ciaran Downey
cf3021ecca Add the set -e option to dockerfiles/build.sh 2014-07-25 12:59:02 -07:00
Andrew Patton
c084a5ba73 Style finesse for “Attachments:” list in issues
Make `#attached-list` attachment labels wrap, make spacing more
consistent, add hover stats to `.attachment-remove` icon, adjust
padding of labels to compensate for `.attachment-remove` icon
2014-07-25 15:35:47 -04:00
无闻
5ed5912ef5 Merge pull request #326 from nuss-justin/feature/keep-text
Save comment/issue drafts in sessionStorage.
2014-07-25 15:05:45 -04:00
Justin Nuß
09cb8c67cb Save comment/issue drafts in sessionStorage. 2014-07-25 20:56:17 +02:00
Justin Nuß
a03a1e87e9 Remove 'None yet' message when adding first label to issue. 2014-07-25 20:15:58 +02:00
无闻
aad91d4b21 Merge pull request #324 from nuss-justin/issue/318
Fix #318. Issues attachments: allow Select Attachments to append files
2014-07-25 13:35:25 -04:00
Justin Nuß
f0da8a68c2 Remove debug comment. 2014-07-25 15:47:42 +02:00
Justin Nuß
12fb42de5a Fix IE bug and show errors. 2014-07-25 11:13:42 +02:00
Justin Nuß
4e2477a1a5 Fix #318. Switch to JS(ON) implementation for issue/comment creation. 2014-07-25 10:47:37 +02:00
Justin Nuß
f7617997ce Ignore EOF error when parsing form. 2014-07-25 10:18:42 +02:00
无闻
204ef41b09 Merge pull request #322 from nuss-justin/issue/321
Fix #321. Allow empty comments as long as there are attachments.
2014-07-25 02:41:22 -04:00
Justin Nuß
dedb156d4a Fix #321. Allow empty comments as long as there are attachments. 2014-07-25 08:01:34 +02:00
无闻
30d7397f97 Merge pull request #314 from nuss-justin/issue/312
Fix #312. Quote file names of attachments.
2014-07-25 01:14:33 -04:00
无闻
0f3414ec39 Merge pull request #315 from nuss-justin/issue/313
Fix #313. Repair broken image extension detection regex.
2014-07-25 01:14:02 -04:00
无闻
2032080d86 Merge pull request #320 from acusti/patch-2
Fix #319 (user not-logged in error)
2014-07-25 01:10:52 -04:00
Andrew Patton
8ccde45c5f Fix #319 (user not-logged in error) 2014-07-24 18:23:46 -04:00
Justin
eafa365453 Fix #313. Repair broken image extension detection regex. 2014-07-24 23:19:21 +02:00
Justin
ad7beb78d0 Fix #312. Quote file names of attachments. 2014-07-24 23:13:35 +02:00
Justin Nuß
835e85b5ce Fix #281. Add mouse-over precise time and on-click switch listener. 2014-07-24 22:31:59 +02:00
无闻
c4eeb803e1 Merge pull request #310 from nuss-justin/issue/303
Fix #303. Specify updated columns explicitly.
2014-07-24 15:26:04 -04:00
Justin Nuß
3e7e9ee289 Fix #303. Specify updated columns explicitly. 2014-07-24 20:07:07 +02:00
无闻
87855d42a0 Merge pull request #309 from nuss-justin/trello/244
[Trello#244] Mention all members of team by mention team name
2014-07-24 13:25:00 -04:00
Justin Nuß
620c0ef297 Merge branch 'dev' of https://github.com/gogits/Gogs into trello/244 2014-07-24 19:15:35 +02:00
Justin Nuß
cbcd08aa17 Mention organisation users when organisation gets mentioned 2014-07-24 19:15:31 +02:00
Unknwon
c20f5dc2ea Merge branch 'dev' of github.com:gogits/gogs into dev 2014-07-24 12:49:43 -04:00
Unknwon
a41a1fe60d Mirror fix 2014-07-24 12:49:40 -04:00
无闻
da0240aacd Merge pull request #307 from nuss-justin/feature/attachments
Feature: Ability to attach files to issues (attachments)
2014-07-24 12:47:55 -04:00
Justin Nuß
9a7349ce64 Change Attachment.Path to TEXT (no maximum size) 2014-07-24 17:02:42 +02:00
Justin Nuß
4d702eb345 Allow disabling uploads 2014-07-24 15:51:40 +02:00
Justin Nuß
9df99681fb Update default config with comments 2014-07-24 15:23:56 +02:00
Justin Nuß
bfe5b86004 Add file upload for attachments 2014-07-24 15:19:59 +02:00
无闻
3db84c8893 Merge pull request #306 from nuss-justin/dev
Fix double decrement of issue counter
2014-07-24 08:21:28 -04:00
Justin Nuß
70b0023b82 Fix double decrement of issue counter 2014-07-24 13:58:39 +02:00
Justin Nuß
43e5de7f83 Show attachments in issues/comments and add preview for images 2014-07-24 13:50:03 +02:00
Justin Nuß
fa1db64ff0 Add files/ directory to .gitignore 2014-07-24 13:49:27 +02:00
Justin Nuß
ef1cbcd761 Allow admins to delete attachments. 2014-07-24 12:39:03 +02:00
Justin Nuß
1129f756c8 Fix missing . (dot) in issue templates 2014-07-24 12:37:26 +02:00
Justin Nuß
967856f36e Merge branch 'dev' into feature/attachments
Conflicts:
	models/issue.go
	routers/repo/issue.go
2014-07-24 12:29:37 +02:00
无闻
a76a948a02 Merge pull request #305 from nuss-justin/feature/commit-issue-fix
Fix #302. Show referencing commits in issue.
2014-07-24 04:25:00 -04:00
Justin Nuß
d43c5895bc Update template and style, only close commit if commit is in same repository 2014-07-24 10:15:05 +02:00
Justin Nuß
3c025b3950 Add delete route for attachments, remove upload buttons from issues/comments 2014-07-24 09:05:15 +02:00
Justin Nuß
34304e6a0c WIP: Allow attachments for issues, not only comments 2014-07-23 21:24:24 +02:00
Justin Nuß
4617bef895 WIP: Allow attachments for comments 2014-07-23 21:15:47 +02:00
Justin Nuß
c850c01007 Update closed issues stats for repository 2014-07-23 13:54:46 +02:00
Justin Nuß
469cbc8813 Update progress of milestones when closing/reopening issues and allow closing of issues in commit messages 2014-07-23 13:48:06 +02:00
无闻
6e9f1c52b1 Merge pull request #301 from nuss-justin/bugfix/milestone-counter
Update milestone issue stats when reopening/closing issue
2014-07-22 16:46:20 -04:00
Justin Nuß
812f71e21b Update milestone issue stats when reopening/closing issue 2014-07-22 22:35:59 +02:00
无闻
94b100ce43 Merge pull request #299 from nuss-justin/issue/216
Fix #216. Change milestones, labels and assigne without reloading the page
2014-07-22 16:24:16 -04:00
无闻
40557a4f79 Merge pull request #298 from nuss-justin/issue/278
Fix issue #278. Fall back to (default) branch for context data, if no branch selected
2014-07-22 16:23:00 -04:00
无闻
8e4debe99d Merge pull request #297 from nuss-justin/issue/288
Fix issue #288. Only show label form if repository collaborator/admin
2014-07-22 16:13:22 -04:00
无闻
dc2e140360 Merge pull request #296 from nuss-justin/dev
Fix issue 280 & unwatch button in Firefox
2014-07-22 16:03:58 -04:00
无闻
5bbd5be0ca Merge pull request #300 from nuss-justin/issue/259
Fix issue #259. Allow links in the repository description
2014-07-22 15:48:05 -04:00
Justin Nuß
0d06c7e5f2 Prevent panic when dividing through zero 2014-07-22 20:57:48 +02:00
Justin Nuß
636a78fed1 Escape tags and quotes in links. 2014-07-22 20:08:04 +02:00
Justin Nuß
e194cf3291 Fix issue #259. Allow links in the repository description 2014-07-22 19:52:37 +02:00
Justin Nuß
ed73af6fa1 Fix #216. Change milestones, labels and assigne without reloading the page 2014-07-22 15:46:15 +02:00
Justin Nuß
267870537d Fix issue #278. Fall back to (default) branch for context data, if no branch selected 2014-07-22 14:46:04 +02:00
Justin Nuß
ccca60a5a1 Fix issue #288. Only show label form if repository collaborator/admin 2014-07-22 14:20:32 +02:00
Justin Nuß
ec26b78d3c Fix issue #280. Update milestone counter when creating an issue 2014-07-22 13:50:34 +02:00
Justin Nuß
18718afb36 Hide watch/unwatch button if not loggedin 2014-07-22 11:57:10 +02:00
Justin Nuß
0b4fcf1224 Fix unwatch button not working in Firefox 2014-07-22 11:56:08 +02:00
无闻
dcb252eff4 Merge pull request #294 from ecnahc515/patch-2
Remove apt-get cleanup from Dockerfile
2014-07-21 23:23:37 -04:00
Chance Zibolski
78103f1df3 Remove apt-get cleanup from Dockerfile
Purging/cleaning packages using apt doesn't actually reduce image size, and only creates additional layers, which doesn't add any benefit to the overall image.
2014-07-21 20:20:35 -07:00
无闻
536f65b8ad Merge pull request #293 from wmark/master
Enable users to upload other key types than RSA (+ ED25519, ECDSA, NTRU, McE)
2014-07-20 21:05:27 -04:00
W-Mark Kubacki
887ad1ec8b Utilize ssh-keygen for checking of keys.
Removes the limitation to RSA and enables us to use all key types
SSH recognizes.
2014-07-20 18:56:07 +02:00
无闻
aab2dbc505 Merge pull request #291 from gima/dev
Make possible for administrators to change user's password (fix proposal...
2014-07-18 01:05:19 -04:00
gima
5a97cc69ed Make possible for administrators to change user's password (fix proposal for #290) 2014-07-18 05:30:57 +03:00
Lunny Xiao
6418caf23a add build script 2014-07-16 09:48:19 +08:00
codeskyblue
9a3e1790a1 update start.sh in order to compatible with supervisor 2014-07-15 10:20:05 +08:00
Unknown
3969d704a0 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-07-12 00:55:35 -04:00
Unknown
0f907301b7 Fix #285 2014-07-12 00:55:19 -04:00
无闻
590f9e599c Merge pull request #284 from compressed/user_name
Only update access usernames where the username is changing
2014-07-11 21:49:50 -04:00
Christopher Brickley
63e47405b2 Only update access usernames where the username is changing #282 2014-07-11 20:57:00 -04:00
fuxiaohei
c127d84777 add organization team-single page 2014-07-07 18:13:42 +08:00
Unknown
63cc14062a Paging function for users and repositories 2014-07-07 04:15:08 -04:00
Unknown
7ffdabb28f Move debug router location 2014-07-06 18:25:07 -04:00
Unknown
9b014d05e4 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-07-06 17:32:39 -04:00
Unknown
097c8e05e6 Able to set timeout for process monitor 2014-07-06 17:32:36 -04:00
无闻
21088a40f5 Merge pull request #275 from nuss-justin/dev
Fix wrong method for profiling routes.
2014-07-05 15:02:31 -04:00
Justin
10f932b952 Fix wrong method for profiling routes. 2014-07-05 17:24:44 +02:00
Unknown
fd5412ec47 Work on #274 2014-07-04 22:43:39 -04:00
Lunny Xiao
baa255e899 remove debug info 2014-07-05 10:37:29 +08:00
Lunny Xiao
3c6da63216 bug fixed 2014-07-05 10:25:45 +08:00
Unknown
aed4271c8d Change martini.Static to custom Static function 2014-07-04 17:26:15 -04:00
Unknown
be8ac7fb75 fix #273 2014-07-04 16:48:36 -04:00
Unknown
7f3015b32b Merge branch 'dev' of github.com:gogits/gogs into dev 2014-07-04 14:44:31 -04:00
Unknown
13b032f829 update name 2014-07-04 14:44:27 -04:00
无闻
ae7f3eed78 Merge pull request #272 from nuss-justin/dev
Add 'pprof' tag for enabling debugging
2014-07-04 14:28:46 -04:00
Justin Nuß
a481672c5c Add 'pprof' tag for enabling debugging 2014-07-04 11:41:43 +02:00
Unknown
0820b24f0b Merge branch 'master' of github.com:gogits/gogs into dev 2014-07-04 01:25:19 -04:00
Unknown
36292060d6 Fix bug that collaborators are able to modify settings of repository 2014-07-04 01:25:06 -04:00
Unknown
cdffdeddc9 Fix bug that collaborators are able to modify settings of repository 2014-07-04 01:23:11 -04:00
Unknown
465dc962b5 Finish create organization team 2014-07-02 16:42:16 -04:00
无闻
3f42cb7c23 Merge pull request #267 from AntonioMeireles/master
fix typos in users' editing template.
2014-06-30 15:22:18 -04:00
António Meireles
3ad20773a2 fix typos in users' editing template. 2014-06-30 20:12:55 +01:00
Unknown
e57aebb316 Add uuid 2014-06-29 16:39:06 -04:00
Unknown
269da8fe7a Merge branch 'master' of github.com:gogits/gogs into dev 2014-06-29 16:32:28 -04:00
Unknown
e4ea5cf598 Finish Teams page 2014-06-29 16:30:41 -04:00
Lunny Xiao
be123588ce clear comments 2014-06-29 22:31:46 +08:00
Unknown
99713e1180 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-06-28 15:43:28 -04:00
Unknown
5dbfe3c26c Finish organization homepage 2014-06-28 15:43:25 -04:00
Lunny Xiao
1c46d68aba bug fixed for message tag 2014-06-28 23:56:41 +08:00
Lunny Xiao
4ce2fa520a Merge branch 'master' into dev 2014-06-28 15:00:38 +08:00
Lunny Xiao
a357cda957 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-06-28 15:00:32 +08:00
Lunny Xiao
54e17c7cca bug fixed #261 2014-06-28 15:00:03 +08:00
Lunny Xiao
86e2627175 Merge branch 'master' of github.com:gogits/gogs
Conflicts:
	models/update.go
	routers/repo/http.go
2014-06-28 14:58:59 +08:00
Lunny Xiao
e5ae41e21f bug fixed #261 2014-06-28 14:55:33 +08:00
Unknown
6e448b0714 Finish delete organization 2014-06-28 00:40:07 -04:00
Unknown
ee9b7f322f Clean code 2014-06-27 23:14:33 -04:00
Unknown
57ac15aa20 Merge branch 'master' of github.com:gogits/gogs into dev 2014-06-27 23:12:55 -04:00
Lunny Xiao
7dbeee94e3 bug fixed #236 2014-06-28 11:06:07 +08:00
fuxiaohei
1d55ecd29c add organization team-create page 2014-06-27 22:04:04 +08:00
fuxiaohei
b5ba2bd268 add organization team-create page 2014-06-27 21:33:49 +08:00
Unknown
19e9104289 Organization settings page 2014-06-27 03:37:01 -04:00
Lunny Xiao
165e3e8f18 path bug fixed 2014-06-26 21:39:27 +08:00
Unknown
32b09681b2 Migrate repository by organization 2014-06-25 05:35:23 -04:00
Unknown
8644c571db Mirror bug fix on create repo action 2014-06-25 05:27:17 -04:00
Unknown
43b33440b5 Work on create organization repo and #257 2014-06-25 05:14:36 -04:00
fuxiaohei
72ba273cc9 select owner when creating repository 2014-06-25 16:03:29 +08:00
Unknown
4cf7a1fca5 Mirror update on create repo page 2014-06-25 03:55:59 -04:00
fuxiaohei
80be060735 select owner when creating repository 2014-06-25 13:08:28 +08:00
Unknown
8e6c254c03 Mirror fix on create repo 2014-06-25 00:53:45 -04:00
Unknown
3624b2a7f1 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-06-25 00:44:59 -04:00
Unknown
e0f9c628c5 Add create organization 2014-06-25 00:44:48 -04:00
fuxiaohei
cc703ee663 select owner when creating repository 2014-06-25 12:22:08 +08:00
Unknown
b2801a2e98 Fix #165 2014-06-24 13:55:47 -04:00
Unknown
ceb415df8a Merge branch 'master' of github.com:gogits/gogs into dev 2014-06-24 09:59:21 -04:00
无闻
63770d93a1 Merge pull request #251 from niphor/master
RepoRootPath must be absolute path
2014-06-24 09:30:16 -04:00
无闻
9bdff5bd97 Merge pull request #253 from eryx/master
Fix #252
2014-06-24 09:26:42 -04:00
Eryx
d5d04a66f3 Fix #252 2014-06-24 16:53:42 +08:00
niphor
29a40c97f3 RepoRootPath must be absolute path 2014-06-24 14:28:47 +08:00
Unknown
98f614a58e Work on #249 issue1 2014-06-23 19:16:09 -04:00
Unknown
47d29a1ee0 Mirror fix on #248 2014-06-23 16:22:34 -04:00
fuxiaohei
fb53cc4fa8 add organization setting page 2014-06-23 19:11:20 +08:00
fuxiaohei
f393dc6520 add organization dashboard page 2014-06-23 12:08:53 +08:00
fuxiaohei
ea507e20d4 add organization create page 2014-06-23 11:40:49 +08:00
Unknown
314193029a Use constants to name template file 2014-06-22 23:11:12 -04:00
Unknown
9c82073091 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-06-22 13:17:47 -04:00
Unknown
9924e65ca1 In progress of name template name constant 2014-06-22 13:14:03 -04:00
fuxiaohei
adda10f4a4 add organization teams page 2014-06-22 21:53:40 +08:00
fuxiaohei
514d7e1922 add organization memebers page 2014-06-22 16:53:46 +08:00
fuxiaohei
bf703ef617 add dashboard context switch button 2014-06-22 14:10:12 +08:00
Unknown
c280415e0b Clean files 2014-06-21 17:57:59 -04:00
Unknown
9d2cef23f2 Fix #165 2014-06-21 00:53:46 -04:00
Unknown
ad5ec45dd6 Fix #165 2014-06-21 00:51:41 -04:00
Unknown
8bfa7ae745 Remove qiniu/log 2014-06-20 01:14:54 -04:00
Unknown
6c8d630bef Add database log adapter 2014-06-20 00:25:23 -04:00
Unknown
f147ad619a Basic process manager 2014-06-19 01:08:03 -04:00
Unknown
8d3276cab0 Fix test cases 2014-06-16 23:19:25 -04:00
Unknown
d952b4200c Add corn rask monitor panel 2014-06-13 13:01:52 -04:00
Unknown
e07674bff1 Support edit release and save as draft 2014-06-12 17:47:23 -04:00
Unknown
fb0972afad Fix #199 2014-06-12 09:35:51 -04:00
Unknown
9961f9a53c Fix #197 2014-06-12 09:10:39 -04:00
Unknown
1161c71ac1 Mirror fix 2014-06-12 07:45:33 -04:00
Unknown
c018b1a88d Merge branch 'master' of github.com:gogits/gogs into dev 2014-06-12 07:44:11 -04:00
codeskyblue
29561acb43 fix gobuld.yml conf missing 2014-06-12 16:58:56 +08:00
无闻
2da9908e29 Merge pull request #243 from tobyzxj/patch-1
Using strings.HasPrefix(...) will cause a misjudgement
2014-06-11 18:50:25 -04:00
toby.zxj
a13a6b14ec Using strings.HasPrefix(...) will misjudgement
`strings.HasPrefix(access.RepoName, uname)` can't handle the situation which like following in access table.

	user_name | repo_name
	----------+-------------
	toby      | toby/blog
	toby      | toby/test
	toby      | tobyzxj/blog
	toby      | tobyzxj/test
2014-06-11 16:54:25 +08:00
Unknown
a3e1383cac Add gogs fix location command 2014-06-10 19:11:53 -04:00
Unknown
f160b4f33c Add tar.gz download button and other mirror updates 2014-06-08 17:53:53 -04:00
Unknown
1f58d6f5d9 Mirror fix on #242 2014-06-08 04:54:52 -04:00
Unknown
a80d8d96fa Merge branch 'dev' of github.com:gogits/gogs into dev 2014-06-08 04:45:38 -04:00
Unknown
302c863cda Fix #242 2014-06-08 04:45:34 -04:00
FuXiaoHei
4fcbf553aa organisation main page ui 2014-06-07 13:27:24 +08:00
无闻
a0318db2f9 Merge pull request #239 from baijum/docker_command
use 'docker.io' command instead of 'docker'
2014-06-06 05:12:56 -04:00
Baiju Muthukadan
c6058e5ea8 locate docker command during running time 2014-06-06 14:22:54 +05:30
Unknown
4f2f3c2857 Code convention 2014-06-05 22:07:35 -04:00
Baiju Muthukadan
925ccc2608 use 'docker.io' command instead of 'docker' 2014-06-05 21:46:46 +05:30
Unknown
11f9d738e8 Fix #237 2014-06-03 21:51:25 -04:00
Unknown
63baf76ab2 Fix #214 2014-06-03 12:51:53 -04:00
Unknown
9c3aa6936a Fix #223 2014-06-03 12:16:44 -04:00
Unknown
32c5fa514c Fix #230 2014-06-02 23:17:21 -04:00
Unknown
eaa7d71fc7 Fix #232 2014-06-02 21:59:56 -04:00
Unknown
e1332c5239 Fix #230 2014-06-01 21:47:48 -04:00
Unknown
afc6cbc479 Update tag 2014-06-01 11:06:03 -04:00
Unknown
1f059502dc Merge branch 'master' of github.com:gogits/gogs into dev 2014-06-01 10:54:15 -04:00
Unknown
01a516b584 Fix #229 2014-06-01 10:53:57 -04:00
无闻
48c98c92c8 Merge pull request #228 from janoliver/patch-1
Fixed directory permissions for the zip download router
2014-06-01 10:42:47 -04:00
Jan Oliver Oelerich
6fe43eb8d4 Fixed directory permissions for the zip download router
If the archives/ directory is created with 0655, it results in a permission error.
2014-06-01 15:22:13 +02:00
Unknown
2657f88d9a Fix #222 2014-05-31 17:15:04 -04:00
Unknown
ddb7f55035 Prepare for v0.4.0 release 2014-05-30 19:19:30 -04:00
Unknown
fbf274b751 Fix #220 2014-05-30 17:57:38 -04:00
Unknown
422043f422 Fix #219 2014-05-30 16:35:35 -04:00
Unknown
617bbe3fee Fix #218 2014-05-30 06:34:24 -04:00
Unknown
9085dfa426 Working on #211 2014-05-29 22:09:50 -04:00
Unknown
6696610aea Fix zombie 2014-05-28 22:15:15 -04:00
slene
e323604d78 display large file 2014-05-28 14:01:41 +08:00
slene
4ee6bc4fca fix for new git api 2014-05-28 14:01:41 +08:00
Unknown
ab13a29cb5 Fix #209 2014-05-28 01:53:06 -04:00
Unknown
ff690fd976 Fix #200, add VERSION to template files 2014-05-28 00:06:31 -04:00
无闻
bcfa78b8b5 Merge pull request #210 from brunoqc/typo
Typo
2014-05-26 12:15:15 -04:00
Bruno Bigras
6227b59b1a Registeration -> Registration 2014-05-26 12:00:36 -04:00
FuXiaoHei
e0a6e6dd1a issue ui update 2014-05-26 21:21:30 +08:00
Unknown
bf5fcfb49c Add * to selected label 2014-05-25 23:46:45 -04:00
Unknown
ff48aeddef Little bug fix 2014-05-25 20:57:01 -04:00
Unknown
d72fdc9900 Change version to v0.3.6 2014-05-25 20:44:58 -04:00
Unknown
5543a0b6dc 增加版本标识确保二进制和模板文件处于同个版本 2014-05-25 20:33:30 -04:00
Unknown
2f820e01d8 Fixed #209 2014-05-25 20:17:26 -04:00
Unknown
688ec6ecbd Fixed #209 2014-05-25 20:11:25 -04:00
Unknown
87854c95a9 Fixed #200 2014-05-24 15:34:02 -04:00
Unknown
80055bde86 Code convention 2014-05-24 15:28:31 -04:00
Unknown
e33a104448 Almost done issue label #200 2014-05-24 03:11:53 -04:00
Unknown
dce17c86ac Almost done issue label #200 2014-05-24 03:05:41 -04:00
Unknown
b1bdbd7f94 Almost done issue label #200 2014-05-24 02:31:58 -04:00
FuXiaoHei
50ba08e2c6 fix issue label ajax 2014-05-24 13:39:12 +08:00
Unknown
5e9a45f74a Code convention 2014-05-21 21:37:13 -04:00
FuXiaoHei
1331134316 finish issue edit content preview 2014-05-21 20:49:47 +08:00
FuXiaoHei
4e8a1bf9c9 fix firefox zclip bug 2014-05-21 20:03:45 +08:00
FuXiaoHei
c82807a713 add issue label attach-detach ui 2014-05-19 23:47:11 +08:00
FuXiaoHei
342baf1dda add label edit and manage ui 2014-05-19 21:55:25 +08:00
Lunny Xiao
fdc6b64f15 Merge pull request #203 from DerDackel/nopasswords
Remove password from log message upon login failure
2014-05-19 16:16:07 +08:00
Sebastian Jackel
02fb088b80 Remove password from log message on failed login 2014-05-19 09:16:56 +02:00
Unknown
5660570d92 Add MustValueRange 2014-05-18 22:05:35 -04:00
Unknown
93f8f92523 Finish create new label 2014-05-18 18:07:04 -04:00
无闻
a4c3ab48a5 Merge pull request #201 from j20/patch-1
Add dropdown-menu-right class to the repo-watching dropdown
2014-05-18 16:58:58 -04:00
Jason
7fd22bea1e Add dropdown-menu-right class to the repo-watching dropdown
The dropdown menu was dropping down to the right and appearing outside of the page container. This made it not visible at smaller browser widths.

This commit makes it drop down into the page container, instead of out, and keeps it visible at all screen sizes.
2014-05-18 15:57:02 -05:00
Unknown
04890904f9 fix #195 2014-05-16 16:24:26 -04:00
Unknown
a0a95d797e Fix ui 2014-05-16 16:21:31 -04:00
Unknown
956f011dd3 Fix #186 2014-05-16 13:41:08 -04:00
FuXiaoHei
16e162b669 issue label ui design 2014-05-16 16:00:09 +08:00
FuXiaoHei
61641d9c63 issue label ui design 2014-05-16 15:47:39 +08:00
Unknown
44f1ef2493 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-15 23:03:31 -04:00
Unknown
be82716b66 Clean old LDAP code 2014-05-15 23:03:26 -04:00
Lunny Xiao
57ad8d50b7 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-16 10:31:54 +08:00
Lunny Xiao
f6c94c29d5 implicated error for ldap dial 2014-05-16 10:31:39 +08:00
Unknown
4744996f9a Make gmail auth work 2014-05-15 14:46:04 -04:00
Unknown
db6b71ad03 Update issue-user when change milestone 2014-05-15 12:08:53 -04:00
Lunny Xiao
f4486f3eec bug fixed #193 2014-05-15 22:34:36 +08:00
Lunny Xiao
4f042d12bd Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-15 20:58:20 +08:00
Lunny Xiao
7869cfccb9 Merge pull request #192 from DerDackel/ldapssl
Add LDAP over SSL support
2014-05-15 20:52:05 +08:00
Sebastian Jackel
eb264a112b Add LDAP over SSL support 2014-05-15 14:27:16 +02:00
Lunny Xiao
839a9bb054 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-15 09:55:16 +08:00
Lunny Xiao
9d5e827a1e Merge branch 'master' of github.com:gogits/gogs into dev 2014-05-15 09:54:59 +08:00
Unknown
b70db61854 Fix #185 2014-05-14 13:04:57 -04:00
Unknown
16bddd593a Finish change issue’s milestone 2014-05-14 11:14:51 -04:00
Unknown
e880a2fa48 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-14 10:55:41 -04:00
Unknown
46fc36c3a6 Finish change issue’s milestone 2014-05-14 10:55:36 -04:00
FuXiaoHei
a1bb3741d5 add milestone in new-issue page 2014-05-14 22:01:20 +08:00
FuXiaoHei
99f2400e3b Merge remote-tracking branch 'origin/dev' into dev 2014-05-14 21:31:29 +08:00
FuXiaoHei
4a4392192b add milestone issue view ui 2014-05-14 21:29:54 +08:00
Unknown
e8dd480f10 Litte bug fix 2014-05-14 09:23:33 -04:00
Unknown
9100786beb Fix #185 2014-05-14 08:51:04 -04:00
Unknown
b0084b1adc Litte bug fix 2014-05-14 08:30:35 -04:00
Unknown
5ed5aa5228 Finish milestone 2014-05-13 19:46:48 -04:00
Unknown
33ec0632ff Fix #183 2014-05-13 19:26:13 -04:00
无闻
f276b37bbb Merge pull request #184 from mlitbk/issue-link
Fix issue link in issues page
2014-05-13 17:53:25 -04:00
Michael Litvak
cca2a53d6f Fix issue link in issues page
The link assumes that the issue belongs to the signed in
user, which is not necessarily the case
I changed it to use repository owner name instead
2014-05-13 23:37:09 +03:00
Unknown
5d5c4535cb Fix #181 2014-05-13 14:49:20 -04:00
Unknown
2eee1e9bc2 Finish edit a milestone 2014-05-13 13:28:21 -04:00
Unknown
98dbbae2ef Fix #166 2014-05-13 12:40:32 -04:00
Unknown
c117f9e73f Fix #166 2014-05-12 20:22:35 -04:00
Unknown
f979d0d6b9 Fix #138 2014-05-12 19:32:35 -04:00
Unknown
a913aff1d0 Show collaborative repositories in dashboard 2014-05-12 15:14:22 -04:00
Unknown
54e95fa367 Finish add new milestone 2014-05-12 14:06:42 -04:00
Unknown
f1130ce5e9 Fix edit auth page bug 2014-05-12 11:02:36 -04:00
无闻
f5b2e5f836 Merge pull request #177 from jacksonpan/master
modify the file path
2014-05-12 10:32:07 -04:00
FuXiaoHei
1769bb2f26 add milestone edit ui 2014-05-12 21:51:22 +08:00
jack
83a10ce880 add tip to modify the command path, add check the log folder, if not then create it. 2014-05-12 21:50:04 +08:00
jack
7ec3f1b2d8 modify the file path
move etc/supervisord.conf to conf/etc/supervisord;
remove tmp folder, then all logs move to log folder;
move the supervisor.pid to /tmp folder.
2014-05-12 21:13:05 +08:00
FuXiaoHei
3fe87cba85 fix preview js 2014-05-12 20:35:26 +08:00
无闻
ca0b6dfa38 Merge pull request #175 from jacksonpan/master
add supervisor support and script, easy to use.
2014-05-12 07:51:13 -04:00
jack
1482bd8fb4 add supervisor support and script, easy to use.
just like ./gogs_supervisord.sh start
./gogs_supervisord.sh stop
./gogs_supervisord.sh restart
and logs all saved tmp folder
2014-05-12 13:20:13 +08:00
Unknown
0970d6cc38 Log to different adapter according to level 2014-05-11 14:37:12 -04:00
Unknown
98eeec4cbb Fix #174 2014-05-11 14:03:51 -04:00
Unknown
68fb62347f Finish issue assignee 2014-05-11 13:46:36 -04:00
Unknown
a196245a87 little fix 2014-05-11 12:20:41 -04:00
Unknown
605a38759f Fix #94 and fix #169 2014-05-11 12:17:10 -04:00
Unknown
fd4b123e88 Fix #94 and fix #169 2014-05-11 11:18:10 -04:00
Unknown
d122aa6d88 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-11 10:37:36 -04:00
Unknown
2c73ced0db Fix #173 2014-05-11 10:37:31 -04:00
FuXiaoHei
fd7b0a2ba4 add user new js 2014-05-11 21:27:06 +08:00
FuXiaoHei
27f9b7a144 add user new js 2014-05-11 21:26:47 +08:00
Lunny Xiao
f68e279150 spell bug fixed 2014-05-11 20:18:57 +08:00
Lunny Xiao
70398ed01a Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-11 20:04:54 +08:00
Lunny Xiao
d2231bb54c smtp login bug fixed 2014-05-11 20:04:28 +08:00
Unknown
65e628d1f4 ignore broken tests 2014-05-11 07:50:05 -04:00
Unknown
c5dbc24ca4 UI fix 2014-05-11 07:43:57 -04:00
Lunny Xiao
bf58679390 add support for smtp authentication 2014-05-11 18:10:37 +08:00
FuXiaoHei
cdc87623dc add auth new js 2014-05-11 16:46:38 +08:00
Lunny Xiao
b33f255c40 add smtp authentication 2014-05-11 15:49:36 +08:00
Lunny Xiao
26c0113ea0 delete unused codes 2014-05-11 14:13:49 +08:00
Lunny Xiao
55019bfbc5 merge all login methods 2014-05-11 14:12:45 +08:00
Lunny Xiao
4d6de6c7b9 add login name for auth type 2014-05-11 11:56:04 +08:00
slene
7d84cc96e8 update with git api 2014-05-10 11:14:24 +08:00
FuXiaoHei
2eabeba6b7 finish milestone add page 2014-05-09 22:33:07 +08:00
FuXiaoHei
045c21de4f assignee ui in issue view 2014-05-09 20:44:08 +08:00
Unknown
4ef9494637 Fix panic when view issue without login 2014-05-09 06:37:32 -04:00
无闻
43ffacd05b Merge pull request #168 from jiangjianxiao/dev
fix news feed repo link
2014-05-09 05:15:28 -04:00
jiangjianxiao
501f70e248 fix news feed repo link 2014-05-09 14:42:50 +08:00
Unknown
09dba7d63e Clean names 2014-05-08 22:12:05 -04:00
Unknown
3f4c040f3f Update import path 2014-05-08 22:06:06 -04:00
Unknown
830494a8aa Remove old files 2014-05-08 22:03:34 -04:00
Unknown
25713ab209 Fix #167 2014-05-08 20:00:07 -04:00
Unknown
914ffa496f Show private repository activities in dashboard if has access 2014-05-08 19:17:43 -04:00
Unknown
a742ee543e Add change assignee back end 2014-05-08 17:17:45 -04:00
Unknown
e867283406 Assignee back end 2014-05-08 12:24:11 -04:00
FuXiaoHei
a03f380fa8 assignee ui in issue view 2014-05-08 21:49:05 +08:00
FuXiaoHei
8eb15815f1 Merge remote-tracking branch 'origin/dev' into dev 2014-05-08 21:02:25 +08:00
FuXiaoHei
11ca10ab2f issue assignee ui 2014-05-08 21:01:47 +08:00
Unknown
23a857d107 Add repo info to web hook post 2014-05-08 08:18:03 -04:00
Unknown
495d939ca5 Waiting for UI 2014-05-07 20:36:00 -04:00
Unknown
7d89e765ab Bug fix 2014-05-07 18:57:00 -04:00
Unknown
31fd45ba02 Bug fix 2014-05-07 17:38:03 -04:00
Unknown
abd8c2a7ca Bug fix 2014-05-07 17:37:09 -04:00
Unknown
e05b1385fb Bug fix 2014-05-07 17:23:02 -04:00
Unknown
8b6766ecbe Bug fix 2014-05-07 17:10:46 -04:00
Unknown
269281ab76 Bug fix 2014-05-07 17:04:32 -04:00
Unknown
4b08d3aacf travis file 2014-05-07 16:57:25 -04:00
Unknown
33d32585b1 Add mention, read/unread support of issue tracker 2014-05-07 16:51:14 -04:00
Unknown
6fb7229bea Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-07 12:09:35 -04:00
Unknown
7407f9caf3 Finish issue design 2014-05-07 12:09:30 -04:00
FuXiaoHei
d76772adb9 add milestone list page 2014-05-07 21:01:00 +08:00
Unknown
8ca14e2109 Improve delete SSH key 2014-05-06 16:28:52 -04:00
Unknown
7cb5a15c9b Batch of mirror fixes 2014-05-06 13:47:47 -04:00
Unknown
e573855a4f Fix #98, support web hook 2014-05-06 11:50:31 -04:00
Unknown
94bccbb148 Finish edit and remove web hook 2014-05-05 21:36:08 -04:00
Unknown
24f614f6db Finish add web hook 2014-05-05 20:52:25 -04:00
Unknown
cb505b22ec Fix #164 2014-05-05 20:09:38 -04:00
Unknown
6e3dba2cc5 Clean repo code 2014-05-05 19:58:13 -04:00
Unknown
bbdfe25769 User code clean and ui improve 2014-05-05 16:21:43 -04:00
Unknown
c1eb4d894a Clean api code 2014-05-05 13:08:01 -04:00
codeskyblue
5f653898f3 add excludes to gobuild.yml 2014-05-06 00:27:09 +08:00
FuXiaoHei
d189b83ac1 some ui fix 2014-05-05 20:50:59 +08:00
FuXiaoHei
d34c3bb751 finish webhook ui,
some ui fix
2014-05-05 20:16:24 +08:00
Unknown
3b7465f817 fix code 2014-05-05 05:32:47 -04:00
Lunny Xiao
d8136c9c3c Merge branch 'dev-ldap' into dev 2014-05-05 16:42:15 +08:00
Lunny Xiao
1652dd5068 basic authentications 2014-05-05 16:40:25 +08:00
Unknown
02687cbdf3 Add mail notify for new collaborator 2014-05-05 04:27:28 -04:00
Unknown
07c3d497a7 Fix #145 2014-05-05 02:49:33 -04:00
Unknown
816c0ed5e7 Fix import path 2014-05-05 02:42:52 -04:00
Unknown
a641854cad command dump 2014-05-05 00:55:17 -04:00
Unknown
bb0bc0a240 Merge branch 'dev' of github.com:gogits/gogs 2014-05-03 01:38:22 -04:00
Unknown
7b60756f2c Fix Collaborators cannot commit 2014-05-03 01:37:49 -04:00
Lunny Xiao
163fcec59f resolved #155 2014-05-03 11:12:15 +08:00
Lunny Xiao
79ea34e70e ldap support 2014-05-03 10:48:14 +08:00
Unknown
e10096ee2e Mirror fix on UI 2014-05-02 19:23:06 -04:00
Unknown
a9e6d49dc6 Fix #159 2014-05-02 17:30:59 -04:00
FuXiaoHei
3e856928a2 add webhooks page ui 2014-05-02 22:07:34 +08:00
Unknown
8bbaf9550a Merge branch 'master' of github.com:gogits/gogs
Conflicts:
	models/action.go
2014-05-01 21:31:16 -04:00
Unknown
e7d8fadb08 Add disable gravatar option 2014-05-01 21:30:04 -04:00
Unknown
3bd5fc6d6f Add command dump and move to cmd did 2014-05-01 21:21:46 -04:00
Unknown
cd2020429a Fix #153 2014-05-01 20:29:51 -04:00
Unknown
ff9872104e Fix #153 2014-05-01 20:26:40 -04:00
Lunny Xiao
a3f807106a add default for Action's IsPrivate 2014-05-02 08:18:44 +08:00
Unknown
100cd181bc Add router log config option 2014-05-01 18:53:41 -04:00
Unknown
03c2468c2f Merge branch 'master' of github.com:gogits/gogs into dev 2014-05-01 12:16:04 -04:00
无闻
fa17989763 Merge pull request #152 from jcfrank/master
Add 'IF EXISTS', otherwise an error would show on MySQL that has no 'gogs' created before.
2014-05-01 12:15:31 -04:00
Unknown
75109bbd65 Fix panic when no master branch 2014-05-01 12:03:10 -04:00
Chen Chao Shih
6ce8fa49ea Add 'IF EXISTS', otherwise an error would show on MySQL that has no
'gogs' created before.
2014-05-01 23:58:48 +08:00
Unknown
0a187dbef5 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-05-01 11:32:25 -04:00
Unknown
f6c4fbeb37 Collaborator 2014-05-01 11:32:12 -04:00
FuXiaoHei
ad71775ae8 fix collaboration js bug 2014-05-01 23:31:35 +08:00
FuXiaoHei
0dfb5560cd Merge remote-tracking branch 'origin/dev' into dev 2014-05-01 21:28:47 +08:00
FuXiaoHei
1c88a541cb fix profile ui 2014-05-01 21:27:12 +08:00
Unknown
a7584d16e4 Fix #150 2014-05-01 09:09:37 -04:00
Unknown
480a4ae8c5 Fix #150 2014-05-01 09:00:30 -04:00
FuXiaoHei
cc1eb5643e Merge branch 'dev' of https://github.com/gogits/gogs into dev 2014-05-01 20:57:11 +08:00
Unknown
a2333d95d5 Fix #148 2014-05-01 08:35:05 -04:00
Unknown
89c99167b2 Fix #149 2014-05-01 08:26:41 -04:00
Unknown
d0ea4c7b68 Fix #149 2014-05-01 07:59:09 -04:00
Unknown
2a1dc0085b fix #91 2014-05-01 07:35:21 -04:00
Unknown
46af92c57e Clean files 2014-05-01 06:55:39 -04:00
FuXiaoHei
52fbb9788a add collaboration page ui 2014-05-01 17:44:22 +08:00
无闻
00ebb5019f Merge pull request #147 from dockboard/dev
Remove 'ENV DEBIAN_FRONTEND noninteractive'
2014-05-01 03:40:29 -04:00
Meaglith Ma
dc5546633f Remove 'ENV DEBIAN_FRONTEND noninteractive' 2014-05-01 15:37:24 +08:00
Unknown
eb463000a9 Clean files 2014-05-01 03:27:26 -04:00
Unknown
49dc57e336 Add /api/v1/users/search 2014-04-30 23:48:01 -04:00
Unknown
de46c06d2e Merge branch 'master' of github.com:gogits/gogs into dev 2014-04-30 03:44:42 -04:00
Unknown
b36448a537 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-04-30 03:44:32 -04:00
Unknown
48bfbb7ddf Mirror changes 2014-04-30 03:44:28 -04:00
Lunny Xiao
1e9f376d3d bug fixed 2014-04-30 11:12:03 +08:00
Lunny Xiao
a85f242030 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-04-30 10:24:00 +08:00
Lunny Xiao
cdc843f06b add fix command for upgrade 2014-04-30 10:23:43 +08:00
无闻
0d6856dbe7 Merge pull request #143 from tsigo/rs-install-default-hosts
Install: Set the default host string based on database type
2014-04-29 17:47:16 -04:00
Robert Speicher
494e5fd40c Install: Set the default host string based on database type 2014-04-29 16:35:25 -04:00
Unknown
2401e68d7e Prepare for v0.3.1 hotfix 2014-04-28 21:53:40 -04:00
无闻
31805e2bbe Merge pull request #135 from clee/show-parents
Show parents in commit diff page
2014-04-27 19:46:38 -04:00
Chris Lee
6700257558 Show parents in commit diff page 2014-04-27 23:43:14 +00:00
Unknown
41b0a7b97c Mirror fix on public key 2014-04-27 17:01:39 -04:00
Unknown
62240b6bc1 Add login by email 2014-04-27 01:54:08 -06:00
Unknown
ce05a8d7b6 Merge branch 'dev' of github.com:gogits/gogs into dev
Conflicts:
	templates/repo/single_list.tmpl
2014-04-27 01:06:57 -06:00
Unknown
62d23e9154 HTTP no follow and offline mode 2014-04-27 01:05:13 -06:00
无闻
9fdf4bc277 Merge pull request #134 from clee/master
Use commit summaries instead of full messages
2014-04-27 00:56:06 -06:00
Chris Lee
8a8f84d245 Use commit summaries instead of full messages 2014-04-27 06:46:03 +00:00
Unknown
59d0e73c35 Batch mirror fix 2014-04-26 22:34:48 -06:00
Unknown
1badb2bbcc Fix #107 2014-04-26 19:06:59 -06:00
Unknown
89b68bdd45 Merge branch 'master' of github.com:gogits/gogs
Conflicts:
	modules/base/conf.go
2014-04-26 18:34:58 -06:00
无闻
597387ad40 Merge pull request #132 from fundon/fix_codename_match
Fixed codename match issue, when using `FROM ubuntu` wil be pulled latest image
2014-04-26 14:18:29 -06:00
fundon
cfa0968191 Fixed codename match issue, when using FROM ubuntu wil be pulled latest image 2014-04-27 01:55:22 +08:00
Unknown
9dfb7de371 Fix #102 2014-04-26 01:22:22 -06:00
Lunny Xiao
1b734501bd bug fixed 2014-04-26 14:25:51 +08:00
Unknown
861a20f464 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-04-26 00:21:52 -06:00
Lunny Xiao
8bab21d795 add login.go 2014-04-26 14:21:04 +08:00
Lunny Xiao
0da329462e bug fixed 2014-04-26 14:14:48 +08:00
Unknown
3684e70dc4 Merge branch 'master' of github.com:gogits/gogs into dev 2014-04-25 23:09:20 -06:00
无闻
83578cff65 Merge pull request #129 from shabbychef/patch-1
explicitly install sudo
2014-04-25 18:40:57 -06:00
无闻
3f2f648035 Merge pull request #124 from fundon/delete-superfluous-variable
delete superfluous environment variables
2014-04-25 17:56:39 -06:00
Steven Pav
d0f887a1ed explicitly install sudo
```deploy.sh``` in the docker container requires ```sudo```; this should resolve #127.
2014-04-25 15:21:48 -07:00
fundon
35a86d04c0 delete superfluous environment variables 2014-04-25 17:31:57 +08:00
无闻
37cbfc032a Merge pull request #112 from juju2013/master
basic support for LDAP/Microsoft Active Directory authentication
2014-04-24 14:25:56 -06:00
Unknown
5898d56205 Merge branch 'dev' of github.com:gogits/gogs into dev 2014-04-24 14:20:27 -06:00
无闻
cf7901fe6a Merge pull request #120 from james-anderson/master
fixed some broken forms in user settings
2014-04-24 14:11:59 -06:00
James Anderson
e5af34a078 fixed some broken forms that were introduced in james-anderson@521c5f0e10 2014-04-24 14:50:24 -04:00
无闻
51550e5b2e Merge pull request #114 from deringer/dev
Missed one typo while fixing another... on the same line. Deplorable eff...
2014-04-23 17:48:44 -06:00
Michael Dyrynda
eb4691cb2f Missed one typo while fixing another... on the same line. Deplorable effort on my part! @bradleyfalzon 2014-04-24 09:12:34 +09:30
无闻
912481019f Merge pull request #113 from deringer/dev
fixed typo
2014-04-23 16:54:14 -06:00
Michael Dyrynda
184f1ae135 fixed typo 2014-04-24 08:20:23 +09:30
juju2013
efc05ea1de initial support for LDAP authentication/MSAD 2014-04-23 23:07:54 +02:00
无闻
521c5f0e10 Merge pull request #111 from james-anderson/master
Changed 'setting' url to settings, and a small typo fix
2014-04-23 16:02:05 -04:00
James Anderson
32ae6896fa Close to Closed 2014-04-23 15:39:37 -04:00
James Anderson
4b58c01603 Changed setting url to settings 2014-04-23 15:30:18 -04:00
Lunny Xiao
ff690840d4 doc improvements 2014-04-23 19:24:26 +08:00
Lunny Xiao
0c5e50a888 Merge branch 'master' of github.com:gogits/gogs 2014-04-23 19:22:04 +08:00
无闻
7ded30ba5b Merge pull request #109 from laofo/master
Create the installation guide for gogs on ubuntu (src & binary)
2014-04-23 05:20:51 -04:00
Lunny Xiao
683e58878a bug fixed 2014-04-23 17:12:50 +08:00
laofo
649d0e1681 format the doc and add comments 2014-04-23 16:33:03 +08:00
laofo
d7956b3fb8 format the doc 2014-04-23 16:30:05 +08:00
laofo
2a95bc1395 use the dedicated user, git, to run gogs 2014-04-23 16:20:53 +08:00
laofo
e554e49c16 add the installation guide on ubuntu, including binary install and source install 2014-04-23 16:18:46 +08:00
Unknown
9abb37b45e Merge branch 'master' of github.com:gogits/gogs into dev 2014-04-23 00:33:52 -04:00
无闻
22f8536577 Merge pull request #105 from dockboard/master
Add Memcached and Redis Docker supported with MySQL and PostGreSQL
2014-04-23 00:33:04 -04:00
Meaglith Ma
8952eb1ce0 Sync with gigs master branch. 2014-04-23 12:30:18 +08:00
Meaglith Ma
ee7bfe2ebe Add memcached and redis Docker supported 2014-04-23 12:29:53 +08:00
crystaldust
b270b34c98 Merge branch 'feature/docker'
Add the sciprt for deplying gogs in docker, support the user to choose database(MySQL or PostgreSQL) and memory cache(redis or memcached).
2014-04-23 03:29:43 +00:00
crystaldust
b01e967a9f Add the configs comments, and update the README.md file 2014-04-23 03:29:17 +00:00
crystaldust
baacba96ca Remove the dependency of Unkwon/com, since gogs has already integrate the lateset version of Unkwon/com. 2014-04-23 03:16:09 +00:00
Unknown
8bc502a1ea New err check style 2014-04-22 22:34:49 -04:00
crystaldust
e5aaf23bb2 Update the githu.com/Unknwon/com module before getting gogs. 2014-04-23 02:26:56 +00:00
crystaldust
a90a014033 Change the image naming, start with "gogits/" 2014-04-23 00:05:14 +00:00
Unknown
88072a1e9b Merge branch 'master' of github.com:gogits/gogs into dev 2014-04-22 16:10:27 -04:00
无闻
f0cdf30134 Merge pull request #100 from gramakri/grammar-fix
Fix grammar
2014-04-22 16:07:49 -04:00
Girish Ramakrishnan
22bb5104c8 Fix grammar 2014-04-22 12:49:22 -07:00
crystaldust
1560abe553 Add the MEM db config replacement script in the deploy.sh. 2014-04-22 10:20:27 +00:00
crystaldust
65ad26feba Checkout to the latest dev branch when building the gogs docker image. 2014-04-22 10:19:23 +00:00
crystaldust
b60d5ecc3e Add the redis Dockerfile 2014-04-22 10:15:12 +00:00
crystaldust
8a6119551b Add the memcache(d) Dockerfile 2014-04-22 10:14:10 +00:00
crystaldust
4b8d72dec2 Change the MySQL password placeholder to THE_DB_PASSWORD. 2014-04-22 09:49:10 +00:00
Unknown
5435b259cc Merge branch 'master' of github.com:gogits/gogs into dev 2014-04-22 05:30:53 -04:00
无闻
dbdaf934e1 Merge pull request #87 from bjohnso5/master
Minor grammatical fix for Disable Registration feature
2014-04-22 05:30:36 -04:00
无闻
d6ff275c58 Merge pull request #95 from octplane/patch-1
Typos
2014-04-22 05:13:11 -04:00
Pierre Baillet
b32407456a Typos
- Very small typo fixes
2014-04-22 11:11:11 +02:00
Unknown
2a9da4b8e5 Fix #92 2014-04-22 03:41:47 -04:00
无闻
9a5e49cccb Merge pull request #90 from cburgdorf/patch-1
fixed typo
2014-04-21 20:16:22 -04:00
Christoph Burgdorf
338fc122fa fixed typo 2014-04-22 00:53:04 +02:00
Bryan Johnson
34d18a19a3 Minor grammatical fix for Disable Registration feature 2014-04-21 18:03:04 -04:00
crystaldust
066d91e113 Allow the user to config the apt source in build.sh 2014-04-15 23:48:33 -04:00
crystaldust
bb84bb8ac3 Add two apt source:aliyun and nchc, make a '#sourcename#' before the RUN command to make the apt source configurable in build.sh 2014-04-15 23:41:46 -04:00
crystaldust
213b366959 Remove the installation of PostgreSQL, which not needed actually. 2014-04-15 23:34:58 -04:00
518 changed files with 163333 additions and 9157 deletions

17
.bra.toml Normal file
View File

@@ -0,0 +1,17 @@
[run]
init_cmds = [["./gogs", "web"]]
watch_all = true
watch_dirs = [
"$WORKDIR/conf/locale",
"$WORKDIR/cmd",
"$WORKDIR/models",
"$WORKDIR/modules",
"$WORKDIR/routers"
]
watch_exts = [".go", ".ini"]
build_delay = 1500
cmds = [
["go", "install"],
["go", "build"],
["./gogs", "web"]
]

7
.gitignore vendored
View File

@@ -7,6 +7,7 @@ data/
.idea/
*.iml
public/img/avatar/
files/
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
@@ -31,6 +32,10 @@ _testmain.go
*.exe
*.exe~
gogs
/gogs
profile/
__pycache__
*.pem
output*
config.codekit
.brackets.json

View File

@@ -1,10 +1,12 @@
filesets:
includes:
- templates
- public
- conf
- etc
- public
- scripts
- templates
- LICENSE
- README.md
- README_ZH.md
- start.bat
- start.sh
excludes:
- \.git

View File

@@ -2,24 +2,30 @@
path = github.com/gogits/gogs
[deps]
github.com/Unknwon/cae =
github.com/Unknwon/com =
github.com/Unknwon/goconfig =
github.com/codegangsta/cli =
github.com/go-martini/martini =
github.com/go-sql-driver/mysql =
github.com/go-xorm/xorm =
github.com/gogits/cache =
github.com/gogits/gfm =
github.com/gogits/git =
github.com/gogits/logs =
github.com/gogits/oauth2 =
github.com/gogits/session =
github.com/lib/pq =
github.com/nfnt/resize =
github.com/qiniu/log =
github.com/robfig/cron =
github.com/beego/memcache = commit:2aea774416
github.com/beego/redigo = commit:856744a0d5
github.com/Unknwon/cae = commit:2e70a1351b
github.com/Unknwon/com = commit:2cbcbc6916
github.com/Unknwon/goconfig = commit:0f8d8dc1c0
github.com/Unknwon/i18n = commit:47baeff8d0
github.com/Unknwon/macaron = commit:f22f45d79a
github.com/codegangsta/cli = commit:7381bc4e62
github.com/go-sql-driver/mysql = commit:8111ee3ec3
github.com/go-xorm/core = commit:750aae0fa5
github.com/go-xorm/xorm = commit:2d8b3135b1
github.com/gogits/gfm = commit:40f747a9c0
github.com/gogits/oauth2 = commit:99cbec870a
github.com/lib/pq = commit:b021d0ef20
github.com/macaron-contrib/cache = commit:204d8e5137
github.com/macaron-contrib/captcha = commit:8f3f1ac0e3
github.com/macaron-contrib/csrf = commit:cd84c01723
github.com/macaron-contrib/i18n = commit:489cc194b5
github.com/macaron-contrib/session = commit:80a88a1bba
github.com/macaron-contrib/toolbox = commit:57127bcc89
github.com/mattn/go-sqlite3 = commit:a80c27ba33
github.com/nfnt/resize = commit:581d15cb53
github.com/saintfish/chardet = commit:3af4cd4741
[res]
include = templates|public|conf
include = conf|etc|public|scripts|templates

15
.pkgr.yml Normal file
View File

@@ -0,0 +1,15 @@
targets:
ubuntu-14.04:
ubuntu-12.04:
debian-7:
build_dependencies:
- mercurial
- bzr
dependencies:
- git
before:
- mv packager/Procfile .
- mv packager/.godir .
after:
- mv bin/main gogs
after_install: ./packager/debian/postinst

6
.travis.yml Normal file
View File

@@ -0,0 +1,6 @@
language: go
go:
- 1.2
- 1.3
- tip

View File

@@ -1,14 +1,54 @@
# Contributing to Gogs
> Thanks [drone](https://github.com/drone/drone) because this guidelines sheet is forked from its [CONTRIBUTING.md](https://github.com/drone/drone/blob/master/CONTRIBUTING.md).
> This guidelines sheet is forked from [CONTRIBUTING.md](https://github.com/drone/drone/blob/master/CONTRIBUTING.md).
**This document is pre^2 release, we're not ready for receiving contribution until v0.5.0 release.**
Want to hack on Gogs? Awesome! Here are instructions to get you started. They are probably not perfect, please let us know if anything feels wrong or incomplete.
Gogs is not perfect and it has bugs, or incomplete features for rare cases. You're welcome to tell us or contribute some code. This document describles details about how can you contribute to Gogs project.
## Contribution guidelines
### Pull requests are always welcome
Depends on the situation, you will:
- Find bug, create an issue
- Need more functionality, make a feature request
- Want to contribute code, open a pull request
- Run into issue, need help
### Bug Report
If you find or consider something is a bug, please create a issue on [GitHub](https://github.com/gogits/gogs/issues). To reduce unnecessary time wasting of interacting and waiting with team members, please use following form as template in the first place:
```
- **Bug Description**:
- **Gogs Version**:
- **Git Version**:
- **System Type**:
- **Error Log**:
- **Other information**:
```
Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
#### Bug Report Example
- **Bug Description**: Crash when create repository with license|
- **Gogs Version**: `v0.4.9.0901`
- **Git Version**: `1.9.0`
- **System Type**: `Ubuntu 12.04`
- **Error Log**:
```
2014/09/01 07:21:49 [E] nil pointer
```
- **Other information**: Use SQLite3 as database
### Feature Request
There is no standard form of making a feature request, just try to describle the feature as clear as possible because team members may not have experience with the functionality you're talking about.
### Pull Request
Pull requests are always welcome, but note that **ALL PULL REQUESTS MUST SEND TO `DEV` BRANCH**.
We are always thrilled to receive pull requests, and do our best to process them as fast as possible. Not sure if that typo is worth a pull request? Do it! We will appreciate it.
@@ -16,16 +56,16 @@ If your pull request is not accepted on the first try, don't be discouraged! If
We're trying very hard to keep Gogs lean and focused. We don't want it to do everything for everybody. This means that we might decide against incorporating a new feature.
### Ask For Help
Before open any new issue, please check your problem on [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md) and [FAQs](http://gogs.io/docs/intro/faqs.html) pages.
## Things To Notice
Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) or card on [Trello](https://trello.com/b/uxAoeLUl/gogs-go-git-service) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
### Discuss your design on the mailing list
We recommend discussing your plans [on the mailing list](https://groups.google.com/forum/#!forum/gogits) before starting to code - especially for more ambitious contributions. This gives other contributors a chance to point you in the right direction, give feedback on your design, and maybe point out if someone else is working on the same thing.
We may close your pull request if not first discussed on the mailing list. We aren't doing this to be jerks. We are doing this to prevent people from spending large amounts of time on changes that may need to be designed or architected in a specific way, or may not align with the vision of the project.
### Create issues...
Any significant improvement should be documented as [a GitHub issue](https://github.com/gogits/gogs/issues) before anybody starts working on it.
### ...but check for existing issues first!
Please take a moment to check that an issue doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
We may close your pull request if not first discussed on the mailing list. We aren't doing this to be jerks. We are doing this to prevent people from spending large amounts of time on changes that may need to be designed or architected in a specific way, or may not align with the vision of the project.

View File

@@ -1,16 +1,16 @@
Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://drone.io/github.com/gogits/gogs/status.png)](https://drone.io/github.com/gogits/gogs/latest)
=====================
Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language.
Gogs(Go Git Service) is a painless self-hosted Git Service written in Go.
![Demo](http://gowalker.org/public/gogs_demo.gif)
![Demo](https://gowalker.org/public/gogs_demo.gif)
##### Current version: 0.3.0 Alpha
##### Current version: 0.5.2 Beta
### NOTICES
- Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in **April 14, 2014** and will reset multiple times after. Please do **NOT** put your important data on the site.
- Demo site [try.gogits.org](http://try.gogits.org) is running under `dev` branch.
- Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) has been reset in **June 21, 2014** and will reset multiple times after. Please do **NOT** put your important data on the site.
- Demo site [try.gogs.io](https://try.gogs.io) is running under `dev` branch.
#### Other language version
@@ -18,39 +18,50 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language
## Purpose
Since we choose to use pure Go implementation of Git manipulation, Gogs certainly supports **ALL platforms** that Go supports, including Linux, Mac OS X, and Windows with **ZERO** dependency.
More importantly, Gogs only needs one binary to setup your own project hosting on the fly!
The goal of this project is to make the easiest, fastest and most painless way to set up a self-hosted Git service. With Go, this can be done in independent binary distribution across **ALL platforms** that Go supports, including Linux, Mac OS X, and Windows.
## Overview
- Please see [Wiki](https://github.com/gogits/gogs/wiki) for project design, known issues, and change log.
- Please see [Documentation](http://gogs.io/docs/intro/) for project design, known issues, and change log.
- See [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
- Try it before anything? Do it [online](http://try.gogits.org/Unknown/gogs) or go down to **Installation -> Install from binary** section!
- Having troubles? Get help from [Troubleshooting](https://github.com/gogits/gogs/wiki/Troubleshooting).
- Try it before anything? Do it [online](https://try.gogs.io/Unknown/gogs) or go down to **Installation -> Install from binary** section!
- Having troubles? Get help from [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md).
## Features
- Activity timeline
- SSH/HTTP(S) protocol support.
- Register/delete/rename account.
- Create/migrate/mirror/delete/watch/rename/transfer public/private repository.
- Repository viewer/release/issue tracker.
- Gravatar and cache support.
- Mail service(register, issue).
- Administration panel.
- Supports MySQL, PostgreSQL and SQLite3.
- SSH/HTTP(S) protocol support
- SMTP/LDAP/reverse proxy authentication support
- Register/delete/rename account
- Create/manage/delete organization with team management
- Create/migrate/mirror/delete/watch/rename/transfer public/private repository
- Repository viewer/release/issue tracker
- Repository and Organization level webhooks
- Add/remove repository collaborators
- Gravatar and cache support
- Mail service(register, issue)
- Administration panel
- Slack webhook integration
- Supports MySQL, PostgreSQL and SQLite3
- Social account login(GitHub, Google, QQ, Weibo)
- Multi-language support(English, Chinese, Germany, French etc.)
## System Requirements
- A cheap Raspberry Pi is powerful enough to match the minimal requirement.
- 4 CPU Cores and 1GB RAM would be the baseline for teamwork.
## Installation
Make sure you install [Prerequirements](https://github.com/gogits/gogs/wiki/Prerequirements) first.
Make sure you install [Prerequirements](http://gogs.io/docs/installation/) first.
There are 3 ways to install Gogs:
There are 5 ways to install Gogs:
- [Install from binary](https://github.com/gogits/gogs/wiki/Install-from-binary): **STRONGLY RECOMMENDED**
- [Install from source](https://github.com/gogits/gogs/wiki/Install-from-source)
- [Ship with Docker](https://github.com/gogits/gogs/tree/master/dockerfiles)
- [Install from binary](http://gogs.io/docs/installation/install_from_binary.md): **STRONGLY RECOMMENDED**
- [Install from source](http://gogs.io/docs/installation/install_from_source.md)
- [Install from packages](http://gogs.io/docs/installation/install_from_packages.md)
- [Ship with Docker](https://github.com/gogits/gogs/tree/master/docker)
- [Install with Vagrant](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
## Acknowledgments
@@ -58,17 +69,13 @@ There are 3 ways to install Gogs:
- Mail Service, modules design is inspired by [WeTalk](https://github.com/beego/wetalk).
- System Monitor Status is inspired by [GoBlog](https://github.com/fuxiaohei/goblog).
- Usage and modification from [beego](http://beego.me) modules.
- Thanks [lavachen](http://www.lavachen.cn/) for designing Logo.
- Thanks [lavachen](http://www.lavachen.cn/) and [Rocker](http://weibo.com/rocker1989) for designing Logo.
- Thanks [gobuild.io](http://gobuild.io) for providing binary compile and download service.
- Great thanks to [Docker China](http://www.dockboard.org/) for providing [dockerfiles](https://github.com/gogits/gogs/tree/master/dockerfiles).
## Contributors
This project was launched by [Unknown](https://github.com/Unknwon) and [lunny](https://github.com/lunny); [fuxiaohei](https://github.com/fuxiaohei), [slene](https://github.com/slene) and [codeskyblue](https://github.com/codeskyblue) joined the team soon after. See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
[![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
[koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1
The [core team](http://gogs.io/team) of this project. See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
## License
Gogs is under the MIT License. See the [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) file for the full license text.
This project is under the MIT License. See the [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) file for the full license text.

View File

@@ -1,47 +1,58 @@
Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://drone.io/github.com/gogits/gogs/status.png)](https://drone.io/github.com/gogits/gogs/latest)
=====================
Gogs(Go Git Service) 是一个 Go 语言编写的自助 Git 托管服务。
Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。
![Demo](http://gowalker.org/public/gogs_demo.gif)
![Demo](https://gowalker.org/public/gogs_demo.gif)
##### 当前版本0.3.0 Alpha
##### 当前版本0.5.2 Beta
## 开发目的
Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依赖,并且支持 Go 语言支持的 **所有平台**,包括 Linux、Mac OS X 以及 Windows。
更重要的是,您只需要一个可执行文件就能借助 Gogs 快速搭建属于您自己的代码托管服务!
Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。使用 Go 语言开发使得 Gogs 能够通过独立的二进制分发,并且支持 Go 语言支持的 **所有平台**,包括 Linux、Mac OS X 以及 Windows。
## 项目概览
- 有关项目设计、已知问题和变更日志,请通过 [Wiki](https://github.com/gogits/gogs/wiki) 查看。
- 有关项目设计、已知问题和变更日志,请通过 [使用手册](http://gogs.io/docs/intro/) 查看。
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
- 想要先睹为快?通过 [在线体验](http://try.gogits.org/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
- 使用过程中遇到问题?尝试从 [故障排查](https://github.com/gogits/gogs/wiki/Troubleshooting) 页面获取帮助。
- 想要先睹为快?通过 [在线体验](https://try.gogs.io/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。
- 使用过程中遇到问题?尝试从 [故障排查](http://gogs.io/docs/intro/troubleshooting.md) 页面获取帮助。
## 功能特性
- 活动时间线
- SSH/HTTP(S) 协议支持
- 注册/删除/重命名用户
- 支持 SSH/HTTP(S) 协议
- 支持 SMTP/LDAP/反向代理 用户认证
- 注册/删除/重命名 用户
- 创建/管理/删除 组织以及团队管理功能
- 创建/迁移/镜像/删除/关注/重命名/转移 公开/私有 仓库
- 仓库 浏览/发布/缺陷追踪
- 仓库 浏览/发布/工单管理
- 仓库和组织级别 Web 钩子
- 添加/删除 仓库协作者
- Gravatar 以及缓存支持
- 邮件服务注册、Issue
- 管理员面板
- Slack Web 钩子集成
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录GitHub、Google、QQ、微博
- 多语言支持(英文、简体中文、德语、法语等等)
## 系统要求
- 最低的系统硬件要求为一个廉价的树莓派
- 如果用于团队项目,建议使用 4 核 CPU 及 1GB 内存
## 安装部署
在安装 Gogs 之前,您需要先安装 [基本环境](https://github.com/gogits/gogs/wiki/Prerequirements)。
在安装 Gogs 之前,您需要先安装 [基本环境](http://gogs.io/docs/installation/)。
然后,您可以通过以下 3 种方式来安装 Gogs
然后,您可以通过以下 5 种方式来安装 Gogs
- [二进制安装](https://github.com/gogits/gogs/wiki/Install-from-binary): **强烈推荐**
- [源码安装](https://github.com/gogits/gogs/wiki/Install-from-source)
- [采用 Docker 部署](https://github.com/gogits/gogs/tree/master/dockerfiles)
- [二进制安装](http://gogs.io/docs/installation/install_from_binary.md): **强烈推荐**
- [源码安装](http://gogs.io/docs/installation/install_from_source.md)
- [包管理安装](http://gogs.io/docs/installation/install_from_packages.md)
- [采用 Docker 部署](https://github.com/gogits/gogs/tree/master/docker)
- [通过 Vagrant 安装](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
## 特别鸣谢
@@ -50,16 +61,12 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依
- [beego](http://beego.me) 模块的使用与修改。
- [martini](http://martini.codegangsta.io/) 的路由与中间件机制。
- 感谢 [gobuild.io](http://gobuild.io) 提供二进制编译与下载服务。
- 感谢 [lavachen](http://www.lavachen.cn/) 设计的 Logo。
- 感谢 [Docker 中文社区](http://www.dockboard.org/) 提供的 [dockerfiles](https://github.com/gogits/gogs/tree/master/dockerfiles)。
- 感谢 [lavachen](http://www.lavachen.cn/) 和 [Rocker](http://weibo.com/rocker1989) 设计的 Logo。
## 贡献成员
本项目最初由 [Unknown](https://github.com/Unknwon) 和 [lunny](https://github.com/lunny) 发起,随后 [fuxiaohei](https://github.com/fuxiaohei)、[slene](https://github.com/slene) 以及 [codeskyblue](https://github.com/codeskyblue) 加入到开发团队。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
[![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
[koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1
本项目的 [开发团队](http://gogs.io/team)。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
## 授权许可
Gogs 采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。
本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。

View File

@@ -1,24 +0,0 @@
{
"version": 0,
"gopm": {
"enable": false,
"install": false
},
"go_install": true,
"watch_ext": [],
"dir_structure": {
"watch_all": true,
"controllers": "routers",
"models": "",
"others": [
"modules",
"$GOPATH/src/github.com/gogits/logs",
"$GOPATH/src/github.com/gogits/git",
"$GOPATH/src/github.com/gogits/gfm"
]
},
"cmd_args": [
"web"
],
"envs": []
}

69
cmd/dump.go Normal file
View File

@@ -0,0 +1,69 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"fmt"
"log"
"os"
"path"
"time"
"github.com/Unknwon/cae/zip"
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/setting"
)
var CmdDump = cli.Command{
Name: "dump",
Usage: "Dump Gogs files and database",
Description: `Dump compresses all related files and database into zip file.
It can be used for backup and capture Gogs server image to send to maintainer`,
Action: runDump,
Flags: []cli.Flag{
cli.BoolFlag{"verbose, v", "show process details", ""},
},
}
func runDump(ctx *cli.Context) {
setting.NewConfigContext()
models.LoadModelsConfig()
models.SetEngine()
log.Printf("Dumping local repositories...%s", setting.RepoRootPath)
zip.Verbose = ctx.Bool("verbose")
defer os.Remove("gogs-repo.zip")
if err := zip.PackTo(setting.RepoRootPath, "gogs-repo.zip", true); err != nil {
log.Fatalf("Fail to dump local repositories: %v", err)
}
log.Printf("Dumping database...")
defer os.Remove("gogs-db.sql")
if err := models.DumpDatabase("gogs-db.sql"); err != nil {
log.Fatalf("Fail to dump database: %v", err)
}
fileName := fmt.Sprintf("gogs-dump-%d.zip", time.Now().Unix())
log.Printf("Packing dump files...")
z, err := zip.Create(fileName)
if err != nil {
os.Remove(fileName)
log.Fatalf("Fail to create %s: %v", fileName, err)
}
workDir, _ := setting.WorkDir()
z.AddFile("gogs-repo.zip", path.Join(workDir, "gogs-repo.zip"))
z.AddFile("gogs-db.sql", path.Join(workDir, "gogs-db.sql"))
z.AddFile("custom/conf/app.ini", path.Join(workDir, "custom/conf/app.ini"))
z.AddDir("log", path.Join(workDir, "log"))
if err = z.Close(); err != nil {
os.Remove(fileName)
log.Fatalf("Fail to save %s: %v", fileName, err)
}
log.Println("Finish dumping!")
}

181
cmd/fix.go Normal file
View File

@@ -0,0 +1,181 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"runtime"
"strings"
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/setting"
)
var CmdFix = cli.Command{
Name: "fix",
Usage: "This command for upgrade from old version",
Action: runFix,
Subcommands: fixCommands,
Flags: []cli.Flag{},
}
func runFix(ctx *cli.Context) {
}
var fixCommands = []cli.Command{
{
Name: "location",
Usage: "Change Gogs app location",
Description: `Command location fixes location change of Gogs
gogs fix location <old Gogs path>
`,
Action: runFixLocation,
},
}
// rewriteAuthorizedKeys replaces old Gogs path to the new one.
func rewriteAuthorizedKeys(sshPath, oldPath, newPath string) error {
fr, err := os.Open(sshPath)
if err != nil {
return err
}
defer fr.Close()
tmpPath := sshPath + ".tmp"
fw, err := os.Create(tmpPath)
if err != nil {
return err
}
defer fw.Close()
oldPath = "command=\"" + oldPath + " serv"
newPath = "command=\"" + newPath + " serv"
buf := bufio.NewReader(fr)
for {
line, errRead := buf.ReadString('\n')
line = strings.TrimSpace(line)
if errRead != nil {
if errRead != io.EOF {
return errRead
}
// Reached end of file, if nothing to read then break,
// otherwise handle the last line.
if len(line) == 0 {
break
}
}
// Still finding the line, copy the line that currently read.
if _, err = fw.WriteString(strings.Replace(line, oldPath, newPath, 1) + "\n"); err != nil {
return err
}
if errRead == io.EOF {
break
}
}
if err = os.Remove(sshPath); err != nil {
return err
}
return os.Rename(tmpPath, sshPath)
}
func rewriteUpdateHook(path, appPath string) error {
if runtime.GOOS == "windows" {
rp := strings.NewReplacer("\\", "/")
appPath = "\"" + rp.Replace(appPath) + "\""
} else {
rp := strings.NewReplacer("\\", "/", " ", "\\ ")
appPath = rp.Replace(appPath)
}
if err := ioutil.WriteFile(path, []byte(fmt.Sprintf(models.TPL_UPDATE_HOOK,
setting.ScriptType, appPath)), os.ModePerm); err != nil {
return err
}
return nil
}
func walkDir(rootPath, recPath, appPath string, depth int) error {
depth++
if depth > 3 {
return nil
} else if depth == 3 {
if err := rewriteUpdateHook(path.Join(rootPath, "hooks/update"), appPath); err != nil {
return err
}
}
dir, err := os.Open(rootPath)
if err != nil {
return err
}
defer dir.Close()
fis, err := dir.Readdir(0)
if err != nil {
return err
}
for _, fi := range fis {
if strings.Contains(fi.Name(), ".DS_Store") {
continue
}
relPath := path.Join(recPath, fi.Name())
curPath := path.Join(rootPath, fi.Name())
if fi.IsDir() {
if err = walkDir(curPath, relPath, appPath, depth); err != nil {
return err
}
}
}
return nil
}
func runFixLocation(ctx *cli.Context) {
if len(ctx.Args()) != 1 {
fmt.Println("Incorrect arguments number, expect 1")
os.Exit(2)
}
execPath, _ := setting.ExecPath()
oldPath := ctx.Args().First()
fmt.Printf("Old location: %s\n", oldPath)
fmt.Println("This command should be executed in the new Gogs path")
fmt.Printf("Do you want to change Gogs app path from old location to:\n")
fmt.Printf("-> %s?\n", execPath)
fmt.Print("Press <enter> to continue, use <Ctrl+c> to exit.")
fmt.Scanln()
// Fix in authorized_keys file.
sshPath := path.Join(models.SshPath, "authorized_keys")
fmt.Printf("Fixing pathes in file: %s\n", sshPath)
if err := rewriteAuthorizedKeys(sshPath, oldPath, execPath); err != nil {
fmt.Println(err)
os.Exit(1)
}
// Fix position in gogs-repositories.
setting.NewConfigContext()
fmt.Printf("Fixing pathes in repositories: %s\n", setting.RepoRootPath)
if err := walkDir(setting.RepoRootPath, "", execPath, 0); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("Fix position finished!")
}

212
cmd/serve.go Normal file
View File

@@ -0,0 +1,212 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
"time"
"github.com/Unknwon/com"
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/modules/uuid"
)
var CmdServ = cli.Command{
Name: "serv",
Usage: "This command should only be called by SSH shell",
Description: `Serv provide access auth for repositories`,
Action: runServ,
Flags: []cli.Flag{},
}
func setup(logPath string) {
setting.NewConfigContext()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
models.LoadModelsConfig()
if models.UseSQLite3 {
workDir, _ := setting.WorkDir()
os.Chdir(workDir)
}
models.SetEngine()
}
func parseCmd(cmd string) (string, string) {
ss := strings.SplitN(cmd, " ", 2)
if len(ss) != 2 {
return "", ""
}
verb, args := ss[0], ss[1]
if verb == "git" {
ss = strings.SplitN(args, " ", 2)
args = ss[1]
verb = fmt.Sprintf("%s %s", verb, ss[0])
}
return verb, strings.Replace(args, "'/", "'", 1)
}
var (
COMMANDS_READONLY = map[string]models.AccessType{
"git-upload-pack": models.WRITABLE,
"git upload-pack": models.WRITABLE,
"git-upload-archive": models.WRITABLE,
}
COMMANDS_WRITE = map[string]models.AccessType{
"git-receive-pack": models.READABLE,
"git receive-pack": models.READABLE,
}
)
func In(b string, sl map[string]models.AccessType) bool {
_, e := sl[b]
return e
}
func runServ(k *cli.Context) {
setup("serv.log")
keys := strings.Split(os.Args[2], "-")
if len(keys) != 2 {
println("Gogs: auth file format error")
log.GitLogger.Fatal(2, "Invalid auth file format: %s", os.Args[2])
}
keyId, err := com.StrTo(keys[1]).Int64()
if err != nil {
println("Gogs: auth file format error")
log.GitLogger.Fatal(2, "Invalid auth file format: %v", err)
}
user, err := models.GetUserByKeyId(keyId)
if err != nil {
if err == models.ErrUserNotKeyOwner {
println("Gogs: you are not the owner of SSH key")
log.GitLogger.Fatal(2, "Invalid owner of SSH key: %d", keyId)
}
println("Gogs: internal error:", err)
log.GitLogger.Fatal(2, "Fail to get user by key ID(%d): %v", keyId, err)
}
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" {
println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.")
return
}
verb, args := parseCmd(cmd)
repoPath := strings.Trim(args, "'")
rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 2 {
println("Gogs: unavailable repository", args)
log.GitLogger.Fatal(2, "Unavailable repository: %v", args)
}
repoUserName := rr[0]
repoName := strings.TrimSuffix(rr[1], ".git")
isWrite := In(verb, COMMANDS_WRITE)
isRead := In(verb, COMMANDS_READONLY)
repoUser, err := models.GetUserByName(repoUserName)
if err != nil {
if err == models.ErrUserNotExist {
println("Gogs: given repository owner are not registered")
log.GitLogger.Fatal(2, "Unregistered owner: %s", repoUserName)
}
println("Gogs: internal error:", err)
log.GitLogger.Fatal(2, "Fail to get repository owner(%s): %v", repoUserName, err)
}
// Access check.
switch {
case isWrite:
has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.WRITABLE)
if err != nil {
println("Gogs: internal error:", err)
log.GitLogger.Fatal(2, "Fail to check write access:", err)
} else if !has {
println("You have no right to write this repository")
log.GitLogger.Fatal(2, "User %s has no right to write repository %s", user.Name, repoPath)
}
case isRead:
repo, err := models.GetRepositoryByName(repoUser.Id, repoName)
if err != nil {
if err == models.ErrRepoNotExist {
println("Gogs: given repository does not exist")
log.GitLogger.Fatal(2, "Repository does not exist: %s/%s", repoUser.Name, repoName)
}
println("Gogs: internal error:", err)
log.GitLogger.Fatal(2, "Fail to get repository: %v", err)
}
if !repo.IsPrivate {
break
}
has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.READABLE)
if err != nil {
println("Gogs: internal error:", err)
log.GitLogger.Fatal(2, "Fail to check read access:", err)
} else if !has {
println("You have no right to access this repository")
log.GitLogger.Fatal(2, "User %s has no right to read repository %s", user.Name, repoPath)
}
default:
println("Unknown command")
return
}
uuid := uuid.NewV4().String()
os.Setenv("uuid", uuid)
gitcmd := exec.Command(verb, repoPath)
gitcmd.Dir = setting.RepoRootPath
gitcmd.Stdout = os.Stdout
gitcmd.Stdin = os.Stdin
gitcmd.Stderr = os.Stderr
if err = gitcmd.Run(); err != nil {
println("Gogs: internal error:", err.Error())
log.GitLogger.Fatal(2, "Fail to execute git command: %v", err)
}
if isWrite {
tasks, err := models.GetUpdateTasksByUuid(uuid)
if err != nil {
log.GitLogger.Fatal(2, "GetUpdateTasksByUuid: %v", err)
}
for _, task := range tasks {
err = models.Update(task.RefName, task.OldCommitId, task.NewCommitId,
user.Name, repoUserName, repoName, user.Id)
if err != nil {
log.GitLogger.Error(2, "Fail to update: %v", err)
}
}
if err = models.DelUpdateTasksByUuid(uuid); err != nil {
log.GitLogger.Fatal(2, "DelUpdateTasksByUuid: %v", err)
}
}
// Update key activity.
key, err := models.GetPublicKeyById(keyId)
if err != nil {
log.GitLogger.Fatal(2, "GetPublicKeyById: %v", err)
}
key.Updated = time.Now()
if err = models.UpdatePublicKey(key); err != nil {
log.GitLogger.Fatal(2, "UpdatePublicKey: %v", err)
}
}

51
cmd/update.go Normal file
View File

@@ -0,0 +1,51 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"os"
"github.com/codegangsta/cli"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
)
var CmdUpdate = cli.Command{
Name: "update",
Usage: "This command should only be called by SSH shell",
Description: `Update get pushed info and insert into database`,
Action: runUpdate,
Flags: []cli.Flag{},
}
func runUpdate(c *cli.Context) {
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" {
return
}
setup("update.log")
args := c.Args()
if len(args) != 3 {
log.GitLogger.Fatal(2, "received less 3 parameters")
} else if args[0] == "" {
log.GitLogger.Fatal(2, "refName is empty, shouldn't use")
}
uuid := os.Getenv("uuid")
task := models.UpdateTask{
Uuid: uuid,
RefName: args[0],
OldCommitId: args[1],
NewCommitId: args[2],
}
if err := models.AddUpdateTask(&task); err != nil {
log.GitLogger.Fatal(2, err.Error())
}
}

381
cmd/web.go Normal file
View File

@@ -0,0 +1,381 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package cmd
import (
"fmt"
"html/template"
"io/ioutil"
"net/http"
"os"
"path"
"github.com/Unknwon/macaron"
"github.com/codegangsta/cli"
"github.com/macaron-contrib/cache"
"github.com/macaron-contrib/captcha"
"github.com/macaron-contrib/csrf"
"github.com/macaron-contrib/i18n"
"github.com/macaron-contrib/session"
"github.com/macaron-contrib/toolbox"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/auth/apiv1"
"github.com/gogits/gogs/modules/avatar"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/middleware/binding"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/routers"
"github.com/gogits/gogs/routers/admin"
"github.com/gogits/gogs/routers/api/v1"
"github.com/gogits/gogs/routers/dev"
"github.com/gogits/gogs/routers/org"
"github.com/gogits/gogs/routers/repo"
"github.com/gogits/gogs/routers/user"
)
var CmdWeb = cli.Command{
Name: "web",
Usage: "Start Gogs web server",
Description: `Gogs web server is the only thing you need to run,
and it takes care of all the other things for you`,
Action: runWeb,
Flags: []cli.Flag{},
}
// checkVersion checks if binary matches the version of templates files.
func checkVersion() {
data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, "templates/.VERSION"))
if err != nil {
log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err)
}
if string(data) != setting.AppVer {
log.Fatal(4, "Binary and template file version does not match, did you forget to recompile?")
}
}
// newMacaron initializes Macaron instance.
func newMacaron() *macaron.Macaron {
m := macaron.New()
m.Use(macaron.Logger())
m.Use(macaron.Recovery())
m.Use(macaron.Static(
path.Join(setting.StaticRootPath, "public"),
macaron.StaticOptions{
SkipLogging: !setting.DisableRouterLog,
},
))
// if setting.EnableGzip {
// m.Use(macaron.Gzip())
// }
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: path.Join(setting.StaticRootPath, "templates"),
Funcs: []template.FuncMap{base.TemplateFuncs},
IndentJSON: macaron.Env != macaron.PROD,
}))
m.Use(i18n.I18n(i18n.Options{
Langs: setting.Langs,
Names: setting.Names,
Redirect: true,
}))
m.Use(cache.Cacher(cache.Options{
Adapter: setting.CacheAdapter,
Interval: setting.CacheInternal,
Conn: setting.CacheConn,
}))
m.Use(captcha.Captchaer())
m.Use(session.Sessioner(session.Options{
Provider: setting.SessionProvider,
Config: *setting.SessionConfig,
}))
m.Use(csrf.Generate(csrf.Options{
Secret: setting.SecretKey,
SetCookie: true,
Header: "X-Csrf-Token",
}))
m.Use(toolbox.Toolboxer(m, toolbox.Options{
HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
&toolbox.HealthCheckFuncDesc{
Desc: "Database connection",
Func: models.Ping,
},
},
}))
m.Use(middleware.Contexter())
return m
}
func runWeb(*cli.Context) {
routers.GlobalInit()
checkVersion()
m := newMacaron()
reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true})
ignSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: setting.Service.RequireSignInView})
ignSignInAndCsrf := middleware.Toggle(&middleware.ToggleOptions{DisableCsrf: true})
reqSignOut := middleware.Toggle(&middleware.ToggleOptions{SignOutRequire: true})
bindIgnErr := binding.BindIgnErr
// Routers.
m.Get("/", ignSignIn, routers.Home)
m.Get("/explore", ignSignIn, routers.Explore)
m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
m.Group("", func(r *macaron.Router) {
r.Get("/pulls", user.Pulls)
r.Get("/issues", user.Issues)
}, reqSignIn)
// API routers.
m.Group("/api", func(_ *macaron.Router) {
m.Group("/v1", func(r *macaron.Router) {
// Miscellaneous.
r.Post("/markdown", bindIgnErr(apiv1.MarkdownForm{}), v1.Markdown)
r.Post("/markdown/raw", v1.MarkdownRaw)
// Users.
m.Group("/users", func(r *macaron.Router) {
r.Get("/search", v1.SearchUsers)
})
// Repositories.
m.Group("/repos", func(r *macaron.Router) {
r.Get("/search", v1.SearchRepos)
r.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), v1.Migrate)
})
r.Any("/*", func(ctx *middleware.Context) {
ctx.JSON(404, &base.ApiJsonErr{"Not Found", v1.DOC_URL})
})
})
})
// User routers.
m.Group("/user", func(r *macaron.Router) {
r.Get("/login", user.SignIn)
r.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost)
r.Get("/login/:name", user.SocialSignIn)
r.Get("/sign_up", user.SignUp)
r.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
r.Get("/reset_password", user.ResetPasswd)
r.Post("/reset_password", user.ResetPasswdPost)
}, reqSignOut)
m.Group("/user/settings", func(r *macaron.Router) {
r.Get("", user.Settings)
r.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
r.Get("/password", user.SettingsPassword)
r.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
r.Get("/ssh", user.SettingsSSHKeys)
r.Post("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
r.Get("/social", user.SettingsSocial)
r.Route("/delete", "GET,POST", user.SettingsDelete)
}, reqSignIn)
m.Group("/user", func(r *macaron.Router) {
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
r.Any("/activate", user.Activate)
r.Get("/email2user", user.Email2User)
r.Get("/forget_password", user.ForgotPasswd)
r.Post("/forget_password", user.ForgotPasswdPost)
r.Get("/logout", user.SignOut)
})
m.Get("/user/:username", ignSignIn, user.Profile) // TODO: Legacy
// Gravatar service.
avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg")
os.MkdirAll("public/img/avatar/", os.ModePerm)
m.Get("/avatar/:hash", avt.ServeHTTP)
adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true})
m.Group("/admin", func(r *macaron.Router) {
m.Get("", adminReq, admin.Dashboard)
r.Get("/config", admin.Config)
r.Get("/monitor", admin.Monitor)
m.Group("/users", func(r *macaron.Router) {
r.Get("", admin.Users)
r.Get("/new", admin.NewUser)
r.Post("/new", bindIgnErr(auth.RegisterForm{}), admin.NewUserPost)
r.Get("/:userid", admin.EditUser)
r.Post("/:userid", bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost)
r.Post("/:userid/delete", admin.DeleteUser)
})
m.Group("/orgs", func(r *macaron.Router) {
r.Get("", admin.Organizations)
})
m.Group("/repos", func(r *macaron.Router) {
r.Get("", admin.Repositories)
})
m.Group("/auths", func(r *macaron.Router) {
r.Get("", admin.Authentications)
r.Get("/new", admin.NewAuthSource)
r.Post("/new", bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost)
r.Get("/:authid", admin.EditAuthSource)
r.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost)
r.Post("/:authid/delete", admin.DeleteAuthSource)
})
}, adminReq)
m.Get("/:username", ignSignIn, user.Profile)
if macaron.Env == macaron.DEV {
m.Get("/template/*", dev.TemplatePreview)
}
reqTrueOwner := middleware.RequireTrueOwner()
// Organization routers.
m.Group("/org", func(r *macaron.Router) {
r.Get("/create", org.Create)
r.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost)
m.Group("/:org", func(r *macaron.Router) {
r.Get("/dashboard", user.Dashboard)
r.Get("/members", org.Members)
r.Get("/members/action/:action", org.MembersAction)
r.Get("/teams", org.Teams)
r.Get("/teams/:team", org.TeamMembers)
r.Get("/teams/:team/repositories", org.TeamRepositories)
r.Get("/teams/:team/action/:action", org.TeamsAction)
r.Get("/teams/:team/action/repo/:action", org.TeamsRepoAction)
}, middleware.OrgAssignment(true, true))
m.Group("/:org", func(r *macaron.Router) {
r.Get("/teams/new", org.NewTeam)
r.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
r.Get("/teams/:team/edit", org.EditTeam)
r.Post("/teams/:team/edit", bindIgnErr(auth.CreateTeamForm{}), org.EditTeamPost)
r.Post("/teams/:team/delete", org.DeleteTeam)
m.Group("/settings", func(r *macaron.Router) {
r.Get("", org.Settings)
r.Post("", bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
r.Get("/hooks", org.SettingsHooks)
r.Get("/hooks/new", repo.WebHooksNew)
r.Post("/hooks/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
r.Post("/hooks/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
r.Get("/hooks/:id", repo.WebHooksEdit)
r.Post("/hooks/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
r.Post("/hooks/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
r.Route("/delete", "GET,POST", org.SettingsDelete)
})
r.Route("/invitations/new", "GET,POST", org.Invitation)
}, middleware.OrgAssignment(true, true, true))
}, reqSignIn)
m.Group("/org", func(r *macaron.Router) {
r.Get("/:org", org.Home)
}, middleware.OrgAssignment(true))
// Repository routers.
m.Group("/repo", func(r *macaron.Router) {
r.Get("/create", repo.Create)
r.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
r.Get("/migrate", repo.Migrate)
r.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
}, reqSignIn)
m.Group("/:username/:reponame", func(r *macaron.Router) {
r.Get("/settings", repo.Settings)
r.Post("/settings", bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
m.Group("/settings", func(r *macaron.Router) {
r.Route("/collaboration", "GET,POST", repo.SettingsCollaboration)
r.Get("/hooks", repo.Webhooks)
r.Get("/hooks/new", repo.WebHooksNew)
r.Post("/hooks/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
r.Post("/hooks/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
r.Get("/hooks/:id", repo.WebHooksEdit)
r.Post("/hooks/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
r.Post("/hooks/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
})
}, reqSignIn, middleware.RepoAssignment(true), reqTrueOwner)
m.Group("/:username/:reponame", func(r *macaron.Router) {
r.Get("/action/:action", repo.Action)
m.Group("/issues", func(r *macaron.Router) {
r.Get("/new", repo.CreateIssue)
r.Post("/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost)
r.Post("/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue)
r.Post("/:index/label", repo.UpdateIssueLabel)
r.Post("/:index/milestone", repo.UpdateIssueMilestone)
r.Post("/:index/assignee", repo.UpdateAssignee)
r.Get("/:index/attachment/:id", repo.IssueGetAttachment)
r.Post("/labels/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
r.Post("/labels/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
r.Post("/labels/delete", repo.DeleteLabel)
r.Get("/milestones", repo.Milestones)
r.Get("/milestones/new", repo.NewMilestone)
r.Post("/milestones/new", bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
r.Get("/milestones/:index/edit", repo.UpdateMilestone)
r.Post("/milestones/:index/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.UpdateMilestonePost)
r.Get("/milestones/:index/:action", repo.UpdateMilestone)
})
r.Post("/comment/:action", repo.Comment)
r.Get("/releases/new", repo.NewRelease)
r.Get("/releases/edit/:tagname", repo.EditRelease)
}, reqSignIn, middleware.RepoAssignment(true))
m.Group("/:username/:reponame", func(r *macaron.Router) {
r.Post("/releases/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
r.Post("/releases/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, reqSignIn, middleware.RepoAssignment(true, true))
m.Group("/:username/:reponame", func(r *macaron.Router) {
r.Get("/issues", repo.Issues)
r.Get("/issues/:index", repo.ViewIssue)
r.Get("/pulls", repo.Pulls)
r.Get("/branches", repo.Branches)
}, ignSignIn, middleware.RepoAssignment(true))
m.Group("/:username/:reponame", func(r *macaron.Router) {
r.Get("/src/:branchname", repo.Home)
r.Get("/src/:branchname/*", repo.Home)
r.Get("/raw/:branchname/*", repo.SingleDownload)
r.Get("/commits/:branchname", repo.Commits)
r.Get("/commits/:branchname/search", repo.SearchCommits)
r.Get("/commits/:branchname/*", repo.FileHistory)
r.Get("/commit/:branchname", repo.Diff)
r.Get("/commit/:branchname/*", repo.Diff)
r.Get("/releases", repo.Releases)
r.Get("/archive/*.*", repo.Download)
r.Get("/compare/:before([a-z0-9]+)...:after([a-z0-9]+)", repo.CompareDiff)
}, ignSignIn, middleware.RepoAssignment(true, true))
m.Group("/:username", func(r *macaron.Router) {
r.Get("/:reponame", ignSignIn, middleware.RepoAssignment(true, true, true), repo.Home)
r.Any("/:reponame/*", ignSignInAndCsrf, repo.Http)
})
// Not found handler.
m.NotFound(routers.NotFound)
var err error
listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
log.Info("Listen: %v://%s", setting.Protocol, listenAddr)
switch setting.Protocol {
case setting.HTTP:
err = http.ListenAndServe(listenAddr, m)
case setting.HTTPS:
err = http.ListenAndServeTLS(listenAddr, setting.CertFile, setting.KeyFile, m)
default:
log.Fatal(4, "Invalid protocol: %s", setting.Protocol)
}
if err != nil {
log.Fatal(4, "Fail to start server: %v", err)
}
}

View File

@@ -1,28 +1,34 @@
; App name that shows on every page title
APP_NAME = Gogs: Go Git Service
APP_LOGO = img/favicon.png
; Change it if you run locally
RUN_USER = git
; Either "dev", "prod" or "test", default is "dev"
RUN_MODE = dev
[repository]
ROOT =
ROOT =
SCRIPT_TYPE = bash
LANG_IGNS = Google Go|C|C++|Python|Ruby|C Sharp|Java|Objective-C|Android
LICENSES = Apache v2 License|GPL v2|MIT License|Affero GPL|Artistic License 2.0|BSD (3-Clause) License
[server]
PROTOCOL = http
DOMAIN = localhost
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
HTTP_ADDR =
HTTP_ADDR =
HTTP_PORT = 3000
SSH_PORT = 22
; Disable CDN even in "prod" mode
OFFLINE_MODE = false
DISABLE_ROUTER_LOG = false
; Generate steps:
; $ cd path/to/gogs/custom/https
; $ go run $GOROOT/src/pkg/crypto/tls/generate_cert.go -ca=true -duration=8760h0m0s -host=myhost.example.com
CERT_FILE = custom/https/cert.pem
KEY_FILE = custom/https/key.pem
; Upper level of template and static file path
; default is the path where Gogs is executed
STATIC_ROOT_PATH =
; Application level GZIP support
#ENABLE_GZIP = false
[database]
; Either "mysql", "postgres" or "sqlite3", it's your choice
@@ -46,6 +52,8 @@ SECRET_KEY = !#@FDEWREWR&*(
LOGIN_REMEMBER_DAYS = 7
COOKIE_USERNAME = gogs_awesome
COOKIE_REMEMBER_NAME = gogs_incredible
; Reverse proxy authentication header name of user name
REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
[service]
ACTIVE_CODE_LIVE_MINUTES = 180
@@ -53,13 +61,21 @@ RESET_PASSWD_CODE_LIVE_MINUTES = 180
; User need to confirm e-mail for registration
REGISTER_EMAIL_CONFIRM = false
; Does not allow register and admin create account only
DISENABLE_REGISTERATION = false
DISABLE_REGISTRATION = false
; User must sign in to view anything.
REQUIRE_SIGNIN_VIEW = false
; Cache avatar as picture
ENABLE_CACHE_AVATAR = false
; Mail notification
ENABLE_NOTIFY_MAIL = false
; More detail: https://github.com/gogits/gogs/issues/165
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
[webhook]
; Cron task interval in minutes
TASK_INTERVAL = 1
; Deliver timeout in seconds
DELIVER_TIMEOUT = 5
[mailer]
ENABLED = false
@@ -70,20 +86,20 @@ SUBJECT = %(APP_NAME)s
; Mail server
; Gmail: smtp.gmail.com:587
; QQ: smtp.qq.com:25
HOST =
HOST =
; Mail from address
FROM =
FROM =
; Mailer user name and password
USER =
PASSWD =
USER =
PASSWD =
[oauth]
ENABLED = false
[oauth.github]
ENABLED = false
CLIENT_ID =
CLIENT_SECRET =
CLIENT_ID =
CLIENT_SECRET =
SCOPES = https://api.github.com/user
AUTH_URL = https://github.com/login/oauth/authorize
TOKEN_URL = https://github.com/login/oauth/access_token
@@ -92,16 +108,16 @@ TOKEN_URL = https://github.com/login/oauth/access_token
; https://console.developers.google.com/project
[oauth.google]
ENABLED = false
CLIENT_ID =
CLIENT_SECRET =
CLIENT_ID =
CLIENT_SECRET =
SCOPES = https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile
AUTH_URL = https://accounts.google.com/o/oauth2/auth
TOKEN_URL = https://accounts.google.com/o/oauth2/token
[oauth.qq]
ENABLED = false
CLIENT_ID =
CLIENT_SECRET =
CLIENT_ID =
CLIENT_SECRET =
SCOPES = all
; QQ 互联
; AUTH_URL = https://graph.qq.com/oauth2.0/authorize
@@ -110,18 +126,10 @@ SCOPES = all
AUTH_URL = https://open.t.qq.com/cgi-bin/oauth2/authorize
TOKEN_URL = https://open.t.qq.com/cgi-bin/oauth2/access_token
[oauth.twitter]
ENABLED = false
CLIENT_ID =
CLIENT_SECRET =
SCOPES = all
AUTH_URL = https://api.twitter.com/oauth/authorize
TOKEN_URL = https://api.twitter.com/oauth/access_token
[oauth.weibo]
ENABLED = false
CLIENT_ID =
CLIENT_SECRET =
CLIENT_ID =
CLIENT_SECRET =
SCOPES = all
AUTH_URL = https://api.weibo.com/oauth2/authorize
TOKEN_URL = https://api.weibo.com/oauth2/access_token
@@ -132,8 +140,8 @@ ADAPTER = memory
; For "memory" only, GC interval in seconds, default is 60
INTERVAL = 60
; For "redis" and "memcache", connection host address
; redis: ":6039"
; memcache: "127.0.0.1:11211"
; redis: `:6039`
; memcache: `127.0.0.1:11211`
HOST =
[session]
@@ -141,9 +149,9 @@ HOST =
PROVIDER = file
; Provider config options
; memory: not have any config yet
; file: session file path, e.g. data/sessions
; redis: config like redis server addr, poolSize, password, e.g. 127.0.0.1:6379,100,astaxie
; mysql: go-sql-driver/mysql dsn config string, e.g. root:password@/session_table
; file: session file path, e.g. `data/sessions`
; redis: config like redis server addr, poolSize, password, e.g. `127.0.0.1:6379,100,gogs`
; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
PROVIDER_CONFIG = data/sessions
; Session cookie name
COOKIE_NAME = i_like_gogits
@@ -163,9 +171,30 @@ SESSION_ID_HASHKEY =
[picture]
; The place to picture data, either "server" or "qiniu", default is "server"
SERVICE = server
DISABLE_GRAVATAR = false
[attachment]
; Whether attachments are enabled. Defaults to `true`
ENABLE = true
; Path for attachments. Defaults to `data/attachments`
PATH = data/attachments
; One or more allowed types, e.g. image/jpeg|image/png
ALLOWED_TYPES = image/jpeg|image/png
; Max size of each file. Defaults to 32MB
MAX_SIZE = 32
; Max number of files per upload. Defaults to 10
MAX_FILES = 10
[time]
; Specifies the format for fully outputed dates. Defaults to RFC1123
; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano
; For more information about the format see http://golang.org/pkg/time/#pkg-constants
FORMAT =
[log]
ROOT_PATH =
; Either "console", "file", "conn", "smtp" or "database", default is "console"
; Use comma to separate multiple modes, e.g. "console, file"
MODE = console
; Buffer length of channel, keep it as it is if you don't know what it is.
BUFFER_LEN = 10000
@@ -174,12 +203,11 @@ LEVEL = Trace
; For "console" mode only
[log.console]
LEVEL =
LEVEL =
; For "file" mode only
[log.file]
LEVEL =
FILE_NAME = log/gogs.log
LEVEL =
; This enables automated log rotate(switch of following options), default is true
LOG_ROTATE = true
; Max line number of single file, default is 1000000
@@ -193,7 +221,7 @@ MAX_DAYS = 7
; For "conn" mode only
[log.conn]
LEVEL =
LEVEL =
; Reconnect host for every single message, default is false
RECONNECT_ON_MSG = false
; Try to reconnect when connection is lost, default is false
@@ -201,23 +229,32 @@ RECONNECT = false
; Either "tcp", "unix" or "udp", default is "tcp"
PROTOCOL = tcp
; Host address
ADDR =
ADDR =
; For "smtp" mode only
[log.smtp]
LEVEL =
LEVEL =
; Name displayed in mail title, default is "Diagnostic message from serve"
SUBJECT = Diagnostic message from serve
; Mail server
HOST =
HOST =
; Mailer user name and password
USER =
USER =
PASSWD =
; Receivers, can be one or more, e.g. ["1@example.com","2@example.com"]
RECEIVERS =
RECEIVERS =
; For "database" mode only
[log.database]
LEVEL =
Driver =
CONN =
LEVEL =
; Either "mysql" or "postgres"
DRIVER =
; Based on xorm, e.g.: root:root@localhost/gogs?charset=utf8
CONN =
[git]
MAX_GITDIFF_LINES = 10000
[i18n]
LANGS = en-US,zh-CN,de-DE,fr-CA
NAMES = English,简体中文,Deutsch,Français

View File

@@ -59,7 +59,7 @@ _ReSharper*
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in

23
conf/license/BSD license Normal file
View File

@@ -0,0 +1,23 @@
Copyright (c) 2014
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,116 @@
CC0 1.0 Universal
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.
For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate,
and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness
depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data in
a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties
of any kind concerning the Work, express, implied, statutory or otherwise,
including without limitation warranties of title, merchantability, fitness
for a particular purpose, non infringement, or the absence of latent or
other defects, accuracy, or the present or absence of errors, whether or not
discoverable, all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without limitation
any person's Copyright and Related Rights in the Work. Further, Affirmer
disclaims responsibility for obtaining any necessary consents, permissions
or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to this
CC0 or use of the Work.
For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>

View File

@@ -0,0 +1,203 @@
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and documentation
distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates'
from a Contributor if it was added to the Program by such Contributor
itself or anyone acting on such Contributor's behalf. Contributions do not
include additions to the Program which: (i) are separate modules of
software distributed in conjunction with the Program under their own
license agreement, and (ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents" mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this
Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly
perform, distribute and sublicense the Contribution of such Contributor,
if any, and such derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under
Licensed Patents to make, use, sell, offer to sell, import and otherwise
transfer the Contribution of such Contributor, if any, in source code and
object code form. This patent license shall apply to the combination of
the Contribution and the Program if, at the time the Contribution is
added by the Contributor, such addition of the Contribution causes such
combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Contribution.
No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses
to its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other
intellectual property rights of any other entity. Each Contributor
disclaims any liability to Recipient for claims brought by any other
entity based on infringement of intellectual property rights or
otherwise. As a condition to exercising the rights and licenses granted
hereunder, each Recipient hereby assumes sole responsibility to secure
any other intellectual property rights needed, if any. For example, if a
third party patent license is required to allow Recipient to distribute
the Program, it is Recipient's responsibility to acquire that license
before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright
license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under
its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties
and conditions, express and implied, including warranties or
conditions of title and non-infringement, and implied warranties or
conditions of merchantability and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and
consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are
offered by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable
manner on or through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained
within the Program.
Each Contributor must identify itself as the originator of its Contribution,
if
any, in a manner that reasonably allows subsequent Recipients to identify the
originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor who
includes the Program in a commercial product offering should do so in a manner
which does not create potential liability for other Contributors. Therefore,
if a Contributor includes the Program in a commercial product offering, such
Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
every other Contributor ("Indemnified Contributor") against any losses,
damages and costs (collectively "Losses") arising from claims, lawsuits and
other legal actions brought by a third party against the Indemnified
Contributor to the extent caused by the acts or omissions of such Commercial
Contributor in connection with its distribution of the Program in a commercial
product offering. The obligations in this section do not apply to any claims
or Losses relating to any actual or alleged intellectual property
infringement. In order to qualify, an Indemnified Contributor must:
a) promptly notify the Commercial Contributor in writing of such claim, and
b) allow the Commercial Contributor to control, and cooperate with the
Commercial Contributor in, the defense and any related settlement
negotiations. The Indemnified Contributor may participate in any such claim at
its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If
that Commercial Contributor then makes performance claims, or offers
warranties related to Product X, those performance claims and warranties are
such Commercial Contributor's responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a
court requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
Recipient is solely responsible for determining the appropriateness of using
and distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement , including but not limited to the
risks and costs of program errors, compliance with applicable laws, damage to
or loss of data, programs or equipment, and unavailability or interruption of
operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of the
remainder of the terms of this Agreement, and without further action by the
parties hereto, such provision shall be reformed to the minimum extent
necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
(excluding combinations of the Program with other software or hardware)
infringes such Recipient's patent(s), then such Recipient's rights granted
under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and does
not cure such failure in a reasonable period of time after becoming aware of
such noncompliance. If all Recipient's rights under this Agreement terminate,
Recipient agrees to cease use and distribution of the Program as soon as
reasonably practicable. However, Recipient's obligations under this Agreement
and any licenses granted by Recipient relating to the Program shall continue
and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be
modified in the following manner. The Agreement Steward reserves the right to
publish new versions (including revisions) of this Agreement from time to
time. No one other than the Agreement Steward has the right to modify this
Agreement. The Eclipse Foundation is the initial Agreement Steward. The
Eclipse Foundation may assign the responsibility to serve as the Agreement
Steward to a suitable separate entity. Each new version of the Agreement will
be given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the
Agreement under which it was received. In addition, after a new version of the
Agreement is published, Contributor may elect to distribute the Program
(including its Contributions) under the new version. Except as expressly
stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
licenses to the intellectual property of any Contributor under this Agreement,
whether expressly, by implication, estoppel or otherwise. All rights in the
Program not expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury trial in
any resulting litigation.

674
conf/license/GPL v3 Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

13
conf/license/ISC license Normal file
View File

@@ -0,0 +1,13 @@
Copyright (c) 2014
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

504
conf/license/LGPL v2.1 Normal file
View File

@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
(This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.)
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random
Hacker.
{signature of Ty Coon}, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

165
conf/license/LGPL v3 Normal file
View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -0,0 +1,362 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. "Contributor"
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. "Incompatible With Secondary Licenses"
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the terms of
a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in a
separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible, whether
at the time of the initial grant or subsequently, any and all of the
rights conveyed by this License.
1.10. "Modifications"
means any of the following:
a. any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the License,
by the making, using, selling, offering for sale, having made, import,
or transfer of either its Contributions or its Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, "control" means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights to
grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter the
recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty, or
limitations of liability) contained within the Source Code Form of the
Covered Software, except that You may alter any license notices to the
extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute,
judicial order, or regulation then You must: (a) comply with the terms of
this License to the maximum extent possible; and (b) describe the
limitations and the code they affect. Such description must be placed in a
text file included with all distributions of the Covered Software under
this License. Except to the extent prohibited by statute or regulation,
such description must be sufficiently detailed for a recipient of ordinary
skill to be able to understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing
basis, if such Contributor fails to notify You of the non-compliance by
some reasonable means prior to 60 days after You have come back into
compliance. Moreover, Your grants from a particular Contributor are
reinstated on an ongoing basis if such Contributor notifies You of the
non-compliance by some reasonable means, this is the first time You have
received notice of non-compliance with this License from such
Contributor, and You become compliant prior to 30 days after Your receipt
of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an "as is" basis,
without warranty of any kind, either expressed, implied, or statutory,
including, without limitation, warranties that the Covered Software is free
of defects, merchantable, fit for a particular purpose or non-infringing.
The entire risk as to the quality and performance of the Covered Software
is with You. Should any Covered Software prove defective in any respect,
You (not any Contributor) assume the cost of any necessary servicing,
repair, or correction. This disclaimer of warranty constitutes an essential
part of this License. No use of any Covered Software is authorized under
this License except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from
such party's negligence to the extent applicable law prohibits such
limitation. Some jurisdictions do not allow the exclusion or limitation of
incidental or consequential damages, so this exclusion and limitation may
not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts
of a jurisdiction where the defendant maintains its principal place of
business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions. Nothing
in this Section shall prevent a party's ability to bring cross-claims or
counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides that
the language of a contract shall be construed against the drafter shall not
be used to construe this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses If You choose to distribute Source Code Form that is
Incompatible With Secondary Licenses under the terms of this version of
the License, the notice described in Exhibit B of this License must be
attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file,
then You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a
notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
This Source Code Form is "Incompatible
With Secondary Licenses", as defined by
the Mozilla Public License, v. 2.0.

View File

@@ -0,0 +1,517 @@
app_desc = Ein einfacher, selbst gehosteter Git-Service, geschrieben in Go.
home = Home
dashboard = Dashboard
explore = Erkunden
help = Hilfe
sign_in = Anmelden
social_sign_in = Social Sign In: 2nd Step <small>associate account</small>
sign_out = Abmelden
sign_up = Sign up
register = Registrieren
website = Webseite
version = Version
page = Seite
template = Vorlage
language = Sprache
username = Benutzername
email = E-Mail
password = Passwort
re_type = wiederholen
captcha = Captcha
repository = Repository
organization = Organisation
mirror = Spiegel
new_repo = Neues Repository
new_migrate = Neue Migration
new_org = Neue Organisation
manage_org = Organisationen verwalten
admin_panel = Admin-Panel
account_settings = Kontoeinstellungen
settings = Einstellungen
news_feed = News Feed
pull_requests = Pull Requests
issues = Issues
cancel = Abbrechen
[home]
uname_holder = Benutzername oder E-Mail
password_holder = Passwort
switch_dashboard_context = Switch Dashboard Context
my_repos = Meine Repositorys
collaborative_repos = Gemeinschaftliche Repositorys
my_orgs = Meine Organisationen
my_mirrors = Meine Spiegel
[auth]
create_new_account = Neues Konto erstellen
register_hepler_msg = Du hast schon ein Konto? Jetzt anmelden!
social_register_hepler_msg = Du hast schon ein soziales Konto? Jetzt verknüpfen!
disable_register_prompt = Es tut uns leid, die Registrierung wurde deaktiviert. Bitte wende dich an den Administrator.
disable_register_mail = Es tut uns leid, die Bestätigung der Registrierungs-E-Mail wurde deaktiviert.
remember_me = angemeldet bleiben
forgot_password= Passwort vergessen
forget_password = Passwort vergessen?
sign_up_now = Du willst ein Konto? Jetzt registrieren!
confirmation_mail_sent_prompt = Eine neu Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden um die Registrierung abzuschließen.
sign_in_email = Melden dich mit deiner E-Mail-Adresse an
active_your_account = Aktivieren dein Konto
resent_limit_prompt = Es tut uns leid, du sendest zu häufig Aktivierungs-E-Mails. Bitte warte 3 Minuten.
has_unconfirmed_mail = Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Falls du noch keine Bestätigungs-E-Mail erhalten hast oder eine neue senden musst, klicke auf den unteren Button.
resend_mail = Hier klicken, um deine Aktivierungs-E-Mail erneut zu versenden
email_not_associate = Diese E-Mail-Adresse ist mit keinem Konto verknüpft.
send_reset_mail = Hier klicken, um die E-Mail zum Passwort-zurücksetzen erneut zu versenden
reset_password = Passwort zurücksetzen
invalid_code = Es tut uns leid, der Bestätigungscode ist abgelaufen oder ungültig.
reset_password_helper = Hier klicken, um das Passwort zurückzusetzen
password_too_short = Das Passwort muss mindenstens 6 Zeichen lang sein
[form]
UserName = Benutzername
RepoName = Repository-Name
Email = E-Mail-Adresse
Password = Passwort
Retype = Passwort erneut eingeben
SSHTitle = SSH-Schlüsselname
HttpsUrl = HTTPS-URL
PayloadUrl = Payload-URL
TeamName = Teamname
AuthName = Authentifizierungsname
require_error = ` darf nicht leer sein.`
alpha_dash_error = ` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.`
alpha_dash_dot_error = ` kann ausschließlich alphanumerische Zeichen und ".-_" enthalten.`
min_size_error = ` muss mindestens %s Zeichen enthalten.`
max_size_error = ` darf höchstens %s Zeichen enthalten.`
email_error = ` ist keine gültige E-Mail-Adresse.`
url_error = ` ist keine gültige URL.`
unknown_error = Unbekannter Fehler:
captcha_incorrect = Captcha stimmt nicht überein.
password_not_match = Die Passwörter stimmen nicht überein.
username_been_taken = Benutzername ist bereits vergeben.
repo_name_been_taken = Repository-Name ist bereits vergeben.
org_name_been_taken = Organisationsname ist bereits vergeben.
team_name_been_taken = Teamname ist bereits vergeben.
email_been_used = E-Mail-Adresse wird bereits verwendet.
ssh_key_been_used = SSH-Schlüsselname wird bereits verwendet.
illegal_username = Benutzername enthält ungültige Zeichen.
illegal_repo_name = Repository-Name enthält ungültige Zeichen.
illegal_org_name = Organisationsname enthält ungültige Zeichen.
illegal_team_name = Teamname enthält ungültige Zeichen.
username_password_incorrect = Benutzername oder Passwort ist nicht korrekt.
enterred_invalid_repo_name = Bitte stelle sicher, dass der eingegeben Repository-Name richtig ist.
enterred_invalid_owner_name = Bitte stelle sicher, dass der eingegeben Besitzername richtig ist.
enterred_invalid_password = Bitte stelle sicher, dass das eingegebene Passwort richtig ist.
user_not_exist = Angegebener Benutzer existiert nicht.
last_org_owner = Der zu entfernende Benutzer ist der letzte Teambesitzer. Es muss einen anderen Besitzer geben.
invalid_ssh_key = Leider sind wir nicht in der Lage, Ihren SSH-Schlüssel zu überprüfen: %s
auth_failed = Authentifizierung fehlgeschlagen: %v
still_own_repo = Dein Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
org_still_own_repo = Diese Organisation besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
still_own_user = Diese Authentifizierung wird noch von einigen Benutzern genutzt. Entferne diese zuvor und lösche erneut.
[settings]
profile = Profil
password = Passwort
ssh_keys = SSH-Schlüssel
social = Soziale Konten
orgs = Organisationen
delete = Konto löschen
public_profile = Öffentliches Profil
profile_desc = Deine E-Mail-Adresse ist öffentlich und dient dazu, dir Benachrichtigungen bezüglich deines Kontos und deiner Repositorys zu schicken.
full_name = Vollständiger Name
website = Webseite
location = Standort
update_profile = Profil aktualisieren
update_profile_success = Profil aktualisiert
change_password = Passwort ändern
old_password = Aktuelles Passwort
new_password = Neues Passwort
password_incorrect = Aktuelles Passwort ist nicht korrekt.
change_password_success = Passwort geändert. Du kannst dich jetzt mit dem neuen Passwort anmelden.
manage_ssh_keys = SSH-Schlüssel verwalten
add_key = SSH-Schlüssel hinzufügen
ssh_desc = Dies ist eine Liste aller SSH-Schlüssel, die mit deinem Konto verknüpft sind. Entferne alle Schlüssel, die du nicht kennst.
ssh_helper = <strong>Du brauchst Hilfe?</strong> Hier ist eine Anleitung zum <a href="https://help.github.com/articles/generating-ssh-keys">Erzeugen von SSH-Schlüsseln</a> oder <a href="https://help.github.com/ssh-issues/">Problemlösen einfacher SSH-Probleme</a>.
add_new_key = SSH-Schlüssel hinzufügen
key_name = Schlüsselname
key_content = Inhalt
add_key_success = SSH-Schlüssel hinzugefügt
delete_key = SSH-Schlüssel löschen
add_on = Hinzugefügt am
last_used = Zuletzt verwendet auf
no_activity = Keine neuen Aktivitäten
manage_social = Verknüpfte soziale Konten verwalten
social_desc = Dies ist eine Liste verknüpfter sozialer Konten. Entferne alle Verknüpfungen, die du nicht kennst.
unbind = Verknüpfung entfernen
unbind_success = Die Verknüpfung zum sozialen Konto wurde entfernt.
delete_account = Konto löschen
delete_prompt = Diese Aktion wird dein Konto dauerhaft löschen und kann <strong>NICHT</strong> rückgängig gemacht werden!
confirm_delete_account = Löschen
[repo]
owner = Besitzer
repo_name = Repository-Name
repo_name_helper = Gute Repository-Namen sind kurz, einprägsam und <strong>einzigartig</strong>.
visibility = Sichtbarkeit
visiblity_helper = Dieses Repository ist <span class="label label-red label-radius">Privat</span>
repo_desc = Beschreibung
repo_lang = Sprache
repo_lang_helper = Wähle eine .gitignore Datei
license = Lizenz
license_helper = Wähle eine Lizenz aus
init_readme = Repository mit README.md initialisieren
create_repo = Repository erstellen
default_branch = Standard-Branch
mirror_interval = Spiegel-Intervall (in Stunden)
goget_meta = Go-Get Meta
goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
goget_meta_helper = Dieses Repository wird man mit <span class="label label-blue label-radius">go get</span> klonen können.
need_auth = Authorisierung benötigt
migrate_type = Migrationstyp
migrate_type_helper = Dieses Repository wird ein <span class="label label-blue label-radius">Spiegel</span>
migrate_repo = Repository migrieren
copy_link = Klonen
clone_helper = Du brauchst Hilef beim klonen? Hier gibt es<a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Hilfe</a>!
unwatch = Beobachtung beenden
watch = Beobachtung
unstar = Markierung aufheben
star = Markierung
fork = Abspaltung
quick_guide = Kurzanleitung
clone_this_repo = Dieses Repository klonen
create_new_repo_command = Erstelle ein neues Repository mittels der Kommandozeile
push_exist_repo = Push an existing repository from the command line
settings = Einstellungen
settings.options = Optionen
settings.collaboration = Zusammenarbeit
settings.hooks = Webhooks
settings.deploy_keys = Deploy-Keys
settings.basic_settings = Grundeinstellungen
settings.danger_zone = Gefahrenzone
settings.site = Offizielle Webseite
settings.update_settings = Aktualisierungseinstellungen
settings.transfer = Besitz übertragen
settings.transfer_desc = Übertrage dieses Repository einem anderen Benutzer oder einer Organisation.
settings.delete = Repository löschen
settings.delete_desc = Wenn dieses Repository gelöschet ist, gibt es keinen Weg zurück. Sei dir sicher!
settings.update_settings_success = Repository-Optionen aktualisiert
settings.transfer_owner = Neuer Besitzer
settings.make_transfer = übertragen
settings.confirm_delete = Löschen
settings.add_collaborator = Mitarbeiter hinzufügen
settings.add_collaborator_success = Mitarbeiter hinzugefügt
settings.remove_collaborator_success = Mitarbeiter entfernt
settings.add_webhook = Webhook hinzufügen
settings.hooks_desc = Webhooks erlauben es externe Dienste zu informieren, wenn etwas bestimmtes in deinem Repository passiert. GoGS sendet dann eine POST-Request an alle angegebenen URLs. Erfahre mehr in unserem <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
settings.remove_hook_success = Webhook entfernt
settings.add_webhook_desc = GoGS sendet einen <code>POST</code>-Request an die unten stehende URL mit Details aller abonierten Ereignisse. Du kannst auch angeben, welches Datenformat du erhalten willst (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). Mehr Informationen findest du im <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
settings.payload_url = Payload-URL
settings.content_type = Inhaltstyp
settings.secret = Secret
settings.event_desc = Welche Ereignisse sollen diesen Webhook auslösen?
settings.event_push_only = Nur das <code>push</code>-Ereignis.
settings.active = Aktiv
settings.active_helper = Ereignisdetails werden ausgeliefert, wenn dieser Webhook ausgelöst wird.
settings.add_hook_success = Webhook hinzugefügt
settings.update_webhook = Webhook aktualisieren
settings.update_hook_success = Webhook aktualisiert
settings.delete_webhook = Webhook löschen
settings.recent_deliveries = letzte Zustellungen
settings.hook_type = Hook Type
settings.add_slack_hook_desc = Add <a href="http://slack.com">Slack</a> integration to your repository.
settings.slack_token = Token
settings.slack_domain = Domain
settings.slack_channel = Channel
[org]
org_name_holder = Name der Organisation
org_name_helper = Gute Namen von Organisationen sind kurz und einprägsam.
org_email_helper = Das E-Mail-Konto der Organisation empfängt alle Benachrichtigungen.
create_org = Organisation erstellen
repo_updated = Aktualisiert
people = Personen
invite_someone = Benutzer einladen
teams = Teams
lower_members = Mitglieder
lower_repositories = Repositorys
create_new_team = Neues Team erstellen
org_desc = Beschreibung
team_name = Teamname
team_desc = Beschreibung
team_name_helper = Verwende diesen Namen, um dich auf dieses Team zu beziehen.
team_desc_helper = Was hat es mit diesem Team auf sich?
team_permission_desc = Welche Berechtigungsstufe soll das Team haben?
settings = Einstellungen
settings.options = Optionen
settings.full_name = Vollständiger Name
settings.website = Webseite
settings.location = Standort
settings.update_settings = Aktualisierungseinstellungen
settings.update_setting_success = Organisationseinstellungen aktualisiert
settings.delete = Organisation löschen
settings.delete_account = Diese Organisation löschen
settings.delete_prompt = Die Organisation wird dauerhaft gelöscht. Dies kann <strong>NICHT</strong> rückgängig gemacht werden!
settings.confirm_delete_account = Löschen
members.public = Öffentlich
members.public_helper = Privat machen
members.private = Privat
members.private_helper = Öffentlich machen
members.owner = Besitzer
members.member = Mitglied
members.conceal = Verbergen
members.remove = Entfernen
members.leave = Verlassen
members.invite_desc = Benutzernamen eingeben, um ihn als neues Mitglied in %s einzuladen:
members.invite_now = Jetzt einladen
teams.join = Beitreten
teams.leave = Verlassen
teams.read_access = Lesezugriff
teams.read_access_helper = Dieses Team wird Repositorys einsehen und klonen können.
teams.write_access = Schreibzugriff
teams.write_access_helper = Dieses Team wird die Repositorys einsehen und in sie hinein pushen können.
teams.admin_access = Adminzugriff
teams.admin_access_helper = Dieses Team wird pull- und push-Rechte für die Repositorys haben und Mitarbeiter einladen können.
teams.no_desc = Dieses Team hat keine Beschreibung
teams.settings = Einstellungen
teams.owners_permission_desc = Besitzer haben vollen Zugriff auf <strong>alle Repositorys</strong> und <strong>Admin Rechte</strong> für diese Organisation.
teams.members = Teammitglieder
teams.update_settings = Einstellungen aktualisieren
teams.delete_team = Dieses Team löschen
teams.add_team_member = Teammitglied hinzufügen
teams.delete_team_success = Team gelöscht
teams.read_permission_desc = Dieses Team erlaubt <strong>Lesezugriff</strong>: Mitglieder können Team-Repositorys einsehen und klonen.
teams.write_permission_desc = Dieses Team erlaubt <strong>Schreibzugriff</strong>: Mitglieder können Team-Repositorys einsehen und hinein pushen.
teams.admin_permission_desc = Diese Team erlaubt <strong>Adminzugriff</strong>: Mitglieder dieses Teams können pullen, pushen und dem Team Mitarbeiter hinzufügen.
teams.repositories = Team-Repositorys
teams.add_team_repository = Team-Repository hinzufügen
teams.remove_repo = Entfernen
[admin]
dashboard = Dashboard
users = Benutzer
organizations = Organisationen
repositories = Repositorys
authentication = Authentifizierung
config = Konfiguration
monitor = Monitoring
prev = zurück
next = vor
dashboard.statistic = Statistik
dashboard.operations = Operationen
dashboard.system_status = System-Monitor-Status
dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organizationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositorys, <b>%d</b> watches, <b>%d</b> stars, <b>%d</b> actions, <b>%d</b> Zugriffe, <b>%d</b> issues, <b>%d</b> Kommentare, <b>%d</b> soziale Konten, <b>%d</b> follows, <b>%d</b> Spiegel, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Milestones, <b>%d</b> Labels, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge.
dashboard.operation_name = Operation Name
dashboard.operation_switch = Switch
dashboard.operation_run = Ausführen
dashboard.clean_unbind_oauth = ungebundene OAuths bereinigen
dashboard.delete_inactivate_accounts = inaktive Konten löschen
dashboard.server_uptime = Server-Uptime
dashboard.current_goroutine = Aktuelle Goroutines
dashboard.current_memory_usage = Aktuelle Speichernutzung
dashboard.total_memory_allocated = Zugeteilter Gesamtspeicher
dashboard.memory_obtained = Erhaltener Speicher
dashboard.pointer_lookup_times = Pointer Lookup Times
dashboard.memory_allocate_times = Memory Allocate Times
dashboard.memory_free_times = Memory Free Times
dashboard.current_heap_usage = Aktuelle Heap-Auslastung
dashboard.heap_memory_obtained = erhaltener Heap-Memory
dashboard.heap_memory_idle = unbenutzter Heap-Memory
dashboard.heap_memory_in_use = benutzter Heap-Memory
dashboard.heap_memory_released = freigegebener Heap-Memory
dashboard.heap_objects = Heap-Objekte
dashboard.bootstrap_stack_usage = Bootstrap-Stack-Auslastung
dashboard.stack_memory_obtained = erhaltener Stack-Memory
dashboard.mspan_structures_usage = MSpan-Structures-Auslastung
dashboard.mspan_structures_obtained = erhaltene MSpan-Structures
dashboard.mcache_structures_usage = MCache-Structures-Auslastung
dashboard.mcache_structures_obtained = erhaltene MCache-Structures
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
dashboard.gc_metadata_obtained = erhaltene GC-Metadata
dashboard.other_system_allocation_obtained = andere erhaltene System-Allokatoren
dashboard.next_gc_recycle = nächster GC-Zyklus
dashboard.last_gc_time = seit letztem GC-Zyklus
dashboard.total_gc_time = gesammte GC-Zeit
dashboard.total_gc_pause = gesammte GC-Pause
dashboard.last_gc_pause = letzte GC-Pause
dashboard.gc_times = GC-Takt
users.user_manage_panel = Benutzer
users.new_account = Neues Konto erstellen
users.name = Name
users.activated = Aktiviert
users.admin = Admin
users.repos = Repositorys
users.created = Erzeugt
users.edit = Bearbeiten
users.auth_source = Auth-Quelle
users.local = Lokal
users.auth_login_name = Auth-Login-Name
users.update_profile_success = Kontoprofil aktualisiert
users.edit_account = Konto bearbeiten
users.is_activated = Dieses Konto ist aktiviert
users.is_admin = Dieses Konto hat Administratorrechte
users.update_profile = Kontoprofil aktualisieren
users.delete_account = Dieses Konto löschen
users.still_own_repo = Dieses Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden.
orgs.org_manage_panel = Organisationenverwaltung
orgs.name = Name
orgs.teams = Teams
orgs.members = Mitglieder
repos.repo_manage_panel = Repositorys
repos.owner = Besitzer
repos.name = Name
repos.private = Privat
repos.watches = Watches
repos.stars = Stars
repos.issues = Issues
auths.auth_manage_panel = Authentifizierung
auths.new = Neu Authentifizierungsquelle hinzufügen
auths.name = Name
auths.type = Typ
auths.enabled = aktiviert
auths.updated = aktualisiert
auths.auth_type = Authentifizierungstyp
auths.auth_name = Authentifizierungsname
auths.domain = Domain
auths.host = Host
auths.port = Port
auths.base_dn = Base DN
auths.attributes = Suchattribute
auths.filter = Suchfilter
auths.ms_ad_sa = Ms Ad SA
auths.smtp_auth = SMTP-Authentifizierungstyp
auths.smtphost = SMTP-Host
auths.smtpport = SMTP-Port
auths.enable_tls = TLS-Verschlüsselung aktivieren
auths.enable_auto_register = Automatische Registrierung aktivieren
auths.tips = Tipps
auths.edit = Authentifizierungseinstellungen bearbeiten
auths.activated = Diese Authentifizierung ist aktiviert
auths.update_success = Authentifizierungseinstellungen aktualisiert
auths.update = Authentifizierungseinstellungen aktualisieren
auths.delete = Authentifizierung löschen
config.server_config = Server-Konfiguration
config.app_name = Anwendungsname
config.app_ver = Anwendungsversion
config.app_url = Anwendungs-URL
config.domain = Domain
config.offline_mode = Offline-Modus
config.disable_router_log = Router-Log deaktivieren
config.run_user = Laufzeit-Benutzer
config.run_mode = Laufzeit-Modus
config.repo_root_path = Repository-Verzeichnis
config.static_file_root_path = Verzeichnis für statische Dateien
config.log_file_root_path = Log-Verzeichnis
config.script_type = Skript-Typ
config.reverse_auth_user = Reverse Authentication User
config.db_config = Datenbankkonfiguration
config.db_type = Typ
config.db_host = Host
config.db_name = Name
config.db_user = Benutzer
config.db_ssl_mode = SSL-Modus
config.db_ssl_mode_helper = (nur für "postgres")
config.db_path = Verzeichnis
config.db_path_helper = (nur für "sqlite3")
config.service_config = Service-Einstellungen
config.register_email_confirm = E-Mail-Bestätigung bei Registrierung
config.disable_register = Registrierung deaktivieren
config.require_sign_in_view = Require Sign In View
config.mail_notify = E-Mail-Benachrichtigung
config.enable_cache_avatar = Avatar-Cache aktivieren
config.active_code_lives = Active Code Lives
config.reset_password_code_lives = Reset Password Code Lives
config.webhook_config = Webhook-Einstellungen
config.task_interval = Task-Intervall
config.deliver_timeout = Zeitlimit für Zustellung
config.mailer_config = Mailer-Einstellungen
config.mailer_enabled = Aktiviert
config.mailer_name = Name
config.mailer_host = Host
config.mailer_user = Benutzer
config.oauth_config = OAuth-Einstellungen
config.oauth_enabled = Aktiviert
config.cache_config = Cache-Einstellungen
config.cache_adapter = Cache-Adapter
config.cache_interval = Cache-Intervall
config.cache_conn = Cache-Anbindung
config.session_config = Session-Einstellungen
config.session_provider = Session-Provider
config.provider_config = Provider-Einstellungen
config.cookie_name = Cookie-Name
config.enable_set_cookie = Enable Set Cookie
config.gc_interval_time = GC-Intervallzeit
config.session_life_time = Session-Lebensdauer
config.https_only = nur HTTPS
config.cookie_life_time = Cookie-Lebensdauer
config.session_hash_function = Session-ID-Hashfunktion
config.session_hash_key = Session-ID-Hashschlüssel
config.picture_config = Bildeinstellungen
config.picture_service = Bildservice
config.disable_gravatar = Gravatar deaktivieren
config.log_config = Log-Einstellungen
config.log_mode = Log-Modus
monitor.cron = Cron-Tasks
monitor.name = Name
monitor.schedule = Zeitplan
monitor.next = nächste Ausführung
monitor.previous = letzte Ausführung
monitor.execute_times = Execute Times
monitor.process = Laufende Prozesse
monitor.desc = Beschreibung
monitor.start = Startzeit
monitor.execute_time = Ausführungszeit
[action]
create_repo = Repository erstellen <a href="/%s">%s</a>
commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
create_issue = opened issue <a href="/%s/issues/%s">%s#%s</a>
comment_issue = commented on issue <a href="/%s/issues/%s">%s#%s</a>
[tool]
ago = vor
from_now = ab sofort
now = Jetzt
1s = 1 Sekunde %s
1m = 1 Minute %s
1h = 1 Stunde %s
1d = 1 Tag %s
1w = 1 Woche %s
1mon = 1 Monat %s
1y = 1 Jahr %s
seconds = %d Sekunden %s
minutes = %d Minuten %s
hours = %d Stunden %s
days = %d Tage %s
weeks = %d Wochen %s
months = %d Monate %s
years = %d Jahre %s
raw_seconds = Sekunden
raw_minutes = Minuten

View File

@@ -0,0 +1,581 @@
app_desc = A painless self-hosted Git service written in Go
home = Home
dashboard = Dashboard
explore = Explore
help = Help
sign_in = Sign In
social_sign_in = Social Sign In: 2nd Step <small>associate account</small>
sign_out = Sign Out
sign_up = Sign Up
register = Register
website = Website
version = Version
page = Page
template = Template
language = Language
username = Username
email = E-mail
password = Password
re_type = Re-Type
captcha = Captcha
repository = Repository
organization = Organization
mirror = Mirror
new_repo = New Repository
new_migrate = New Migration
new_org = New Organization
manage_org = Manage Organizations
admin_panel = Admin Panel
account_settings = Account Settings
settings = Settings
news_feed = News Feed
pull_requests = Pull Requests
issues = Issues
cancel = Cancel
[install]
install = Installation
title = Install Steps For First-time Run
requite_db_desc = Gogs requires MySQL, PostgreSQL or SQLite3, but SQLite3 is usually available in the official binary version.
db_type = Database Type
host = Host
user = User
password = Password
db_name = Database Name
db_helper = Please use INNODB engine with utf8_general_ci charset for MySQL.
ssl_mode = SSL Mode
path = Path
sqlite_helper = The file path of SQLite3 database.
general_title = General Settings of Gogs
repo_path = Repository Root Path
repo_path_helper = All Git remote repositories will be saved to this directory.
run_user = Run User
run_user_helper = The user must have access to Repository Root Path and run Gogs.
domain = Domain
domain_helper = This affects SSH clone URLs.
app_url = Application URL
app_url_helper = This affects HTTP/HTTPS clone URL and somewhere in e-mail.
email_title = Email Service Settings(Optional)
smtp_host = SMTP Host
mailer_user = Sender E-mail
mailer_password = Sender Password
notify_title = Notification Settings(Optional)
register_confirm = Enable Register Confirmation
mail_notify = Enable Mail Notification
admin_title = Admin Account Settings
admin_name = Username
admin_password = Password
confirm_password = Confirm Password
admin_email = E-mail
install_gogs = Install Gogs
test_git_failed = Fail to test 'git' command: %v
sqlite3_not_available = Your release version does not support SQLite3, please download the official binary version from http://gogs.io/docs/installation/install_from_binary.html, NOT the gobuild version.
invalid_db_setting = Database setting is not correct: %v
invalid_repo_path = Repository root path is invalid: %v
run_user_not_match = Run user isn't the current user: %s -> %s
save_config_failed = Fail to save configuration: %v
invalid_admin_setting = Admin account setting is invalid: %v
install_success = Welcome! We're glad that you choose Gogs, have fun and take care.
[home]
uname_holder = Username or E-mail
password_holder = Password
switch_dashboard_context = Switch Dashboard Context
my_repos = My Repositories
collaborative_repos = Collaborative Repositories
my_orgs = My Organizations
my_mirrors = My Mirrors
[explore]
repos = Repositories
[auth]
create_new_account = Create New Account
register_hepler_msg = Already have an account? Sign in now!
social_register_hepler_msg = Already have an account? Bind now!
disable_register_prompt = Sorry, registration has been disabled. Please contact the site administrator.
disable_register_mail = Sorry, Register Mail Confirmation has been disabled.
remember_me = Remember Me
forgot_password= Forgot Password
forget_password = Forgot password?
sign_up_now = Need an account? Sign up now.
confirmation_mail_sent_prompt = A new confirmation e-mail has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete your registration.
sign_in_email = Sign in to your e-mail
active_your_account = Activate Your Account
resent_limit_prompt = Sorry, you are sending an activation e-mail too frequently. Please wait 3 minutes.
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address(<b>%s</b>). If you haven't received a confirmation e-mail or need to resend a new one, please click on the button below.
resend_mail = Click here to resend your activation e-mail
email_not_associate = This e-mail address does not associate to any account.
send_reset_mail = Click here to (re)send your password reset e-mail
reset_password = Reset Your Password
invalid_code = Sorry, your confirmation code has expired or not valid.
reset_password_helper = Click here to reset your password
password_too_short = Password length cannot be less then 6.
[form]
UserName = Username
RepoName = Repository name
Email = E-mail address
Password = Password
Retype = Re-type password
SSHTitle = SSH key name
HttpsUrl = HTTPS URL
PayloadUrl = Payload URL
TeamName = Team name
AuthName = Authorization name
AdminEmail = Admin E-mail
require_error = ` cannot be empty.`
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.`
alpha_dash_dot_error = ` must be valid alpha or numeric or dash(-_) or dot characters.`
min_size_error = ` must contain at least %s characters.`
max_size_error = ` must contain at most %s characters.`
email_error = ` is not a valid e-mail address.`
url_error = ` is not a valid URL.`
unknown_error = Unknown error:
captcha_incorrect = Captcha didn't match.
password_not_match = Password and confirm password are not same.
username_been_taken = Username has been already taken.
repo_name_been_taken = Repository name has been already taken.
org_name_been_taken = Organization name has been already taken.
team_name_been_taken = Team name has been already taken.
email_been_used = E-mail address has been already used.
ssh_key_been_used = Public key name has been used.
illegal_username = Your username contains illegal characters.
illegal_repo_name = Repository name contains illegal characters.
illegal_org_name = Organization name contains illegal characters.
illegal_team_name = Team name contains illegal characters.
username_password_incorrect = Username or password is not correct.
enterred_invalid_repo_name = Please make sure you entered repository name is correct.
enterred_invalid_owner_name = Please make sure you entered owner name is correct.
enterred_invalid_password = Please make sure you entered password is correct.
user_not_exist = Given user does not exist.
last_org_owner = The user to remove is the last member in owner team. There must be another owner.
invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s
auth_failed = Authentication failed: %v
still_own_repo = Your account still have ownership of repository, you have to delete or transfer them first.
org_still_own_repo = This organization still have ownership of repository, you have to delete or transfer them first.
still_own_user = This authentication still has used by some users, you should move them and then delete again.
[settings]
profile = Profile
password = Password
ssh_keys = SSH Keys
social = Social Accounts
orgs = Organizations
delete = Delete Account
uid = Uid
public_profile = Public Profile
profile_desc = Your Email address is public and will be used for any account related notifications, and any web based operations made via the site.
full_name = Full Name
website = Website
location = Location
update_profile = Update Profile
update_profile_success = Your profile has been successfully updated.
change_password = Change Password
old_password = Current Password
new_password = New Password
password_incorrect = Current password is not correct.
change_password_success = Password is changed successfully. You can now sign in via new password.
manage_ssh_keys = Manage SSH Keys
add_key = Add Key
ssh_desc = This is a list of SSH keys associated with your account. Remove any keys that you do not recognize.
ssh_helper = <strong>Need help?</strong> Check out our guide to <a href="https://help.github.com/articles/generating-ssh-keys">generating SSH keys</a> or troubleshoot <a href="https://help.github.com/ssh-issues/">common SSH Problems</a>.
add_new_key = Add SSH Key
key_name = Key Name
key_content = Content
add_key_success = New SSH Key has been added!
delete_key = Delete
add_on = Added on
last_used = Last used on
no_activity = No recent activity
manage_social = Manage Associated Social Accounts
social_desc = This is a list of associated social accounts. Remove any binding that you do not recognize.
unbind = Unbind
unbind_success = Social account has been unbound.
delete_account = Delete Your Account
delete_prompt = The operation will delete your account permanently, and <strong>CANNOT</strong> be undone!
confirm_delete_account = Confirm Deletion
[repo]
owner = Owner
repo_name = Repository Name
repo_name_helper = Great repository names are short, memorable and <strong>unique</strong>.
visibility = Visibility
visiblity_helper = This repository is <span class="label label-red label-radius">Private</span>
repo_desc = Description
repo_lang = Language
repo_lang_helper = Select a .gitignore file
license = License
license_helper = Select a license file
init_readme = Initialize this repository with a README.md
create_repo = Create Repository
default_branch = Default Branch
mirror_interval = Mirror Interval(hour)
goget_meta = Go-Get Meta
goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
need_auth = Need Authorization
migrate_type = Migration Type
migrate_type_helper = This repository will be a <span class="label label-blue label-radius">Mirror</span>
migrate_repo = Migrate Repository
copy_link = Copy
clone_helper = Need help cloning? Visit <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">Help</a>!
unwatch = Unwatch
watch = Watch
unstar = Unstar
star = Star
fork = Fork
quick_guide = Quick Guide
clone_this_repo = Clone this repository
create_new_repo_command = Create a new repository on the command line
push_exist_repo = Push an existing repository from the command line
settings = Settings
settings.options = Options
settings.collaboration = Collaboration
settings.hooks = Webhooks
settings.deploy_keys = Deploy Keys
settings.basic_settings = Basic Settings
settings.danger_zone = Danger Zone
settings.site = Official Site
settings.update_settings = Update Settings
settings.transfer = Transfer Ownership
settings.transfer_desc = Transfer this repo to another user or to an organization where you have admin rights.
settings.new_owner_has_same_repo = New owner already has a repository with same name.
settings.delete = Delete This Repository
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
settings.update_settings_success = Repository options has been successfully updated.
settings.transfer_owner = New Owner
settings.make_transfer = Make Transfer
settings.transfer_succeed = Repository ownership has been successfully transferred.
settings.confirm_delete = Confirm Deletion
settings.add_collaborator = Add New Collaborator
settings.add_collaborator_success = New collaborator has been added.
settings.remove_collaborator_success = Collaborator has been removed.
settings.add_webhook = Add Webhook
settings.hooks_desc = Webhooks allow external services to be notified when certain events happen on Gogs. When the specified events happen, we'll send a POST request to each of the URLs you provide. Learn more in our <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
settings.remove_hook_success = Webhook has been removed.
settings.add_webhook_desc = Well send a <code>POST</code> request to the URL below with details of any subscribed events. You can also specify which data format you'd like to receive (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). More information can be found in <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>.
settings.payload_url = Payload URL
settings.content_type = Content Type
settings.secret = Secret
settings.event_desc = Which events would you like to trigger this webhook?
settings.event_push_only = Just the <code>push</code> event.
settings.active = Active
settings.active_helper = We will deliver event details when this hook is triggered.
settings.add_hook_success = New webhook has been added.
settings.update_webhook = Update Webhook
settings.update_hook_success = Webhook has been updated.
settings.delete_webhook = Delete Webhook
settings.recent_deliveries = Recent Deliveries
settings.hook_type = Hook Type
settings.add_slack_hook_desc = Add <a href="http://slack.com">Slack</a> integration to your repository.
settings.slack_token = Token
settings.slack_domain = Domain
settings.slack_channel = Channel
[org]
org_name_holder = Organization Name
org_name_helper = Great organization names are short and memorable.
org_email_helper = Organization's Email receives all notifications and confirmations.
create_org = Create Organization
repo_updated = Updated
people = People
invite_someone = Invite Someone
teams = Teams
lower_members = members
lower_repositories = repositories
create_new_team = Create New Team
org_desc = Description
team_name = Team Name
team_desc = Description
team_name_helper = You'll use this name to mention this team in conversations.
team_desc_helper = What is this team all about?
team_permission_desc = What permission level should this team have?
settings = Settings
settings.options = Options
settings.full_name = Full Name
settings.website = Website
settings.location = Location
settings.update_settings = Update Settings
settings.update_setting_success = Organization setting has been successfully updated.
settings.delete = Delete Organization
settings.delete_account = Delete This Organization
settings.delete_prompt = The operation will delete this organization permanently, and <strong>CANNOT</strong> be undone!
settings.confirm_delete_account = Confirm Deletion
settings.hooks_desc = Add webhooks that will be triggered for <strong>all repositories</strong> under this organization.
members.public = Public
members.public_helper = make private
members.private = Private
members.private_helper = make public
members.owner = Owner
members.member = Member
members.conceal = Conceal
members.remove = Remove
members.leave = Leave
members.invite_desc = Start typing a username to invite a new member to %s:
members.invite_now = Invite Now
teams.join = Join
teams.leave = Leave
teams.read_access = Read Access
teams.read_access_helper = This team will be able to view and clone its repositories.
teams.write_access = Write Access
teams.write_access_helper = This team will be able to read its repositories, as well as push to them.
teams.admin_access = Admin Access
teams.admin_access_helper = This team will be able to push/pull to its repositories, as well as add other collaborators to them.
teams.no_desc = This team has no description
teams.settings = Settings
teams.owners_permission_desc = Owners have full access to <strong>all repositories</strong> and have <strong>admin rights</strong> to the organization.
teams.members = Team Members
teams.update_settings = Update Settings
teams.delete_team = Delete This Team
teams.add_team_member = Add Team Member
teams.delete_team_success = Given team has been successfully deleted.
teams.read_permission_desc = This team grants <strong>Read</strong> access: members can view and clone the team's repositories.
teams.write_permission_desc = This team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
teams.admin_permission_desc = This team grants <strong>Admin</strong> access: members can read from, push to, and add collaborators to the team's repositories.
teams.repositories = Team Repositories
teams.add_team_repository = Add Team Repository
teams.remove_repo = Remove
[admin]
dashboard = Dashboard
users = Users
organizations = Organizations
repositories = Repositories
authentication = Authentications
config = Configuration
monitor = Monitoring
prev = Prev.
next = Next
dashboard.statistic = Statistic
dashboard.operations = Operations
dashboard.system_status = System Monitor Status
dashboard.statistic_info = Gogs database has <b>%d</b> users, <b>%d</b> organizations, <b>%d</b> public keys, <b>%d</b> repositories, <b>%d</b> watches, <b>%d</b> stars, <b>%d</b> actions, <b>%d</b> accesses, <b>%d</b> issues, <b>%d</b> comments, <b>%d</b> social accounts, <b>%d</b> follows, <b>%d</b> mirrors, <b>%d</b> releases, <b>%d</b> login sources, <b>%d</b> webhooks, <b>%d</b> milestones, <b>%d</b> labels, <b>%d</b> hook tasks, <b>%d</b> teams, <b>%d</b> update tasks, <b>%d</b> attachments.
dashboard.operation_name = Operation Name
dashboard.operation_switch = Switch
dashboard.operation_run = Run
dashboard.clean_unbind_oauth = Clean unbound OAuthes
dashboard.delete_inactivate_accounts = Delete all inactive accounts
dashboard.server_uptime = Server Uptime
dashboard.current_goroutine = Current Goroutines
dashboard.current_memory_usage = Current Memory Usage
dashboard.total_memory_allocated = Total Memory Allocated
dashboard.memory_obtained = Memory Obtained
dashboard.pointer_lookup_times = Pointer Lookup Times
dashboard.memory_allocate_times = Memory Allocate Times
dashboard.memory_free_times = Memory Free Times
dashboard.current_heap_usage = Current Heap Usage
dashboard.heap_memory_obtained = Heap Memory Obtained
dashboard.heap_memory_idle = Heap Memory Idle
dashboard.heap_memory_in_use = Heap Memory In Use
dashboard.heap_memory_released = Heap Memory Released
dashboard.heap_objects = Heap Objects
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage
dashboard.stack_memory_obtained = Stack Memory Obtained
dashboard.mspan_structures_usage = MSpan Structures Usage
dashboard.mspan_structures_obtained = MSpan Structures Obtained
dashboard.mcache_structures_usage = MCache Structures Usage
dashboard.mcache_structures_obtained = MCache Structures Obtained
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
dashboard.gc_metadata_obtained = GC Metadada Obtained
dashboard.other_system_allocation_obtained = Other System Allocation Obtained
dashboard.next_gc_recycle = Next GC Recycle
dashboard.last_gc_time = Since Last GC Time
dashboard.total_gc_time = Total GC Pause
dashboard.total_gc_pause = Total GC Pause
dashboard.last_gc_pause = Last GC Pause
dashboard.gc_times = GC Times
users.user_manage_panel = User Manage Panel
users.new_account = Create New Account
users.name = Name
users.activated = Activated
users.admin = Admin
users.repos = Repos
users.created = Created
users.edit = Edit
users.auth_source = Authorization Source
users.local = Local
users.auth_login_name = Authorization Login Name
users.update_profile_success = Account profile has been successfully updated.
users.edit_account = Edit Account
users.is_activated = This account is activated
users.is_admin = This account has administrator permissions
users.update_profile = Update Account Profile
users.delete_account = Delete This Account
users.still_own_repo = This account still have ownership of repository, you have to delete or transfer them first.
orgs.org_manage_panel = Organization Manage Panel
orgs.name = Name
orgs.teams = Teams
orgs.members = Members
repos.repo_manage_panel = Repository Manage Panel
repos.owner = Owner
repos.name = Name
repos.private = Private
repos.watches = Watches
repos.stars = Stars
repos.issues = Issues
auths.auth_manage_panel = Authorization Manage Panel
auths.new = Add New Authorization Source
auths.name = Name
auths.type = Type
auths.enabled = Enabled
auths.updated = Updated
auths.auth_type = Authorization Type
auths.auth_name = Authorization Name
auths.domain = Domain
auths.host = Host
auths.port = Port
auths.base_dn = Base DN
auths.attributes = Search Attributes
auths.filter = Search Filter
auths.ms_ad_sa = Ms Ad SA
auths.smtp_auth = SMTP Authorization Type
auths.smtphost = SMTP Host
auths.smtpport = SMTP Port
auths.enable_tls = Enable TLS Encryption
auths.enable_auto_register = Enable Auto Registration
auths.tips = Tips
auths.edit = Edit Authorization Setting
auths.activated = This authentication has activated
auths.update_success = Authorization setting has been successfully updated.
auths.update = Update Authorization Setting
auths.delete = Delete This Authorization
config.server_config = Server Configuration
config.app_name = Application Name
config.app_ver = Application Version
config.app_url = Application URL
config.domain = Domain
config.offline_mode = Offline Mode
config.disable_router_log = Disable Router Log
config.run_user = Run User
config.run_mode = Run Mode
config.repo_root_path = Repository Root Path
config.static_file_root_path = Static File Root Path
config.log_file_root_path = Log File Root Path
config.script_type = Script Type
config.reverse_auth_user = Reverse Authentication User
config.db_config = Database Configuration
config.db_type = Type
config.db_host = Host
config.db_name = Name
config.db_user = User
config.db_ssl_mode = SSL Mode
config.db_ssl_mode_helper = (for "postgres" only)
config.db_path = Path
config.db_path_helper = (for "sqlite3" only)
config.service_config = Service Configuration
config.register_email_confirm = Register Email Confirmation
config.disable_register = Disable Registration
config.require_sign_in_view = Require Sign In View
config.mail_notify = Mail Notification
config.enable_cache_avatar = Enable Cache Avatar
config.active_code_lives = Active Code Lives
config.reset_password_code_lives = Reset Password Code Lives
config.webhook_config = Webhook Configuration
config.task_interval = Task Interval
config.deliver_timeout = Deliver Timeout
config.mailer_config = Mailer Configuration
config.mailer_enabled = Enabled
config.mailer_name = Name
config.mailer_host = Host
config.mailer_user = User
config.oauth_config = OAuth Configuration
config.oauth_enabled = Enabled
config.cache_config = Cache Configuration
config.cache_adapter = Cache Adapter
config.cache_interval = Cache Interval
config.cache_conn = Cache Connection
config.session_config = Session Configuration
config.session_provider = Session Provider
config.provider_config = Provider Config
config.cookie_name = Cookie Name
config.enable_set_cookie = Enable Set Cookie
config.gc_interval_time = GC Interval Time
config.session_life_time = Session Life Time
config.https_only = HTTPS Only
config.cookie_life_time = Cookie Life Time
config.session_hash_function = Session ID Hash Function
config.session_hash_key = Session ID Hash Key
config.picture_config = Picture Configuration
config.picture_service = Picture Service
config.disable_gravatar = Disable Gravatar
config.log_config = Log Configuration
config.log_mode = Log Mode
monitor.cron = Cron Tasks
monitor.name = Name
monitor.schedule = Schedule
monitor.next = Next Time
monitor.previous = Previous Time
monitor.execute_times = Execute Times
monitor.process = Running Processes
monitor.desc = Description
monitor.start = Start Time
monitor.execute_time = Execution Time
[action]
create_repo = created repository <a href="/%s">%s</a>
commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>
create_issue = opened issue <a href="/%s/issues/%s">%s#%s</a>
comment_issue = commented on issue <a href="/%s/issues/%s">%s#%s</a>
[tool]
ago = ago
from_now = from now
now = now
1s = 1 second %s
1m = 1 minute %s
1h = 1 hour %s
1d = 1 day %s
1w = 1 week %s
1mon = 1 month %s
1y = 1 year %s
seconds = %d seconds %s
minutes = %d minutes %s
hours = %d hours %s
days = %d days %s
weeks = %d weeks %s
months = %d months %s
years = %d years %s
raw_seconds = seconds
raw_minutes = minutes

View File

@@ -0,0 +1,516 @@
app_desc = Un service Git écrit en Go auto-hébergé
home = Accueil
dashboard = Tableau de bord
explore = Explorer
help = Aide
sign_in = Connexion
social_sign_in = Authentification via Internet: 2ème étape <small>associé le compte</small>
sign_out = Déconnexion
sign_up = Créer un compte
register = S'inscrire
website = Site web
version = Version
page = Page
template = Gabarit
language = Langage
username = Usager
email = Courriel
password = Mot de passe
re_type = Saisir à nouveau
captcha = Captcha
repository = Dépôt
organization = Organisation
mirror = Mirroir
new_repo = Nouveau dépôt
new_migrate = Nouvelle migration
new_org = Nouvel organisation
manage_org = Gestion des organisations
admin_panel = Gestion
account_settings = Profil usager
settings = Configuration
news_feed = Fil de nouvelles
pull_requests = Demandes de fusion (pull requests)
issues = Suivi de problèmes
cancel = Annuler
[home]
uname_holder = Nom d'usager ou courriel
password_holder = Mot de passe
switch_dashboard_context = Changer de tableau de bord
my_repos = Mes dépôts
collaborative_repos = Dépôts partagés
my_orgs = Mes organisations
my_mirrors = Mes mirroirs
[auth]
create_new_account = Créer un nouveau compte
register_hepler_msg = Déjà inscrits? Connectez-vous maintenant!
social_register_hepler_msg = Déjà inscrits? Branchez-vous!
disable_register_prompt = Désolé, l'auto-inscription n'est pas activée. Contactez l'admnistrateur du site.
disable_register_mail = Désolé, la confirmation d'inscription par courriel est désactivée. Contactez l'administrateur du site.
remember_me = Se souvenir de moi
forgot_password= Mot de passe oublié
forget_password = Mot de passe oublié?
sign_up_now = Besoin d'un compte? Inscrivez-vous maintenant.
confirmation_mail_sent_prompt = Un courriel de confirmation à été envoyé à <b>%s</b>, consultez vos courriels d'ici %d heures pour terminer l'inscription.
sign_in_email = Connexion avec votre courriel
active_your_account = Activez votre compte
resent_limit_prompt = Désolé vous demandez trop souvent un courriel de confirmation. S.v.p. patientez 3 minutes.
has_unconfirmed_mail = Bonjour %s, votre adresse courriel n'est pas vérifiée(<b>%s</b>). Si vous n'avez pas reçu de courriel de confirmation ou si vous avez besoin d'en envoyer un maintenant, appuyez sur le bouton ci-dessous.
resend_mail = Appuyez ici pour envoyer de nouveau un courriel de confirmation.
email_not_associate = Ce courriel ne correspond à aucun compte.
send_reset_mail = Appuyez ici pour (ré)envoyer un courriel pour réinitialiser le mot de passe.
reset_password = Réinitialiser votre mot de passe
invalid_code = Désolé, ce code de confirmation est périmé ou non-valide.
reset_password_helper = Appuyez ici pour réinitialiser votre mot de passe
password_too_short = La longueur du mot de passe doit être d'au moins 6 caractères.
[form]
UserName = Nom d'usager
RepoName = Nom du dépôt
Email = Adresse de courriel
Password = Mot de passe
Retype = Mot de passe (confirmation)
SSHTitle = Nom de la clé SSH
HttpsUrl = URL HTTPS
PayloadUrl = URL cible
TeamName = Nom de l'équipe
AuthName = Nom d'usager
require_error = ` ne peut être vide.`
alpha_dash_error = ` doit être composé de caractères alpha-numériques et/ou d'un tiret(-_).`
alpha_dash_dot_error = ` doit être composé de caractères alpha-numérique, un point(.) et/ou tiret(-_).`
min_size_error = ` doit être composé d'au moins %s caractères.`
max_size_error = ` doit être conposé d'au plus %s caractères.`
email_error = ` n'est pas une adresse de courriel bien formée.`
url_error = ` n'est pas un URL valide.`
unknown_error = Erreur inconnue:
captcha_incorrect = Le captcha ne concorde pas.
password_not_match = Les deux mots de passe diffèrent.
username_been_taken = `Nom d'usager dèjà utilisé.`
repo_name_been_taken = Nom de dépôt déjà utilisé.
org_name_been_taken = Nom d'organisation déjà utilisé.
team_name_been_taken = Nom d'équipe déjà utilisé.
email_been_used = Adresse de courriel déjà utilisée.
ssh_key_been_used = Nom de clé publique déjà utilisé.
illegal_username = Votre nom d'usager contient des caractères interdits.
illegal_repo_name = Le nom du dépôt contient des caractères interdits.
illegal_org_name = Le nom de l'organisation contient des caractères interdits.
illegal_team_name = Le nom de l'équipe contient des caractères interdits.
username_password_incorrect = Nom d'usager ou mot de passe erroné.
enterred_invalid_repo_name = Nom de dépôt inexistant.
enterred_invalid_owner_name = Responsable de dépôt inexistant.
enterred_invalid_password = Mot de passe erroné.
user_not_exist = Nom d'usager inexistant.
last_org_owner = Ceci est le dernier responsable du dépôt. Il doit y avoir obligatoirement au moins un usager responsable.
invalid_ssh_key = Désolé, impossible de vérifier votre clé SSH: %
auth_failed = Erreur d'authentification : %v
still_own_repo = Votre compte est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager.
org_still_own_repo = Cette organisation est responsable d'au moins un dépôt. Vous devez soit détruire ces dépôts, soit transférer la responsabilité à un autre usager ou organisation.
still_own_user = Cette authentification est utilisée par un usager.
[settings]
profile = Profil
password = Mot de passe
ssh_keys = Clés SSH
social = Comptes Internet
orgs = Organisations
delete = Supprimer votre compte
public_profile = Profil public
profile_desc = Votre adresse de courriel est publique et sera utilisée pour les avis produits par le site.
full_name = Nom complet
website = Site web
location = Endroit
update_profile = Mettre à jour le profil
update_profile_success = Mise à jour du profil réussie.
change_password = Changer le mot de passe
old_password = Mot de passe actuel
new_password = Nouveau mot de passe
password_incorrect = Mot de passe actuel erroné.
change_password_success = Modification du mot de passe effectuée. Vous pouvez dorénavant vous connecter avec le nouveau mot de passe.
manage_ssh_keys = Gestion des clés SSH
add_key = Ajouter une clé
ssh_desc = Voici la liste de clés SSH associées à votre profil. Retirez les clés que vous ne reconnaissez pas.
ssh_helper = <strong>Beson d'aide?</strong> Consultez le guide au <a href="https://help.github.com/articles/generating-ssh-keys">generating SSH keys</a> ou vérifiez <a href="https://help.github.com/ssh-issues/">les problèmes SSH fréquents</a>.
add_new_key = Ajouter une clé SSH
key_name = Nom de la clé
key_content = Contenu
add_key_success = Clé SSH ajoutée!
delete_key = Détruire
add_on = Ajoutée le
last_used = Dernière utilisation le
no_activity = Pas d'activité récente
manage_social = Gestion des comptes Internets associés
social_desc = Ceci est une liste de comptes Internet associés. Retirez les comptes que vous ne reconnaissez pas.
unbind = Désassocier
unbind_success = Compte Internet déassocié.
delete_account = Detruire votre compte
delete_prompt = Cette opération détruira votre compte et <strong>ne pourra être annulée</strong>!
confirm_delete_account = Confirmez la suppression
[repo]
owner = Responsable
repo_name = Nom du dépôt
repo_name_helper = Les bons noms de dépôts sont courts, mémorables et <strong>uniques</strong>.
visibility = Visibilité
visiblity_helper = Ce dépôt est <span class="label label-red label-radius">privé</span>
repo_desc = Description
repo_lang = Langue
repo_lang_helper = Choisir un fichier .gitignore
license = License
license_helper = Choisir un fichier de licence
init_readme = Initialiser le dépôt avec un fichier README.md
create_repo = Créer le dépôt
default_branch = Branche par défaut
mirror_interval = Intervale de synchronisation (heures)
goget_meta = Métadonnées Go-Get
goget_meta_helper = Ce dépôt sera <span class="label label-blue label-radius">Go-Getable</span>
need_auth = Authorisation requise
migrate_type = Type de migration
migrate_type_helper = Ce dépôt sera un <span class="label label-blue label-radius">mirroir</span>
migrate_repo = Migrer le dépôt
copy_link = Copier
clone_helper = Besoin d'aide pour cloner? Obtenez de l' <a target="_blank" href="http://git-scm.com/book/fr/Les-bases-de-Git-Démarrer-un-dépôt-Git">aide</a>!
unwatch = Ne plus suivre
watch = Suivre
unstar = Retirer étoile
star = Étoile
fork = Fork
quick_guide = Guide rapide
clone_this_repo = Cloner ce dépôt
create_new_repo_command = Créer un nouveau dépôt à la ligne de commande
push_exist_repo = Pousser un dépôt existant depuis la ligne de commande
settings = Réglages
settings.options = Réglages de base
settings.collaboration = Collaboration
settings.hooks = Webhooks
settings.deploy_keys = Clé de déploiement
settings.basic_settings = réglages de base
settings.danger_zone = Danger!
settings.site = Site officiel
settings.update_settings = Réglage des mises à jour
settings.transfer = Transférer la responsabilité
settings.transfer_desc = Transférer ce dépôt à un autre usager ou organisation si vous en avez la responsabilité.
settings.delete = Détruire ce dépôt
settings.delete_desc = La destruction est irrémédiable, impossible d'annuler. Soyez sûr de votre décision.
settings.update_settings_success = Réglages modifiés
settings.transfer_owner = Nouveau responsable
settings.make_transfer = Faire le transfert
settings.confirm_delete = Confirmer la destruction
settings.add_collaborator = Ajouter un nouveau collaborateur
settings.add_collaborator_success = Nouveau collaborateur ajouté.
settings.remove_collaborator_success = Collaborateur supprimé.
settings.add_webhook = Ajouter un Webhook
settings.hooks_desc = Les Webhooks permettent à des services externes d'être avertis de certains changements sur Gogs. Lorque qu'un changement se produit, Gogs envoie une requête POST à chacun des URLs spécifiés. Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>.
settings.remove_hook_success = Webhook supprimé.
settings.add_webhook_desc = Gogs envoiera un POST à l'URL ci-dessous avec le détail de l'événement souscrit. Vous pouvez aussi spécifier dans quel format vous désirez recevoir les données (JSON,<code>x-www-form-urlencoded</code>, <em>etc</em>). Plus d'info disponible sur notre <a target="_blank" href="http://gogs.io/docs/features/webhook.html">guide Webhooks'</a>.
settings.payload_url = URL cible
settings.content_type = Content Type
settings.secret = Secret
settings.event_desc = Quels changements déclencheront le webhook?
settings.event_push_only = Uniquement les <code>push</code>.
settings.active = Activé
settings.active_helper = Gogs fournira le détail de l'événement lorsque ce webhook sera déclenché.
settings.add_hook_success = Nouveau webhook ajouté.
settings.update_webhook = Mettre à jour le webhook
settings.update_hook_success = Webhook mis à jour.
settings.delete_webhook = Détruire le webhook
settings.recent_deliveries = Livraisons récentes
settings.hook_type = Type de déclencheur
settings.add_slack_hook_desc = Ajouter la compatibilité <a href="http://slack.com">Slack</a> à ce dépôt.
settings.slack_token = Jeton (token)
settings.slack_domain = Domaine
settings.slack_channel = Canal
[org]
org_name_holder = Nom de l'organisation
org_name_helper = Les bons noms d'organisations sont courts, mémorables et uniques
org_email_helper = Le courriel de l'organisation recevra toutes les notifications et les confirmations.
create_org = Créer une organisation
repo_updated = Changement effectué
people = Personne
invite_someone = Inviter quelqu'un
teams = Équipes
lower_members = Membres
lower_repositories = Dépôts
create_new_team = Créer une nouvelle équipe
org_desc = Description
team_name = Nom de l'équipe
team_desc = Description
team_name_helper = Le nom qui sera utilisé pour mentionner cette équipe dans les conversations.
team_desc_helper = Quel est la raison d'être de cette équipe?
team_permission_desc = Quel niveau de permission attribuer à cette équipe?
settings = Réglages
settings.options = Paramètres
settings.full_name = Nom complet
settings.website = Site web
settings.location = Endroit
settings.update_settings = Mettre à jour les paramètres
settings.update_setting_success = Paramètres mis à jour.
settings.delete = Détruire l'organisation
settings.delete_account = Détruire cette organisation
settings.delete_prompt = La destruction de l'organisation est irrémédiable, impossible d'annuler. Soyez sûr de votre décision.
settings.confirm_delete_account = Confirmer la destruction
members.public = Publique
members.public_helper = Rendre privé
members.private = Privé
members.private_helper = Rendre publique
members.owner = Responsable
members.member = Membre
members.conceal = Caché
members.remove = Retirer
members.leave = Quitter
members.invite_desc = Commencez à saisir un nom d'usager pour l'inviter à %s:
members.invite_now = Inviter
teams.join = Rejoindre
teams.leave = Quitter
teams.read_access = Droits de lecture
teams.read_access_helper = Cette équipe pourra voir et cloner ses dépôts.
teams.write_access = Droits d'écriture
teams.write_access_helper = Cette équipe pourra voir et cloner ses dépôts ainsi que pousser vers ceux-ci.
teams.admin_access = Droits de gestion
teams.admin_access_helper = En plus des droits d'écriture, cette équipe pourra gérer les collaborateurs.
teams.no_desc = Cette équipe ne posséde pas de description
teams.settings = Réglages
teams.owners_permission_desc = Les responsables ont accès à <strong>tous</strong> les dépôts et en possédent les droits de gestion.
teams.members = Membre de l'équipe
teams.update_settings = Mettre à jour
teams.delete_team = Détruire cette équipe
teams.add_team_member = Ajouter un membre à l'équipe
teams.delete_team_success = Équipe détruite
teams.read_permission_desc = La participation à cette équipe confère les droits de lecture. Ses membres peuvent voir et cloner ses dépôts.
teams.write_permission_desc = La participation à cette équipe confère les droits d'écriture en plus des droits de lecture. Ses membres peuvent pousser vers les dépôts de l'équipe.
teams.admin_permission_desc = La participation à cette équire confère les droits de gestion. Ses membres peuvent voir, cloner, pousser et gérer les collaborateurs des dépôts.
teams.repositories = Dépôts de l'équipe
teams.add_team_repository = Ajouer un dépôt à l'équipe
teams.remove_repo = Enlever
[admin]
dashboard = Tableau de bord
users = Usagers
organizations = Organisations
repositories = Dépôts
authentication = Sources d'authentifications
config = Configuration
monitor = Monitoring
prev = Préc.
next = Suiv.
dashboard.statistic = Statistiques
dashboard.operations = Opérations
dashboard.system_status = État du monitoring système
dashboard.statistic_info = La BD Gogs compte <b>%d</b> usagers, <b>%d</b> organisations, <b>%d</b> clé SSH, <b>%d</b> dépôts, <b>%d</b> suivis, <b>%d</b> étoiles, <b>%d</b> actions, <b>%d</b> accès, <b>%d</b> tickets, <b>%d</b> commentaires, <b>%d</b> comptes Internet, <b>%d</b> suivis, <b>%d</b> mirroirs, <b>%d</b> publications, <b>%d</b> sources d'authentification, <b>%d</b> webhooks, <b>%d</b> jalons, <b>%d</b> tags, <b>%d</b> tâches hook, <b>%d</b> équipes, <b>%d</b> tâches de mise à jours, <b>%d</b> fichiers joints.
dashboard.operation_name = Nom de l'opération
dashboard.operation_switch = Commande
dashboard.operation_run = Lancer
dashboard.clean_unbind_oauth = Nettoyer les OAuths orphelins
dashboard.delete_inactivate_accounts = Détruire les comptes inactifs
dashboard.server_uptime = Démarré depuis
dashboard.current_goroutine = Nombre de Goroutines
dashboard.current_memory_usage = Usage mémoire actuel
dashboard.total_memory_allocated = Mémoire allouée totale
dashboard.memory_obtained = Memoire obtenue
dashboard.pointer_lookup_times = Accès pointeur
dashboard.memory_allocate_times = Allocation mémoire
dashboard.memory_free_times = Désallocation mémoire
dashboard.current_heap_usage = Taille du heap actuelle
dashboard.heap_memory_obtained = Mémoire heap obtenue
dashboard.heap_memory_idle = Mémoire heap inactive
dashboard.heap_memory_in_use = Mémoire heap utilisée
dashboard.heap_memory_released = Mémoire heap relachée
dashboard.heap_objects = Objets dans le heap
dashboard.bootstrap_stack_usage = Bootstrap Stack Usage
dashboard.stack_memory_obtained = Stack Memory Obtained
dashboard.mspan_structures_usage = MSpan Structures Usage
dashboard.mspan_structures_obtained = MSpan Structures Obtained
dashboard.mcache_structures_usage = MCache Structures Usage
dashboard.mcache_structures_obtained = MCache Structures Obtained
dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
dashboard.gc_metadata_obtained = GC Metadada Obtained
dashboard.other_system_allocation_obtained = Other System Allocation Obtained
dashboard.next_gc_recycle = Next GC Recycle
dashboard.last_gc_time = Since Last GC Time
dashboard.total_gc_time = Total GC Pause
dashboard.total_gc_pause = Total GC Pause
dashboard.last_gc_pause = Last GC Pause
dashboard.gc_times = GC Times
users.user_manage_panel = Gestion des usager
users.new_account = Creér un nouveau compte
users.name = Nom
users.activated = Activé
users.admin = Gestionnaire
users.repos = Dépôts
users.created = Créé
users.edit = Editer
users.auth_source = Source d'authentification
users.local = Locale
users.auth_login_name = Identifiant d'authentification
users.update_profile_success = Compte crée.
users.edit_account = Éditer compte
users.is_activated = Ce compte est activé
users.is_admin = Ce compte a les droits de gestionnaire
users.update_profile = Mettre à jour le compte
users.delete_account = Détruire ce compte
users.still_own_repo = Ce compte est responsables d'un dépôt. I faut détruire le dépôt ou transférer la responsabilité avant de détruire ce compte.
orgs.org_manage_panel = Gestion des organisations
orgs.name = Nom
orgs.teams = Équipes
orgs.members = Membres
repos.repo_manage_panel = Gestion des dépôts
repos.owner = Responsable
repos.name = Nom
repos.private = Privé
repos.watches = Suivis
repos.stars = Étoiles
repos.issues = Ticket
auths.auth_manage_panel = Gestion des sources d'authentification
auths.new = Ajouter une nouvelle source d'authentification
auths.name = Nom
auths.type = Type
auths.enabled = Activé
auths.updated = Mis à jour
auths.auth_type = Type d'authentification
auths.auth_name = Nom de l'authentification
auths.domain = Domaine
auths.host = Serveur
auths.port = Port
auths.base_dn = DN de base
auths.attributes = Attributs de recherche
auths.filter = Filtre de recherche
auths.ms_ad_sa = Microsoft Active Directory
auths.smtp_auth = Authentification SMTP
auths.smtphost = Serveur SMTP
auths.smtpport = Port SMTP
auths.enable_tls = Chiffrement TLS
auths.enable_auto_register = Activer auto-abonnement
auths.tips = Trucs
auths.edit = Éditer réglages d'authentification
auths.activated = Source d'authentification activée
auths.update_success = Réglages mis à jour.
auths.update = Mettre à jour réglages
auths.delete = Détruire cette source
config.server_config = Configuration du serveur
config.app_name = Nom de l'applicaiton
config.app_ver = Version de l'application
config.app_url = URL de l'application
config.domain = Domaine
config.offline_mode = Mode hors-ligne
config.disable_router_log = Journal du routeur désactivé
config.run_user = Éxécuté en tant que
config.run_mode = Mode de fonctionnement
config.repo_root_path = Dossier contenant les dépôts
config.static_file_root_path = Dossier contenant les fichiers statiques
config.log_file_root_path = Dossier contenant les journaux
config.script_type = Type de script
config.reverse_auth_user = Usager d'authentification inversée
config.db_config = Configuration de la BD
config.db_type = Type
config.db_host = Serveur
config.db_name = Nom
config.db_user = Usager
config.db_ssl_mode = Mode SSL
config.db_ssl_mode_helper = (pour "postgres" seulement)
config.db_path = Path
config.db_path_helper = (pour "sqlite3" seulement)
config.service_config = Configuration du service
config.register_email_confirm = Confirmation d'abonnement par courriel
config.disable_register = Auto-inscription désactivée
config.require_sign_in_view = Connexion requise pour visualiser
config.mail_notify = Notifications par courriel
config.enable_cache_avatar = Cache avatar activée
config.active_code_lives = Jeton d'activation
config.reset_password_code_lives = Jeton de modification mot-de-passe
config.webhook_config = Configuration Webhook
config.task_interval = Intervalle
config.deliver_timeout = Expiration des appels
config.mailer_config = Configuration expédition de courriels
config.mailer_enabled = Activé
config.mailer_name = Nom
config.mailer_host = Serveur
config.mailer_user = Usager
config.oauth_config = Configuration OAuth
config.oauth_enabled = Activé
config.cache_config = Configuration du cache
config.cache_adapter = Mécanisme de cache
config.cache_interval = Intervalle
config.cache_conn = Chaîne de connexion
config.session_config = Configuration des session
config.session_provider = Mécanisme
config.provider_config = Configuration du mécanisme
config.cookie_name = Nom du fichier témoin
config.enable_set_cookie = Fichier témoin actvité
config.gc_interval_time = Intervalle GC
config.session_life_time = Durée de la session
config.https_only = HTTPS exigé
config.cookie_life_time = Expiration du fichier témoin
config.session_hash_function = Fonction de hashage ID de session
config.session_hash_key = Clé de hashage ID de session
config.picture_config = Configuration des avatars
config.picture_service = Service image
config.disable_gravatar = Désactivé Gravatar
config.log_config = Configuration du journal
config.log_mode = Mode de journal
monitor.cron = Cron Tasks
monitor.name = Name
monitor.schedule = Schedule
monitor.next = Next Time
monitor.previous = Previous Time
monitor.execute_times = Execute Times
monitor.process = Running Processes
monitor.desc = Description
monitor.start = Start Time
monitor.execute_time = Execution Time
[action]
create_repo = a créé le dépôt <a href="/%s">%s</a>
commit_repo = a poussé sur <a href="/%s/src/%s">%s</a> à <a href="/%s">%s</a>
create_issue = a ouvert le ticket <a href="/%s/issues/%s">%s#%s</a>
comment_issue = a commenté sur le ticket <a href="/%s/issues/%s">%s#%s</a>
[tool]
ago = auparavant
from_now = depuis
now = maintenant
1s = 1 seconde %s
1m = 1 minute %s
1h = 1 heure %s
1d = 1 jour %s
1w = 1 semaine %s
1mon = 1 mos %s
1y = 1 an %s
seconds = %d secondes %s
minutes = %d minutes %s
hours = %d heures %s
days = %d jours %s
weeks = %d semaines %s
months = %d mois %s
years = %d années %s
raw_seconds = secondes
raw_minutes = minutes

View File

@@ -0,0 +1,578 @@
app_desc = 基于 Go 语言的自助 Git 服务
home = 首页
dashboard = 控制面板
explore = 探索
help = 帮助
sign_in = 登录
social_sign_in = 社交帐号登录:第 2 步 <small>关联帐号</small>
sign_out = 退出
sign_up = 注册
register = 注册
website = 官方网站
version = 当前版本
page = 页面
template = 模板
language = 语言选项
username = 用户名
email = 邮箱
password = 密码
re_type = 确认密码
captcha = 验证码
repository = 仓库
organization = 组织
mirror = 镜像
new_repo = 创建新的仓库
new_migrate = 迁移外部仓库
new_org = 创建新的组织
manage_org = 管理我的组织
admin_panel = 管理面板
account_settings = 帐户设置
settings = 帐户设置
news_feed = 最新活动
pull_requests = 合并请求
issues = 工单管理
cancel = 取消
[install]
install = 安装页面
title = 首次运行安装程序
requite_db_desc = Gogs 允许后端数据库为 MySQL、PostgreSQL 或 SQLite3但是 SQLite3 一般只有官方二进制发行版才支持。
db_type = 数据库类型
host = 数据库主机
user = 数据库用户
password = 数据库用户密码
db_name = 数据库名称
db_helper = 如果您使用 MySQL请使用 INNODB 引擎以及 utf8_general_ci 字符集。
ssl_mode = SSL 模式
path = 数据库文件路径
sqlite_helper = SQLite3 数据库的文件路径。
general_title = 应用基本设置
repo_path = 仓库根目录
repo_path_helper = 所有 Git 远程仓库都将被存放于该目录。
run_user = 运行系统用户
run_user_helper = 该用户必须具有对仓库根目录和运行 Gogs 的操作权限。
domain = 域名
domain_helper = 该设置影响 SSH 克隆地址。
app_url = 应用 URL
app_url_helper = 该设置影响 HTTP/HTTPS 克隆地址和一些邮箱中的链接。
email_title = 邮件服务设置(可选)
smtp_host = SMTP 主机
mailer_user = 发送邮箱
mailer_password = 发送邮箱密码
notify_title = 通知提醒设置(可选)
register_confirm = 启用注册邮箱确认
mail_notify = 启用邮件通知提醒
admin_title = 管理员帐号设置
admin_name = 管理员用户名
admin_password = 管理员密码
confirm_password = 确认密码
admin_email = 管理员邮箱
install_gogs = 立即安装
test_git_failed = 无法识别 'git' 命令:%v
sqlite3_not_available = 您所使用的发行版不支持 SQLite3请从 http://gogs.io/docs/installation/install_from_binary.html 下载官方二进制发行版,而不是 gobuild 版本。
invalid_db_setting = 数据库设置不正确:%v
invalid_repo_path = 仓库根目录设置不正确:%v
run_user_not_match = 运行系统用户非当前用户:%s -> %s
save_config_failed = 应用配置保存失败:%v
invalid_admin_setting = 管理员帐户设置不正确:%v
install_success = 您好!我们很高兴您选择使用 Gogs祝您使用愉快代码从此无 BUG
[home]
uname_holder = 用户名或邮箱
password_holder = 密码
switch_dashboard_context = 切换控制面板用户
my_repos = 我的仓库
collaborative_repos = 参与协作的仓库
my_orgs = 我的组织
my_mirrors = 我的镜像
[explore]
repos = 探索仓库
[auth]
create_new_account = 创建帐户
register_hepler_msg = 已经注册?立即登录!
social_register_hepler_msg = 已经注册?立即绑定!
disable_register_prompt = 对不起,注册功能已被关闭。请联系网站管理员。
disable_register_mail = 对不起,注册邮箱确认功能已被关闭。
remember_me = 记住登录
forgot_password = 忘记密码
forget_password = 忘记密码?
sign_up_now = 还没帐户?马上注册。
confirmation_mail_sent_prompt = 一封新的确认邮件已经被发送至 <b>%s</b>,请检查您的收件箱并在 %d 小时内完成确认注册操作。
sign_in_email = 登录到您的邮箱
active_your_account = 激活您的帐户
resent_limit_prompt = 对不起,您请求发送激活邮件过于频繁,请等待 3 分钟后再试!
has_unconfirmed_mail = %s 您好,系统检测到您有一封发送至 <b>%s</b> 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。
resend_mail = 单击此处重新发送确认邮件
email_not_associate = 您输入的邮箱地址未被关联到任何帐号!
send_reset_mail = 单击此处(重新)发送您的密码重置邮件
reset_password = 重置密码
invalid_code = 对不起,您的确认代码已过期或已失效。
reset_password_helper = 单击此处重置密码
password_too_short = 密码长度不能少于 6 位!
[form]
UserName = 用户名
RepoName = 仓库名称
Email = 邮箱地址
Password = 密码
Retype = 确认密码
SSHTitle = SSH 密钥名称
HttpsUrl = HTTPS URL 地址
PayloadUrl = 推送地址
TeamName = 团队名称
AuthName = 认证名称
AdminEmail = 管理员邮箱
require_error = 不能为空。
alpha_dash_error = 必须为英文字母、阿拉伯数字或横线(-_
alpha_dash_dot_error = 必须为英文字母、阿拉伯数字、横线(-_或点。
min_size_error = 长度最小为 %s 个字符。
max_size_error = 长度最大为 %s 个字符。
email_error = 不是一个有效的邮箱地址。
url_error = 不是一个有效的 URL。
unknown_error = 未知错误:
captcha_incorrect = 验证码未匹配。
password_not_match = 密码与确认密码未匹配。
username_been_taken = 用户名已经被占用。
repo_name_been_taken = 仓库名称已经被占用。
org_name_been_taken = 组织名称已经被占用。
team_name_been_taken = 团队名称已经被占用。
email_been_used = 邮箱地址已经被使用。
ssh_key_been_used = SSH 密钥已经被使用。
illegal_username = 您的用户名包含非法字符。
illegal_repo_name = 仓库名称包含非法字符。
illegal_org_name = 组织名称包含非法字符。
illegal_team_name = 团队名称包含非法字符。
username_password_incorrect = 用户名或密码不正确。
enterred_invalid_repo_name = 请检查您输入的仓库名称是正确。
enterred_invalid_owner_name = 请检查您输入的新所有者用户名是否正确。
enterred_invalid_password = 请检查您输入的密码是否正确。
user_not_exist = 被操作的用户不存在!
last_org_owner = 被移除用户为最后一位管理员。请添加一位新的管理员再进行移除成员操作!
invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s
auth_failed = 授权验证失败:%v
still_own_repo = 您的帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作!
org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除组织操作!
still_own_user = 该授权认证依旧被部分用户使用,请先删除该部分用户后再试!
[settings]
profile = 个人信息
password = 修改密码
ssh_keys = 管理 SSH 密钥
social = 社交帐号绑定
orgs = 管理组织
delete = 删除帐户
uid = 用户 ID
public_profile = 公开信息
profile_desc = 您的邮箱地址将会被公开,并被用于接收帐户的所有提醒和通知。
full_name = 自定义名称
website = 个人网站
location = 所在地区
update_profile = 更新信息
update_profile_success = 您的个人信息更新成功!
change_password = 修改密码
old_password = 当前密码
new_password = 新的密码
password_incorrect = 当前密码不正确!
change_password_success = 密码修改成功!您现在可以使用新的密码登录。
manage_ssh_keys = 管理 SSH 密钥
add_key = 增加密钥
ssh_desc = 以下是与您帐户所关联的 SSH 密钥,如果您发现有陌生的密钥,请立即删除它!
ssh_helper = <strong>需要帮助?</strong> 请查看有关 <a href="https://help.github.com/articles/generating-ssh-keys">如何生成 SSH 密钥</a> 或 <a href="https://help.github.com/ssh-issues/">常见 SSH 问题</a> 寻找答案。
add_new_key = 增加 SSH 密钥
key_name = 密钥名称
key_content = 密钥内容
add_key_success = 新的 SSH 密钥添加成功!
delete_key = 删除
add_on = 增加于
last_used = 上次使用在
no_activity = 没有最近活动
manage_social = 管理关联社交帐户
social_desc = 以下是与您帐户所关联的社交帐号,如果您发现有陌生的关联,请立即解除绑定!
unbind = 解除绑定
unbind_success = 社交帐号解除绑定成功!
delete_account = 删除当前帐户
delete_prompt = 删除操作会永久清除您的帐户信息,并且 <strong>不可恢复</strong>
confirm_delete_account = 确认删除帐户
[repo]
owner = 拥有者
repo_name = 仓库名称
repo_name_helper = 伟大的仓库名称一般都较短、令人深刻并且 <strong>独一无二</strong> 的。
visibility = 可见性
visiblity_helper = 本仓库将是 <span class="label label-red label-radius">私有的</span>
repo_desc = 仓库描述
repo_lang = 仓库语言
repo_lang_helper = 请选择 .gitignore 文件
license = 授权许可
license_helper = 请选择授权许可文件
init_readme = 使用 README.md 文件初始化仓库
create_repo = 创建仓库
default_branch = 默认分支
mirror_interval = 镜像同步周期(小时)
goget_meta = Go-Get 支持
goget_meta_helper = 本仓库将可以通过 <span class="label label-blue label-radius">Go Get</span> 获取
need_auth = 需要授权验证
migrate_type = 迁移类型
migrate_type_helper = 本仓库将是 <span class="label label-blue label-radius">镜像</span>
migrate_repo = 迁移仓库
copy_link = 复制链接
clone_helper = 不知道如何操作?访问 <a target="_blank" href="http://git-scm.com/book/zh/Git-基础-取得项目的-Git-仓库">此处</a> 查看帮助!
unwatch = 取消关注
watch = 关注
unstar = 取消点赞
star = 点赞
fork = 派生
quick_guide = 快速帮助
clone_this_repo = 克隆当前仓库
create_new_repo_command = 从命令行创建一个新的仓库
push_exist_repo = 从命令行推送已经创建的仓库
settings = 仓库设置
settings.options = 基本设置
settings.collaboration = 管理协作者
settings.hooks = 管理 Web 钩子
settings.deploy_keys = 管理部署密钥
settings.basic_settings = 基本设置
settings.danger_zone = 危险操作区
settings.site = 官方网站
settings.update_settings = 更新仓库设置
settings.transfer = 转移仓库所有权
settings.transfer_desc = 您可以将仓库转移至您拥有管理员权限的帐户或组织。
settings.new_owner_has_same_repo = 新的仓库拥有者已经存在同名仓库!
settings.delete = 删除本仓库
settings.delete_desc = 删除仓库操作不可逆转,请三思而后行。
settings.update_settings_success = 仓库设置更新成功!
settings.transfer_owner = 新拥有者
settings.make_transfer = 确认转移仓库
settings.transfer_succeed = 仓库所有权转移成功!
settings.confirm_delete = 确认删除仓库
settings.add_collaborator = 增加新的协作者
settings.add_collaborator_success = 成功添加新的协作者!
settings.remove_collaborator_success = 被操作的协作者已经被收回权限!
settings.add_webhook = 添加 Web 钩子
settings.hooks_desc = Web 钩子允许您设定在 Gogs 上发生指定事件时对指定 URL 发送 POST 通知。查看 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。
settings.remove_hook_success = Web 钩子删除成功!
settings.add_webhook_desc = 我们会通过 <code>POST</code> 请求将订阅事件信息发送至向指定 URL 地址。您可以设置不同的数据接收方式JSON 或 <code>x-www-form-urlencoded</code>)。 请查阅 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。
settings.payload_url = 推送地址
settings.content_type = 数据格式
settings.secret = 密钥文本
settings.event_desc = 请设置您希望触发 Web 钩子的事件:
settings.event_push_only = 只推送 <code>push</code> 事件。
settings.active = 是否激活
settings.active_helper = 当指定事件发生时我们将会触发此 Web 钩子。
settings.add_hook_success = Web 钩子添加成功!
settings.update_webhook = 更新 Web 钩子
settings.update_hook_success = Web 钩子更新成功!
settings.delete_webhook = 删除 Web 钩子
settings.recent_deliveries = 最近推送记录
settings.hook_type = 钩子类型
settings.add_slack_hook_desc = 为您的仓库增加 <a href="http://slack.com">Slack</a> 集成
settings.slack_token = 令牌
settings.slack_domain = 域名
settings.slack_channel = 频道
[org]
org_name_holder = 组织名称
org_name_helper = 伟大的组织都有一个简短而寓意深刻的名字。
org_email_helper = 组织的邮箱用于接收所有通知和确认邮件。
create_org = 创建组织
repo_updated = 最后更新于
people = 组织成员
invite_someone = 邀请他人加入
teams = 组织团队
lower_members = 名成员
lower_repositories = 个仓库
create_new_team = 创建新的团队
org_desc = 组织描述
team_name = 团队名称
team_desc = 团队描述
team_name_helper = 您可以使用该名称来通知改组全体成员。
team_desc_helper = 一句话描述这个团队是做什么的。
team_permission_desc = 请选择该团队所具有的权限等级:
settings = 组织设置
settings.options = 基本设置
settings.full_name = 组织全名
settings.website = 官方网站
settings.location = 所在地区
settings.update_settings = 更新组织设置
settings.update_setting_success = 组织设置更新成功!
settings.delete = 删除组织
settings.delete_account = 删除当前组织
settings.delete_prompt = 删除操作会永久清除该组织的信息,并且 <strong>不可恢复</strong>
settings.confirm_delete_account = 确认删除组织
members.public = 公开成员
members.public_helper = 设为私有
members.private = 私有成员
members.private_helper = 设为公开
members.owner = 管理员
members.member = 普通成员
members.conceal = 隐藏身份
members.remove = 移除成员
members.leave = 离开组织
members.invite_desc = 请输入被邀请到组织 %s 的用户名称:
members.invite_now = 立即邀请
teams.join = 加入团队
teams.leave = 离开团队
teams.read_access = 读取权限
teams.read_access_helper = 这个团队将拥有查看和克隆所属仓库的权限。
teams.write_access = 写入权限
teams.write_access_helper = 这个团队将拥有查看、克隆和推送所属仓库的权限。
teams.admin_access = 管理权限
teams.admin_access_helper = 这个团队将拥有查看、克隆、推送和添加其他组织成员到团队的权限。
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_success = 指定团队删除成功!
teams.read_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 权限,团队成员可以进行查看和克隆等只读操作。
teams.write_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 和 <strong>写入</strong> 的权限。
teams.admin_permission_desc = 该团队拥有一定的 <strong>管理</strong> 权限,团队成员可以读取、克隆、推送以及添加其它仓库协作者。
teams.repositories = 团队仓库
teams.add_team_repository = 添加团队仓库
teams.remove_repo = 移除仓库
[admin]
dashboard = 控制面板
users = 用户管理
organizations = 组织管理
repositories = 仓库管理
authentication = 授权认证管理
config = 应用配置管理
monitor = 应用监控面板
prev = 上一页
next = 下一页
dashboard.statistic = 应用统计数据
dashboard.operations = 管理员操作
dashboard.system_status = 系统监视状态
dashboard.statistic_info = Gogs 数据库统计:<b>%d</b> 位用户,<b>%d</b> 个组织,<b>%d</b> 个公钥,<b>%d</b> 个仓库,<b>%d</b> 个仓库关注,<b>%d</b> 个赞,<b>%d</b> 次行为,<b>%d</b> 条权限记录,<b>%d</b> 张工单,<b>%d</b> 次评论,<b>%d</b> 个社交帐号,<b>%d</b> 个用户关注,<b>%d</b> 个镜像,<b>%d</b> 个版本发布,<b>%d</b> 个登录源,<b>%d</b> 个 Web 钩子,<b>%d</b> 个里程碑,<b>%d</b> 个标签,<b>%d</b> 个钩子任务,<b>%d</b> 个团队,<b>%d</b> 个更新任务,<b>%d</b> 个附件。
dashboard.operation_name = 操作名称
dashboard.operation_switch = 开关
dashboard.operation_run = 执行
dashboard.clean_unbind_oauth = 清理未绑定社交帐号
dashboard.delete_inactivate_accounts = 删除所有未激活帐户
dashboard.server_uptime = 服务运行时间
dashboard.current_goroutine = 当前 Goroutines 数量
dashboard.current_memory_usage = 当前内存使用量
dashboard.total_memory_allocated = 所有被分配的内存
dashboard.memory_obtained = 内存占用量
dashboard.pointer_lookup_times = 指针查找次数
dashboard.memory_allocate_times = 内存分配次数
dashboard.memory_free_times = 内存释放次数
dashboard.current_heap_usage = 当前 Heap 内存使用量
dashboard.heap_memory_obtained = Heap 内存占用量
dashboard.heap_memory_idle = Heap 内存空闲量
dashboard.heap_memory_in_use = 正在使用的 Heap 内存
dashboard.heap_memory_released = 被释放的 Heap 内存
dashboard.heap_objects = Heap 对象数量
dashboard.bootstrap_stack_usage = 启动 Stack 使用量
dashboard.stack_memory_obtained = 被分配的 Stack 内存
dashboard.mspan_structures_usage = MSpan 结构内存使用量
dashboard.mspan_structures_obtained = 被分配的 MSpan 结构内存
dashboard.mcache_structures_usage = MCache 结构内存使用量
dashboard.mcache_structures_obtained = 被分配的 MCache 结构内存
dashboard.profiling_bucket_hash_table_obtained = 被分配的剖析哈希表内存
dashboard.gc_metadata_obtained = 被分配的 GC 元数据内存
dashboard.other_system_allocation_obtained = 其它被分配的系统内存
dashboard.next_gc_recycle = 下次 GC 内存回收量
dashboard.last_gc_time = 距离上次 GC 时间
dashboard.total_gc_time = GC 执行时间总量
dashboard.total_gc_pause = GC 暂停时间总量
dashboard.last_gc_pause = 上次 GC 暂停时间
dashboard.gc_times = GC 执行次数
users.user_manage_panel = 用户管理面板
users.new_account = 创建新的帐户
users.name = 用户名
users.activated = 已激活
users.admin = 管理员
users.repos = 仓库数
users.created = 创建时间
users.edit = 编辑
users.auth_source = 认证源
users.local = 本地
users.auth_login_name = 认证登录名
users.update_profile_success = 该用户信息更新成功!
users.edit_account = 编辑用户信息
users.is_activated = 该用户已被激活
users.is_admin = 该用户具有管理员权限
users.update_profile = 更新用户信息
users.delete_account = 删除该用户
orgs.org_manage_panel = 组织管理面板
orgs.name = 组织名称
orgs.teams = 团队数
orgs.members = 成员数
repos.repo_manage_panel = 仓库管理界面
repos.owner = 所有者
repos.name = 仓库名称
repos.private = 私有库
repos.watches = 关注数
repos.stars = 点赞数
repos.issues = 工单数
auths.auth_manage_panel = 授权认证管理面板
auths.new = 添加新的认证源
auths.name = 认证名称
auths.type = 认证类型
auths.enabled = 已启用
auths.updated = 最后更新时间
auths.auth_type = 授权类型
auths.auth_name = 授权名称
auths.domain = 域名
auths.host = 主机地址
auths.port = 主机端口
auths.base_dn = Base DN
auths.attributes = Search Attributes
auths.filter = Search Filter
auths.ms_ad_sa = Ms Ad SA
auths.smtp_auth = SMTP 授权类型
auths.smtphost = SMTP 主机地址
auths.smtpport = SMTP 主机端口
auths.enable_tls = 启用 TLS 加密
auths.enable_auto_register = 允许授权用户自动注册
auths.tips = 帮助提示
auths.edit = 修改授权认证设置
auths.activated = 该授权认证已经启用
auths.update_success = 授权认证设置更新成功!
auths.update = 更新授权认证信息
auths.delete = 删除该授权认证
config.server_config = 服务器配置
config.app_name = 应用名称
config.app_ver = 应用版本
config.app_url = 应用 URL
config.domain = 应用域名
config.offline_mode = 离线模式
config.disable_router_log = 关闭路由日志
config.run_user = 运行用户
config.run_mode = 运行模式
config.repo_root_path = 仓库根目录
config.static_file_root_path = 静态文件根目录
config.log_file_root_path = 日志文件根目录
config.script_type = 脚本类型
config.reverse_auth_user = 反向代理认证
config.db_config = 数据库配置
config.db_type = 数据库类型
config.db_host = 主机地址
config.db_name = 数据库名称
config.db_user = 连接用户
config.db_ssl_mode = SSL 模式
config.db_ssl_mode_helper = (仅限 "postgres" 使用)
config.db_path = 数据库路径
config.db_path_helper = (仅限 "sqlite3" 使用)
config.service_config = 服务配置
config.register_email_confirm = 注册邮件确认
config.disable_register = 关闭注册功能
config.require_sign_in_view = 强制登录浏览
config.mail_notify = 邮件通知提醒
config.enable_cache_avatar = 开启缓存头像
config.active_code_lives = 激活用户链接有效期
config.reset_password_code_lives = 重置密码链接有效期
config.webhook_config = Web 钩子配置
config.task_interval = 任务周期
config.deliver_timeout = 推送超时
config.mailer_config = 邮件配置
config.mailer_enabled = 启用服务
config.mailer_name = 发送者名称
config.mailer_host = 邮件主机地址
config.mailer_user = 发送者帐号
config.oauth_config = 社交帐号配置
config.oauth_enabled = 启用服务
config.cache_config = Cache 配置
config.cache_adapter = Cache 适配器
config.cache_interval = Cache 周期
config.cache_conn = Cache 连接字符串
config.session_config = Session 配置
config.session_provider = Session 提供者
config.provider_config = 提供者配置
config.cookie_name = Cookie 名称
config.enable_set_cookie = 启用设置 Cookie
config.gc_interval_time = GC 周期
config.session_life_time = Session 生命周期
config.https_only = 仅限 HTTPS
config.cookie_life_time = Cookie 生命周期
config.session_hash_function = Session ID 哈希函数
config.session_hash_key = Session ID 哈希健值
config.picture_config = 图片配置
config.picture_service = 图片服务
config.disable_gravatar = 禁用 Gravatar 头像
config.log_config = 日志配置
config.log_mode = 日志模式
monitor.cron = Cron 任务
monitor.name = 任务名称
monitor.schedule = 任务安排
monitor.next = 下次执行时间
monitor.previous = 上次执行时间
monitor.execute_times = 执行次数
monitor.process = 运行中进程
monitor.desc = 进程描述
monitor.start = 开始时间
monitor.execute_time = 已执行时间
[action]
create_repo = 创建了仓库 <a href="/%s">%s</a>
commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a>
create_issue = 创建了工单 <a href="/%s/issues/%s">%s#%s</a>
comment_issue = 评论了工单 <a href="/%s/issues/%s">%s#%s</a>
[tool]
ago = 之前
from_now = 之后
now = 现在
1s = 1 秒%s
1m = 1 分钟%s
1h = 1 小时%s
1d = 1 天%s
1w = 1 周%s
1mon = 1 月%s
1y = 1 年%s
seconds = %d 秒%s
minutes = %d 分钟%s
hours = %d 小时%s
days = %d 天%s
weeks = %d 周%s
months = %d 月%s
years = %d 年%s
raw_seconds =
raw_minutes = 分钟

View File

@@ -1,8 +0,0 @@
[program:gogs]
user=git
command = /home/git/gogs/start.sh
directory = /home/git/gogs
autostart = true
stdout_logfile = /var/gogs.log
stderr_logfile = /var/gogs-error.log
environment=HOME="/home/git"

89
docker/README.md Normal file
View File

@@ -0,0 +1,89 @@
Docker
======
TOOLS ARE WRITTEN FOR TESTING AND TO SEE WHAT IT IS!
For this to work you will need the nifty docker tool [fig].
The most simple setup will look like this:
```sh
./assemble_blocks.sh docker_gogs w_db option_db_mysql
fig up
```
That's it. You have GoGS running in docker linked to a MySQL docker container.
Now visit http://localhost:3000/ and give details for the admin account an you're up and running.
How does it work
----------------
`./assemble_blocks.sh` will look in `blocks` for subdirectories.
In the subdirectories there are three relevant files: `Dockerfile`, `config` and `fig`.
`Dockerfile` will be copied to `docker/` (also means last `Dockerfile` wins).
The `config` file contains lines which will in the gogs docker container end up in `$GOGS_PATH/custom/config/app.ini` and by this gogs will be configured.
Here you can define things like the MySQL server for your database block.
The `fig` file will just be added to `fig.yml`, which is used by fig to manage your containers.
This inculdes container linking!
Just have a look at them and it will be clear how to write your own blocks.
Just some things
- all files (`Dockerfile`, `fig` and `config`) are optional
- the gogs block should always be the first block
Currently the blocks are designed that, the blocks that start with `docker` pull in the base docker image.
Then one block starting with `w` defines, what containers should be linked to the gogs container.
For every option in the `w` block you need to add an `option` container.
Example:
```sh
./assemble_blocks.sh docker_gogs w_db_cache option_db_mysql option_cache_redis
```
More sophisticated Example
--------------------------
Her is a more elaborated example
```sh
./assemble_blocks.sh docker_gogs w_db_cache_session option_db_postgresql option_cache_redis option_session_mysql
fig up
```
This will set up four containters and link them proberly. One for each of
- gogs
- database (postgresql)
- cache (redis)
- session (mysql)
WARNING: This will not work at the Moment! MySQL session is broken!
Remark
------
After you execute `assemble_blocks.sh` you should always trigger `fig build` to inculde the the new init script `init_gogs.sh` in the docker image.
If you want to use another GoGS docker file, but keep everything else the same, you can create a block, e.g. `docker_gogs_custom`, with only a `Dockerfile` and call
```sh
./assemble_blocks.sh docker_gogs_custom w_db option_database_mysql
```
This will pull in the `Dockerfile` from `docker_gogs` instead of the one from `docker_gogs`.
`Dockerfile`s for the `master` and `dev` branch are provided as `docker_gogs` and `docker_gogs_dev`
[fig]:http://www.fig.sh/

72
docker/assemble_blocks.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
blocks_dir=blocks
docker_dir=docker
template_dir=templates
docker_file=Dockerfile
gogs_config_file=conf.tmp
gogs_config=config
gogs_init_file=$docker_dir/init_gogs.sh
fig_file=fig.yml
fig_config=fig
gogs_init_template=$template_dir/init_gogs.sh.tpl
if [ "$#" == 0 ]; then
blocks=`ls $blocks_dir`
if [ -z "$blocks" ]; then
echo "No Blocks available in $blocks_dir"
else
echo "Available Blocks:"
for block in $blocks; do
echo " $block"
done
fi
exit 0
fi
for file in $gogs_config_file $fig_file; do
if [ -e $file ]; then
echo "Deleting $file"
rm $file
fi
done
for dir in $@; do
current_dir=$blocks_dir/$dir
if [ ! -d "$current_dir" ]; then
echo "$current_dir is not a directory"
exit 1
fi
if [ -e $current_dir/$docker_file ]; then
echo "Copying $current_dir/$docker_file to $docker_dir/$docker_file"
cp $current_dir/$docker_file $docker_dir/$docker_file
fi
if [ -e $current_dir/$gogs_config ]; then
echo "Adding $current_dir/$gogs_config to $gogs_config_file"
cat $current_dir/$gogs_config >> $gogs_config_file
echo "" >> $gogs_config_file
fi
if [ -e $current_dir/$fig_config ]; then
echo "Adding $current_dir/$fig_config to $fig_file"
cat $current_dir/fig >> $fig_file
echo "" >> $fig_file
fi
done
echo "Creating $gogs_init_file"
sed "/{{ CONFIG }}/{
r $gogs_config_file
d
}" $gogs_init_template > $gogs_init_file
if [ -e $gogs_config_file ]; then
echo "Removing temporary GoGS config"
rm $gogs_config_file
fi

View File

@@ -0,0 +1,52 @@
FROM ubuntu:14.04
# This part is taken from the official docker image --------------------
RUN apt-get update && apt-get install -y \
build-essential ca-certificates curl \
bzr git mercurial \
--no-install-recommends
ENV GOLANG_VERSION 1.3
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \
| tar -v -C /usr/src -xz
WORKDIR /usr/src/go
RUN cd src && ./make.bash --no-clean 2>&1
ENV PATH /usr/src/go/bin:$PATH
RUN mkdir -p /go/src
ENV GOPATH /go
ENV PATH /go/bin:$PATH
WORKDIR /go
# ----------------------------------------------------------------------
RUN useradd -m git
ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs
ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf
ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini
RUN go get -u -d github.com/gogits/gogs
# WORKDIR $GOGS_PATH
WORKDIR /go/src/github.com/gogits/gogs
RUN go build github.com/gogits/gogs
RUN chown -R git $GOGS_PATH
ADD init_gogs.sh /tmp/
RUN chown git /tmp/init_gogs.sh
RUN chmod +x /tmp/init_gogs.sh
USER git
ENV HOME /home/git
ENV USER git
ENV PATH $GOGS_PATH:$PATH
RUN git config --global user.name "GoGS"
ENTRYPOINT ["/tmp/init_gogs.sh"]
CMD ["gogs", "web"]

View File

@@ -0,0 +1,53 @@
FROM ubuntu:14.04
# This part is derived from the official docker image ------------------
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -qy \
build-essential ca-certificates curl \
bzr git mercurial \
--no-install-recommends
ENV GOLANG_VERSION 1.3
RUN curl -sSL http://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \
| tar -v -C /usr/src -xz
WORKDIR /usr/src/go
RUN cd src && ./make.bash --no-clean 2>&1
ENV PATH /usr/src/go/bin:$PATH
RUN mkdir -p /go/src
ENV GOPATH /go
ENV PATH /go/bin:$PATH
WORKDIR /go
# ----------------------------------------------------------------------
RUN useradd -m git
ENV GOGS_PATH $GOPATH/src/github.com/gogits/gogs
ENV GOGS_CUSTOM_CONF_PATH $GOGS_PATH/custom/conf
ENV GOGS_CUSTOM_CONF $GOGS_CUSTOM_CONF_PATH/app.ini
RUN git clone -b dev https://github.com/gogits/gogs.git $GOGS_PATH
# WORKDIR $GOGS_PATH
WORKDIR /go/src/github.com/gogits/gogs
RUN go get -d && go build
RUN chown -R git $GOGS_PATH
ADD init_gogs.sh /tmp/
RUN chown git /tmp/init_gogs.sh
RUN chmod +x /tmp/init_gogs.sh
USER git
ENV HOME /home/git
ENV USER git
ENV PATH $GOGS_PATH:$PATH
RUN git config --global user.name "GoGS"
ENTRYPOINT ["/tmp/init_gogs.sh"]
CMD ["gogs", "web"]

View File

@@ -0,0 +1,3 @@
[cache]
DB_TYPE = memcache
HOST = HOST = ${CACHE_1_PORT_11211_TCP_ADDR}:${CACHE_1_PORT_11211_TCP_PORT}

View File

@@ -0,0 +1,2 @@
cache:
image: sylvainlasnier/memcached:latest

View File

@@ -0,0 +1,3 @@
[cache]
DB_TYPE = redis
HOST = ${CACHE_1_PORT_6379_TCP_ADDR}:${CACHE_1_PORT_6379_TCP_PORT}

View File

@@ -0,0 +1,2 @@
cache:
image: redis:latest

View File

@@ -0,0 +1,6 @@
[database]
DB_TYPE = mysql
HOST = ${DB_1_PORT_3306_TCP_ADDR}:${DB_1_PORT_3306_TCP_PORT}
NAME = ${DB_1_ENV_MYSQL_DATABASE}
USER = ${DB_1_ENV_MYSQL_USER}
PASSWD = ${DB_1_ENV_MYSQL_PASSWORD}

View File

@@ -0,0 +1,7 @@
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: gogs
MYSQL_USER: gogs
MYSQL_PASSWORD: password

View File

@@ -0,0 +1,6 @@
[database]
DB_TYPE = postgres
HOST = ${DB_1_PORT_5432_TCP_ADDR}:${DB_1_PORT_5432_TCP_PORT}
NAME = ${DB_1_ENV_POSTGRESQL_DB}
USER = ${DB_1_ENV_POSTGRESQL_USER}
PASSWD = ${DB_1_ENV_POSTGRESQL_PASS}

View File

@@ -0,0 +1,6 @@
db:
image: wyaeld/postgres:9.3
environment:
POSTGRESQL_DB: gogs
POSTGRESQL_USER: gogs
POSTGRESQL_PASS: password

View File

@@ -0,0 +1,3 @@
[session]
PROVIDER = mysql
PROVIDER_CONFIG = ${SESSION_1_ENV_MYSQL_USER}:${SESSION_1_ENV_MYSQL_PASSWORD}@SESSION_1_PORT_3306_TCP_PROTO(${SESSION_1_PORT_3306_TCP_ADDR}:${SESSION_1_PORT_3306_TCP_PORT})/${SESSION_1_ENV_MYSQL_DATABASE}

View File

@@ -0,0 +1,7 @@
session:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: gogs_session
MYSQL_USER: gogs
MYSQL_PASSWORD: password

View File

@@ -0,0 +1,6 @@
gogs:
build: docker
links:
- cache
ports:
- "3000:3000"

View File

@@ -0,0 +1,7 @@
gogs:
build: docker
links:
- cache
- session
ports:
- "3000:3000"

6
docker/blocks/w_db/fig Normal file
View File

@@ -0,0 +1,6 @@
gogs:
build: docker
links:
- db
ports:
- "3000:3000"

View File

@@ -0,0 +1,7 @@
gogs:
build: docker
links:
- db
- cache
ports:
- "3000:3000"

View File

@@ -0,0 +1,8 @@
gogs:
build: docker
links:
- db
- cache
- session
ports:
- "3000:3000"

View File

@@ -0,0 +1,7 @@
gogs:
build: docker
links:
- db
- session
ports:
- "3000:3000"

4
docker/blocks/w_none/fig Normal file
View File

@@ -0,0 +1,4 @@
gogs:
build: docker
ports:
- "3000:3000"

View File

@@ -0,0 +1,6 @@
gogs:
build: docker
links:
- session
ports:
- "3000:3000"

View File

@@ -0,0 +1,12 @@
#!/bin/sh
if [ ! -d "$DIRECTORY" ]; then
mkdir -p $GOGS_CUSTOM_CONF_PATH
echo "
{{ CONFIG }}
" >> $GOGS_CUSTOM_CONF
fi
exec "$@"

View File

@@ -1,59 +0,0 @@
### Gogs Install With Docker
#### Gogs With MySQL
Deply gogs in [Docker](http://www.docker.io/) is just as easy as eating a pie, what you do is just open the `dockerfiles/build.sh` file, replace the confis:
```
MYSQL_PASSWORD="YOUR_MYSQL_PASSWORD"
MYSQL_RUN_NAME="YOUR_MYSQL_RUN_NAME"
HOST_PORT="YOUR_HOST_PORT"
```
And run:
```
cd dockerfiles
./build.sh
```
The build might take some time, just be paient. After it finishes, you will receive the message:
```
Now we have the MySQL image(running) and gogs image, use the follow command to start gogs service( the content might be different, according to your own configs):
docker run -i -t --link gogs_mysql:db -p 3333:3000 gogs/gogits
```
Just follow the message, run:
```
docker run -i -t --link gogs_mysql:db -p 3333:3000 gogs/gogits
```
Now we have gogs running! Open the browser and navigate to:
```
http://YOUR_HOST_IP:YOUR_HOST_PORT
```
Let's 'gogs'!
#### Gogs With PostgreSQL
Installing Gogs with PostgreSQL is nearly the same with installing it with MySQL. What you do is just change the DB_TYPE in build.sh to 'postgres'.
#### Gogs, MySQL With Redis
#### Gogs, MySQL With Memcached
#### Gogs, PostgreSQL With Redis
#### Gogs, PostgreSQL With Memcached

View File

@@ -1,29 +0,0 @@
# Configs of the docker images, you might have specify your own configs here.
# type of database, support 'mysql' and 'postgres'
DB_TYPE="postgres"
DB_PASSWORD="YOUR_DB_PASSWORD"
DB_RUN_NAME="YOUR_DB_RUN_NAME"
HOST_PORT="YOUR_HOST_PORT"
# Replace the database root password in database image Dockerfile.
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/$DB_TYPE/Dockerfile
# Replace the database root password in gogits image deploy.sh file.
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/gogits/deploy.sh
# Replace the database type in gogits image deploy.sh file.
sed -i "s/THE_DB_TYPE/$DB_TYPE/g" images/gogits/deploy.sh
# Build the database image
cd images/$DB_TYPE
docker build -t gogs/$DB_TYPE .
#
## Build the gogits image
cd ../gogits
docker build -t gogs/gogits .
#
## Run MySQL image with name
docker run -d --name $DB_RUN_NAME gogs/$DB_TYPE
#
## Run gogits image and link it to the database image
echo "Now we have the $DB_TYPE image(running) and gogs image, use the follow command to start gogs service:"
echo -e "\033[33m docker run -i -t --link $DB_RUN_NAME:db -p $HOST_PORT:3000 gogs/gogits \033[0m"

View File

@@ -1,29 +0,0 @@
# Configs of the docker images, you might have specify your own configs here.
# type of database, support 'mysql' and 'postgres'
DB_TYPE="postgres"
DB_PASSWORD="YOUR_DB_PASSWORD"
DB_RUN_NAME="YOUR_DB_RUN_NAME"
HOST_PORT="YOUR_HOST_PORT"
# Replace the database root password in database image Dockerfile.
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/$DB_TYPE/Dockerfile
# Replace the database root password in gogits image deploy.sh file.
sed -i "s/THE_DB_PASSWORD/$DB_PASSWORD/g" images/gogits/deploy.sh
# Replace the database type in gogits image deploy.sh file.
sed -i "s/THE_DB_TYPE/$DB_TYPE/g" images/gogits/deploy.sh
# Build the database image
cd images/$DB_TYPE
docker build -t gogs/$DB_TYPE .
#
## Build the gogits image
cd ../gogits
docker build -t gogs/gogits .
#
## Run MySQL image with name
docker run -d --name $DB_RUN_NAME gogs/$DB_TYPE
#
## Run gogits image and link it to the database image
echo "Now we have the $DB_TYPE image(running) and gogs image, use the follow command to start gogs service:"
echo -e "\033[33m docker run -i -t --link $DB_RUN_NAME:db -p $HOST_PORT:3000 gogs/gogits \033[0m"

View File

@@ -1,33 +0,0 @@
FROM stackbrew/ubuntu:13.10
MAINTAINER Meaglith Ma <genedna@gmail.com> (@genedna)
ENV DEBIAN_FRONTEND noninteractive
RUN echo "deb http://mirrors.aliyun.com/ubuntu/ saucy main restricted" > /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy-updates main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy universe" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy-updates universe" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy multiverse" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy-updates multiverse" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy-backports main restricted universe multiverse" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy-security main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy-security universe" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ saucy-security multiverse" >> /etc/apt/sources.list
RUN mkdir -p /go
ENV PATH /usr/local/go/bin:/go/bin:$PATH
ENV GOROOT /usr/local/go
ENV GOPATH /go
RUN apt-get update && apt-get install --yes --force-yes curl git mercurial zip wget ca-certificates build-essential
RUN curl -s http://docker.u.qiniudn.com/go1.2.1.src.tar.gz | tar -v -C /usr/local -xz
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1
# You may need a proxy, if github is very slow.
#RUN http_proxy=106.187.38.45:3128 go get -u github.com/gogits/gogs
RUN go get -u github.com/gogits/gogs
RUN cd $GOPATH/src/github.com/gogits/gogs && go build
# Clean all the unused packages
RUN apt-get autoremove -y
RUN apt-get clean all
# Add the deploy script to the docker image and assign execution permission to it.
ADD ./deploy.sh /
RUN chmod +x deploy.sh
EXPOSE 3000
CMD /deploy.sh

View File

@@ -1,35 +0,0 @@
# deploy.sh in gogits image, replace the configs and run gogs
## Replace the database password
DB_TYPE=THE_DB_TYPE
DB_PASSWORD=THE_DB_PASSWORD
DB_ALIAS=DB
DB_TYPE_LINE=`awk '$0 ~ str{print NR}' str="DB_TYPE = mysql" $GOPATH/src/github.com/gogits/gogs/conf/app.ini`
DB_PASSWORD_LINE=`awk '$0 ~ str{print NR+1}' str="USER = root" $GOPATH/src/github.com/gogits/gogs/conf/app.ini`
sed -i "${DB_TYPE_LINE}s/.*$/DB_TYPE = $DB_TYPE/g" $GOPATH/src/github.com/gogits/gogs/conf/app.ini
sed -i "${DB_PASSWORD_LINE}s/.*$/PASSWD = $DB_PASSWORD/g" $GOPATH/src/github.com/gogits/gogs/conf/app.ini
if [ $DB_TYPE = "postgres" ]
then
# Add the postgres in gogs image.
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
apt-get update
apt-get -y -q install python-software-properties software-properties-common
apt-get -y -q install postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3
fi
## Replace the database address and port
# When using --link in docker run, the database image's info looks like this:
# DB_PORT=tcp://172.17.0.2:3306
# DB_PORT_3306_TCP_PORT=3306
# DB_PORT_3306_TCP_PROTO=tcp
# DB_PORT_3306_TCP_ADDR=172.17.0.2
#sed -i "/HOST = 127.0.0.1:3306/c\HOST = $DB_PORT_3306_TCP_ADDR:$DB_PORT_3306_TCP_PORT" $GOPATH/src/github.com/gogits/gogs/conf/app.ini
sed -i "/HOST = 127.0.0.1:3306/c\HOST = `echo $DB_PORT | cut -d '/' -f 3`" $GOPATH/src/github.com/gogits/gogs/conf/app.ini
cd $GOPATH/src/github.com/gogits/gogs/
# The sudo is a must here, or the go within docker container won't get the current user by os.Getenv("USERNAME")
sudo ./gogs web

View File

@@ -1,13 +0,0 @@
# Configs
MYSQL_PASSWORD="kuajie8402"
MYSQL_RUN_NAME="gogs_mysql"
typeset -u MYSQL_ALIAS
MYSQL_ALIAS="db"
HOST_PORT="3000"
## Run MySQL image with name
docker run -d --name $MYSQL_RUN_NAME gogs/mysql
#
## Run gogits image and link it to the MySQL image
docker run --link $MYSQL_RUN_NAME:$MYSQL_ALIAS -p $HOST_PORT:3000 gogs/gogits

View File

@@ -1,2 +1,2 @@
DROP DATABASE gogs;
CREATE DATABASE IF NOT EXISTS gogs CHARACTER SET utf8 COLLATE utf8_general_ci;
DROP DATABASE IF EXISTS gogs;
CREATE DATABASE IF NOT EXISTS gogs CHARACTER SET utf8 COLLATE utf8_general_ci;

26
etc/supervisord.conf Normal file
View File

@@ -0,0 +1,26 @@
[unix_http_server]
file=/tmp/supervisor.sock ; path to your socket file
[supervisord]
logfile=log/supervisord.log ; supervisord log file
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
loglevel=warn ; info, debug, warn, trace
pidfile=/tmp/supervisord.pid ; pidfile location
nodaemon=false ; run supervisord as a daemon
minfds=1024 ; number of startup file descriptors
minprocs=200 ; number of process descriptors
user=root ; default user
childlogdir=log
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[program:gogs]
command = /root/Developer/gopath/src/github.com/gogits/gogs/start.sh ; here must be the real url, not ~ or $GOROOT like
autostart = true
stdout_logfile = log/supervisor-gogs-stderr.log
stderr_logfile = log/supervisor-gogs-error.log

20
gogs.go
View File

@@ -4,7 +4,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language.
// Gogs(Go Git Service) is a painless self-hosted Git Service written in Go.
package main
import (
@@ -13,17 +13,15 @@ import (
"github.com/codegangsta/cli"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/cmd"
"github.com/gogits/gogs/modules/setting"
)
// Test that go1.2 tag above is included in builds. main.go refers to this definition.
const go12tag = true
const APP_VER = "0.3.0.0421 Alpha"
const APP_VER = "0.5.2.0917 Beta"
func init() {
base.AppVer = APP_VER
runtime.GOMAXPROCS(runtime.NumCPU())
setting.AppVer = APP_VER
}
func main() {
@@ -32,9 +30,11 @@ func main() {
app.Usage = "Go Git Service"
app.Version = APP_VER
app.Commands = []cli.Command{
CmdWeb,
CmdServ,
CmdUpdate,
cmd.CmdWeb,
cmd.CmdServ,
cmd.CmdUpdate,
cmd.CmdFix,
cmd.CmdDump,
}
app.Flags = append(app.Flags, []cli.Flag{}...)
app.Run(os.Args)

View File

@@ -11,26 +11,27 @@ import (
"github.com/go-xorm/xorm"
)
// Access types.
type AccessType int
const (
AU_READABLE = iota + 1
AU_WRITABLE
READABLE AccessType = iota + 1
WRITABLE
)
// Access represents the accessibility of user to repository.
type Access struct {
Id int64
UserName string `xorm:"unique(s)"`
RepoName string `xorm:"unique(s)"` // <user name>/<repo name>
Mode int `xorm:"unique(s)"`
Created time.Time `xorm:"created"`
UserName string `xorm:"UNIQUE(s)"`
RepoName string `xorm:"UNIQUE(s)"` // <user name>/<repo name>
Mode AccessType `xorm:"UNIQUE(s)"`
Created time.Time `xorm:"CREATED"`
}
// AddAccess adds new access record.
func AddAccess(access *Access) error {
access.UserName = strings.ToLower(access.UserName)
access.RepoName = strings.ToLower(access.RepoName)
_, err := orm.Insert(access)
_, err := x.Insert(access)
return err
}
@@ -38,7 +39,13 @@ func AddAccess(access *Access) error {
func UpdateAccess(access *Access) error {
access.UserName = strings.ToLower(access.UserName)
access.RepoName = strings.ToLower(access.RepoName)
_, err := orm.Id(access.Id).Update(access)
_, err := x.Id(access.Id).Update(access)
return err
}
// DeleteAccess deletes access record.
func DeleteAccess(access *Access) error {
_, err := x.Delete(access)
return err
}
@@ -52,12 +59,16 @@ func UpdateAccessWithSession(sess *xorm.Session, access *Access) error {
}
// HasAccess returns true if someone can read or write to given repository.
func HasAccess(userName, repoName string, mode int) (bool, error) {
// The repoName should be in format <username>/<reponame>.
func HasAccess(uname, repoName string, mode AccessType) (bool, error) {
if len(repoName) == 0 {
return false, nil
}
access := &Access{
UserName: strings.ToLower(userName),
UserName: strings.ToLower(uname),
RepoName: strings.ToLower(repoName),
}
has, err := orm.Get(access)
has, err := x.Get(access)
if err != nil {
return false, err
} else if !has {

View File

@@ -6,46 +6,69 @@ package models
import (
"encoding/json"
"errors"
"fmt"
"path"
"regexp"
"strings"
"time"
"github.com/gogits/git"
"unicode"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
// Operation types of user action.
type ActionType int
const (
OP_CREATE_REPO = iota + 1
OP_DELETE_REPO
OP_STAR_REPO
OP_FOLLOW_REPO
OP_COMMIT_REPO
OP_CREATE_ISSUE
OP_PULL_REQUEST
OP_TRANSFER_REPO
OP_PUSH_TAG
CREATE_REPO ActionType = iota + 1 // 1
DELETE_REPO // 2
STAR_REPO // 3
FOLLOW_REPO // 4
COMMIT_REPO // 5
CREATE_ISSUE // 6
PULL_REQUEST // 7
TRANSFER_REPO // 8
PUSH_TAG // 9
COMMENT_ISSUE // 10
)
var (
ErrNotImplemented = errors.New("Not implemented yet")
)
var (
// Same as Github. See https://help.github.com/articles/closing-issues-via-commit-messages
IssueKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
IssueKeywordsPat *regexp.Regexp
)
func init() {
IssueKeywordsPat = regexp.MustCompile(fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(IssueKeywords, "|")))
}
// Action represents user operation type and other information to repository.,
// it implemented interface base.Actioner so that can be used in template render.
type Action struct {
Id int64
UserId int64 // Receiver user id.
OpType int // Operations: CREATE DELETE STAR ...
ActUserId int64 // Action user id.
ActUserName string // Action user name.
ActEmail string
RepoId int64
RepoName string
RefName string
Content string `xorm:"TEXT"`
Created time.Time `xorm:"created"`
Id int64
UserId int64 // Receiver user id.
OpType ActionType
ActUserId int64 // Action user id.
ActUserName string // Action user name.
ActEmail string
RepoId int64
RepoUserName string
RepoName string
RefName string
IsPrivate bool `xorm:"NOT NULL DEFAULT false"`
Content string `xorm:"TEXT"`
Created time.Time `xorm:"created"`
}
func (a Action) GetOpType() int {
return a.OpType
return int(a.OpType)
}
func (a Action) GetActUserName() string {
@@ -56,10 +79,18 @@ func (a Action) GetActEmail() string {
return a.ActEmail
}
func (a Action) GetRepoUserName() string {
return a.RepoUserName
}
func (a Action) GetRepoName() string {
return a.RepoName
}
func (a Action) GetRepoLink() string {
return path.Join(a.RepoUserName, a.RepoName)
}
func (a Action) GetBranch() string {
return a.RefName
}
@@ -68,80 +99,274 @@ func (a Action) GetContent() string {
return a.Content
}
// CommitRepoAction adds new action for committing repository.
func CommitRepoAction(userId int64, userName, actEmail string,
repoId int64, repoName string, refName string, commit *base.PushCommits) error {
// log.Trace("action.CommitRepoAction(start): %d/%s", userId, repoName)
func (a Action) GetCreate() time.Time {
return a.Created
}
opType := OP_COMMIT_REPO
func (a Action) GetIssueInfos() []string {
return strings.SplitN(a.Content, "|", 2)
}
func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, commits []*base.PushCommit) error {
for _, c := range commits {
refs := IssueKeywordsPat.FindAllString(c.Message, -1)
for _, ref := range refs {
ref := ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, func(c rune) bool {
return !unicode.IsDigit(c)
})
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s/%s%s", repoUserName, repoName, ref)
} else if strings.Contains(ref, "/") == false {
// We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
if err != nil {
return err
}
url := fmt.Sprintf("/%s/%s/commit/%s", repoUserName, repoName, c.Sha1)
message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
if _, err = CreateComment(userId, issue.RepoId, issue.Id, 0, 0, COMMIT, message, nil); err != nil {
return err
}
if issue.RepoId == repoId {
if issue.IsClosed {
continue
}
issue.IsClosed = true
if err = UpdateIssue(issue); err != nil {
return err
}
if err = ChangeMilestoneIssueStats(issue); err != nil {
return err
}
// If commit happened in the referenced repository, it means the issue can be closed.
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, CLOSE, "", nil); err != nil {
return err
}
}
}
}
return nil
}
// CommitRepoAction adds new action for committing repository.
func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
repoId int64, repoUserName, repoName string, refFullName string, commit *base.PushCommits, oldCommitId string, newCommitId string) error {
opType := COMMIT_REPO
// Check it's tag push or branch.
if strings.HasPrefix(refName, "refs/tags/") {
opType = OP_PUSH_TAG
if strings.HasPrefix(refFullName, "refs/tags/") {
opType = PUSH_TAG
commit = &base.PushCommits{}
}
refName = git.RefEndName(refName)
refName := git.RefEndName(refFullName)
bs, err := json.Marshal(commit)
if err != nil {
log.Error("action.CommitRepoAction(json): %d/%s", userId, repoName)
return err
}
if err = NotifyWatchers(&Action{ActUserId: userId, ActUserName: userName, ActEmail: actEmail,
OpType: opType, Content: string(bs), RepoId: repoId, RepoName: repoName, RefName: refName}); err != nil {
log.Error("action.CommitRepoAction(notify watchers): %d/%s", userId, repoName)
return err
return errors.New("action.CommitRepoAction(json): " + err.Error())
}
// Change repository bare status and update last updated time.
repo, err := GetRepositoryByName(userId, repoName)
repo, err := GetRepositoryByName(repoUserId, repoName)
if err != nil {
log.Error("action.CommitRepoAction(GetRepositoryByName): %d/%s", userId, repoName)
return err
return errors.New("action.CommitRepoAction(GetRepositoryByName): " + err.Error())
}
repo.IsBare = false
if err = UpdateRepository(repo); err != nil {
log.Error("action.CommitRepoAction(UpdateRepository): %d/%s", userId, repoName)
return err
return errors.New("action.CommitRepoAction(UpdateRepository): " + err.Error())
}
log.Trace("action.CommitRepoAction(end): %d/%s", userId, repoName)
err = updateIssuesCommit(userId, repoId, repoUserName, repoName, commit.Commits)
if err != nil {
log.Debug("action.CommitRepoAction(updateIssuesCommit): ", err)
}
if err = NotifyWatchers(&Action{ActUserId: userId, ActUserName: userName, ActEmail: actEmail,
OpType: opType, Content: string(bs), RepoId: repoId, RepoUserName: repoUserName,
RepoName: repoName, RefName: refName,
IsPrivate: repo.IsPrivate}); err != nil {
return errors.New("action.CommitRepoAction(NotifyWatchers): " + err.Error())
}
//qlog.Info("action.CommitRepoAction(end): %d/%s", repoUserId, repoName)
// New push event hook.
if err := repo.GetOwner(); err != nil {
return errors.New("action.CommitRepoAction(GetOwner): " + err.Error())
}
ws, err := GetActiveWebhooksByRepoId(repoId)
if err != nil {
return errors.New("action.CommitRepoAction(GetActiveWebhooksByRepoId): " + err.Error())
}
// check if repo belongs to org and append additional webhooks
if repo.Owner.IsOrganization() {
// get hooks for org
orgws, err := GetActiveWebhooksByOrgId(repo.OwnerId)
if err != nil {
return errors.New("action.CommitRepoAction(GetActiveWebhooksByOrgId): " + err.Error())
}
ws = append(ws, orgws...)
}
if len(ws) == 0 {
return nil
}
repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
compareUrl := ""
// if not the first commit, set the compareUrl
if !strings.HasPrefix(oldCommitId, "0000000") {
compareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId)
}
pusher_email, pusher_name := "", ""
pusher, err := GetUserByName(userName)
if err == nil {
pusher_email = pusher.Email
pusher_name = pusher.GetFullNameFallback()
}
commits := make([]*PayloadCommit, len(commit.Commits))
for i, cmt := range commit.Commits {
author_username := ""
author, err := GetUserByEmail(cmt.AuthorEmail)
if err == nil {
author_username = author.Name
}
commits[i] = &PayloadCommit{
Id: cmt.Sha1,
Message: cmt.Message,
Url: fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1),
Author: &PayloadAuthor{
Name: cmt.AuthorName,
Email: cmt.AuthorEmail,
UserName: author_username,
},
}
}
p := &Payload{
Ref: refFullName,
Commits: commits,
Repo: &PayloadRepo{
Id: repo.Id,
Name: repo.LowerName,
Url: repoLink,
Description: repo.Description,
Website: repo.Website,
Watchers: repo.NumWatches,
Owner: &PayloadAuthor{
Name: repo.Owner.GetFullNameFallback(),
Email: repo.Owner.Email,
UserName: repo.Owner.Name,
},
Private: repo.IsPrivate,
},
Pusher: &PayloadAuthor{
Name: pusher_name,
Email: pusher_email,
UserName: userName,
},
Before: oldCommitId,
After: newCommitId,
CompareUrl: compareUrl,
}
for _, w := range ws {
w.GetEvent()
if !w.HasPushEvent() {
continue
}
switch w.HookTaskType {
case SLACK:
{
s, err := GetSlackPayload(p, w.Meta)
if err != nil {
return errors.New("action.GetSlackPayload: " + err.Error())
}
CreateHookTask(&HookTask{
Type: w.HookTaskType,
Url: w.Url,
BasePayload: s,
ContentType: w.ContentType,
IsSsl: w.IsSsl,
})
}
default:
{
p.Secret = w.Secret
CreateHookTask(&HookTask{
Type: w.HookTaskType,
Url: w.Url,
BasePayload: p,
ContentType: w.ContentType,
IsSsl: w.IsSsl,
})
}
}
}
go DeliverHooks()
return nil
}
// NewRepoAction adds new action for creating repository.
func NewRepoAction(user *User, repo *Repository) (err error) {
if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email,
OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoName: repo.Name}); err != nil {
log.Error("action.NewRepoAction(notify watchers): %d/%s", user.Id, repo.Name)
func NewRepoAction(u *User, repo *Repository) (err error) {
if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email,
OpType: CREATE_REPO, RepoId: repo.Id, RepoUserName: repo.Owner.Name, RepoName: repo.Name,
IsPrivate: repo.IsPrivate}); err != nil {
log.Error(4, "NotifyWatchers: %d/%s", u.Id, repo.Name)
return err
}
log.Trace("action.NewRepoAction: %s/%s", user.LowerName, repo.LowerName)
log.Trace("action.NewRepoAction: %s/%s", u.Name, repo.Name)
return err
}
// TransferRepoAction adds new action for transfering repository.
func TransferRepoAction(user, newUser *User, repo *Repository) (err error) {
if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email,
OpType: OP_TRANSFER_REPO, RepoId: repo.Id, RepoName: repo.Name, Content: newUser.Name}); err != nil {
log.Error("action.TransferRepoAction(notify watchers): %d/%s", user.Id, repo.Name)
func TransferRepoAction(u, newUser *User, repo *Repository) (err error) {
if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email,
OpType: TRANSFER_REPO, RepoId: repo.Id, RepoName: repo.Name, Content: newUser.Name,
IsPrivate: repo.IsPrivate}); err != nil {
log.Error(4, "NotifyWatchers: %d/%s", u.Id, repo.Name)
return err
}
log.Trace("action.TransferRepoAction: %s/%s", user.LowerName, repo.LowerName)
log.Trace("action.TransferRepoAction: %s/%s", u.Name, repo.Name)
return err
}
// GetFeeds returns action list of given user in given context.
func GetFeeds(userid, offset int64, isProfile bool) ([]Action, error) {
actions := make([]Action, 0, 20)
sess := orm.Limit(20, int(offset)).Desc("id").Where("user_id=?", userid)
func GetFeeds(uid, offset int64, isProfile bool) ([]*Action, error) {
actions := make([]*Action, 0, 20)
sess := x.Limit(20, int(offset)).Desc("id").Where("user_id=?", uid)
if isProfile {
sess.And("act_user_id=?", userid)
} else {
sess.And("act_user_id!=?", userid)
sess.Where("is_private=?", false).And("act_user_id=?", uid)
}
err := sess.Find(&actions)
return actions, err

View File

@@ -6,15 +6,18 @@ package models
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"strings"
"time"
"github.com/gogits/git"
"github.com/Unknwon/com"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
)
// Diff line types.
@@ -49,6 +52,7 @@ type DiffSection struct {
type DiffFile struct {
Name string
Index int
Addition, Deletion int
Type int
IsBin bool
@@ -66,7 +70,7 @@ func (diff *Diff) NumFiles() int {
const DIFF_HEAD = "diff --git "
func ParsePatch(reader io.Reader) (*Diff, error) {
func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff, error) {
scanner := bufio.NewScanner(reader)
var (
curFile *DiffFile
@@ -75,6 +79,7 @@ func ParsePatch(reader io.Reader) (*Diff, error) {
}
leftLine, rightLine int
isTooLong bool
)
diff := &Diff{Files: make([]*DiffFile, 0)}
@@ -86,18 +91,19 @@ func ParsePatch(reader io.Reader) (*Diff, error) {
continue
}
i = i + 1
// Diff data too large.
if i == 5000 {
log.Warn("Diff data too large")
return &Diff{}, nil
}
if line == "" {
continue
}
i = i + 1
// Diff data too large, we only show the first about maxlines lines
if i == maxlines {
isTooLong = true
log.Warn("Diff data too large")
//return &Diff{}, nil
}
switch {
case line[0] == ' ':
diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine}
@@ -106,6 +112,10 @@ func ParsePatch(reader io.Reader) (*Diff, error) {
curSection.Lines = append(curSection.Lines, diffLine)
continue
case line[0] == '@':
if isTooLong {
return diff, nil
}
curSection = &DiffSection{}
curFile.Sections = append(curFile.Sections, curSection)
ss := strings.Split(line, "@@")
@@ -114,8 +124,8 @@ func ParsePatch(reader io.Reader) (*Diff, error) {
// Parse line number.
ranges := strings.Split(ss[len(ss)-2][1:], " ")
leftLine, _ = base.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int()
rightLine, _ = base.StrTo(strings.Split(ranges[1], ",")[0]).Int()
leftLine, _ = com.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int()
rightLine, _ = com.StrTo(strings.Split(ranges[1], ",")[0]).Int()
continue
case line[0] == '+':
curFile.Addition++
@@ -139,11 +149,16 @@ func ParsePatch(reader io.Reader) (*Diff, error) {
// Get new file.
if strings.HasPrefix(line, DIFF_HEAD) {
if isTooLong {
return diff, nil
}
fs := strings.Split(line[len(DIFF_HEAD):], " ")
a := fs[0]
curFile = &DiffFile{
Name: a[strings.Index(a, "/")+1:],
Index: len(diff.Files) + 1,
Type: DIFF_FILE_CHANGE,
Sections: make([]*DiffSection, 0, 10),
}
@@ -169,44 +184,63 @@ func ParsePatch(reader io.Reader) (*Diff, error) {
return diff, nil
}
func GetDiff(repoPath, commitid string) (*Diff, error) {
func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string, maxlines int) (*Diff, error) {
repo, err := git.OpenRepository(repoPath)
if err != nil {
return nil, err
}
commit, err := repo.GetCommit(commitid)
commit, err := repo.GetCommit(afterCommitId)
if err != nil {
return nil, err
}
// First commit of repository.
if commit.ParentCount() == 0 {
rd, wr := io.Pipe()
go func() {
cmd := exec.Command("git", "show", commitid)
cmd.Dir = repoPath
cmd.Stdout = wr
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Run()
wr.Close()
}()
defer rd.Close()
return ParsePatch(rd)
}
rd, wr := io.Pipe()
var cmd *exec.Cmd
// if "after" commit given
if beforeCommitId == "" {
// First commit of repository.
if commit.ParentCount() == 0 {
cmd = exec.Command("git", "show", afterCommitId)
} else {
c, _ := commit.Parent(0)
cmd = exec.Command("git", "diff", c.Id.String(), afterCommitId)
}
} else {
cmd = exec.Command("git", "diff", beforeCommitId, afterCommitId)
}
cmd.Dir = repoPath
cmd.Stdout = wr
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
done := make(chan error)
go func() {
c, _ := commit.Parent(0)
cmd := exec.Command("git", "diff", c.Id.String(), commitid)
cmd.Dir = repoPath
cmd.Stdout = wr
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Run()
cmd.Start()
done <- cmd.Wait()
wr.Close()
}()
defer rd.Close()
return ParsePatch(rd)
desc := fmt.Sprintf("GetDiffRange(%s)", repoPath)
pid := process.Add(desc, cmd)
go func() {
// In case process became zombie.
select {
case <-time.After(5 * time.Minute):
if errKill := process.Kill(pid); errKill != nil {
log.Error(4, "git_diff.ParsePatch(Kill): %v", err)
}
<-done
// return "", ErrExecTimeout.Error(), ErrExecTimeout
case err = <-done:
process.Remove(pid)
}
}()
return ParsePatch(pid, maxlines, cmd, rd)
}
func GetDiffCommit(repoPath, commitId string, maxlines int) (*Diff, error) {
return GetDiffRange(repoPath, "", commitId, maxlines)
}

File diff suppressed because it is too large Load Diff

364
models/login.go Normal file
View File

@@ -0,0 +1,364 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"net/smtp"
"strings"
"time"
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/auth/ldap"
"github.com/gogits/gogs/modules/log"
)
type LoginType int
const (
NOTYPE LoginType = iota
PLAIN
LDAP
SMTP
)
var (
ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
ErrAuthenticationNotExist = errors.New("Authentication does not exist")
ErrAuthenticationUserUsed = errors.New("Authentication has been used by some users")
)
var LoginTypes = map[LoginType]string{
LDAP: "LDAP",
SMTP: "SMTP",
}
// Ensure structs implmented interface.
var (
_ core.Conversion = &LDAPConfig{}
_ core.Conversion = &SMTPConfig{}
)
type LDAPConfig struct {
ldap.Ldapsource
}
func (cfg *LDAPConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, &cfg.Ldapsource)
}
func (cfg *LDAPConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg.Ldapsource)
}
type SMTPConfig struct {
Auth string
Host string
Port int
TLS bool
}
func (cfg *SMTPConfig) FromDB(bs []byte) error {
return json.Unmarshal(bs, cfg)
}
func (cfg *SMTPConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}
type LoginSource struct {
Id int64
Type LoginType
Name string `xorm:"UNIQUE"`
IsActived bool `xorm:"NOT NULL DEFAULT false"`
Cfg core.Conversion `xorm:"TEXT"`
AllowAutoRegister bool `xorm:"NOT NULL DEFAULT false"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
}
func (source *LoginSource) TypeString() string {
return LoginTypes[source.Type]
}
func (source *LoginSource) LDAP() *LDAPConfig {
return source.Cfg.(*LDAPConfig)
}
func (source *LoginSource) SMTP() *SMTPConfig {
return source.Cfg.(*SMTPConfig)
}
func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
if colName == "type" {
ty := (*val).(int64)
switch LoginType(ty) {
case LDAP:
source.Cfg = new(LDAPConfig)
case SMTP:
source.Cfg = new(SMTPConfig)
}
}
}
func CreateSource(source *LoginSource) error {
_, err := x.Insert(source)
return err
}
func GetAuths() ([]*LoginSource, error) {
var auths = make([]*LoginSource, 0, 5)
err := x.Find(&auths)
return auths, err
}
func GetLoginSourceById(id int64) (*LoginSource, error) {
source := new(LoginSource)
has, err := x.Id(id).Get(source)
if err != nil {
return nil, err
} else if !has {
return nil, ErrAuthenticationNotExist
}
return source, nil
}
func UpdateSource(source *LoginSource) error {
_, err := x.Id(source.Id).AllCols().Update(source)
return err
}
func DelLoginSource(source *LoginSource) error {
cnt, err := x.Count(&User{LoginSource: source.Id})
if err != nil {
return err
}
if cnt > 0 {
return ErrAuthenticationUserUsed
}
_, err = x.Id(source.Id).Delete(&LoginSource{})
return err
}
// UserSignIn validates user name and password.
func UserSignIn(uname, passwd string) (*User, error) {
var u *User
if strings.Contains(uname, "@") {
u = &User{Email: uname}
} else {
u = &User{LowerName: strings.ToLower(uname)}
}
has, err := x.Get(u)
if err != nil {
return nil, err
}
if u.LoginType == NOTYPE {
if has {
u.LoginType = PLAIN
} else {
return nil, ErrUserNotExist
}
}
// For plain login, user must exist to reach this line.
// Now verify password.
if u.LoginType == PLAIN {
newUser := &User{Passwd: passwd, Salt: u.Salt}
newUser.EncodePasswd()
if u.Passwd != newUser.Passwd {
return nil, ErrUserNotExist
}
return u, nil
} else {
if !has {
var sources []LoginSource
if err = x.UseBool().Find(&sources,
&LoginSource{IsActived: true, AllowAutoRegister: true}); err != nil {
return nil, err
}
for _, source := range sources {
if source.Type == LDAP {
u, err := LoginUserLdapSource(nil, uname, passwd,
source.Id, source.Cfg.(*LDAPConfig), true)
if err == nil {
return u, nil
}
log.Warn("Fail to login(%s) by LDAP(%s): %v", uname, source.Name, err)
} else if source.Type == SMTP {
u, err := LoginUserSMTPSource(nil, uname, passwd,
source.Id, source.Cfg.(*SMTPConfig), true)
if err == nil {
return u, nil
}
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
}
}
return nil, ErrUserNotExist
}
var source LoginSource
hasSource, err := x.Id(u.LoginSource).Get(&source)
if err != nil {
return nil, err
} else if !hasSource {
return nil, ErrLoginSourceNotExist
} else if !source.IsActived {
return nil, ErrLoginSourceNotActived
}
switch u.LoginType {
case LDAP:
return LoginUserLdapSource(u, u.LoginName, passwd,
source.Id, source.Cfg.(*LDAPConfig), false)
case SMTP:
return LoginUserSMTPSource(u, u.LoginName, passwd,
source.Id, source.Cfg.(*SMTPConfig), false)
}
return nil, ErrUnsupportedLoginType
}
}
// Query if name/passwd can login against the LDAP direcotry pool
// Create a local user if success
// Return the same LoginUserPlain semantic
func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAPConfig, autoRegister bool) (*User, error) {
mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
if !logged {
// user not in LDAP, do nothing
return nil, ErrUserNotExist
}
if !autoRegister {
return u, nil
}
// fake a local user creation
u = &User{
LowerName: strings.ToLower(name),
Name: strings.ToLower(name),
LoginType: LDAP,
LoginSource: sourceId,
LoginName: name,
IsActive: true,
Passwd: passwd,
Email: mail,
}
err := CreateUser(u)
return u, err
}
type loginAuth struct {
username, password string
}
func LoginAuth(username, password string) smtp.Auth {
return &loginAuth{username, password}
}
func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
return "LOGIN", []byte(a.username), nil
}
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
switch string(fromServer) {
case "Username:":
return []byte(a.username), nil
case "Password:":
return []byte(a.password), nil
}
}
return nil, nil
}
var (
SMTP_PLAIN = "PLAIN"
SMTP_LOGIN = "LOGIN"
SMTPAuths = []string{SMTP_PLAIN, SMTP_LOGIN}
)
func SmtpAuth(host string, port int, a smtp.Auth, useTls bool) error {
c, err := smtp.Dial(fmt.Sprintf("%s:%d", host, port))
if err != nil {
return err
}
defer c.Close()
if err = c.Hello("gogs"); err != nil {
return err
}
if useTls {
if ok, _ := c.Extension("STARTTLS"); ok {
config := &tls.Config{ServerName: host}
if err = c.StartTLS(config); err != nil {
return err
}
} else {
return errors.New("SMTP server unsupports TLS")
}
}
if ok, _ := c.Extension("AUTH"); ok {
if err = c.Auth(a); err != nil {
return err
}
return nil
}
return ErrUnsupportedLoginType
}
// Query if name/passwd can login against the LDAP direcotry pool
// Create a local user if success
// Return the same LoginUserPlain semantic
func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTPConfig, autoRegister bool) (*User, error) {
var auth smtp.Auth
if cfg.Auth == SMTP_PLAIN {
auth = smtp.PlainAuth("", name, passwd, cfg.Host)
} else if cfg.Auth == SMTP_LOGIN {
auth = LoginAuth(name, passwd)
} else {
return nil, errors.New("Unsupported SMTP auth type")
}
if err := SmtpAuth(cfg.Host, cfg.Port, auth, cfg.TLS); err != nil {
if strings.Contains(err.Error(), "Username and Password not accepted") {
return nil, ErrUserNotExist
}
return nil, err
}
if !autoRegister {
return u, nil
}
var loginName = name
idx := strings.Index(name, "@")
if idx > -1 {
loginName = name[:idx]
}
// fake a local user creation
u = &User{
LowerName: strings.ToLower(loginName),
Name: strings.ToLower(loginName),
LoginType: SMTP,
LoginSource: sourceId,
LoginName: name,
IsActive: true,
Passwd: passwd,
Email: name,
}
err := CreateUser(u)
return u, err
}

View File

@@ -14,11 +14,11 @@ import (
"github.com/go-xorm/xorm"
_ "github.com/lib/pq"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/setting"
)
var (
orm *xorm.Engine
x *xorm.Engine
tables []interface{}
HasEngine bool
@@ -32,98 +32,89 @@ var (
)
func init() {
tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow),
new(Mirror), new(Release))
tables = append(tables, new(User), new(PublicKey),
new(Repository), new(Watch), new(Star), new(Action), new(Access),
new(Issue), new(Comment), new(Oauth2), new(Follow),
new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser),
new(UpdateTask), new(Attachment))
}
func LoadModelsConfig() {
DbCfg.Type = base.Cfg.MustValue("database", "DB_TYPE")
DbCfg.Type = setting.Cfg.MustValue("database", "DB_TYPE")
if DbCfg.Type == "sqlite3" {
UseSQLite3 = true
}
DbCfg.Host = base.Cfg.MustValue("database", "HOST")
DbCfg.Name = base.Cfg.MustValue("database", "NAME")
DbCfg.User = base.Cfg.MustValue("database", "USER")
DbCfg.Pwd = base.Cfg.MustValue("database", "PASSWD")
DbCfg.SslMode = base.Cfg.MustValue("database", "SSL_MODE")
DbCfg.Path = base.Cfg.MustValue("database", "PATH", "data/gogs.db")
DbCfg.Host = setting.Cfg.MustValue("database", "HOST")
DbCfg.Name = setting.Cfg.MustValue("database", "NAME")
DbCfg.User = setting.Cfg.MustValue("database", "USER")
if len(DbCfg.Pwd) == 0 {
DbCfg.Pwd = setting.Cfg.MustValue("database", "PASSWD")
}
DbCfg.SslMode = setting.Cfg.MustValue("database", "SSL_MODE")
DbCfg.Path = setting.Cfg.MustValue("database", "PATH", "data/gogs.db")
}
func NewTestEngine(x *xorm.Engine) (err error) {
func getEngine() (*xorm.Engine, error) {
cnnstr := ""
switch DbCfg.Type {
case "mysql":
x, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name))
cnnstr = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name)
case "postgres":
var host, port = "127.0.0.1", "5432"
fields := strings.Split(DbCfg.Host, ":")
if len(fields) > 0 {
if len(fields) > 0 && len(strings.TrimSpace(fields[0])) > 0 {
host = fields[0]
}
if len(fields) > 1 {
if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 {
port = fields[1]
}
cnnstr := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
cnnstr = fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode)
//fmt.Println(cnnstr)
x, err = xorm.NewEngine("postgres", cnnstr)
case "sqlite3":
if !EnableSQLite3 {
return fmt.Errorf("Unknown database type: %s", DbCfg.Type)
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
}
os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm)
x, err = xorm.NewEngine("sqlite3", DbCfg.Path)
cnnstr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc"
default:
return fmt.Errorf("Unknown database type: %s", DbCfg.Type)
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
}
return xorm.NewEngine(DbCfg.Type, cnnstr)
}
func NewTestEngine(x *xorm.Engine) (err error) {
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to conntect database): %v", err)
}
return x.Sync(tables...)
}
func SetEngine() (err error) {
switch DbCfg.Type {
case "mysql":
orm, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name))
case "postgres":
var host, port = "127.0.0.1", "5432"
fields := strings.Split(DbCfg.Host, ":")
if len(fields) > 0 {
host = fields[0]
}
if len(fields) > 1 {
port = fields[1]
}
orm, err = xorm.NewEngine("postgres", fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode))
case "sqlite3":
os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm)
orm, err = xorm.NewEngine("sqlite3", DbCfg.Path)
default:
return fmt.Errorf("Unknown database type: %s", DbCfg.Type)
}
x, err = getEngine()
if err != nil {
return fmt.Errorf("models.init(fail to conntect database): %v", err)
}
// WARNNING: for serv command, MUST remove the output to os.stdout,
// so use log file to instead print to stdout.
execDir, _ := base.ExecDir()
logPath := execDir + "/log/xorm.log"
logPath := path.Join(setting.LogRootPath, "xorm.log")
os.MkdirAll(path.Dir(logPath), os.ModePerm)
f, err := os.Create(logPath)
if err != nil {
return fmt.Errorf("models.init(fail to create xorm.log): %v", err)
}
orm.Logger = xorm.NewSimpleLogger(f)
x.Logger = xorm.NewSimpleLogger(f)
orm.ShowSQL = true
orm.ShowDebug = true
orm.ShowErr = true
x.ShowSQL = true
x.ShowInfo = true
x.ShowDebug = true
x.ShowErr = true
x.ShowWarn = true
return nil
}
@@ -131,7 +122,7 @@ func NewEngine() (err error) {
if err = SetEngine(); err != nil {
return err
}
if err = orm.Sync(tables...); err != nil {
if err = x.Sync2(tables...); err != nil {
return fmt.Errorf("sync database struct error: %v\n", err)
}
return nil
@@ -139,24 +130,46 @@ func NewEngine() (err error) {
type Statistic struct {
Counter struct {
User, PublicKey, Repo,
Watch, Action, Access,
Issue, Comment,
Mirror, Oauth, Release int64
User, Org, PublicKey,
Repo, Watch, Star, Action, Access,
Issue, Comment, Oauth, Follow,
Mirror, Release, LoginSource, Webhook,
Milestone, Label, HookTask,
Team, UpdateTask, Attachment int64
}
}
func GetStatistic() (stats Statistic) {
stats.Counter.User, _ = orm.Count(new(User))
stats.Counter.PublicKey, _ = orm.Count(new(PublicKey))
stats.Counter.Repo, _ = orm.Count(new(Repository))
stats.Counter.Watch, _ = orm.Count(new(Watch))
stats.Counter.Action, _ = orm.Count(new(Action))
stats.Counter.Access, _ = orm.Count(new(Access))
stats.Counter.Issue, _ = orm.Count(new(Issue))
stats.Counter.Comment, _ = orm.Count(new(Comment))
stats.Counter.Mirror, _ = orm.Count(new(Mirror))
stats.Counter.Oauth, _ = orm.Count(new(Oauth2))
stats.Counter.Release, _ = orm.Count(new(Release))
stats.Counter.User = CountUsers()
stats.Counter.Org = CountOrganizations()
stats.Counter.PublicKey, _ = x.Count(new(PublicKey))
stats.Counter.Repo = CountRepositories()
stats.Counter.Watch, _ = x.Count(new(Watch))
stats.Counter.Star, _ = x.Count(new(Star))
stats.Counter.Action, _ = x.Count(new(Action))
stats.Counter.Access, _ = x.Count(new(Access))
stats.Counter.Issue, _ = x.Count(new(Issue))
stats.Counter.Comment, _ = x.Count(new(Comment))
stats.Counter.Oauth, _ = x.Count(new(Oauth2))
stats.Counter.Follow, _ = x.Count(new(Follow))
stats.Counter.Mirror, _ = x.Count(new(Mirror))
stats.Counter.Release, _ = x.Count(new(Release))
stats.Counter.LoginSource, _ = x.Count(new(LoginSource))
stats.Counter.Webhook, _ = x.Count(new(Webhook))
stats.Counter.Milestone, _ = x.Count(new(Milestone))
stats.Counter.Label, _ = x.Count(new(Label))
stats.Counter.HookTask, _ = x.Count(new(HookTask))
stats.Counter.Team, _ = x.Count(new(Team))
stats.Counter.UpdateTask, _ = x.Count(new(UpdateTask))
stats.Counter.Attachment, _ = x.Count(new(Attachment))
return
}
func Ping() error {
return x.Ping()
}
// DumpDatabase dumps all data from database to file system.
func DumpDatabase(filePath string) error {
return x.DumpAllToFile(filePath)
}

View File

@@ -1,55 +0,0 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"fmt"
"testing"
"github.com/lunny/xorm"
_ "github.com/mattn/go-sqlite3"
. "github.com/smartystreets/goconvey/convey"
"github.com/gogits/gogs/modules/base"
)
func init() {
var err error
orm, err = xorm.NewEngine("sqlite3", "./test.db")
if err != nil {
fmt.Println(err)
}
orm.ShowSQL = true
orm.ShowDebug = true
err = orm.Sync(&User{}, &Repository{})
if err != nil {
fmt.Println(err)
}
base.RepoRootPath = "test"
}
func TestCreateRepository(t *testing.T) {
user := User{Id: 1, Name: "foobar", Type: UT_INDIVIDUAL}
_, err := CreateRepository(&user, "test", "", "", "test repo desc", false, false)
if err != nil {
t.Error(err)
}
}
func TestDeleteRepository(t *testing.T) {
err := DeleteRepository(1, 1, "foobar")
if err != nil {
t.Error(err)
}
}
func TestCommitRepoAction(t *testing.T) {
Convey("Create a commit repository action", t, func() {
})
}

View File

@@ -6,18 +6,19 @@ package models
import (
"errors"
"time"
)
// OT: Oauth2 Type
type OauthType int
const (
OT_GITHUB = iota + 1
OT_GOOGLE
OT_TWITTER
OT_QQ
OT_WEIBO
OT_BITBUCKET
OT_OSCHINA
OT_FACEBOOK
GITHUB OauthType = iota + 1
GOOGLE
TWITTER
QQ
WEIBO
BITBUCKET
FACEBOOK
)
var (
@@ -26,27 +27,30 @@ var (
)
type Oauth2 struct {
Id int64
Uid int64 `xorm:"unique(s)"` // userId
User *User `xorm:"-"`
Type int `xorm:"unique(s) unique(oauth)"` // twitter,github,google...
Identity string `xorm:"unique(s) unique(oauth)"` // id..
Token string `xorm:"TEXT not null"`
Id int64
Uid int64 `xorm:"unique(s)"` // userId
User *User `xorm:"-"`
Type int `xorm:"unique(s) unique(oauth)"` // twitter,github,google...
Identity string `xorm:"unique(s) unique(oauth)"` // id..
Token string `xorm:"TEXT not null"`
Created time.Time `xorm:"CREATED"`
Updated time.Time
HasRecentActivity bool `xorm:"-"`
}
func BindUserOauth2(userId, oauthId int64) error {
_, err := orm.Id(oauthId).Update(&Oauth2{Uid: userId})
_, err := x.Id(oauthId).Update(&Oauth2{Uid: userId})
return err
}
func AddOauth2(oa *Oauth2) error {
_, err := orm.Insert(oa)
_, err := x.Insert(oa)
return err
}
func GetOauth2(identity string) (oa *Oauth2, err error) {
oa = &Oauth2{Identity: identity}
isExist, err := orm.Get(oa)
isExist, err := x.Get(oa)
if err != nil {
return
} else if !isExist {
@@ -60,7 +64,7 @@ func GetOauth2(identity string) (oa *Oauth2, err error) {
func GetOauth2ById(id int64) (oa *Oauth2, err error) {
oa = new(Oauth2)
has, err := orm.Id(id).Get(oa)
has, err := x.Id(id).Get(oa)
if err != nil {
return nil, err
} else if !has {
@@ -69,8 +73,34 @@ func GetOauth2ById(id int64) (oa *Oauth2, err error) {
return oa, nil
}
// GetOauthByUserId returns list of oauthes that are releated to given user.
func GetOauthByUserId(uid int64) (oas []*Oauth2, err error) {
err = orm.Find(&oas, Oauth2{Uid: uid})
return oas, err
// UpdateOauth2 updates given OAuth2.
func UpdateOauth2(oa *Oauth2) error {
_, err := x.Id(oa.Id).AllCols().Update(oa)
return err
}
// GetOauthByUserId returns list of oauthes that are releated to given user.
func GetOauthByUserId(uid int64) ([]*Oauth2, error) {
socials := make([]*Oauth2, 0, 5)
err := x.Find(&socials, Oauth2{Uid: uid})
if err != nil {
return nil, err
}
for _, social := range socials {
social.HasRecentActivity = social.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
return socials, err
}
// DeleteOauth2ById deletes a oauth2 by ID.
func DeleteOauth2ById(id int64) error {
_, err := x.Delete(&Oauth2{Id: id})
return err
}
// CleanUnbindOauth deletes all unbind OAuthes.
func CleanUnbindOauth() error {
_, err := x.Delete(&Oauth2{Uid: -1})
return err
}

1085
models/org.go Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -21,22 +21,25 @@ import (
"github.com/Unknwon/com"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
"github.com/gogits/gogs/modules/setting"
)
const (
// "### autogenerated by gitgos, DO NOT EDIT\n"
TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s`
_TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
)
var (
ErrKeyAlreadyExist = errors.New("Public key already exist")
ErrKeyNotExist = errors.New("Public key does not exist")
)
var sshOpLocker = sync.Mutex{}
var (
sshPath string
appPath string
SshPath string // SSH directory.
appPath string // Execution(binary) path.
)
// exePath returns the executable path.
@@ -52,7 +55,7 @@ func exePath() (string, error) {
func homeDir() string {
home, err := com.HomeDir()
if err != nil {
return "/"
log.Fatal(4, "Fail to get home directory: %v", err)
}
return home
}
@@ -60,40 +63,129 @@ func homeDir() string {
func init() {
var err error
appPath, err = exePath()
if err != nil {
fmt.Printf("publickey.init(fail to get app path): %v\n", err)
os.Exit(2)
if appPath, err = exePath(); err != nil {
log.Fatal(4, "fail to get app path: %v\n", err)
}
appPath = strings.Replace(appPath, "\\", "/", -1)
// Determine and create .ssh path.
sshPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(sshPath, os.ModePerm); err != nil {
fmt.Printf("publickey.init(fail to create sshPath(%s)): %v\n", sshPath, err)
os.Exit(2)
SshPath = filepath.Join(homeDir(), ".ssh")
if err = os.MkdirAll(SshPath, 0700); err != nil {
log.Fatal(4, "fail to create SshPath(%s): %v\n", SshPath, err)
}
}
// PublicKey represents a SSH key of user.
// PublicKey represents a SSH key.
type PublicKey struct {
Id int64
OwnerId int64 `xorm:"unique(s) index not null"`
Name string `xorm:"unique(s) not null"`
Fingerprint string
Content string `xorm:"TEXT not null"`
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
Id int64
OwnerId int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"UNIQUE(s) NOT NULL"`
Fingerprint string
Content string `xorm:"TEXT NOT NULL"`
Created time.Time `xorm:"CREATED"`
Updated time.Time
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
}
// GenAuthorizedKey returns formatted public key string.
func GenAuthorizedKey(keyId int64, key string) string {
return fmt.Sprintf(TPL_PUBLICK_KEY+"\n", appPath, keyId, key)
// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string {
return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, key.Content)
}
// AddPublicKey adds new public key to database and SSH key file.
var (
MinimumKeySize = map[string]int{
"(ED25519)": 256,
"(ECDSA)": 256,
"(NTRU)": 1087,
"(MCE)": 1702,
"(McE)": 1702,
"(RSA)": 2048,
}
)
// CheckPublicKeyString checks if the given public key string is recognized by SSH.
func CheckPublicKeyString(content string) (bool, error) {
if strings.ContainsAny(content, "\n\r") {
return false, errors.New("Only a single line with a single key please")
}
// write the key to a file…
tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest")
if err != nil {
return false, err
}
tmpPath := tmpFile.Name()
defer os.Remove(tmpPath)
tmpFile.WriteString(content)
tmpFile.Close()
// Check if ssh-keygen recognizes its contents.
stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath)
if err != nil {
return false, errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
return false, errors.New("ssh-keygen returned not enough output to evaluate the key")
}
// The ssh-keygen in Windows does not print key type, so no need go further.
if setting.IsWindows {
return true, nil
}
sshKeygenOutput := strings.Split(stdout, " ")
if len(sshKeygenOutput) < 4 {
return false, errors.New("Not enough fields returned by ssh-keygen -l -f")
}
// Check if key type and key size match.
keySize, err := com.StrTo(sshKeygenOutput[0]).Int()
if err != nil {
return false, errors.New("Cannot get key size of the given key")
}
keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])
if minimumKeySize := MinimumKeySize[keyType]; minimumKeySize == 0 {
return false, errors.New("Sorry, unrecognized public key type")
} else if keySize < minimumKeySize {
return false, fmt.Errorf("The minimum accepted size of a public key %s is %d", keyType, minimumKeySize)
}
return true, nil
}
// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
func saveAuthorizedKeyFile(key *PublicKey) error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
fpath := filepath.Join(SshPath, "authorized_keys")
f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return err
}
defer f.Close()
finfo, err := f.Stat()
if err != nil {
return err
}
// FIXME: following command does not support in Windows.
if !setting.IsWindows {
if finfo.Mode().Perm() > 0600 {
log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", finfo.Mode().Perm().String())
if err = f.Chmod(0600); err != nil {
return err
}
}
}
_, err = f.WriteString(key.GetAuthorizedString())
return err
}
// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(key *PublicKey) (err error) {
// Check if public key name has been used.
has, err := orm.Get(key)
has, err := x.Get(key)
if err != nil {
return err
} else if has {
@@ -101,26 +193,26 @@ func AddPublicKey(key *PublicKey) (err error) {
}
// Calculate fingerprint.
tmpPath := strings.Replace(filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
"id_rsa.pub"), "\\", "/", -1)
os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
return err
}
stdout, _, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-l", "-f", tmpPath)
if err != nil {
return err
return errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
return errors.New("Not enough output for calculating fingerprint")
}
key.Fingerprint = strings.Split(stdout, " ")[1]
// Save SSH key.
if _, err = orm.Insert(key); err != nil {
if _, err = x.Insert(key); err != nil {
return err
}
if err = SaveAuthorizedKeyFile(key); err != nil {
if _, err2 := orm.Delete(key); err2 != nil {
} else if err = saveAuthorizedKeyFile(key); err != nil {
// Roll back.
if _, err2 := x.Delete(key); err2 != nil {
return err2
}
return err
@@ -129,8 +221,35 @@ func AddPublicKey(key *PublicKey) (err error) {
return nil
}
// GetPublicKeyById returns public key by given ID.
func GetPublicKeyById(keyId int64) (*PublicKey, error) {
key := new(PublicKey)
has, err := x.Id(keyId).Get(key)
if err != nil {
return nil, err
} else if !has {
return nil, ErrKeyNotExist
}
return key, nil
}
// ListPublicKey returns a list of all public keys that user has.
func ListPublicKey(uid int64) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 5)
err := x.Find(&keys, &PublicKey{OwnerId: uid})
if err != nil {
return nil, err
}
for _, key := range keys {
key.HasUsed = key.Updated.After(key.Created)
key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
return keys, nil
}
// rewriteAuthorizedKeys finds and deletes corresponding line in authorized_keys file.
func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
// Delete SSH key in SSH key file.
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
@@ -140,12 +259,14 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
}
defer fr.Close()
fw, err := os.Create(tmpP)
fw, err := os.OpenFile(tmpP, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return err
}
defer fw.Close()
isFound := false
keyword := fmt.Sprintf("key-%d", key.Id)
buf := bufio.NewReader(fr)
for {
line, errRead := buf.ReadString('\n')
@@ -164,7 +285,8 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
}
// Found the line and copy rest of file.
if strings.Contains(line, fmt.Sprintf("key-%d", key.Id)) && strings.Contains(line, key.Content) {
if !isFound && strings.Contains(line, keyword) && strings.Contains(line, key.Content) {
isFound = true
continue
}
// Still finding the line, copy the line that currently read.
@@ -179,50 +301,31 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
return nil
}
// UpdatePublicKey updates given public key.
func UpdatePublicKey(key *PublicKey) error {
_, err := x.Id(key.Id).AllCols().Update(key)
return err
}
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
func DeletePublicKey(key *PublicKey) (err error) {
// Delete SSH key in database.
has, err := orm.Id(key.Id).Get(key)
func DeletePublicKey(key *PublicKey) error {
has, err := x.Get(key)
if err != nil {
return err
} else if !has {
return errors.New("Public key does not exist")
return ErrKeyNotExist
}
if _, err = orm.Delete(key); err != nil {
if _, err = x.Delete(key); err != nil {
return err
}
p := filepath.Join(sshPath, "authorized_keys")
tmpP := filepath.Join(sshPath, "authorized_keys.tmp")
log.Trace("ssh.DeletePublicKey(authorized_keys): %s", p)
if err = rewriteAuthorizedKeys(key, p, tmpP); err != nil {
fpath := filepath.Join(SshPath, "authorized_keys")
tmpPath := filepath.Join(SshPath, "authorized_keys.tmp")
if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
return err
} else if err = os.Remove(p); err != nil {
} else if err = os.Remove(fpath); err != nil {
return err
}
return os.Rename(tmpP, p)
}
// ListPublicKey returns a list of public keys that user has.
func ListPublicKey(userId int64) ([]PublicKey, error) {
keys := make([]PublicKey, 0)
err := orm.Find(&keys, &PublicKey{OwnerId: userId})
return keys, err
}
// SaveAuthorizedKeyFile writes SSH key content to SSH key file.
func SaveAuthorizedKeyFile(key *PublicKey) error {
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
p := filepath.Join(sshPath, "authorized_keys")
f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
return err
}
defer f.Close()
_, err = f.WriteString(GenAuthorizedKey(key.Id, key.Content))
return err
return os.Rename(tmpPath, fpath)
}

View File

@@ -6,15 +6,16 @@ package models
import (
"errors"
"sort"
"strings"
"time"
"github.com/Unknwon/com"
"github.com/gogits/git"
"github.com/gogits/gogs/modules/git"
)
var (
ErrReleaseAlreadyExist = errors.New("Release already exist")
ErrReleaseNotExist = errors.New("Release does not exist")
)
// Release represents a release of repository.
@@ -23,21 +24,17 @@ type Release struct {
RepoId int64
PublisherId int64
Publisher *User `xorm:"-"`
Title string
TagName string
LowerTagName string
SHA1 string
Target string
Title string
Sha1 string `xorm:"VARCHAR(40)"`
NumCommits int
NumCommitsBehind int `xorm:"-"`
Note string `xorm:"TEXT"`
IsDraft bool `xorm:"NOT NULL DEFAULT false"`
IsPrerelease bool
Created time.Time `xorm:"created"`
}
// GetReleasesByRepoId returns a list of releases of repository.
func GetReleasesByRepoId(repoId int64) (rels []*Release, err error) {
err = orm.Desc("created").Find(&rels, Release{RepoId: repoId})
return rels, err
Created time.Time `xorm:"CREATED"`
}
// IsReleaseExist returns true if release with given tag name already exists.
@@ -46,11 +43,38 @@ func IsReleaseExist(repoId int64, tagName string) (bool, error) {
return false, nil
}
return orm.Get(&Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)})
return x.Get(&Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)})
}
func createTag(gitRepo *git.Repository, rel *Release) error {
// Only actual create when publish.
if !rel.IsDraft {
if !gitRepo.IsTagExist(rel.TagName) {
commit, err := gitRepo.GetCommitOfBranch(rel.Target)
if err != nil {
return err
}
if err = gitRepo.CreateTag(rel.TagName, commit.Id.String()); err != nil {
return err
}
} else {
commit, err := gitRepo.GetCommitOfTag(rel.TagName)
if err != nil {
return err
}
rel.NumCommits, err = commit.CommitsCount()
if err != nil {
return err
}
}
}
return nil
}
// CreateRelease creates a new release of repository.
func CreateRelease(repoPath string, rel *Release, gitRepo *git.Repository) error {
func CreateRelease(gitRepo *git.Repository, rel *Release) error {
isExist, err := IsReleaseExist(rel.RepoId, rel.TagName)
if err != nil {
return err
@@ -58,26 +82,65 @@ func CreateRelease(repoPath string, rel *Release, gitRepo *git.Repository) error
return ErrReleaseAlreadyExist
}
if !git.IsTagExist(repoPath, rel.TagName) {
_, stderr, err := com.ExecCmdDir(repoPath, "git", "tag", rel.TagName, "-m", rel.Title)
if err != nil {
return err
} else if strings.Contains(stderr, "fatal:") {
return errors.New(stderr)
}
} else {
commit, err := gitRepo.GetCommitOfTag(rel.TagName)
if err != nil {
return err
}
rel.NumCommits, err = commit.CommitsCount()
if err != nil {
return err
}
if err = createTag(gitRepo, rel); err != nil {
return err
}
rel.LowerTagName = strings.ToLower(rel.TagName)
_, err = orm.InsertOne(rel)
_, err = x.InsertOne(rel)
return err
}
// GetRelease returns release by given ID.
func GetRelease(repoId int64, tagName string) (*Release, error) {
isExist, err := IsReleaseExist(repoId, tagName)
if err != nil {
return nil, err
} else if !isExist {
return nil, ErrReleaseNotExist
}
rel := &Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)}
_, err = x.Get(rel)
return rel, err
}
// GetReleasesByRepoId returns a list of releases of repository.
func GetReleasesByRepoId(repoId int64) (rels []*Release, err error) {
err = x.Desc("created").Find(&rels, Release{RepoId: repoId})
return rels, err
}
type ReleaseSorter struct {
rels []*Release
}
func (rs *ReleaseSorter) Len() int {
return len(rs.rels)
}
func (rs *ReleaseSorter) Less(i, j int) bool {
diffNum := rs.rels[i].NumCommits - rs.rels[j].NumCommits
if diffNum != 0 {
return diffNum > 0
}
return rs.rels[i].Created.After(rs.rels[j].Created)
}
func (rs *ReleaseSorter) Swap(i, j int) {
rs.rels[i], rs.rels[j] = rs.rels[j], rs.rels[i]
}
// SortReleases sorts releases by number of commits and created time.
func SortReleases(rels []*Release) {
sorter := &ReleaseSorter{rels: rels}
sort.Sort(sorter)
}
// UpdateRelease updates information of a release.
func UpdateRelease(gitRepo *git.Repository, rel *Release) (err error) {
if err = createTag(gitRepo, rel); err != nil {
return err
}
_, err = x.Id(rel.Id).AllCols().Update(rel)
return err
}

File diff suppressed because it is too large Load Diff

125
models/slack.go Normal file
View File

@@ -0,0 +1,125 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"encoding/json"
"errors"
"fmt"
"strings"
)
const (
SLACK_COLOR string = "#dd4b39"
)
type Slack struct {
Domain string `json:"domain"`
Token string `json:"token"`
Channel string `json:"channel"`
}
type SlackPayload struct {
Channel string `json:"channel"`
Text string `json:"text"`
Username string `json:"username"`
IconUrl string `json:"icon_url"`
UnfurlLinks int `json:"unfurl_links"`
LinkNames int `json:"link_names"`
Attachments []SlackAttachment `json:"attachments"`
}
type SlackAttachment struct {
Color string `json:"color"`
Text string `json:"text"`
}
func GetSlackURL(domain string, token string) string {
return fmt.Sprintf(
"https://%s.slack.com/services/hooks/incoming-webhook?token=%s",
domain,
token,
)
}
func (p SlackPayload) GetJSONPayload() ([]byte, error) {
data, err := json.Marshal(p)
if err != nil {
return []byte{}, err
}
return data, nil
}
func GetSlackPayload(p *Payload, meta string) (*SlackPayload, error) {
slack := &Slack{}
slackPayload := &SlackPayload{}
if err := json.Unmarshal([]byte(meta), &slack); err != nil {
return slackPayload, errors.New("GetSlackPayload meta json:" + err.Error())
}
// TODO: handle different payload types: push, new branch, delete branch etc.
// when they are added to gogs. Only handles push now
return getSlackPushPayload(p, slack)
}
func getSlackPushPayload(p *Payload, slack *Slack) (*SlackPayload, error) {
// n new commits
refSplit := strings.Split(p.Ref, "/")
branchName := refSplit[len(refSplit)-1]
var commitString string
if len(p.Commits) == 1 {
commitString = "1 new commit"
if p.CompareUrl != "" {
commitString = SlackLinkFormatter(p.CompareUrl, commitString)
}
} else {
commitString = fmt.Sprintf("%d new commits", len(p.Commits))
if p.CompareUrl != "" {
commitString = SlackLinkFormatter(p.CompareUrl, commitString)
}
}
repoLink := SlackLinkFormatter(p.Repo.Url, p.Repo.Name)
branchLink := SlackLinkFormatter(p.Repo.Url+"/src/"+branchName, branchName)
text := fmt.Sprintf("[%s:%s] %s pushed by %s", repoLink, branchLink, commitString, p.Pusher.Name)
var attachmentText string
// for each commit, generate attachment text
for i, commit := range p.Commits {
attachmentText += fmt.Sprintf("%s: %s - %s", SlackLinkFormatter(commit.Url, commit.Id[:7]), SlackTextFormatter(commit.Message), SlackTextFormatter(commit.Author.Name))
// add linebreak to each commit but the last
if i < len(p.Commits)-1 {
attachmentText += "\n"
}
}
slackAttachments := []SlackAttachment{{Color: SLACK_COLOR, Text: attachmentText}}
return &SlackPayload{
Channel: slack.Channel,
Text: text,
Username: "gogs",
IconUrl: "https://raw.githubusercontent.com/gogits/gogs/master/public/img/favicon.png",
UnfurlLinks: 0,
LinkNames: 0,
Attachments: slackAttachments,
}, nil
}
// see: https://api.slack.com/docs/formatting
func SlackTextFormatter(s string) string {
// take only first line of commit
first := strings.Split(s, "\n")[0]
// replace & < >
first = strings.Replace(first, "&", "&amp;", -1)
first = strings.Replace(first, "<", "&lt;", -1)
first = strings.Replace(first, ">", "&gt;", -1)
return first
}
func SlackLinkFormatter(url string, text string) string {
return fmt.Sprintf("<%s|%s>", url, SlackTextFormatter(text))
}

View File

@@ -1,37 +1,115 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"container/list"
"fmt"
"os/exec"
"strings"
"github.com/gogits/git"
"github.com/gogits/gogs/modules/base"
qlog "github.com/qiniu/log"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
)
func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId int64) {
type UpdateTask struct {
Id int64
Uuid string `xorm:"index"`
RefName string
OldCommitId string
NewCommitId string
}
func AddUpdateTask(task *UpdateTask) error {
_, err := x.Insert(task)
return err
}
func GetUpdateTasksByUuid(uuid string) ([]*UpdateTask, error) {
task := &UpdateTask{
Uuid: uuid,
}
tasks := make([]*UpdateTask, 0)
err := x.Find(&tasks, task)
if err != nil {
return nil, err
}
return tasks, nil
}
func DelUpdateTasksByUuid(uuid string) error {
_, err := x.Delete(&UpdateTask{Uuid: uuid})
return err
}
func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) error {
isNew := strings.HasPrefix(oldCommitId, "0000000")
if isNew &&
strings.HasPrefix(newCommitId, "0000000") {
qlog.Fatal("old rev and new rev both 000000")
return fmt.Errorf("old rev and new rev both 000000")
}
f := RepoPath(userName, repoName)
f := RepoPath(repoUserName, repoName)
gitUpdate := exec.Command("git", "update-server-info")
gitUpdate.Dir = f
gitUpdate.Run()
isDel := strings.HasPrefix(newCommitId, "0000000")
if isDel {
log.GitLogger.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId)
return nil
}
repo, err := git.OpenRepository(f)
if err != nil {
qlog.Fatalf("runUpdate.Open repoId: %v", err)
return fmt.Errorf("runUpdate.Open repoId: %v", err)
}
ru, err := GetUserByName(repoUserName)
if err != nil {
return fmt.Errorf("runUpdate.GetUserByName: %v", err)
}
repos, err := GetRepositoryByName(ru.Id, repoName)
if err != nil {
return fmt.Errorf("runUpdate.GetRepositoryByName userId: %v", err)
}
// Push tags.
if strings.HasPrefix(refName, "refs/tags/") {
tagName := git.RefEndName(refName)
tag, err := repo.GetTag(tagName)
if err != nil {
log.GitLogger.Fatal(4, "runUpdate.GetTag: %v", err)
}
var actEmail string
if tag.Tagger != nil {
actEmail = tag.Tagger.Email
} else {
cmt, err := tag.Commit()
if err != nil {
log.GitLogger.Fatal(4, "runUpdate.GetTag Commit: %v", err)
}
actEmail = cmt.Committer.Email
}
commit := &base.PushCommits{}
if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
repos.Id, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil {
log.GitLogger.Fatal(4, "runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
}
return err
}
newCommit, err := repo.GetCommit(newCommitId)
if err != nil {
qlog.Fatalf("runUpdate GetCommit of newCommitId: %v", err)
return
return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err)
}
var l *list.List
@@ -39,30 +117,26 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId
if isNew {
l, err = newCommit.CommitsBefore()
if err != nil {
qlog.Fatalf("Find CommitsBefore erro: %v", err)
return fmt.Errorf("Find CommitsBefore erro: %v", err)
}
} else {
l, err = newCommit.CommitsBeforeUntil(oldCommitId)
if err != nil {
qlog.Fatalf("Find CommitsBeforeUntil erro: %v", err)
return
return fmt.Errorf("Find CommitsBeforeUntil erro: %v", err)
}
}
if err != nil {
qlog.Fatalf("runUpdate.Commit repoId: %v", err)
}
repos, err := GetRepositoryByName(userId, repoName)
if err != nil {
qlog.Fatalf("runUpdate.GetRepositoryByName userId: %v", err)
return fmt.Errorf("runUpdate.Commit repoId: %v", err)
}
// if commits push
commits := make([]*base.PushCommit, 0)
var maxCommits = 3
var maxCommits = 2
var actEmail string
for e := l.Front(); e != nil; e = e.Next() {
commit := e.Value.(*git.Commit)
if actEmail == "" {
actEmail = commit.Committer.Email
}
@@ -77,8 +151,9 @@ func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId
}
//commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()})
if err = CommitRepoAction(userId, userName, actEmail,
repos.Id, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil {
qlog.Fatalf("runUpdate.models.CommitRepoAction: %v", err)
if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}, oldCommitId, newCommitId); err != nil {
return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
}
return nil
}

View File

@@ -14,91 +14,165 @@ import (
"strings"
"time"
"github.com/gogits/git"
"github.com/Unknwon/com"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/git"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
// User types.
const (
UT_INDIVIDUAL = iota + 1
UT_ORGANIZATION
)
type UserType int
// Login types.
const (
LT_PLAIN = iota + 1
LT_LDAP
INDIVIDUAL UserType = iota // Historic reason to make it starts at 0.
ORGANIZATION
)
var (
ErrUserOwnRepos = errors.New("User still have ownership of repositories")
ErrUserAlreadyExist = errors.New("User already exist")
ErrUserNotExist = errors.New("User does not exist")
ErrEmailAlreadyUsed = errors.New("E-mail already used")
ErrUserNameIllegal = errors.New("User name contains illegal characters")
ErrKeyNotExist = errors.New("Public key does not exist")
ErrUserOwnRepos = errors.New("User still have ownership of repositories")
ErrUserHasOrgs = errors.New("User still have membership of organization")
ErrUserAlreadyExist = errors.New("User already exist")
ErrUserNotExist = errors.New("User does not exist")
ErrUserNotKeyOwner = errors.New("User does not the owner of public key")
ErrEmailAlreadyUsed = errors.New("E-mail already used")
ErrUserNameIllegal = errors.New("User name contains illegal characters")
ErrLoginSourceNotExist = errors.New("Login source does not exist")
ErrLoginSourceNotActived = errors.New("Login source is not actived")
ErrUnsupportedLoginType = errors.New("Login source is unknown")
)
// User represents the object of individual and member of organization.
type User struct {
Id int64
LowerName string `xorm:"unique not null"`
Name string `xorm:"unique not null"`
Email string `xorm:"unique not null"`
Passwd string `xorm:"not null"`
LoginType int
Type int
LowerName string `xorm:"UNIQUE NOT NULL"`
Name string `xorm:"UNIQUE NOT NULL"`
FullName string
Email string `xorm:"UNIQUE NOT NULL"`
Passwd string `xorm:"NOT NULL"`
LoginType LoginType
LoginSource int64 `xorm:"NOT NULL DEFAULT 0"`
LoginName string
Type UserType
Orgs []*User `xorm:"-"`
Repos []*Repository `xorm:"-"`
NumFollowers int
NumFollowings int
NumStars int
NumRepos int
Avatar string `xorm:"varchar(2048) not null"`
AvatarEmail string `xorm:"not null"`
Avatar string `xorm:"VARCHAR(2048) NOT NULL"`
AvatarEmail string `xorm:"NOT NULL"`
Location string
Website string
IsActive bool
IsAdmin bool
Rands string `xorm:"VARCHAR(10)"`
Salt string `xorm:"VARCHAR(10)"`
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
// For organization.
Description string
NumTeams int
NumMembers int
Teams []*Team `xorm:"-"`
Members []*User `xorm:"-"`
}
// DashboardLink returns the user dashboard page link.
func (u *User) DashboardLink() string {
if u.IsOrganization() {
return "/org/" + u.Name + "/dashboard/"
}
return "/"
}
// HomeLink returns the user home page link.
func (user *User) HomeLink() string {
return "/user/" + user.Name
func (u *User) HomeLink() string {
return "/user/" + u.Name
}
// AvatarLink returns the user gravatar link.
func (user *User) AvatarLink() string {
if base.Service.EnableCacheAvatar {
return "/avatar/" + user.Avatar
// AvatarLink returns user gravatar link.
func (u *User) AvatarLink() string {
if setting.DisableGravatar {
return "/img/avatar_default.jpg"
} else if setting.Service.EnableCacheAvatar {
return "/avatar/" + u.Avatar
}
return "//1.gravatar.com/avatar/" + user.Avatar
return "//1.gravatar.com/avatar/" + u.Avatar
}
// NewGitSig generates and returns the signature of given user.
func (user *User) NewGitSig() *git.Signature {
func (u *User) NewGitSig() *git.Signature {
return &git.Signature{
Name: user.Name,
Email: user.Email,
Name: u.Name,
Email: u.Email,
When: time.Now(),
}
}
// EncodePasswd encodes password to safe format.
func (user *User) EncodePasswd() {
newPasswd := base.PBKDF2([]byte(user.Passwd), []byte(user.Salt), 10000, 50, sha256.New)
user.Passwd = fmt.Sprintf("%x", newPasswd)
func (u *User) EncodePasswd() {
newPasswd := base.PBKDF2([]byte(u.Passwd), []byte(u.Salt), 10000, 50, sha256.New)
u.Passwd = fmt.Sprintf("%x", newPasswd)
}
// Member represents user is member of organization.
type Member struct {
Id int64
OrgId int64 `xorm:"unique(member) index"`
UserId int64 `xorm:"unique(member)"`
// ValidtePassword checks if given password matches the one belongs to the user.
func (u *User) ValidtePassword(passwd string) bool {
newUser := &User{Passwd: passwd, Salt: u.Salt}
newUser.EncodePasswd()
return u.Passwd == newUser.Passwd
}
// IsOrganization returns true if user is actually a organization.
func (u *User) IsOrganization() bool {
return u.Type == ORGANIZATION
}
// IsUserOrgOwner returns true if user is in the owner team of given organization.
func (u *User) IsUserOrgOwner(orgId int64) bool {
return IsOrganizationOwner(orgId, u.Id)
}
// IsPublicMember returns true if user public his/her membership in give organization.
func (u *User) IsPublicMember(orgId int64) bool {
return IsPublicMembership(orgId, u.Id)
}
// GetOrganizationCount returns count of membership of organization of user.
func (u *User) GetOrganizationCount() (int64, error) {
return x.Where("uid=?", u.Id).Count(new(OrgUser))
}
// GetRepositories returns all repositories that user owns, including private repositories.
func (u *User) GetRepositories() (err error) {
u.Repos, err = GetRepositories(u.Id, true)
return err
}
// GetOrganizations returns all organizations that user belongs to.
func (u *User) GetOrganizations() error {
ous, err := GetOrgUsersByUserId(u.Id)
if err != nil {
return err
}
u.Orgs = make([]*User, len(ous))
for i, ou := range ous {
u.Orgs[i], err = GetUserById(ou.OrgId)
if err != nil {
return err
}
}
return nil
}
// GetFullNameFallback returns Full Name if set, otherwise username
func (u *User) GetFullNameFallback() string {
if u.FullName == "" {
return u.Name
}
return u.FullName
}
// IsUserExist checks if given user name exist,
@@ -107,7 +181,7 @@ func IsUserExist(name string) (bool, error) {
if len(name) == 0 {
return false, nil
}
return orm.Get(&User{LowerName: strings.ToLower(name)})
return x.Get(&User{LowerName: strings.ToLower(name)})
}
// IsEmailUsed returns true if the e-mail has been used.
@@ -115,62 +189,76 @@ func IsEmailUsed(email string) (bool, error) {
if len(email) == 0 {
return false, nil
}
return orm.Get(&User{Email: email})
return x.Get(&User{Email: email})
}
// return a user salt token
// GetUserSalt returns a user salt token
func GetUserSalt() string {
return base.GetRandomString(10)
}
// RegisterUser creates record of a new user.
func RegisterUser(user *User) (*User, error) {
if !IsLegalName(user.Name) {
return nil, ErrUserNameIllegal
// CreateUser creates record of a new user.
func CreateUser(u *User) error {
if !IsLegalName(u.Name) {
return ErrUserNameIllegal
}
isExist, err := IsUserExist(user.Name)
isExist, err := IsUserExist(u.Name)
if err != nil {
return nil, err
return err
} else if isExist {
return nil, ErrUserAlreadyExist
return ErrUserAlreadyExist
}
isExist, err = IsEmailUsed(user.Email)
isExist, err = IsEmailUsed(u.Email)
if err != nil {
return nil, err
return err
} else if isExist {
return nil, ErrEmailAlreadyUsed
return ErrEmailAlreadyUsed
}
user.LowerName = strings.ToLower(user.Name)
user.Avatar = base.EncodeMd5(user.Email)
user.AvatarEmail = user.Email
user.Rands = GetUserSalt()
user.Salt = GetUserSalt()
user.EncodePasswd()
if _, err = orm.Insert(user); err != nil {
return nil, err
} else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil {
if _, err := orm.Id(user.Id).Delete(&User{}); err != nil {
return nil, errors.New(fmt.Sprintf(
"both create userpath %s and delete table record faild: %v", user.Name, err))
}
return nil, err
u.LowerName = strings.ToLower(u.Name)
u.Avatar = base.EncodeMd5(u.Email)
u.AvatarEmail = u.Email
u.Rands = GetUserSalt()
u.Salt = GetUserSalt()
u.EncodePasswd()
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
if user.Id == 1 {
user.IsAdmin = true
user.IsActive = true
_, err = orm.Id(user.Id).UseBool().Update(user)
if _, err = sess.Insert(u); err != nil {
sess.Rollback()
return err
} else if err = os.MkdirAll(UserPath(u.Name), os.ModePerm); err != nil {
sess.Rollback()
return err
} else if err = sess.Commit(); err != nil {
return err
}
return user, err
// Auto-set admin for user whose ID is 1.
if u.Id == 1 {
u.IsAdmin = true
u.IsActive = true
_, err = x.Id(u.Id).UseBool().Update(u)
}
return err
}
// CountUsers returns number of users.
func CountUsers() int64 {
count, _ := x.Where("type=0").Count(new(User))
return count
}
// GetUsers returns given number of user objects with offset.
func GetUsers(num, offset int) ([]User, error) {
users := make([]User, 0, num)
err := orm.Limit(num, offset).Asc("id").Find(&users)
func GetUsers(num, offset int) ([]*User, error) {
users := make([]*User, 0, num)
err := x.Limit(num, offset).Where("type=0").Asc("id").Find(&users)
return users, err
}
@@ -186,7 +274,7 @@ func getVerifyUser(code string) (user *User) {
if user, err = GetUserByName(string(b)); user != nil {
return user
}
log.Error("user.getVerifyUser: %v", err)
log.Error(4, "user.getVerifyUser: %v", err)
}
return nil
@@ -194,12 +282,12 @@ func getVerifyUser(code string) (user *User) {
// verify active code when active account
func VerifyUserActiveCode(code string) (user *User) {
minutes := base.Service.ActiveCodeLives
minutes := setting.Service.ActiveCodeLives
if user = getVerifyUser(code); user != nil {
// time limit code
prefix := code[:base.TimeLimitCodeLength]
data := base.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
data := com.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
if base.VerifyTimeLimitCode(data, minutes, prefix) {
return user
@@ -209,16 +297,20 @@ func VerifyUserActiveCode(code string) (user *User) {
}
// ChangeUserName changes all corresponding setting from old user name to new one.
func ChangeUserName(user *User, newUserName string) (err error) {
func ChangeUserName(u *User, newUserName string) (err error) {
if !IsLegalName(newUserName) {
return ErrUserNameIllegal
}
newUserName = strings.ToLower(newUserName)
// Update accesses of user.
accesses := make([]Access, 0, 10)
if err = orm.Find(&accesses, &Access{UserName: user.LowerName}); err != nil {
if err = x.Find(&accesses, &Access{UserName: u.LowerName}); err != nil {
return err
}
sess := orm.NewSession()
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
@@ -226,35 +318,38 @@ func ChangeUserName(user *User, newUserName string) (err error) {
for i := range accesses {
accesses[i].UserName = newUserName
if strings.HasPrefix(accesses[i].RepoName, user.LowerName+"/") {
accesses[i].RepoName = strings.Replace(accesses[i].RepoName, user.LowerName, newUserName, 1)
if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil {
return err
}
if strings.HasPrefix(accesses[i].RepoName, u.LowerName+"/") {
accesses[i].RepoName = strings.Replace(accesses[i].RepoName, u.LowerName, newUserName, 1)
}
if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil {
return err
}
}
repos, err := GetRepositories(user, true)
repos, err := GetRepositories(u.Id, true)
if err != nil {
return err
}
for i := range repos {
accesses = make([]Access, 0, 10)
// Update accesses of user repository.
if err = orm.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repos[i].LowerName}); err != nil {
if err = x.Find(&accesses, &Access{RepoName: u.LowerName + "/" + repos[i].LowerName}); err != nil {
return err
}
for j := range accesses {
accesses[j].RepoName = newUserName + "/" + repos[i].LowerName
if err = UpdateAccessWithSession(sess, &accesses[j]); err != nil {
return err
// if the access is not the user's access (already updated above)
if accesses[j].UserName != u.LowerName {
accesses[j].RepoName = newUserName + "/" + repos[i].LowerName
if err = UpdateAccessWithSession(sess, &accesses[j]); err != nil {
return err
}
}
}
}
// Change user directory name.
if err = os.Rename(UserPath(user.LowerName), UserPath(newUserName)); err != nil {
if err = os.Rename(UserPath(u.LowerName), UserPath(newUserName)); err != nil {
sess.Rollback()
return err
}
@@ -263,106 +358,118 @@ func ChangeUserName(user *User, newUserName string) (err error) {
}
// UpdateUser updates user's information.
func UpdateUser(user *User) (err error) {
user.LowerName = strings.ToLower(user.Name)
func UpdateUser(u *User) error {
u.LowerName = strings.ToLower(u.Name)
if len(user.Location) > 255 {
user.Location = user.Location[:255]
if len(u.Location) > 255 {
u.Location = u.Location[:255]
}
if len(user.Website) > 255 {
user.Website = user.Website[:255]
if len(u.Website) > 255 {
u.Website = u.Website[:255]
}
if len(u.Description) > 255 {
u.Description = u.Description[:255]
}
_, err = orm.Id(user.Id).AllCols().Update(user)
_, err := x.Id(u.Id).AllCols().Update(u)
return err
}
// DeleteUser completely deletes everything of the user.
func DeleteUser(user *User) error {
// TODO: need some kind of mechanism to record failure.
// DeleteUser completely and permanently deletes everything of user.
func DeleteUser(u *User) error {
// Check ownership of repository.
count, err := GetRepositoryCount(user)
count, err := GetRepositoryCount(u)
if err != nil {
return errors.New("modesl.GetRepositories: " + err.Error())
return errors.New("GetRepositoryCount: " + err.Error())
} else if count > 0 {
return ErrUserOwnRepos
}
// Check membership of organization.
count, err = u.GetOrganizationCount()
if err != nil {
return errors.New("modesl.GetRepositories(GetOrganizationCount): " + err.Error())
} else if count > 0 {
return ErrUserHasOrgs
}
// TODO: check issues, other repos' commits
// TODO: roll backable in some point.
// Delete all followers.
if _, err = orm.Delete(&Follow{FollowId: user.Id}); err != nil {
if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil {
return err
}
// Delete oauth2.
if _, err = orm.Delete(&Oauth2{Uid: user.Id}); err != nil {
if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil {
return err
}
// Delete all feeds.
if _, err = orm.Delete(&Action{UserId: user.Id}); err != nil {
if _, err = x.Delete(&Action{UserId: u.Id}); err != nil {
return err
}
// Delete all watches.
if _, err = orm.Delete(&Watch{UserId: user.Id}); err != nil {
if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil {
return err
}
// Delete all accesses.
if _, err = orm.Delete(&Access{UserName: user.LowerName}); err != nil {
if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil {
return err
}
// Delete all SSH keys.
keys := make([]PublicKey, 0, 10)
if err = orm.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil {
keys := make([]*PublicKey, 0, 10)
if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
return err
}
for _, key := range keys {
if err = DeletePublicKey(&key); err != nil {
if err = DeletePublicKey(key); err != nil {
return err
}
}
// Delete user directory.
if err = os.RemoveAll(UserPath(user.Name)); err != nil {
if err = os.RemoveAll(UserPath(u.Name)); err != nil {
return err
}
_, err = orm.Delete(user)
_, err = x.Delete(u)
return err
}
// DeleteInactivateUsers deletes all inactivate users.
func DeleteInactivateUsers() error {
_, err := x.Where("is_active=?", false).Delete(new(User))
return err
}
// UserPath returns the path absolute path of user repositories.
func UserPath(userName string) string {
return filepath.Join(base.RepoRootPath, strings.ToLower(userName))
return filepath.Join(setting.RepoRootPath, strings.ToLower(userName))
}
func GetUserByKeyId(keyId int64) (*User, error) {
user := new(User)
rawSql := "SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?"
has, err := orm.Sql(rawSql, keyId).Get(user)
has, err := x.Sql(rawSql, keyId).Get(user)
if err != nil {
return nil, err
} else if !has {
err = errors.New("not exist key owner")
return nil, err
return nil, ErrUserNotKeyOwner
}
return user, nil
}
// GetUserById returns the user object by given id if exists.
// GetUserById returns the user object by given ID if exists.
func GetUserById(id int64) (*User, error) {
user := new(User)
has, err := orm.Id(id).Get(user)
u := new(User)
has, err := x.Id(id).Get(u)
if err != nil {
return nil, err
}
if !has {
} else if !has {
return nil, ErrUserNotExist
}
return user, nil
return u, nil
}
// GetUserByName returns the user object by given name if exists.
@@ -371,7 +478,7 @@ func GetUserByName(name string) (*User, error) {
return nil, ErrUserNotExist
}
user := &User{LowerName: strings.ToLower(name)}
has, err := orm.Get(user)
has, err := x.Get(user)
if err != nil {
return nil, err
} else if !has {
@@ -393,13 +500,26 @@ func GetUserEmailsByNames(names []string) []string {
return mails
}
// GetUserIdsByNames returns a slice of ids corresponds to names.
func GetUserIdsByNames(names []string) []int64 {
ids := make([]int64, 0, len(names))
for _, name := range names {
u, err := GetUserByName(name)
if err != nil {
continue
}
ids = append(ids, u.Id)
}
return ids
}
// GetUserByEmail returns the user object by given e-mail if exists.
func GetUserByEmail(email string) (*User, error) {
if len(email) == 0 {
return nil, ErrUserNotExist
}
user := &User{Email: strings.ToLower(email)}
has, err := orm.Get(user)
has, err := x.Get(user)
if err != nil {
return nil, err
} else if !has {
@@ -408,22 +528,23 @@ func GetUserByEmail(email string) (*User, error) {
return user, nil
}
// LoginUserPlain validates user by raw user name and password.
func LoginUserPlain(name, passwd string) (*User, error) {
user := User{LowerName: strings.ToLower(name)}
has, err := orm.Get(&user)
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotExist
// SearchUserByName returns given number of users whose name contains keyword.
func SearchUserByName(opt SearchOption) (us []*User, err error) {
// Prevent SQL inject.
opt.Keyword = strings.TrimSpace(opt.Keyword)
if len(opt.Keyword) == 0 {
return us, nil
}
newUser := &User{Passwd: passwd, Salt: user.Salt}
newUser.EncodePasswd()
if user.Passwd != newUser.Passwd {
return nil, ErrUserNotExist
opt.Keyword = strings.Split(opt.Keyword, " ")[0]
if len(opt.Keyword) == 0 {
return us, nil
}
return &user, nil
opt.Keyword = strings.ToLower(opt.Keyword)
us = make([]*User, 0, opt.Limit)
err = x.Limit(opt.Limit).Where("type=0").And("lower_name like '%" + opt.Keyword + "%'").Find(&us)
return us, err
}
// Follow is connection request for receiving user notifycation.
@@ -435,7 +556,7 @@ type Follow struct {
// FollowUser marks someone be another's follower.
func FollowUser(userId int64, followId int64) (err error) {
session := orm.NewSession()
session := x.NewSession()
defer session.Close()
session.Begin()
@@ -460,7 +581,7 @@ func FollowUser(userId int64, followId int64) (err error) {
// UnFollowUser unmarks someone be another's follower.
func UnFollowUser(userId int64, unFollowId int64) (err error) {
session := orm.NewSession()
session := x.NewSession()
defer session.Close()
session.Begin()
@@ -482,3 +603,45 @@ func UnFollowUser(userId int64, unFollowId int64) (err error) {
}
return session.Commit()
}
func UpdateMentions(userNames []string, issueId int64) error {
users := make([]*User, 0, len(userNames))
if err := x.Where("name IN (?)", strings.Join(userNames, "\",\"")).OrderBy("name ASC").Find(&users); err != nil {
return err
}
ids := make([]int64, 0, len(userNames))
for _, user := range users {
ids = append(ids, user.Id)
if user.Type == INDIVIDUAL {
continue
}
if user.NumMembers == 0 {
continue
}
tempIds := make([]int64, 0, user.NumMembers)
orgUsers, err := GetOrgUsersByOrgId(user.Id)
if err != nil {
return err
}
for _, orgUser := range orgUsers {
tempIds = append(tempIds, orgUser.Id)
}
ids = append(ids, tempIds...)
}
if err := UpdateIssueUserPairsByMentions(ids, issueId); err != nil {
return err
}
return nil
}

302
models/webhook.go Normal file
View File

@@ -0,0 +1,302 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"encoding/json"
"errors"
"io/ioutil"
"time"
"github.com/gogits/gogs/modules/httplib"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
"github.com/gogits/gogs/modules/uuid"
)
var (
ErrWebhookNotExist = errors.New("Webhook does not exist")
)
type HookContentType int
const (
JSON HookContentType = iota + 1
FORM
)
// HookEvent represents events that will delivery hook.
type HookEvent struct {
PushOnly bool `json:"push_only"`
}
// Webhook represents a web hook object.
type Webhook struct {
Id int64
RepoId int64
Url string `xorm:"TEXT"`
ContentType HookContentType
Secret string `xorm:"TEXT"`
Events string `xorm:"TEXT"`
*HookEvent `xorm:"-"`
IsSsl bool
IsActive bool
HookTaskType HookTaskType
Meta string `xorm:"TEXT"` // store hook-specific attributes
OrgId int64
}
// GetEvent handles conversion from Events to HookEvent.
func (w *Webhook) GetEvent() {
w.HookEvent = &HookEvent{}
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
log.Error(4, "webhook.GetEvent(%d): %v", w.Id, err)
}
}
func (w *Webhook) GetSlackHook() *Slack {
s := &Slack{}
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
log.Error(4, "webhook.GetSlackHook(%d): %v", w.Id, err)
}
return s
}
// UpdateEvent handles conversion from HookEvent to Events.
func (w *Webhook) UpdateEvent() error {
data, err := json.Marshal(w.HookEvent)
w.Events = string(data)
return err
}
// HasPushEvent returns true if hook enbaled push event.
func (w *Webhook) HasPushEvent() bool {
if w.PushOnly {
return true
}
return false
}
// CreateWebhook creates a new web hook.
func CreateWebhook(w *Webhook) error {
_, err := x.Insert(w)
return err
}
// GetWebhookById returns webhook by given ID.
func GetWebhookById(hookId int64) (*Webhook, error) {
w := &Webhook{Id: hookId}
has, err := x.Get(w)
if err != nil {
return nil, err
} else if !has {
return nil, ErrWebhookNotExist
}
return w, nil
}
// GetActiveWebhooksByRepoId returns all active webhooks of repository.
func GetActiveWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
err = x.Where("repo_id=?", repoId).And("is_active=?", true).Find(&ws)
return ws, err
}
// GetWebhooksByRepoId returns all webhooks of repository.
func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
err = x.Find(&ws, &Webhook{RepoId: repoId})
return ws, err
}
// UpdateWebhook updates information of webhook.
func UpdateWebhook(w *Webhook) error {
_, err := x.Id(w.Id).AllCols().Update(w)
return err
}
// DeleteWebhook deletes webhook of repository.
func DeleteWebhook(hookId int64) error {
_, err := x.Delete(&Webhook{Id: hookId})
return err
}
// GetWebhooksByOrgId returns all webhooks for an organization.
func GetWebhooksByOrgId(orgId int64) (ws []*Webhook, err error) {
err = x.Find(&ws, &Webhook{OrgId: orgId})
return ws, err
}
// GetActiveWebhooksByOrgId returns all active webhooks for an organization.
func GetActiveWebhooksByOrgId(orgId int64) (ws []*Webhook, err error) {
err = x.Where("org_id=?", orgId).And("is_active=?", true).Find(&ws)
return ws, err
}
// ___ ___ __ ___________ __
// / | \ ____ ____ | | _\__ ___/____ _____| | __
// / ~ \/ _ \ / _ \| |/ / | | \__ \ / ___/ |/ /
// \ Y ( <_> | <_> ) < | | / __ \_\___ \| <
// \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \
// \/ \/ \/ \/ \/
type HookTaskType int
const (
GOGS HookTaskType = iota + 1
SLACK
)
type HookEventType string
const (
PUSH HookEventType = "push"
)
type PayloadAuthor struct {
Name string `json:"name"`
Email string `json:"email"`
UserName string `json:"username"`
}
type PayloadCommit struct {
Id string `json:"id"`
Message string `json:"message"`
Url string `json:"url"`
Author *PayloadAuthor `json:"author"`
}
type PayloadRepo struct {
Id int64 `json:"id"`
Name string `json:"name"`
Url string `json:"url"`
Description string `json:"description"`
Website string `json:"website"`
Watchers int `json:"watchers"`
Owner *PayloadAuthor `json:"owner"`
Private bool `json:"private"`
}
type BasePayload interface {
GetJSONPayload() ([]byte, error)
}
// Payload represents a payload information of hook.
type Payload struct {
Secret string `json:"secret"`
Ref string `json:"ref"`
Commits []*PayloadCommit `json:"commits"`
Repo *PayloadRepo `json:"repository"`
Pusher *PayloadAuthor `json:"pusher"`
Before string `json:"before"`
After string `json:"after"`
CompareUrl string `json:"compare_url"`
}
func (p Payload) GetJSONPayload() ([]byte, error) {
data, err := json.Marshal(p)
if err != nil {
return []byte{}, err
}
return data, nil
}
// HookTask represents a hook task.
type HookTask struct {
Id int64
Uuid string
Type HookTaskType
Url string
BasePayload `xorm:"-"`
PayloadContent string `xorm:"TEXT"`
ContentType HookContentType
EventType HookEventType
IsSsl bool
IsDelivered bool
IsSucceed bool
}
// CreateHookTask creates a new hook task,
// it handles conversion from Payload to PayloadContent.
func CreateHookTask(t *HookTask) error {
data, err := t.BasePayload.GetJSONPayload()
if err != nil {
return err
}
t.Uuid = uuid.NewV4().String()
t.PayloadContent = string(data)
_, err = x.Insert(t)
return err
}
// UpdateHookTask updates information of hook task.
func UpdateHookTask(t *HookTask) error {
_, err := x.Id(t.Id).AllCols().Update(t)
return err
}
// DeliverHooks checks and delivers undelivered hooks.
func DeliverHooks() {
tasks := make([]*HookTask, 0, 10)
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
x.Where("is_delivered=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
req := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Header("X-Gogs-Delivery", t.Uuid).
Header("X-Gogs-Event", string(t.EventType))
switch t.ContentType {
case JSON:
req = req.Header("Content-Type", "application/json").Body(t.PayloadContent)
case FORM:
req.Param("payload", t.PayloadContent)
}
t.IsDelivered = true
// TODO: record response.
switch t.Type {
case GOGS:
{
if _, err := req.Response(); err != nil {
log.Error(4, "Delivery: %v", err)
} else {
t.IsSucceed = true
}
}
case SLACK:
{
if res, err := req.Response(); err != nil {
log.Error(4, "Delivery: %v", err)
} else {
defer res.Body.Close()
contents, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Error(4, "%s", err)
} else {
if string(contents) != "ok" {
log.Error(4, "slack failed with: %s", string(contents))
} else {
t.IsSucceed = true
}
}
}
}
}
tasks = append(tasks, t)
if t.IsSucceed {
log.Trace("Hook delivered(%s): %s", t.Uuid, t.PayloadContent)
}
return nil
})
// Update hook task status.
for _, t := range tasks {
if err := UpdateHookTask(t); err != nil {
log.Error(4, "UpdateHookTask(%d): %v", t.Id, err)
}
}
}

27
modules/asn1-ber/LICENSE Normal file
View File

@@ -0,0 +1,27 @@
Copyright (c) 2012 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

11
modules/asn1-ber/Makefile Normal file
View File

@@ -0,0 +1,11 @@
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
include $(GOROOT)/src/Make.inc
TARG=github.com/mmitton/asn1-ber
GOFILES=\
ber.go\
include $(GOROOT)/src/Make.pkg

14
modules/asn1-ber/README Normal file
View File

@@ -0,0 +1,14 @@
ASN1 BER Encoding / Decoding Library for the GO programming language.
Required Librarys:
None
Working:
Very basic encoding / decoding needed for LDAP protocol
Tests Implemented:
None
TODO:
Fix all encoding / decoding to conform to ASN1 BER spec
Implement Tests / Benchmarks

492
modules/asn1-ber/ber.go Normal file
View File

@@ -0,0 +1,492 @@
package ber
import (
"bytes"
"fmt"
"io"
"reflect"
)
type Packet struct {
ClassType uint8
TagType uint8
Tag uint8
Value interface{}
ByteValue []byte
Data *bytes.Buffer
Children []*Packet
Description string
}
const (
TagEOC = 0x00
TagBoolean = 0x01
TagInteger = 0x02
TagBitString = 0x03
TagOctetString = 0x04
TagNULL = 0x05
TagObjectIdentifier = 0x06
TagObjectDescriptor = 0x07
TagExternal = 0x08
TagRealFloat = 0x09
TagEnumerated = 0x0a
TagEmbeddedPDV = 0x0b
TagUTF8String = 0x0c
TagRelativeOID = 0x0d
TagSequence = 0x10
TagSet = 0x11
TagNumericString = 0x12
TagPrintableString = 0x13
TagT61String = 0x14
TagVideotexString = 0x15
TagIA5String = 0x16
TagUTCTime = 0x17
TagGeneralizedTime = 0x18
TagGraphicString = 0x19
TagVisibleString = 0x1a
TagGeneralString = 0x1b
TagUniversalString = 0x1c
TagCharacterString = 0x1d
TagBMPString = 0x1e
TagBitmask = 0x1f // xxx11111b
)
var TagMap = map[uint8]string{
TagEOC: "EOC (End-of-Content)",
TagBoolean: "Boolean",
TagInteger: "Integer",
TagBitString: "Bit String",
TagOctetString: "Octet String",
TagNULL: "NULL",
TagObjectIdentifier: "Object Identifier",
TagObjectDescriptor: "Object Descriptor",
TagExternal: "External",
TagRealFloat: "Real (float)",
TagEnumerated: "Enumerated",
TagEmbeddedPDV: "Embedded PDV",
TagUTF8String: "UTF8 String",
TagRelativeOID: "Relative-OID",
TagSequence: "Sequence and Sequence of",
TagSet: "Set and Set OF",
TagNumericString: "Numeric String",
TagPrintableString: "Printable String",
TagT61String: "T61 String",
TagVideotexString: "Videotex String",
TagIA5String: "IA5 String",
TagUTCTime: "UTC Time",
TagGeneralizedTime: "Generalized Time",
TagGraphicString: "Graphic String",
TagVisibleString: "Visible String",
TagGeneralString: "General String",
TagUniversalString: "Universal String",
TagCharacterString: "Character String",
TagBMPString: "BMP String",
}
const (
ClassUniversal = 0 // 00xxxxxxb
ClassApplication = 64 // 01xxxxxxb
ClassContext = 128 // 10xxxxxxb
ClassPrivate = 192 // 11xxxxxxb
ClassBitmask = 192 // 11xxxxxxb
)
var ClassMap = map[uint8]string{
ClassUniversal: "Universal",
ClassApplication: "Application",
ClassContext: "Context",
ClassPrivate: "Private",
}
const (
TypePrimitive = 0 // xx0xxxxxb
TypeConstructed = 32 // xx1xxxxxb
TypeBitmask = 32 // xx1xxxxxb
)
var TypeMap = map[uint8]string{
TypePrimitive: "Primative",
TypeConstructed: "Constructed",
}
var Debug bool = false
func PrintBytes(buf []byte, indent string) {
data_lines := make([]string, (len(buf)/30)+1)
num_lines := make([]string, (len(buf)/30)+1)
for i, b := range buf {
data_lines[i/30] += fmt.Sprintf("%02x ", b)
num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
}
for i := 0; i < len(data_lines); i++ {
fmt.Print(indent + data_lines[i] + "\n")
fmt.Print(indent + num_lines[i] + "\n\n")
}
}
func PrintPacket(p *Packet) {
printPacket(p, 0, false)
}
func printPacket(p *Packet, indent int, printBytes bool) {
indent_str := ""
for len(indent_str) != indent {
indent_str += " "
}
class_str := ClassMap[p.ClassType]
tagtype_str := TypeMap[p.TagType]
tag_str := fmt.Sprintf("0x%02X", p.Tag)
if p.ClassType == ClassUniversal {
tag_str = TagMap[p.Tag]
}
value := fmt.Sprint(p.Value)
description := ""
if p.Description != "" {
description = p.Description + ": "
}
fmt.Printf("%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value)
if printBytes {
PrintBytes(p.Bytes(), indent_str)
}
for _, child := range p.Children {
printPacket(child, indent+1, printBytes)
}
}
func resizeBuffer(in []byte, new_size uint64) (out []byte) {
out = make([]byte, new_size)
copy(out, in)
return
}
func readBytes(reader io.Reader, buf []byte) error {
idx := 0
buflen := len(buf)
for idx < buflen {
n, err := reader.Read(buf[idx:])
if err != nil {
return err
}
idx += n
}
return nil
}
func ReadPacket(reader io.Reader) (*Packet, error) {
buf := make([]byte, 2)
err := readBytes(reader, buf)
if err != nil {
return nil, err
}
idx := uint64(2)
datalen := uint64(buf[1])
if Debug {
fmt.Printf("Read: datalen = %d len(buf) = %d ", datalen, len(buf))
for _, b := range buf {
fmt.Printf("%02X ", b)
}
fmt.Printf("\n")
}
if datalen&128 != 0 {
a := datalen - 128
idx += a
buf = resizeBuffer(buf, 2+a)
err := readBytes(reader, buf[2:])
if err != nil {
return nil, err
}
datalen = DecodeInteger(buf[2 : 2+a])
if Debug {
fmt.Printf("Read: a = %d idx = %d datalen = %d len(buf) = %d", a, idx, datalen, len(buf))
for _, b := range buf {
fmt.Printf("%02X ", b)
}
fmt.Printf("\n")
}
}
buf = resizeBuffer(buf, idx+datalen)
err = readBytes(reader, buf[idx:])
if err != nil {
return nil, err
}
if Debug {
fmt.Printf("Read: len( buf ) = %d idx=%d datalen=%d idx+datalen=%d\n", len(buf), idx, datalen, idx+datalen)
for _, b := range buf {
fmt.Printf("%02X ", b)
}
}
p := DecodePacket(buf)
return p, nil
}
func DecodeString(data []byte) (ret string) {
for _, c := range data {
ret += fmt.Sprintf("%c", c)
}
return
}
func DecodeInteger(data []byte) (ret uint64) {
for _, i := range data {
ret = ret * 256
ret = ret + uint64(i)
}
return
}
func EncodeInteger(val uint64) []byte {
var out bytes.Buffer
found := false
shift := uint(56)
mask := uint64(0xFF00000000000000)
for mask > 0 {
if !found && (val&mask != 0) {
found = true
}
if found || (shift == 0) {
out.Write([]byte{byte((val & mask) >> shift)})
}
shift -= 8
mask = mask >> 8
}
return out.Bytes()
}
func DecodePacket(data []byte) *Packet {
p, _ := decodePacket(data)
return p
}
func decodePacket(data []byte) (*Packet, []byte) {
if Debug {
fmt.Printf("decodePacket: enter %d\n", len(data))
}
p := new(Packet)
p.ClassType = data[0] & ClassBitmask
p.TagType = data[0] & TypeBitmask
p.Tag = data[0] & TagBitmask
datalen := DecodeInteger(data[1:2])
datapos := uint64(2)
if datalen&128 != 0 {
datalen -= 128
datapos += datalen
datalen = DecodeInteger(data[2 : 2+datalen])
}
p.Data = new(bytes.Buffer)
p.Children = make([]*Packet, 0, 2)
p.Value = nil
value_data := data[datapos : datapos+datalen]
if p.TagType == TypeConstructed {
for len(value_data) != 0 {
var child *Packet
child, value_data = decodePacket(value_data)
p.AppendChild(child)
}
} else if p.ClassType == ClassUniversal {
p.Data.Write(data[datapos : datapos+datalen])
p.ByteValue = value_data
switch p.Tag {
case TagEOC:
case TagBoolean:
val := DecodeInteger(value_data)
p.Value = val != 0
case TagInteger:
p.Value = DecodeInteger(value_data)
case TagBitString:
case TagOctetString:
p.Value = DecodeString(value_data)
case TagNULL:
case TagObjectIdentifier:
case TagObjectDescriptor:
case TagExternal:
case TagRealFloat:
case TagEnumerated:
p.Value = DecodeInteger(value_data)
case TagEmbeddedPDV:
case TagUTF8String:
case TagRelativeOID:
case TagSequence:
case TagSet:
case TagNumericString:
case TagPrintableString:
p.Value = DecodeString(value_data)
case TagT61String:
case TagVideotexString:
case TagIA5String:
case TagUTCTime:
case TagGeneralizedTime:
case TagGraphicString:
case TagVisibleString:
case TagGeneralString:
case TagUniversalString:
case TagCharacterString:
case TagBMPString:
}
} else {
p.Data.Write(data[datapos : datapos+datalen])
}
return p, data[datapos+datalen:]
}
func (p *Packet) DataLength() uint64 {
return uint64(p.Data.Len())
}
func (p *Packet) Bytes() []byte {
var out bytes.Buffer
out.Write([]byte{p.ClassType | p.TagType | p.Tag})
packet_length := EncodeInteger(p.DataLength())
if p.DataLength() > 127 || len(packet_length) > 1 {
out.Write([]byte{byte(len(packet_length) | 128)})
out.Write(packet_length)
} else {
out.Write(packet_length)
}
out.Write(p.Data.Bytes())
return out.Bytes()
}
func (p *Packet) AppendChild(child *Packet) {
p.Data.Write(child.Bytes())
if len(p.Children) == cap(p.Children) {
newChildren := make([]*Packet, cap(p.Children)*2)
copy(newChildren, p.Children)
p.Children = newChildren[0:len(p.Children)]
}
p.Children = p.Children[0 : len(p.Children)+1]
p.Children[len(p.Children)-1] = child
}
func Encode(ClassType, TagType, Tag uint8, Value interface{}, Description string) *Packet {
p := new(Packet)
p.ClassType = ClassType
p.TagType = TagType
p.Tag = Tag
p.Data = new(bytes.Buffer)
p.Children = make([]*Packet, 0, 2)
p.Value = Value
p.Description = Description
if Value != nil {
v := reflect.ValueOf(Value)
if ClassType == ClassUniversal {
switch Tag {
case TagOctetString:
sv, ok := v.Interface().(string)
if ok {
p.Data.Write([]byte(sv))
}
}
}
}
return p
}
func NewSequence(Description string) *Packet {
return Encode(ClassUniversal, TypePrimitive, TagSequence, nil, Description)
}
func NewBoolean(ClassType, TagType, Tag uint8, Value bool, Description string) *Packet {
intValue := 0
if Value {
intValue = 1
}
p := Encode(ClassType, TagType, Tag, nil, Description)
p.Value = Value
p.Data.Write(EncodeInteger(uint64(intValue)))
return p
}
func NewInteger(ClassType, TagType, Tag uint8, Value uint64, Description string) *Packet {
p := Encode(ClassType, TagType, Tag, nil, Description)
p.Value = Value
p.Data.Write(EncodeInteger(Value))
return p
}
func NewString(ClassType, TagType, Tag uint8, Value, Description string) *Packet {
p := Encode(ClassType, TagType, Tag, nil, Description)
p.Value = Value
p.Data.Write([]byte(Value))
return p
}

View File

@@ -5,49 +5,23 @@
package auth
import (
"net/http"
"reflect"
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/i18n"
"github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware/binding"
)
type AdminEditUserForm struct {
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Website string `form:"website" binding:"MaxSize(50)"`
Location string `form:"location" binding:"MaxSize(50)"`
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
Active string `form:"active"`
Admin string `form:"admin"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Passwd string `form:"password"`
Website string `form:"website" binding:"MaxSize(50)"`
Location string `form:"location" binding:"MaxSize(50)"`
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
Active bool `form:"active"`
Admin bool `form:"admin"`
LoginType int `form:"login_type"`
}
func (f *AdminEditUserForm) Name(field string) string {
names := map[string]string{
"Email": "E-mail address",
"Website": "Website",
"Location": "Location",
"Avatar": "Gravatar Email",
}
return names[field]
}
func (f *AdminEditUserForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("AdminEditUserForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}

View File

@@ -0,0 +1,79 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package apiv1
import (
"reflect"
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/i18n"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware/binding"
)
type MarkdownForm struct {
Text string `form:"text" binding:"Required"`
Mode string `form:"mode"`
Context string `form:"context"`
}
func (f *MarkdownForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validateApiReq(errs, ctx.Data, f, l)
}
func validateApiReq(errs *binding.Errors, data map[string]interface{}, f interface{}, l i18n.Locale) {
if errs.Count() == 0 {
return
} else if len(errs.Overall) > 0 {
for _, err := range errs.Overall {
log.Error(4, "%s: %v", reflect.TypeOf(f), err)
}
return
}
data["HasError"] = true
typ := reflect.TypeOf(f)
val := reflect.ValueOf(f)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
val = val.Elem()
}
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
fieldName := field.Tag.Get("form")
// Allow ignored fields in the struct
if fieldName == "-" {
continue
}
if err, ok := errs.Fields[field.Name]; ok {
switch err {
case binding.BindingRequireError:
data["ErrorMsg"] = fieldName + " cannot be empty"
case binding.BindingAlphaDashError:
data["ErrorMsg"] = fieldName + " must be valid alpha or numeric or dash(-_) characters"
case binding.BindingAlphaDashDotError:
data["ErrorMsg"] = fieldName + " must be valid alpha or numeric or dash(-_) or dot characters"
case binding.BindingMinSizeError:
data["ErrorMsg"] = fieldName + " must contain at least " + auth.GetMinSize(field) + " characters"
case binding.BindingMaxSizeError:
data["ErrorMsg"] = fieldName + " must contain at most " + auth.GetMaxSize(field) + " characters"
case binding.BindingEmailError:
data["ErrorMsg"] = fieldName + " is not a valid e-mail address"
case binding.BindingUrlError:
data["ErrorMsg"] = fieldName + " is not a valid URL"
default:
data["ErrorMsg"] = "Unknown error: " + err
}
return
}
}
}

View File

@@ -9,138 +9,68 @@ import (
"reflect"
"strings"
"github.com/go-martini/martini"
"github.com/macaron-contrib/i18n"
"github.com/macaron-contrib/session"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware/binding"
"github.com/gogits/gogs/modules/setting"
)
// Web form interface.
type Form interface {
Name(field string) string
}
type RegisterForm struct {
UserName string `form:"username" binding:"Required;AlphaDash;MaxSize(30)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
RetypePasswd string `form:"retypepasswd"`
}
func (f *RegisterForm) Name(field string) string {
names := map[string]string{
"UserName": "Username",
"Email": "E-mail address",
"Password": "Password",
"RetypePasswd": "Re-type password",
}
return names[field]
}
func (f *RegisterForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
// SignedInId returns the id of signed in user.
func SignedInId(header http.Header, sess session.Store) int64 {
if !models.HasEngine {
return 0
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("RegisterForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}
type LogInForm struct {
UserName string `form:"username" binding:"Required;AlphaDash;MaxSize(30)"`
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
Remember string `form:"remember"`
}
func (f *LogInForm) Name(field string) string {
names := map[string]string{
"UserName": "Username",
"Password": "Password",
}
return names[field]
}
func (f *LogInForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("LogInForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}
func getMinMaxSize(field reflect.StructField) string {
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") {
return rule[8 : len(rule)-1]
}
}
return ""
}
func validate(errors *base.BindingErrors, data base.TmplData, form Form) {
typ := reflect.TypeOf(form)
val := reflect.ValueOf(form)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
val = val.Elem()
}
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
fieldName := field.Tag.Get("form")
// Allow ignored fields in the struct
if fieldName == "-" {
continue
}
if err, ok := errors.Fields[field.Name]; ok {
data["Err_"+field.Name] = true
switch err {
case base.BindingRequireError:
data["ErrorMsg"] = form.Name(field.Name) + " cannot be empty"
case base.BindingAlphaDashError:
data["ErrorMsg"] = form.Name(field.Name) + " must be valid alpha or numeric or dash(-_) characters"
case base.BindingMinSizeError:
data["ErrorMsg"] = form.Name(field.Name) + " must contain at least " + getMinMaxSize(field) + " characters"
case base.BindingMaxSizeError:
data["ErrorMsg"] = form.Name(field.Name) + " must contain at most " + getMinMaxSize(field) + " characters"
case base.BindingEmailError:
data["ErrorMsg"] = form.Name(field.Name) + " is not a valid e-mail address"
case base.BindingUrlError:
data["ErrorMsg"] = form.Name(field.Name) + " is not a valid URL"
default:
data["ErrorMsg"] = "Unknown error: " + err
if setting.Service.EnableReverseProxyAuth {
webAuthUser := header.Get(setting.ReverseProxyAuthUser)
if len(webAuthUser) > 0 {
u, err := models.GetUserByName(webAuthUser)
if err != nil {
if err != models.ErrUserNotExist {
log.Error(4, "GetUserByName: %v", err)
}
return 0
}
return
return u.Id
}
}
uid := sess.Get("uid")
if uid == nil {
return 0
}
if id, ok := uid.(int64); ok {
if _, err := models.GetUserById(id); err != nil {
if err != models.ErrUserNotExist {
log.Error(4, "GetUserById: %v", err)
}
return 0
}
return id
}
return 0
}
// SignedInUser returns the user object of signed user.
func SignedInUser(header http.Header, sess session.Store) *models.User {
uid := SignedInId(header, sess)
if uid <= 0 {
return nil
}
u, err := models.GetUserById(uid)
if err != nil {
log.Error(4, "GetUserById: %v", err)
return nil
}
return u
}
// AssignForm assign form values back to the template data.
func AssignForm(form interface{}, data base.TmplData) {
func AssignForm(form interface{}, data map[string]interface{}) {
typ := reflect.TypeOf(form)
val := reflect.ValueOf(form)
@@ -162,53 +92,75 @@ func AssignForm(form interface{}, data base.TmplData) {
}
}
type InstallForm struct {
Database string `form:"database" binding:"Required"`
Host string `form:"host"`
User string `form:"user"`
Passwd string `form:"passwd"`
DatabaseName string `form:"database_name"`
SslMode string `form:"ssl_mode"`
DatabasePath string `form:"database_path"`
RepoRootPath string `form:"repo_path"`
RunUser string `form:"run_user"`
Domain string `form:"domain"`
AppUrl string `form:"app_url"`
AdminName string `form:"admin_name" binding:"Required"`
AdminPasswd string `form:"admin_pwd" binding:"Required;MinSize(6);MaxSize(30)"`
AdminEmail string `form:"admin_email" binding:"Required;Email;MaxSize(50)"`
SmtpHost string `form:"smtp_host"`
SmtpEmail string `form:"mailer_user"`
SmtpPasswd string `form:"mailer_pwd"`
RegisterConfirm string `form:"register_confirm"`
MailNotify string `form:"mail_notify"`
}
func (f *InstallForm) Name(field string) string {
names := map[string]string{
"Database": "Database name",
"AdminName": "Admin user name",
"AdminPasswd": "Admin password",
"AdminEmail": "Admin e-maill address",
func getSize(field reflect.StructField, prefix string) string {
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
if strings.HasPrefix(rule, prefix) {
return rule[8 : len(rule)-1]
}
}
return names[field]
return ""
}
func (f *InstallForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
func GetMinSize(field reflect.StructField) string {
return getSize(field, "MinSize(")
}
func GetMaxSize(field reflect.StructField) string {
return getSize(field, "MaxSize(")
}
func validate(errs *binding.Errors, data map[string]interface{}, f interface{}, l i18n.Locale) {
if errs.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("InstallForm.Validate: %v", err)
} else if len(errs.Overall) > 0 {
for _, err := range errs.Overall {
log.Error(4, "%s: %v", reflect.TypeOf(f), err)
}
return
}
validate(errors, data, f)
data["HasError"] = true
AssignForm(f, data)
typ := reflect.TypeOf(f)
val := reflect.ValueOf(f)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
val = val.Elem()
}
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
fieldName := field.Tag.Get("form")
// Allow ignored fields in the struct
if fieldName == "-" {
continue
}
if err, ok := errs.Fields[field.Name]; ok {
data["Err_"+field.Name] = true
trName := l.Tr("form." + field.Name)
switch err {
case binding.BindingRequireError:
data["ErrorMsg"] = trName + l.Tr("form.require_error")
case binding.BindingAlphaDashError:
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
case binding.BindingAlphaDashDotError:
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")
case binding.BindingMinSizeError:
data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field))
case binding.BindingMaxSizeError:
data["ErrorMsg"] = trName + l.Tr("form.max_size_error", GetMaxSize(field))
case binding.BindingEmailError:
data["ErrorMsg"] = trName + l.Tr("form.email_error")
case binding.BindingUrlError:
data["ErrorMsg"] = trName + l.Tr("form.url_error")
default:
data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + err
}
return
}
}
}

36
modules/auth/auth_form.go Normal file
View File

@@ -0,0 +1,36 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/i18n"
"github.com/gogits/gogs/modules/middleware/binding"
)
type AuthenticationForm struct {
Id int64 `form:"id"`
Type int `form:"type"`
AuthName string `form:"name" binding:"Required;MaxSize(50)"`
Domain string `form:"domain"`
Host string `form:"host"`
Port int `form:"port"`
UseSSL bool `form:"usessl"`
BaseDN string `form:"base_dn"`
Attributes string `form:"attributes"`
Filter string `form:"filter"`
MsAdSA string `form:"ms_ad_sa"`
IsActived bool `form:"is_actived"`
SmtpAuth string `form:"smtpauth"`
SmtpHost string `form:"smtphost"`
SmtpPort int `form:"smtpport"`
Tls bool `form:"tls"`
AllowAutoRegister bool `form:"allowautoregister"`
}
func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}

View File

@@ -1,49 +0,0 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"net/http"
"reflect"
"github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
)
type CreateIssueForm struct {
IssueName string `form:"title" binding:"Required;MaxSize(50)"`
MilestoneId int64 `form:"milestoneid"`
AssigneeId int64 `form:"assigneeid"`
Labels string `form:"labels"`
Content string `form:"content"`
}
func (f *CreateIssueForm) Name(field string) string {
names := map[string]string{
"IssueName": "Issue name",
}
return names[field]
}
func (f *CreateIssueForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("CreateIssueForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}

View File

@@ -0,0 +1,43 @@
LDAP authentication
===================
## Goal
Authenticat user against LDAP directories
It will bind with the user's login/pasword and query attributs ("mail" for instance) in a pool of directory servers
The first OK wins.
If there's connection error, the server will be disabled and won't be checked again
## Usage
In the [security] section, set
> LDAP_AUTH = true
then for each LDAP source, set
> [LdapSource-someuniquename]
> name=canonicalName
> host=hostname-or-ip
> port=3268 # or regular LDAP port
> # the following settings depend highly how you've configured your AD
> basedn=dc=ACME,dc=COM
> MSADSAFORMAT=%s@ACME.COM
> filter=(&(objectClass=user)(sAMAccountName=%s))
### Limitation
Only tested on an MS 2008R2 DC, using global catalog (TCP/3268)
This MSAD is a mess.
The way how one checks the directory (CN, DN etc...) may be highly depending local custom configuration
### Todo
* Define a timeout per server
* Check servers marked as "Disabled" when they'll come back online
* Find a more flexible way to define filter/MSADSAFORMAT/Attributes etc... maybe text/template ?
* Check OpenLDAP server
* SSL support ?

96
modules/auth/ldap/ldap.go Normal file
View File

@@ -0,0 +1,96 @@
// Copyright github.com/juju2013. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// package ldap provide functions & structure to query a LDAP ldap directory
// For now, it's mainly tested again an MS Active Directory service, see README.md for more information
package ldap
import (
"fmt"
"github.com/gogits/gogs/modules/ldap"
"github.com/gogits/gogs/modules/log"
)
// Basic LDAP authentication service
type Ldapsource struct {
Name string // canonical name (ie. corporate.ad)
Host string // LDAP host
Port int // port number
UseSSL bool // Use SSL
BaseDN string // Base DN
Attributes string // Attribut to search
Filter string // Query filter to validate entry
MsAdSAFormat string // in the case of MS AD Simple Authen, the format to use (see: http://msdn.microsoft.com/en-us/library/cc223499.aspx)
Enabled bool // if this source is disabled
}
//Global LDAP directory pool
var (
Authensource []Ldapsource
)
// Add a new source (LDAP directory) to the global pool
func AddSource(name string, host string, port int, usessl bool, basedn string, attributes string, filter string, msadsaformat string) {
ldaphost := Ldapsource{name, host, port, usessl, basedn, attributes, filter, msadsaformat, true}
Authensource = append(Authensource, ldaphost)
}
//LoginUser : try to login an user to LDAP sources, return requested (attribut,true) if ok, ("",false) other wise
//First match wins
//Returns first attribute if exists
func LoginUser(name, passwd string) (a string, r bool) {
r = false
for _, ls := range Authensource {
a, r = ls.SearchEntry(name, passwd)
if r {
return
}
}
return
}
// searchEntry : search an LDAP source if an entry (name, passwd) is valide and in the specific filter
func (ls Ldapsource) SearchEntry(name, passwd string) (string, bool) {
l, err := ldapDial(ls)
if err != nil {
log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err)
ls.Enabled = false
return "", false
}
defer l.Close()
nx := fmt.Sprintf(ls.MsAdSAFormat, name)
err = l.Bind(nx, passwd)
if err != nil {
log.Debug("LDAP Authan failed for %s, reason: %s", nx, err.Error())
return "", false
}
search := ldap.NewSearchRequest(
ls.BaseDN,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf(ls.Filter, name),
[]string{ls.Attributes},
nil)
sr, err := l.Search(search)
if err != nil {
log.Debug("LDAP Authen OK but not in filter %s", name)
return "", false
}
log.Debug("LDAP Authen OK: %s", name)
if len(sr.Entries) > 0 {
r := sr.Entries[0].GetAttributeValue(ls.Attributes)
return r, true
}
return "", true
}
func ldapDial(ls Ldapsource) (*ldap.Conn, error) {
if ls.UseSSL {
return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), nil)
} else {
return ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
}
}

View File

@@ -0,0 +1,29 @@
package ldap
// import (
// "fmt"
// "testing"
// )
// var ldapServer = "ldap.itd.umich.edu"
// var ldapPort = 389
// var baseDN = "dc=umich,dc=edu"
// var filter = []string{
// "(cn=cis-fac)",
// "(&(objectclass=rfc822mailgroup)(cn=*Computer*))",
// "(&(objectclass=rfc822mailgroup)(cn=*Mathematics*))"}
// var attributes = []string{
// "cn",
// "description"}
// var msadsaformat = ""
// func TestLDAP(t *testing.T) {
// AddSource("test", ldapServer, ldapPort, baseDN, attributes, filter, msadsaformat)
// user, err := LoginUserLdap("xiaolunwen", "")
// if err != nil {
// t.Error(err)
// return
// }
// fmt.Println(user)
// }

59
modules/auth/org.go Normal file
View File

@@ -0,0 +1,59 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/i18n"
"github.com/gogits/gogs/modules/middleware/binding"
)
// ________ .__ __ .__
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
// / | \ | \/ /_/ > __ \| | \ |/ / / __ \| | | ( <_> ) | \
// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
// \/ /_____/ \/ \/ \/ \/ \/
type CreateOrgForm struct {
OrgName string `form:"org_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
}
func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
type UpdateOrgSettingForm struct {
OrgUserName string `form:"uname" binding:"Required;MaxSize(35)"`
OrgFullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Description string `form:"desc" binding:"MaxSize(255)"`
Website string `form:"website" binding:"Url;MaxSize(100)"`
Location string `form:"location" binding:"MaxSize(50)"`
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
}
func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// ___________
// \__ ___/___ _____ _____
// | |_/ __ \\__ \ / \
// | |\ ___/ / __ \| Y Y \
// |____| \___ >____ /__|_| /
// \/ \/ \/
type CreateTeamForm struct {
TeamName string `form:"team_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `form:"desc" binding:"MaxSize(255)"`
Permission string `form:"permission"`
}
func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}

View File

@@ -0,0 +1,21 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/i18n"
"github.com/gogits/gogs/modules/middleware/binding"
)
type AddSSHKeyForm struct {
SSHTitle string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
}
func (f *AddSSHKeyForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}

View File

@@ -1,50 +0,0 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"net/http"
"reflect"
"github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
)
type NewReleaseForm struct {
TagName string `form:"tag_name" binding:"Required"`
Title string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
Prerelease bool `form:"prerelease"`
}
func (f *NewReleaseForm) Name(field string) string {
names := map[string]string{
"TagName": "Tag name",
"Title": "Release title",
"Content": "Release content",
}
return names[field]
}
func (f *NewReleaseForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("NewReleaseForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}

View File

@@ -1,89 +0,0 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"net/http"
"reflect"
"github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
)
type CreateRepoForm struct {
RepoName string `form:"repo" binding:"Required;AlphaDash"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(100)"`
Language string `form:"language"`
License string `form:"license"`
InitReadme bool `form:"initReadme"`
}
func (f *CreateRepoForm) Name(field string) string {
names := map[string]string{
"RepoName": "Repository name",
"Description": "Description",
}
return names[field]
}
func (f *CreateRepoForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("CreateRepoForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}
type MigrateRepoForm struct {
Url string `form:"url" binding:"Url"`
AuthUserName string `form:"auth_username"`
AuthPasswd string `form:"auth_password"`
RepoName string `form:"repo" binding:"Required;AlphaDash"`
Mirror bool `form:"mirror"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(100)"`
}
func (f *MigrateRepoForm) Name(field string) string {
names := map[string]string{
"Url": "Migration URL",
"RepoName": "Repository name",
"Description": "Description",
}
return names[field]
}
func (f *MigrateRepoForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("MigrateRepoForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}

179
modules/auth/repo_form.go Normal file
View File

@@ -0,0 +1,179 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/i18n"
"github.com/gogits/gogs/modules/middleware/binding"
)
// _______________________________________ _________.______________________ _______________.___.
// \______ \_ _____/\______ \_____ \ / _____/| \__ ___/\_____ \\______ \__ | |
// | _/| __)_ | ___// | \ \_____ \ | | | | / | \| _// | |
// | | \| \ | | / | \/ \| | | | / | \ | \\____ |
// |____|_ /_______ / |____| \_______ /_______ /|___| |____| \_______ /____|_ // ______|
// \/ \/ \/ \/ \/ \/ \/
type CreateRepoForm struct {
Uid int64 `form:"uid" binding:"Required"`
RepoName string `form:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(255)"`
Gitignore string `form:"gitignore"`
License string `form:"license"`
InitReadme bool `form:"init_readme"`
}
func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
type MigrateRepoForm struct {
HttpsUrl string `form:"url" binding:"Required;Url"`
AuthUserName string `form:"auth_username"`
AuthPasswd string `form:"auth_password"`
Uid int64 `form:"uid" binding:"Required"`
RepoName string `form:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Mirror bool `form:"mirror"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(255)"`
}
func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
type RepoSettingForm struct {
RepoName string `form:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Description string `form:"desc" binding:"MaxSize(255)"`
Website string `form:"site" binding:"Url;MaxSize(100)"`
Branch string `form:"branch"`
Interval int `form:"interval"`
Private bool `form:"private"`
GoGet bool `form:"goget"`
}
func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// __ __ ___. .__ .__ __
// / \ / \ ____\_ |__ | |__ | |__ ____ | | __
// \ \/\/ // __ \| __ \| | \| | \ / _ \| |/ /
// \ /\ ___/| \_\ \ Y \ Y ( <_> ) <
// \__/\ / \___ >___ /___| /___| /\____/|__|_ \
// \/ \/ \/ \/ \/ \/
type NewWebhookForm struct {
HookTaskType string `form:"hook_type" binding:"Required"`
PayloadUrl string `form:"payload_url" binding:"Required;Url"`
ContentType string `form:"content_type" binding:"Required"`
Secret string `form:"secret"`
PushOnly bool `form:"push_only"`
Active bool `form:"active"`
}
func (f *NewWebhookForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
type NewSlackHookForm struct {
HookTaskType string `form:"hook_type" binding:"Required"`
Domain string `form:"domain" binding:"Required`
Token string `form:"token" binding:"Required"`
Channel string `form:"channel" binding:"Required"`
PushOnly bool `form:"push_only"`
Active bool `form:"active"`
}
func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// .___
// | | ______ ________ __ ____
// | |/ ___// ___/ | \_/ __ \
// | |\___ \ \___ \| | /\ ___/
// |___/____ >____ >____/ \___ >
// \/ \/ \/
type CreateIssueForm struct {
IssueName string `form:"title" binding:"Required;MaxSize(50)"`
MilestoneId int64 `form:"milestoneid"`
AssigneeId int64 `form:"assigneeid"`
Labels string `form:"labels"`
Content string `form:"content"`
}
func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// _____ .__.__ __
// / \ |__| | ____ _______/ |_ ____ ____ ____
// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
// / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/
// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
// \/ \/ \/ \/ \/
type CreateMilestoneForm struct {
Title string `form:"title" binding:"Required;MaxSize(50)"`
Content string `form:"content"`
Deadline string `form:"due_date"`
}
func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// .____ ___. .__
// | | _____ \_ |__ ____ | |
// | | \__ \ | __ \_/ __ \| |
// | |___ / __ \| \_\ \ ___/| |__
// |_______ (____ /___ /\___ >____/
// \/ \/ \/ \/
type CreateLabelForm struct {
Title string `form:"title" binding:"Required;MaxSize(50)"`
Color string `form:"color" binding:"Required;Size(7)"`
}
func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// __________ .__
// \______ \ ____ | | ____ _____ ______ ____
// | _// __ \| | _/ __ \\__ \ / ___// __ \
// | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
// |____|_ /\___ >____/\___ >____ /____ >\___ >
// \/ \/ \/ \/ \/ \/
type NewReleaseForm struct {
TagName string `form:"tag_name" binding:"Required"`
Target string `form:"tag_target" binding:"Required"`
Title string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
Draft string `form:"draft"`
Prerelease bool `form:"prerelease"`
}
func (f *NewReleaseForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
type EditReleaseForm struct {
Target string `form:"tag_target" binding:"Required"`
Title string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
Draft string `form:"draft"`
Prerelease bool `form:"prerelease"`
}
func (f *EditReleaseForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}

View File

@@ -1,53 +0,0 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"net/http"
"reflect"
"strings"
"github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
)
type AddSSHKeyForm struct {
KeyName string `form:"keyname" binding:"Required"`
KeyContent string `form:"key_content" binding:"Required"`
}
func (f *AddSSHKeyForm) Name(field string) string {
names := map[string]string{
"KeyName": "SSH key name",
"KeyContent": "SSH key content",
}
return names[field]
}
func (f *AddSSHKeyForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
AssignForm(f, data)
if req.Method == "GET" || errors.Count() == 0 {
if req.Method == "POST" &&
(len(f.KeyContent) < 100 || !strings.HasPrefix(f.KeyContent, "ssh-rsa")) {
data["HasError"] = true
data["ErrorMsg"] = "SSH key content is not valid"
}
return
}
data["HasError"] = true
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("AddSSHKeyForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}

View File

@@ -1,144 +0,0 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"net/http"
"reflect"
"github.com/go-martini/martini"
"github.com/gogits/session"
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
)
// SignedInId returns the id of signed in user.
func SignedInId(session session.SessionStore) int64 {
if !models.HasEngine {
return 0
}
userId := session.Get("userId")
if userId == nil {
return 0
}
if s, ok := userId.(int64); ok {
if _, err := models.GetUserById(s); err != nil {
return 0
}
return s
}
return 0
}
// SignedInName returns the name of signed in user.
func SignedInName(session session.SessionStore) string {
userName := session.Get("userName")
if userName == nil {
return ""
}
if s, ok := userName.(string); ok {
return s
}
return ""
}
// SignedInUser returns the user object of signed user.
func SignedInUser(session session.SessionStore) *models.User {
id := SignedInId(session)
if id <= 0 {
return nil
}
user, err := models.GetUserById(id)
if err != nil {
log.Error("user.SignedInUser: %v", err)
return nil
}
return user
}
// IsSignedIn check if any user has signed in.
func IsSignedIn(session session.SessionStore) bool {
return SignedInId(session) > 0
}
type FeedsForm struct {
UserId int64 `form:"userid" binding:"Required"`
Page int64 `form:"p"`
}
type UpdateProfileForm struct {
UserName string `form:"username" binding:"Required;AlphaDash;MaxSize(30)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Website string `form:"website" binding:"MaxSize(50)"`
Location string `form:"location" binding:"MaxSize(50)"`
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
}
func (f *UpdateProfileForm) Name(field string) string {
names := map[string]string{
"UserName": "Username",
"Email": "E-mail address",
"Website": "Website",
"Location": "Location",
"Avatar": "Gravatar Email",
}
return names[field]
}
func (f *UpdateProfileForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("UpdateProfileForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}
type UpdatePasswdForm struct {
OldPasswd string `form:"oldpasswd" binding:"Required;MinSize(6);MaxSize(30)"`
NewPasswd string `form:"newpasswd" binding:"Required;MinSize(6);MaxSize(30)"`
RetypePasswd string `form:"retypepasswd"`
}
func (f *UpdatePasswdForm) Name(field string) string {
names := map[string]string{
"OldPasswd": "Old password",
"NewPasswd": "New password",
"RetypePasswd": "Re-type password",
}
return names[field]
}
func (f *UpdatePasswdForm) Validate(errors *base.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("UpdatePasswdForm.Validate: %v", err)
}
return
}
validate(errors, data, f)
}

99
modules/auth/user_form.go Normal file
View File

@@ -0,0 +1,99 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/i18n"
"github.com/gogits/gogs/modules/middleware/binding"
)
type InstallForm struct {
Database string `form:"database" binding:"Required"`
DbHost string `form:"host"`
DbUser string `form:"user"`
DbPasswd string `form:"passwd"`
DatabaseName string `form:"database_name"`
SslMode string `form:"ssl_mode"`
DatabasePath string `form:"database_path"`
RepoRootPath string `form:"repo_path" binding:"Required"`
RunUser string `form:"run_user" binding:"Required"`
Domain string `form:"domain" binding:"Required"`
AppUrl string `form:"app_url" binding:"Required"`
SmtpHost string `form:"smtp_host"`
SmtpEmail string `form:"mailer_user"`
SmtpPasswd string `form:"mailer_pwd"`
RegisterConfirm string `form:"register_confirm"`
MailNotify string `form:"mail_notify"`
AdminName string `form:"admin_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
AdminPasswd string `form:"admin_pwd" binding:"Required;MinSize(6);MaxSize(255)"`
ConfirmPasswd string `form:"confirm_passwd" binding:"Required;MinSize(6);MaxSize(255)"`
AdminEmail string `form:"admin_email" binding:"Required;Email;MaxSize(50)"`
}
func (f *InstallForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// _____ ____ _________________ ___
// / _ \ | | \__ ___/ | \
// / /_\ \| | / | | / ~ \
// / | \ | / | | \ Y /
// \____|__ /______/ |____| \___|_ /
// \/ \/
type RegisterForm struct {
UserName string `form:"uname" binding:"Required;AlphaDashDot;MaxSize(35)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Password string `form:"password" binding:"Required;MinSize(6);MaxSize(255)"`
Retype string `form:"retype"`
LoginType string `form:"logintype"`
LoginName string `form:"loginname"`
}
func (f *RegisterForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
type SignInForm struct {
UserName string `form:"uname" binding:"Required;MaxSize(35)"`
Password string `form:"password" binding:"Required;MinSize(6);MaxSize(255)"`
Remember bool `form:"remember"`
}
func (f *SignInForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
// __________________________________________.___ _______ ________ _________
// / _____/\_ _____/\__ ___/\__ ___/| |\ \ / _____/ / _____/
// \_____ \ | __)_ | | | | | |/ | \/ \ ___ \_____ \
// / \ | \ | | | | | / | \ \_\ \/ \
// /_______ //_______ / |____| |____| |___\____|__ /\______ /_______ /
// \/ \/ \/ \/ \/
type UpdateProfileForm struct {
UserName string `form:"uname" binding:"Required;MaxSize(35)"`
FullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Website string `form:"website" binding:"Url;MaxSize(100)"`
Location string `form:"location" binding:"MaxSize(50)"`
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
}
func (f *UpdateProfileForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
type ChangePasswordForm struct {
OldPassword string `form:"old_password" binding:"Required;MinSize(6);MaxSize(255)"`
Password string `form:"password" binding:"Required;MinSize(6);MaxSize(255)"`
Retype string `form:"retype"`
}
func (f *ChangePasswordForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}

View File

@@ -5,54 +5,12 @@
package base
type (
// Type TmplData represents data in the templates.
TmplData map[string]interface{}
)
TplName string
// __________.__ .___.__
// \______ \__| ____ __| _/|__| ____ ____
// | | _/ |/ \ / __ | | |/ \ / ___\
// | | \ | | \/ /_/ | | | | \/ /_/ >
// |______ /__|___| /\____ | |__|___| /\___ /
// \/ \/ \/ \//_____/
// Errors represents the contract of the response body when the
// binding step fails before getting to the application.
type BindingErrors struct {
Overall map[string]string `json:"overall"`
Fields map[string]string `json:"fields"`
}
// Total errors is the sum of errors with the request overall
// and errors on individual fields.
func (err BindingErrors) Count() int {
return len(err.Overall) + len(err.Fields)
}
func (this *BindingErrors) Combine(other BindingErrors) {
for key, val := range other.Fields {
if _, exists := this.Fields[key]; !exists {
this.Fields[key] = val
}
ApiJsonErr struct {
Message string `json:"message"`
DocUrl string `json:"documentation_url"`
}
for key, val := range other.Overall {
if _, exists := this.Overall[key]; !exists {
this.Overall[key] = val
}
}
}
const (
BindingRequireError string = "Required"
BindingAlphaDashError string = "AlphaDash"
BindingMinSizeError string = "MinSize"
BindingMaxSizeError string = "MaxSize"
BindingEmailError string = "Email"
BindingUrlError string = "Url"
BindingDeserializationError string = "DeserializationError"
BindingIntegerTypeError string = "IntegerTypeError"
BindingBooleanTypeError string = "BooleanTypeError"
BindingFloatTypeError string = "FloatTypeError"
)
var GoGetMetas = make(map[string]bool)

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