xaizek / rocketgit (License: AGPLv3+) (since 2018-12-09)
Light and fast Git hosting solution suitable to serve both as a hub or as a personal code storage with its tickets, pull requests, API and much more.
Commit 16a893cae9b7754a3e9ff9a0f380c00ccc52a907

Checkpoint
Author: Catalin(ux) M. BOIE
Author date (UTC): 2013-02-05 19:35
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2013-02-05 19:39
Parent(s): 30f559c9d7701b0a06344f286f113e154a39805b
Signing key:
Tree: 0b824311c1fd9b3acea73c698db91021a0141351
File Lines added Lines deleted
.exclude 0 2
Makefile.in 22 15
README 7 2
TODO 65 47
inc/bug.inc.php 322 95
inc/fixes.inc.php 2 0
inc/prof.inc.php 1 1
inc/repo.inc.php 17 13
inc/ssh.inc.php 2 2
inc/struct.inc.php 12 0
inc/user.inc.php 2 6
inc/user/repo-page.php 6 2
inc/user/repo/bug/add/add.php 6 31
inc/user/repo/bug/main.php 1 1
inc/user/repo/bug/show/add_note.php 43 0
inc/user/repo/bug/show/edit.php 38 0
inc/user/repo/bug/show/show.php 80 41
inc/util.inc.php 59 10
inc/watch.inc.php 190 0
rocketgit.spec.in 42 19
root/index.php 1 1
root/themes/default/mail/user/repo/bug/new.body.txt 19 0
root/themes/default/mail/user/repo/bug/new.head.txt 0 0
root/themes/default/mail/user/repo/bug/new.subj.txt 1 0
root/themes/default/mail/user/repo/bug/new_note.body.txt 16 0
root/themes/default/mail/user/repo/bug/new_note.head.txt 0 0
root/themes/default/mail/user/repo/bug/new_note.subj.txt 1 0
root/themes/default/mail/user/repo/new.body.txt 1 0
root/themes/default/mail/user/repo/update.body.txt 2 0
root/themes/default/main.css 31 8
root/themes/default/repo/bug/b_close.html 7 0
root/themes/default/repo/bug/b_edit.html 6 0
root/themes/default/repo/bug/b_reopen.html 7 0
root/themes/default/repo/bug/b_unwatch.html 6 0
root/themes/default/repo/bug/b_watch.html 6 0
root/themes/default/repo/bug/bug_add_edit.html 8 2
root/themes/default/repo/bug/list/line.html 2 2
root/themes/default/repo/bug/note_add.html 1 1
root/themes/default/repo/bug/show.html 23 5
samples/cron 2 2
samples/rg.conf 3 2
scripts/cron.sh 14 0
scripts/events.php 1 0
scripts/events.sh 1 1
scripts/q.sh 3 3
scripts/remote.php 1 1
selinux/.gitignore 2 0
selinux/build.sh 20 0
selinux/rocketgit.fc 16 0
selinux/rocketgit.if 0 0
selinux/rocketgit.te 124 0
tests/Makefile 1 1
tests/bug.php 5 2
tests/repo.php 1 1
File .exclude changed (mode: 100644) (index 6b34cf2..f3c7a7c)
1 *.log
2 1 Makefile Makefile
3 *.out
File Makefile.in changed (mode: 100644) (index 1ff9dbc..f273734)
1 1 .PHONY: all .PHONY: all
2 all: junk
2 all: selinux
3 3
4 .PHONY:
5 junk:
6 @-/bin/true
7 @echo "Done!"
4 .PHONY: selinux
5 selinux:
6 @echo "Building SELinux..."
7 cd selinux && ./build.sh
8 8
9 9 .PHONY: clean .PHONY: clean
10 10 clean: clean:
11 make -C tests clean
11 12 @-rm -f $(PRJ)-*.rpm $(PRJ)-*-*-*.tgz $(PRJ)-*.tar.gz @-rm -f $(PRJ)-*.rpm $(PRJ)-*-*-*.tgz $(PRJ)-*.tar.gz
13 @-rm -rf selinux/out
14 @find . -type f -name '*.strace' -exec rm -f {} \;
15 @find . -type f -name '*.log' -exec rm -f {} \;
16 @find . -type f -name '*.out' -exec rm -f {} \;
12 17
13 18 install: all install: all
14 19 @mkdir -p $(I_USR_SHARE)/$(PRJ) @mkdir -p $(I_USR_SHARE)/$(PRJ)
15 20 cp -vdr admin inc hooks root scripts $(I_USR_SHARE)/$(PRJ) cp -vdr admin inc hooks root scripts $(I_USR_SHARE)/$(PRJ)
16 21 @mkdir -p $(I_ETC)/xinetd.d @mkdir -p $(I_ETC)/xinetd.d
17 cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/rocketgit
22 cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/$(PRJ)
18 23 @mkdir -p $(I_ETC)/cron.d @mkdir -p $(I_ETC)/cron.d
19 cp -vd samples/cron $(I_ETC)/cron.d/rocketgit
24 cp -vd samples/cron $(I_ETC)/cron.d/$(PRJ)
20 25 @mkdir -p $(I_ETC)/httpd/conf.d @mkdir -p $(I_ETC)/httpd/conf.d
21 cp -vd --no-clobber samples/rg.conf $(I_ETC)/httpd/conf.d/rocketgit.conf
22 @mkdir -p $(I_ETC)/rocketgit
23 cp -vd --no-clobber samples/config.php $(I_ETC)/rocketgit/
24 cp -vd samples/config.php $(I_ETC)/rocketgit/config.php.sample
26 cp -vd --no-clobber samples/rg.conf $(I_ETC)/httpd/conf.d/$(PRJ).conf
27 @mkdir -p $(I_ETC)/$(PRJ)
28 cp -vd --no-clobber samples/config.php $(I_ETC)/$(PRJ)/
29 cp -vd samples/config.php $(I_ETC)/$(PRJ)/config.php.sample
25 30 @mkdir -p $(I_ETC)/logrotate.d @mkdir -p $(I_ETC)/logrotate.d
26 cp -vd samples/logrotate $(I_ETC)/logrotate.d/rocketgit
31 cp -vd samples/logrotate $(I_ETC)/logrotate.d/$(PRJ)
27 32 @mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ) @mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ)
28 @chown rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ)
33 @-chown rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ)
29 34 @chmod 0700 $(I_VAR_LOG)/$(PRJ) @chmod 0700 $(I_VAR_LOG)/$(PRJ)
30 35 @mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ)-web @mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ)-web
31 @chown apache:apache $(I_VAR_LOG)/$(PRJ)-web
36 @-chown apache:apache $(I_VAR_LOG)/$(PRJ)-web
32 37 @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ) @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)
33 38 @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/locks @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/locks
34 39 @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/repos @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/repos
35 40 @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/q_merge_requests @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/q_merge_requests
36 41 @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/qstats @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/qstats
37 42 @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/sockets @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/sockets
38 @chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ)
43 @-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ)
44 @mkdir -p --mode=0755 $(I_USR_SHARE)/selinux/targeted
45 cp -vd selinux/out/$(PRJ)-targeted.pp $(I_USR_SHARE)/selinux/targeted/$(PRJ).pp
File README changed (mode: 100644) (index c9877b4..ce94995)
58 58 md5 for authentication. Also, you may want to change 'listen_addresses' md5 for authentication. Also, you may want to change 'listen_addresses'
59 59 to '*'. You may also want to activate SSL. Check PostgreSQL manual. to '*'. You may also want to activate SSL. Check PostgreSQL manual.
60 60
61 . Mail
62 To be able to generate e-mails as other user, you have to:
63 For sendmail:
64 - Edit /etc/mail/trusted-users and add 'rocketgit'.
65 - Run 'make -C /etc/mail'.
66 - Restart daemon: 'systemctl restart sendmail.service' (Fedora)
67
61 68 . Run instalation script . Run instalation script
62 69 # php /usr/share/rocketgit/admin/init.php # php /usr/share/rocketgit/admin/init.php
63 70
 
77 84 . PHP . PHP
78 85 Adjust php.ini to allow enough RAM and execution time. Adjust php.ini to allow enough RAM and execution time.
79 86
80 . Mail
81 For sendmail, add rocketgit user to /etc/mail/trusted-users.
82 87
83 88 == Thanks == == Thanks ==
84 89 . Special thanks to my family that supported me in this project. . Special thanks to my family that supported me in this project.
File TODO changed (mode: 100644) (index d9694e6..f81b7b3)
1 == BEFORE NEXT RELEASE ==
2
1 3 == BEFORE FIRST RELEASE! == == BEFORE FIRST RELEASE! ==
2 [ ] Remove last form in PHP: user.form.php.
3 [ ] type=1400 audit(1357428371.130:170): avc: denied { connectto } for pid=20687 comm="httpd" path="/var/lib/rocketgit/sockets/event.sock" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:system_cronjob_t:s0-s0:c0.c1023 tclass=unix_stream_socket
4 [ ] type=1400 audit(1357428371.166:171): avc: denied { read write } for pid=18085 comm="sendmail" path="/var/lib/rocketgit/locks/events.sh.lock" dev="sda3" ino=50862906 scontext=system_u:system_r:system_mail_t:s0-s0:c0.c1023 tcontext=system_u:object_r:cron_var_lib_t:s0 tclass=file
5 [ ] Current menu is not correctly shown as selected.
6 [ ] Use (organization, user, repo) instead of user/repo only.
4 [ ] Check if adding/editing a bug generates notifications correctly.
5 Maybe use a global function for notify_one.
6 [ ] When we cannot process an event, mark it as failed and do not touch it again.
7 7 [ ] Big confusion! An logged in user has a different ID than the one of the repo [ ] Big confusion! An logged in user has a different ID than the one of the repo
8 8 and it may have admin rights! Audit everything (rg_ui/login_ui/$uid). and it may have admin rights! Audit everything (rg_ui/login_ui/$uid).
9 [ ] X-Authentication-Warning: r1.dyn.embedromix.ro: rocketgit set sender to
10 rg1@embedromix.ro using -f
11 9 [ ] Checking mtime of event.php is not enough. Maybe checking version. [ ] Checking mtime of event.php is not enough. Maybe checking version.
12 10 Think of includes that may change. Think of includes that may change.
13 11 [ ] Fix this shit: isset($_REQUEST['rights']) ? rg_rights_a2s(rg_var_str("rights")) : $rg [ ] Fix this shit: isset($_REQUEST['rights']) ? rg_rights_a2s(rg_var_str("rights")) : $rg
14 [ ] bug tracker is private?
15 [ ] It is not clear that the owner has full rights (repo->admin->edit).
16 12 [ ] Checking for "rg_ui['uid'] == 0" may not be enough. [ ] Checking for "rg_ui['uid'] == 0" may not be enough.
17 13 Maybe rg_ui[['uid'] = repo['uid']? Maybe rg_ui[['uid'] = repo['uid']?
18 14 Or, everywhere add 'uid = ?' in queries. Or, everywhere add 'uid = ?' in queries.
19 [ ] List on the first page the latest commits.
20 Do not forget to exclude private repos.
21 [ ] bug_update does not update labels!
22 [ ] Integrate remote_add.html.
23 [ ] Should we expire the reset password token? Why?
24 Somebody can request another one!
25 15 [ ] All operations must be verified with tokens. [ ] All operations must be verified with tokens.
16 [ ] Check if we can give rights for a non-owning repo!
17 We should check if the user that gives rights is the owner or has admin
18 rights!
19
20 == Medium ==
21 [ ] The link to a note should have an anchor to be able to go directly to the note.
22 [ ] bug tracker is private? If the repo is, it should be also.
23 [ ] When you watch a project, a note add to a bug will notify that watcher?
24 Or we limit to edit/add/close bugs?
25 [ ] We should also add organization/user next to repo in e-mails.
26 [ ] Feature to be able to mark a note and the rest under it as read?
27 [ ] Return error in rg_*_info( when you do not have access?
28 [ ] SELinux: is not clear how I use SourceX: for .if/.te/.fc.
29 [ ] SELinux: what about rocketgit_t access to postgresql through apache?
30 [ ] Check why only 'tageted' policy is installed.
31 [ ] Should I move the socket to /var/run (using tmp.d)?
32 [ ] Use (organization, user, repo) instead of user/repo only.
33 [ ] Bug:List: saved searches with spaces inside the name are not correctly escaped.
34 Use _ instead of space, or properly escape it (ugly: %20 etc.)?
35 [ ] "if ($res === FALSE) break" must set the error message!
36 [ ] Carefull order the events. We do not want to build list notifications
37 before adding a user to the watch list.
38 [ ] If description is empty, do not insert a \n in 'new repo' e-mail.
39 [ ] Remove last form in PHP: user.form.php.
40 [ ] Current menu is not correctly shown as selected.
26 41 [ ] If the confirmation code is truncated, an internal error is generated [ ] If the confirmation code is truncated, an internal error is generated
27 42 instead of a user error! instead of a user error!
28 43 [ ] Third option: anybody can create an account but must be validated by admin. [ ] Third option: anybody can create an account but must be validated by admin.
29 44 [ ] After creating the account, keep the user logged in and allow login [ ] After creating the account, keep the user logged in and allow login
30 45 even if is not confirmed (option in config). even if is not confirmed (option in config).
31 [ ] Check if we can give rights for a non-owning repo!
32 We should check if the user that gives rights is the owner!
33 [ ] Add possibility to close a bug. Maybe also when adding a note.
34 [ ] Add possibility to edit a bug.
35 [ ] Add possibility to add/remove labels to a bug. Also whwn adding a note.
36
37
38 == Medium ==
46 [ ] 'application_name' must be set something like rocketgit-q/web/etc.
47 [ ] When I close a bug, seems I add myself to the watch table again!
48 [ ] Should we load the lables in rg_bug_info?
49 [ ] Do we need a rg_bug_cosmetic for notes/users/repos/etc?
50 [ ] when rights are revoked, also the watch list must be checked.
51 [ ] When adding a note, add also a checkbox to watch that bug?
52 [ ] Integrate remote_add.html.
53 [ ] When I edit a bug, should I remove notes and add_note form?
54 [ ] Add possibility to add/remove labels when adding a note?
55 [ ] Bugs: show what filtering is active.
56 [ ] Seems I cannot push to rg1! Do an update and check again?
57 [ ] Bug: Do not allow adding labels if you do not have admin rights.
58 [ ] Bug: Do not allow close/assign/etc. if you do not have admin rights.
59 [ ] Menu must be loaded from template.
60 [ ] Remove any HTML from code.
61 [ ] List on the first page the latest commits.
62 Do not forget to exclude private repos.
63 [ ] Should we expire the reset password token? Why?
64 Somebody can request another one!
65 [ ] It is not clear that the owner has full rights (repo->admin->edit).
39 66 [ ] Allow editing of bug searches. [ ] Allow editing of bug searches.
40 67 [ ] Admin: add a feature to become any user. This way we will not duplicate [ ] Admin: add a feature to become any user. This way we will not duplicate
41 68 a lot of code for editing users/repos/etc. Allow admin to switch a lot of code for editing users/repos/etc. Allow admin to switch
 
... ... them after processing is done.
190 217 [ ] [ ]
191 218
192 219 == Normal priority == == Normal priority ==
220 [ ]
193 221 [ ] Show last time use of a ssh key, or how many times was used, or both. [ ] Show last time use of a ssh key, or how many times was used, or both.
194 222 [ ] Add hint about "ssh rocketgit@server" to quickly find status etc. [ ] Add hint about "ssh rocketgit@server" to quickly find status etc.
195 223 [ ] rg_redirect does not record profiling information! [ ] rg_redirect does not record profiling information!
 
... ... them after processing is done.
197 225 [ ] How to sign merge requests?! [ ] How to sign merge requests?!
198 226 [ ] Signal, with red, if a key was uploaded in the last X days. [ ] Signal, with red, if a key was uploaded in the last X days.
199 227 [ ] Store in a cookie the last uid used, and if > 0, lookup e-mail and prefill [ ] Store in a cookie the last uid used, and if > 0, lookup e-mail and prefill
200 forgot password e-mail field.
228 forgot password e-mail field. Not good. An attacker may iterate over all
229 uids. But, with a token will be nice!
201 230 [ ] Yeah BitBucket's pricing is much better they only charge on the number of collaborators. [ ] Yeah BitBucket's pricing is much better they only charge on the number of collaborators.
202 231 [ ] Permit "log" to see more rows. [ ] Permit "log" to see more rows.
203 232 [ ] Allow admin to upload keys for a user. [ ] Allow admin to upload keys for a user.
204 [ ] Make an option to not allow a client to upload keys.
233 [ ] Make an option to not allow a client to upload keys. Why?
234 To restrict this to admin?
205 235 [ ] Can we bypass ssh auth to allow pushes? [ ] Can we bypass ssh auth to allow pushes?
206 236 This way maybe we can identify client by fingerprint. This way maybe we can identify client by fingerprint.
207 237 [ ] Use rg_git_diff_tree to test for path based restrictions. Also, take care of renmaes, copies etc. [ ] Use rg_git_diff_tree to test for path based restrictions. Also, take care of renmaes, copies etc.
208 238 [ ] See Gerrit: https://codereview.qt-project.org/#change,22764 [ ] See Gerrit: https://codereview.qt-project.org/#change,22764
209 239 [ ] user-conf: option: auto-create-repo-on-push [ ] user-conf: option: auto-create-repo-on-push
210 240 [ ] Use git push to do all kind of commands: create repo, delete repo, update description etc. [ ] Use git push to do all kind of commands: create repo, delete repo, update description etc.
211 [ ] Allow creating a template for repositories.
241 [ ] Allow user to create a template for repositories.
212 242 [ ] Optionally init a repo with some files (README, TODO etc.) [ ] Optionally init a repo with some files (README, TODO etc.)
213 243 [ ] Check https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html [ ] Check https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html
214 244 [ ] Add RocketGit to https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html [ ] Add RocketGit to https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html
 
... ... them after processing is done.
223 253 [ ] Check if a merge request was integrated (hm; what integrated means?!) and [ ] Check if a merge request was integrated (hm; what integrated means?!) and
224 254 signal this in merge requests list? signal this in merge requests list?
225 255 [ ] Add rg_branch_allow_chars and rg_tags_allow_chars. [ ] Add rg_branch_allow_chars and rg_tags_allow_chars.
226 [ ] repo/tag|branch/<name> page shoul put next to the commit also the tag/branch.
256 [ ] repo/tag|branch/<name> page should put next to the commit also the tag/branch.
227 257 [ ] Order tags by mtime desc. [ ] Order tags by mtime desc.
228 [ ] If a user pushes an unknown repo, we may automatically create a repo!
229 [ ] Fix the "edit repo" page!
230 [ ] rg-repos should be split in rg_repos and rg_var_lib.
231 [ ] 'cop' variable is not good - I do not remember what it means!
258 [ ] rg_repos should be split in rg_repos and rg_var_lib.
232 259 [ ] $blocks = explode("@@left@@-=ROCKETGIT=-@@left@@", $a) - seems that \0 is replaced! [ ] $blocks = explode("@@left@@-=ROCKETGIT=-@@left@@", $a) - seems that \0 is replaced!
233 260 [ ] Changing repo name probably is not working right. [ ] Changing repo name probably is not working right.
234 261 [ ] Check XSRF attacks and other types. [ ] Check XSRF attacks and other types.
 
... ... them after processing is done.
240 267 still work. still work.
241 268 [ ] Differentiate between owner of a repository, currently logged in user and admin. [ ] Differentiate between owner of a repository, currently logged in user and admin.
242 269 [ ] Warn before deleting a repo! [ ] Warn before deleting a repo!
243 [ ] Update of database must be done from a global init function, not by admin.
244 270 [ ] Switch all menus to templates. [ ] Switch all menus to templates.
245 [ ] Switch all forms to templates.
246 271 [ ] Check double slashes in URLs. [ ] Check double slashes in URLs.
247 272 [ ] Automatically create user on anonymous push? [ ] Automatically create user on anonymous push?
248 273 [ ] I am not sure I can reload xinetd and httpd from spec file [ ] I am not sure I can reload xinetd and httpd from spec file
249 274 [ ] Check SELinux context on /var/lib/rocketgit [ ] Check SELinux context on /var/lib/rocketgit
250 [ ] admin: "Lock or accounts" and "Reset password for all accounts and send mail".
275 [ ] admin: "Lock all accounts" and "Reset password for all accounts and send mail".
251 276 [ ] rg_repo_allow seems to not be used. [ ] rg_repo_allow seems to not be used.
252 277 [ ] Get memory statistics from /proc. [ ] Get memory statistics from /proc.
253 278 [ ] Delay connection to database. [ ] Delay connection to database.
 
... ... them after processing is done.
255 280 [ ] When logging _SERVER variables, log only the ones prefixed by ROCKETGIT_. [ ] When logging _SERVER variables, log only the ones prefixed by ROCKETGIT_.
256 281 [ ] Ask password when doing any critical change of the account and send mail. [ ] Ask password when doing any critical change of the account and send mail.
257 282 [ ] Add commercial posibility for VPNs to be sure you can push/fetch safely. [ ] Add commercial posibility for VPNs to be sure you can push/fetch safely.
258 [ ] Add a possibiliy (link shown in push message) to delete/update/etc. the
283 [ ] Add a possibility (link shown in push message) to delete/update/etc. the
259 284 merge request. merge request.
260 285 [ ] Allow a nonstandard port for web. [ ] Allow a nonstandard port for web.
261 286 [ ] Put form error messages next to the label. [ ] Put form error messages next to the label.
262 [ ] Get rid of $rr!
263 [ ] favicon.ico is not in theme!
287 [ ] favicon.ico is not in theme! Should we put it in HTML?
264 288 [ ] Create unit testing for all functions. [ ] Create unit testing for all functions.
265 289 [ ] Test error code for rg_sql_query. [ ] Test error code for rg_sql_query.
266 290 [ ] Log $ret['errmsg'] for rg_exec [ ] Log $ret['errmsg'] for rg_exec
267 291 [ ] Audit code to replace parts with rg_internal_error. [ ] Audit code to replace parts with rg_internal_error.
268 [ ] TODO feature for projects.
269 292 [ ] Allow SSH keys per repository (only)? [ ] Allow SSH keys per repository (only)?
270 293 [ ] Allow remote 'gc' of a repo, besides an automatic one. [ ] Allow remote 'gc' of a repo, besides an automatic one.
271 294 [ ] Take care of caching of passwords. Maybe allow a purge of a file from browser? [ ] Take care of caching of passwords. Maybe allow a purge of a file from browser?
 
... ... them after processing is done.
283 306 [ ] Log files may be written per repo and per user, with locking... [ ] Log files may be written per repo and per user, with locking...
284 307 [ ] Push may be always allowed - but will be done as a merge request! Cool. [ ] Push may be always allowed - but will be done as a merge request! Cool.
285 308 Disk space accounting? Disk space accounting?
286 [ ] We should make a repo dirty ony if user pushed something with success.
309 [ ] We should make a repo dirty only if user pushed something with success.
287 310 [ ] <link rel="icon" type="image/png" id="favicon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACGFjVEwAAAASAAAAAJNtBPIAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAALuAD6AABhIDeugAAALhJREFUOI2Nk8sNxCAMRDlGohauXFOMpfTiAlxICqAELltHLqlgctg1InzMRhpFAc%2BLGWTnmoeZYamt78zXdZmaQtQMADlnU0OIAlbmJUBEcO4bRKQY2rUXIPmAGnDuG%2FBx3%2FfvOPVaDUg%2BoAPUf1PArIMCSD5glMEsUGaG%2BkyAFWIBaCsKuA%2BHGCNijLgP133XgOEtaPFMy2vUolEGJoCIzBmoRUR9%2B7rxj16DZaW%2FmgtmxnJ8V3oAnApQwNS5zpcAAAAaZmNUTAAAAAEAAAAQAAAAEAAAAAAAAAAAAB4D6AIB52fclgAAACpmZEFUAAAAAjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9WF%2Bu8QAAABpmY1RMAAAAAwAAABAAAAAQAAAAAAAAAAAAHgPoAgEK8Q9%2FAAAAFmZkQVQAAAAEOI1jYBgFo2AUjAIIAAAEEAAB0xIn4wAAABpmY1RMAAAABQAAABAAAAAQAAAAAAAAAAAAHgPoAgHnO30FAAAAQGZkQVQAAAAGOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVfozYcAAAABpmY1RMAAAABwAAABAAAAAQAAAAAAAAAAAAHgPoAgEKra7sAAAAFmZkQVQAAAAIOI1jYBgFo2AUjAIIAAAEEAABM9s3hAAAABpmY1RMAAAACQAAABAAAAAQAAAAAAAAAAAAHgPoAgHn3p%2BwAAAAKmZkQVQAAAAKOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F1BhPl6AAAAGmZjVEwAAAALAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQpITFkAAAAWZmRBVAAAAAw4jWNrgAWjYBSMArgAAAQQAAHaszpmAAAAGmZjVEwAAAANAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeeCPiMAAABAZmRBVAAAAA44jWNrgJ5gpxrDf2LEcIL%2FpzAVYxPDavP%2FUwz%2FpW79%2F%2F%2F%2FFMP%2FnWoQjC5GOxcgu4QYsVEwCmAAAOE0KxUmBL0KAAAAGmZjVEwAAAAPAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQoU7coAAAAWZmRBVAAAABA4jWNrgAWjYBSMArgAAAQQAAEpOBELAAAAGmZjVEwAAAARAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeYVWtoAAAAqZmRBVAAAABI4jWNrgAVYQXNz839ixHBq3qnG8B9ZAzYx2rlgFIwCcgAA8psX%2FWvpAecAAAAaZmNUTAAAABMAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC4OJMwAAABZmZEFUAAAAFDiNY2AYBaNgFIwCCAAABBAAAcBQHOkAAAAaZmNUTAAAABUAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5kn7SQAAAEBmZEFUAAAAFjiNY2AYnmCnGsN%2FYsRwgv%2BnMBVjE8Nq8%2F9TDP%2Blbv3%2F%2F%2F8Uw%2F%2BdahCMLkY7FyC7hBixUTAKYAAA4TQrFc%2BcEoQAAAAaZmNUTAAAABcAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC98ooAAAABZmZEFUAAAAGDiNY2AYBaNgFIwCCAAABBAAASCZDI4AAAAaZmNUTAAAABkAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5qwZ%2FAAAACpmZEFUAAAAGjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9cjJWbAAAABpmY1RMAAAAGwAAABAAAAAQAAAAAAAAAAAAHgPoAgELOsoVAAAAFmZkQVQAAAAcOI1jYBgFo2AUjAIIAAAEEAAByfEBbAAAABpmY1RMAAAAHQAAABAAAAAQAAAAAAAAAAAAHgPoAgHm8LhvAAAAQGZkQVQAAAAeOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVlxR3%2FgAAABpmY1RMAAAAHwAAABAAAAAQAAAAAAAAAAAAHgPoAgELZmuGAAAAFmZkQVQAAAAgOI1jYBgFo2AUjAIIAAAEEAABHP5cFQAAABpmY1RMAAAAIQAAABAAAAAQAAAAAAAAAAAAHgPoAgHlgtAOAAAAKmZkQVQAAAAiOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F0%2FMvDdAAAAAElFTkSuQmCC"/> [ ] <link rel="icon" type="image/png" id="favicon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACGFjVEwAAAASAAAAAJNtBPIAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAALuAD6AABhIDeugAAALhJREFUOI2Nk8sNxCAMRDlGohauXFOMpfTiAlxICqAELltHLqlgctg1InzMRhpFAc%2BLGWTnmoeZYamt78zXdZmaQtQMADlnU0OIAlbmJUBEcO4bRKQY2rUXIPmAGnDuG%2FBx3%2FfvOPVaDUg%2BoAPUf1PArIMCSD5glMEsUGaG%2BkyAFWIBaCsKuA%2BHGCNijLgP133XgOEtaPFMy2vUolEGJoCIzBmoRUR9%2B7rxj16DZaW%2FmgtmxnJ8V3oAnApQwNS5zpcAAAAaZmNUTAAAAAEAAAAQAAAAEAAAAAAAAAAAAB4D6AIB52fclgAAACpmZEFUAAAAAjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9WF%2Bu8QAAABpmY1RMAAAAAwAAABAAAAAQAAAAAAAAAAAAHgPoAgEK8Q9%2FAAAAFmZkQVQAAAAEOI1jYBgFo2AUjAIIAAAEEAAB0xIn4wAAABpmY1RMAAAABQAAABAAAAAQAAAAAAAAAAAAHgPoAgHnO30FAAAAQGZkQVQAAAAGOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVfozYcAAAABpmY1RMAAAABwAAABAAAAAQAAAAAAAAAAAAHgPoAgEKra7sAAAAFmZkQVQAAAAIOI1jYBgFo2AUjAIIAAAEEAABM9s3hAAAABpmY1RMAAAACQAAABAAAAAQAAAAAAAAAAAAHgPoAgHn3p%2BwAAAAKmZkQVQAAAAKOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F1BhPl6AAAAGmZjVEwAAAALAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQpITFkAAAAWZmRBVAAAAAw4jWNrgAWjYBSMArgAAAQQAAHaszpmAAAAGmZjVEwAAAANAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeeCPiMAAABAZmRBVAAAAA44jWNrgJ5gpxrDf2LEcIL%2FpzAVYxPDavP%2FUwz%2FpW79%2F%2F%2F%2FFMP%2FnWoQjC5GOxcgu4QYsVEwCmAAAOE0KxUmBL0KAAAAGmZjVEwAAAAPAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQoU7coAAAAWZmRBVAAAABA4jWNrgAWjYBSMArgAAAQQAAEpOBELAAAAGmZjVEwAAAARAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeYVWtoAAAAqZmRBVAAAABI4jWNrgAVYQXNz839ixHBq3qnG8B9ZAzYx2rlgFIwCcgAA8psX%2FWvpAecAAAAaZmNUTAAAABMAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC4OJMwAAABZmZEFUAAAAFDiNY2AYBaNgFIwCCAAABBAAAcBQHOkAAAAaZmNUTAAAABUAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5kn7SQAAAEBmZEFUAAAAFjiNY2AYnmCnGsN%2FYsRwgv%2BnMBVjE8Nq8%2F9TDP%2Blbv3%2F%2F%2F8Uw%2F%2BdahCMLkY7FyC7hBixUTAKYAAA4TQrFc%2BcEoQAAAAaZmNUTAAAABcAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC98ooAAAABZmZEFUAAAAGDiNY2AYBaNgFIwCCAAABBAAASCZDI4AAAAaZmNUTAAAABkAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5qwZ%2FAAAACpmZEFUAAAAGjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9cjJWbAAAABpmY1RMAAAAGwAAABAAAAAQAAAAAAAAAAAAHgPoAgELOsoVAAAAFmZkQVQAAAAcOI1jYBgFo2AUjAIIAAAEEAAByfEBbAAAABpmY1RMAAAAHQAAABAAAAAQAAAAAAAAAAAAHgPoAgHm8LhvAAAAQGZkQVQAAAAeOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVlxR3%2FgAAABpmY1RMAAAAHwAAABAAAAAQAAAAAAAAAAAAHgPoAgELZmuGAAAAFmZkQVQAAAAgOI1jYBgFo2AUjAIIAAAEEAABHP5cFQAAABpmY1RMAAAAIQAAABAAAAAQAAAAAAAAAAAAHgPoAgHlgtAOAAAAKmZkQVQAAAAiOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F0%2FMvDdAAAAAElFTkSuQmCC"/>
288 311 [ ] "Add key" form may be joined with list keys command! [ ] "Add key" form may be joined with list keys command!
289 312 [ ] Allow to recover a deleted repository. [ ] Allow to recover a deleted repository.
 
... ... them after processing is done.
292 315 [ ] Add memcache caching for all database lookups. [ ] Add memcache caching for all database lookups.
293 316 [ ] Allow to configure the limit of the patch size to prevent abuses. [ ] Allow to configure the limit of the patch size to prevent abuses.
294 317 [ ] Allow to configure to refuse binary files. [ ] Allow to configure to refuse binary files.
295 [ ] Allow to configure to refuse commits with broken spaces/tab mixes.
296 318 [ ] Add a repo_prop_set/get function that will set/get a file in .git folder. [ ] Add a repo_prop_set/get function that will set/get a file in .git folder.
297 319 This way we can speed up some lookups (no need for database). Hm. This way we can speed up some lookups (no need for database). Hm.
298 320 [ ] When we delete a repository, we will do repo_prop_set(repo, disabled) and we will [ ] When we delete a repository, we will do repo_prop_set(repo, disabled) and we will
299 321 return OK, in the background we will do the removing. return OK, in the background we will do the removing.
300 322 Do not forget to also remove clones. Hm. Do not forget to also remove clones. Hm.
301 323 [ ] E-mail aliases section. [ ] E-mail aliases section.
302 [ ] User details section (full name, blog, avatar, mail notifications).
324 [ ] User details section (blog, avatar, mail notifications).
303 325 [ ] Check if user is over-quota on push. [ ] Check if user is over-quota on push.
304 326 [ ] The cron will have to: [ ] The cron will have to:
305 327 [ ] Compute disk usage, ignoring hard links. Hm. Probably we will add [ ] Compute disk usage, ignoring hard links. Hm. Probably we will add
 
... ... them after processing is done.
314 336 [ ] Check if we have to respect 4HEXA also on SSH. I think not. [ ] Check if we have to respect 4HEXA also on SSH. I think not.
315 337 [ ] Limit number of simultaneously connection per repo and per user. [ ] Limit number of simultaneously connection per repo and per user.
316 338 Maybe also the time! Maybe also the time!
317 [ ] Make everywhere present a "Make a sugestion" area.
318 [ ] On rocketgit website, add "Feedback" area.
319 339 [ ] Allow multiple virtual hosts, with different configurations. [ ] Allow multiple virtual hosts, with different configurations.
320 340 [ ] session_time should be set at login time? And/or default s_t should be set from database? [ ] session_time should be set at login time? And/or default s_t should be set from database?
321 341 [ ] Do not let user upload an already uploaded key. [ ] Do not let user upload an already uploaded key.
 
... ... them after processing is done.
337 357 [ ] Do not show submenus if user is not logged in on repopage (ialbeascu) [ ] Do not show submenus if user is not logged in on repopage (ialbeascu)
338 358 - duplicate menus?! maybe add an admin link in repopage that goes - duplicate menus?! maybe add an admin link in repopage that goes
339 359 to repo. to repo.
340 [ ] Undo SELinux stuff when uninstalling applications.
341 360 [ ] Nice graphic (unrelated to git): http://tctechcrunch2011.files.wordpress.com/2011/07/hadoop2.png?w=640 [ ] Nice graphic (unrelated to git): http://tctechcrunch2011.files.wordpress.com/2011/07/hadoop2.png?w=640
342 361 [ ] git-notes may be used to attach messages to commits. Nice. [ ] git-notes may be used to attach messages to commits. Nice.
343 362 [ ] Store also the size of the patch along history/commit info. [ ] Store also the size of the patch along history/commit info.
344 363 [ ] Check SELinux MLS [ ] Check SELinux MLS
345 [ ] Store users and repositories to /var/lib/rocketgit so we can set a proper
346 SELinux context on that folder.
347 364 [ ] Test if 'first_install' state is working correctly. [ ] Test if 'first_install' state is working correctly.
348 365 [ ] Deal with empty repositories (rg_git_ls_tree etc.). [ ] Deal with empty repositories (rg_git_ls_tree etc.).
349 366 [ ] Show age of an user/org/repo. Example: 1 year, 3 months, 4 days. [ ] Show age of an user/org/repo. Example: 1 year, 3 months, 4 days.
350 [ ] The rewrite engine should pass a single op for user and for org, but with para org=0 or 1.
367 [ ] The rewrite engine should pass a single op for user and for org, but with
368 para org=0 or 1.
351 369 This is to have the same page for both types of users. This is to have the same page for both types of users.
352 370 [ ] From: http://lwn.net/Articles/460376/ [ ] From: http://lwn.net/Articles/460376/
353 371 I can confirm that shortcomings with Gitorious' ACL systems were I can confirm that shortcomings with Gitorious' ACL systems were
File inc/bug.inc.php changed (mode: 100644) (index 898c800..679ef0d)
... ... require_once($INC . "/log.inc.php");
4 4 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
5 5 require_once($INC . "/user.inc.php"); require_once($INC . "/user.inc.php");
6 6 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
7 require_once($INC . "/events.inc.php");
8 require_once($INC . "/watch.inc.php");
7 9
8 10 $rg_bug_error = ""; $rg_bug_error = "";
9 11
 
... ... $rg_bug_states = array(
26 28 "2" => "Closed" "2" => "Closed"
27 29 ); );
28 30
31 /*
32 * Event functions
33 */
34 $rg_bug_functions = array(
35 4000 => "rg_bug_event_note_add_all",
36 4001 => "rg_bug_event_note_add_one",
37 4100 => "rg_bug_event_add_all",
38 4101 => "rg_bug_event_add_one"
39 );
40 rg_event_register_functions($rg_bug_functions);
41
42 /*
43 * Notify one user when a bug is added
44 */
45 function rg_bug_event_add_one($db, $event)
46 {
47 rg_log("DEBUG: bug_event_add_one event=" . rg_array2string($event));
48
49 $ret = FALSE;
50 do {
51 // lookup user email
52 $ui = rg_user_info($db, $event['target_uid'], "", "");
53 if ($ui['exists'] != 1) {
54 rg_internal_error("User does not exists!");
55 break;
56 }
57
58 // send e-mail
59 $event['ui.email'] = $ui['email'];
60 $r = rg_mail("mail/user/repo/bug/new", $event);
61 if ($r === FALSE)
62 return FALSE;
63 } while (0);
64
65 return array();
66 }
67
68 /*
69 * Notify when somebody adds a bug
70 */
71 function rg_bug_event_add_all($db, $event)
72 {
73 rg_prof_start("bug_event_add");
74 $ret = array();
75
76 $x = $event;
77 $x['category'] = 4101;
78 $x['prio'] = 100;
79
80 // We will sent notifications to all watchers of a repo
81 $r = rg_watch_load_by_obj_id($db, "repo", $event['repo.repo_id'], 0);
82 if ($r === FALSE)
83 return FALSE;
84 if (!empty($r)) {
85 foreach ($r as $index => $uid) {
86 $x['target_uid'] = $uid;
87 $ret[] = $x;
88 }
89 }
90
91 // We will sent notifications to all watchers of a bug
92 $r = rg_watch_load_by_obj_id($db, "bug", $event['repo.repo_id'],
93 $event['bug.bug_id']);
94 if ($r === FALSE)
95 return FALSE;
96 if (!empty($r)) {
97 foreach ($r as $index => $uid) {
98 $x['target_uid'] = $uid;
99 $ret[] = $x;
100 }
101 }
102
103 rg_prof_end("bug_event_add");
104 return $ret;
105 }
106
107 /*
108 * Notify one user when a note is added to a bug
109 */
110 function rg_bug_event_note_add_one($db, $event)
111 {
112 rg_log("DEBUG: bug_event_note_add_one event=" . rg_array2string($event));
113
114 $ret = FALSE;
115
116 do {
117 // lookup user email
118 $ui = rg_user_info($db, $event['target_uid'], "", "");
119 if ($ui['exists'] != 1) {
120 rg_internal_error("User does not exists!");
121 break;
122 }
123
124 // send e-mail
125 $event['ui.email'] = $ui['email'];
126 $r = rg_mail("mail/user/repo/bug/new_note", $event);
127 if ($r === FALSE)
128 return FALSE;
129 } while (0);
130
131 return array();
132 }
133
134 /*
135 * Notify users when a note is added to a bug
136 */
137 function rg_bug_event_note_add_all($db, $event)
138 {
139 rg_prof_start("bug_event_note_add_all");
140 $ret = array();
141
142 $x = $event;
143 $x['category'] = 4001;
144 $x['prio'] = 100;
145
146 // Now, build the list of users that will receive notification
147 $r = rg_watch_load_by_obj_id($db, "bug", $event['repo.repo_id'],
148 $event['bug_id']);
149 if ($r === FALSE)
150 return FALSE;
151 if (!empty($r)) {
152 foreach ($r as $index => $uid) {
153 $x['target_uid'] = $uid;
154 $ret[] = $x;
155 }
156 }
157
158 rg_log_ml("DEBUG: ret: " . print_r($ret, TRUE));
159 rg_prof_end("bug_event_note_add_all");
160 return $ret;
161 }
162
29 163 /* /*
30 164 * Return the state of a bug, as string * Return the state of a bug, as string
31 165 */ */
 
... ... function rg_bug_state_select($value, $exclude)
67 201 /* /*
68 202 * We want the bug number to be consecutive per repo. * We want the bug number to be consecutive per repo.
69 203 * This is why we use a separate table (bugs_max) to track last id. * This is why we use a separate table (bugs_max) to track last id.
70 * This function must be inside a transaction.
204 * This function must called from inside a transaction.
71 205 */ */
72 206 function rg_bug_next_id($db, $repo_id) function rg_bug_next_id($db, $repo_id)
73 207 { {
 
... ... function rg_bug_next_id($db, $repo_id)
96 230 break; break;
97 231
98 232 /* If we are here, it means that we have no entry in bugs_max. */ /* If we are here, it means that we have no entry in bugs_max. */
99 $res = rg_sql_begin($db);
100 if ($res === FALSE) {
101 rg_bug_set_error("cannot start txn (" . rg_sql_error() . ")");
102 break;
103 }
104 233
105 234 $sql = "LOCK TABLE bugs_max IN ACCESS EXCLUSIVE MODE"; $sql = "LOCK TABLE bugs_max IN ACCESS EXCLUSIVE MODE";
106 235 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
 
... ... function rg_bug_next_id($db, $repo_id)
113 242 /* /*
114 243 * Here, another client may just did the insert and commited * Here, another client may just did the insert and commited
115 244 * and we obtain the lock. So, we have to check if a insert * and we obtain the lock. So, we have to check if a insert
116 * took place. if we
245 * took place.
117 246 */ */
118 247 $sql = "SELECT 1 FROM bugs_max WHERE repo_id = $repo_id"; $sql = "SELECT 1 FROM bugs_max WHERE repo_id = $repo_id";
119 248 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
 
... ... function rg_bug_next_id($db, $repo_id)
137 266 $next_bug_id = 1; $next_bug_id = 1;
138 267 } }
139 268
140 // commit (will also unlock)
141 $res = rg_sql_commit($db);
142 if ($res === FALSE) {
143 rg_bug_set_error("cannot commit (" . rg_sql_error() . ")");
144 break;
145 }
146
147 269 /* /*
148 270 * The other client was faster than us. Just repeat * The other client was faster than us. Just repeat
149 271 * the whole operation. * the whole operation.
 
... ... function rg_bug_next_id($db, $repo_id)
156 278 return $next_bug_id; return $next_bug_id;
157 279 } }
158 280
281 /*
282 * Helper for loading default values for a bug.
283 */
284 function rg_bug_vars_defaults()
285 {
286 $ret = array();
287 $ret['bug_id'] = 0;
288 $ret['title'] = "";
289 $ret['body'] = "";
290 $ret['state'] = 1;
291 $ret['labels'] = "";
292 $ret['assigned_to'] = "";
293
294 return $ret;
295 }
296
297 /*
298 * Helper for loading POST variables into an array, with validation.
299 */
300 function rg_bug_vars()
301 {
302 $ret = array();
303 $ret['bug_id'] = rg_var_str("bug_id");
304 $ret['title'] = rg_var_str("title");
305 $ret['body'] = rg_var_str("body");
306 $ret['state'] = rg_var_uint("state");
307 $ret['labels'] = rg_var_str("labels");
308 $ret['assigned_to'] = rg_var_str("assigned_to");
309
310 return $ret;
311 }
312
159 313 /* /*
160 314 * Helper function to populate some fields for a bug * Helper function to populate some fields for a bug
161 315 */ */
 
... ... function rg_bug_cosmetic($db, &$row)
168 322 $row['owner'] = $_ui['username']; $row['owner'] = $_ui['username'];
169 323
170 324 $row['HTML:body'] = nl2br($row['body']); $row['HTML:body'] = nl2br($row['body']);
171 unset($row['body']);
172 325 $row['creation'] = gmdate("Y-m-d H:i", $row['itime']); $row['creation'] = gmdate("Y-m-d H:i", $row['itime']);
173 326
174 327 if ($row['utime'] > 0) if ($row['utime'] > 0)
 
... ... function rg_bug_cosmetic($db, &$row)
176 329 else else
177 330 $row['updated'] = "-"; $row['updated'] = "-";
178 331
179 $row['assigned_to'] = "-";
332 $row['assigned_to'] = "";
180 333 if ($row['assigned_uid'] > 0) { if ($row['assigned_uid'] > 0) {
181 334 $_ui = rg_user_info($db, $row['assigned_uid'], "", ""); $_ui = rg_user_info($db, $row['assigned_uid'], "", "");
182 335 if ($_ui['exists'] == 1) if ($_ui['exists'] == 1)
183 336 $row['assigned_to'] = $_ui['username']; $row['assigned_to'] = $_ui['username'];
184 337 } }
185 338
186 $row['state'] = rg_bug_state($row['state']);
339 $row['state_text'] = rg_bug_state($row['state']);
187 340 } }
188 341
189 342 /* /*
 
... ... function rg_bug_info($db, $repo_id, $bug_id)
233 386 } }
234 387
235 388 /* /*
236 * Add a bug
389 * Add/edit a bug
390 * If bug_id > 0 - edit, else add
237 391 */ */
238 function rg_bug_add($db, $repo_id, $uid, $data)
392 function rg_bug_edit($db, $ri, $login_ui, $data)
239 393 { {
240 rg_prof_start("bug_add");
241 rg_log("bug_add: repo_id=$repo_id uid=$uid"
242 . " data: " . rg_array2string($data));
394 rg_prof_start("bug_edit");
395 rg_log("bug_edit: data: " . rg_array2string($data));
243 396
244 // TODO: test if user is allowed to add a bug
397 // TODO: test if user is allowed to add/edit a bug
245 398
246 399 $e_data = $data; $e_data = $data;
247 400 $e_data['title'] = rg_sql_escape($db, $data['title']); $e_data['title'] = rg_sql_escape($db, $data['title']);
248 401 $e_data['body'] = rg_sql_escape($db, $data['body']); $e_data['body'] = rg_sql_escape($db, $data['body']);
249 402 $e_data['state'] = sprintf("%u", $data['state']); $e_data['state'] = sprintf("%u", $data['state']);
250 $e_data['labels'] = rg_sql_escape($db, $data['labels']);
403 $e_data['labels'] = isset($data['labels']) ? rg_sql_escape($db, $data['labels']) : "";
251 404
252 405 $itime = time(); $itime = time();
253 406 $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ""; $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "";
 
... ... function rg_bug_add($db, $repo_id, $uid, $data)
255 408 $ret = FALSE; $ret = FALSE;
256 409 $rollback = 0; $rollback = 0;
257 410 do { do {
258 if (rg_sql_begin($db) !== TRUE)
411 if (empty($data['title'])) {
412 rg_bug_set_error("title cannot be empty");
259 413 break; break;
414 }
260 415
261 $rollback = 1;
416 if (empty($data['body'])) {
417 rg_bug_set_error("description cannot be empty");
418 break;
419 }
262 420
263 $bug_id = rg_bug_next_id($db, $repo_id);
264 if ($bug_id === FALSE)
421 if (($data['state'] < 1) || ($data['state'] > 3)) {
422 rg_bug_set_error("invalid state");
265 423 break; break;
424 }
266 425
267 $err = rg_bug_label_insert($db, $repo_id, $bug_id, $data['labels']);
268 if ($err !== TRUE)
426 if (empty($data['assigned_to'])) {
427 $assigned_uid = 0;
428 $assigned_to_text = "N/A";
429 } else {
430 $aui = rg_user_info($db, 0, $data['assigned_to'], "");
431 if ($aui['exists'] != 1) {
432 rg_bug_set_error("user you assigned to does not exists");
433 break;
434 }
435 $assigned_uid = $aui['uid'];
436 $assigned_to_text = $aui['username'];
437 }
438
439 if (rg_sql_begin($db) !== TRUE) {
440 rg_bug_set_error("start traqnsaction failed");
269 441 break; break;
442 }
443
444 $rollback = 1;
270 445
271 $sql = "INSERT INTO bugs (bug_id, itime, utime, repo_id, uid"
272 . ", ip, title, body, state, assigned_uid, deleted)"
273 . " VALUES ($bug_id, $itime, 0, $repo_id, $uid"
274 . ", '$ip', '" . $e_data['title'] . "'"
275 . ", '" . $e_data['body'] . "'"
276 . ", " . $e_data['state']
277 . ", " . $e_data['assigned_uid']
278 . ", 0)";
446 $bug_id = $data['bug_id'];
447 if ($bug_id == 0) {
448 $bug_id = rg_bug_next_id($db, $ri['repo_id']);
449 if ($bug_id === FALSE)
450 break;
451 }
452
453 if (!empty($data['labels'])) {
454 $err = rg_bug_label_insert($db, $ri['repo_id'], $bug_id,
455 $data['labels']);
456 if ($err !== TRUE)
457 break;
458 }
459
460 if ($data['bug_id'] == 0) {
461 $sql = "INSERT INTO bugs (bug_id, itime, utime, repo_id"
462 . ", uid, ip, title, body, state, assigned_uid"
463 . ", deleted)"
464 . " VALUES ($bug_id, $itime, 0"
465 . ", " . $ri['repo_id']
466 . ", " . $login_ui['uid']
467 . ", '$ip', '" . $e_data['title'] . "'"
468 . ", '" . $e_data['body'] . "'"
469 . ", " . $e_data['state']
470 . ", " . $assigned_uid
471 . ", 0)";
472 } else {
473 $sql = "UPDATE bugs SET utime = $itime"
474 . ", title = '" . $e_data['title'] . "'"
475 . ", body = '" . $e_data['body'] . "'"
476 . ", state = " . $e_data['state']
477 . ", assigned_uid = " . $assigned_uid
478 . " WHERE repo_id = " . $ri['repo_id']
479 . " AND bug_id = $bug_id";
480 }
279 481 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
280 482 if ($res === FALSE) { if ($res === FALSE) {
281 rg_bug_set_error("Cannot insert bug (" . rg_sql_error() . ")");
483 rg_bug_set_error("cannot insert bug (" . rg_sql_error() . ")");
282 484 break; break;
283 485 } }
284 486 rg_sql_free_result($res); rg_sql_free_result($res);
285 487
488 // Add reporter and assignee to the watch list
489 $r = rg_watch_add($db, "bug", $login_ui['uid'], $ri['repo_id'],
490 $bug_id);
491 if ($r === FALSE) {
492 rg_bug_set_error("cannot add to watch list"
493 . " (" . rg_watch_error() . ")");
494 break;
495 }
496
497 if ($assigned_uid > 0) {
498 $r = rg_watch_add($db, "bug", $assigned_uid,
499 $ri['repo_id'], $bug_id);
500 if ($r === FALSE) {
501 rg_bug_set_error("cannot add to watch list"
502 . " (" . rg_watch_error() . ")");
503 break;
504 }
505 }
506
507 $data['bug_id'] = $bug_id;
508 $event = array("category" => 4100, "prio" => 200,
509 "repo.repo_id" => $ri['repo_id'],
510 "repo.name" => $ri['name'],
511 "bug.who_added" => $login_ui['uid'],
512 "bug.who_added_text" => $login_ui['username'],
513 "bug.url" => rg_base_url() . rg_re_bugpage($login_ui, $ri['name'], $bug_id),
514 "bug.assigned_to_text" => $assigned_to_text,
515 "bug.state_text" => rg_bug_state($data['state']),
516 "IP" => rg_var_str("REMOTE_ADDR"));
517 $event = rg_array_merge($event, "bug", $data);
518 $r = rg_event_add($db, $event);
519 if ($r !== TRUE) {
520 rg_bug_set_error("cannot add event"
521 . " ( . rg_event_error() . )");
522 break;
523 }
524
286 525 if (rg_sql_commit($db) === FALSE) { if (rg_sql_commit($db) === FALSE) {
287 rg_bug_set_error("Cannot commit (" . rg_sql_error() . ")");
526 rg_bug_set_error("cannot commit (" . rg_sql_error() . ")");
288 527 break; break;
289 528 } }
290 529
 
... ... function rg_bug_add($db, $repo_id, $uid, $data)
295 534 if ($rollback == 1) if ($rollback == 1)
296 535 rg_sql_rollback($db); rg_sql_rollback($db);
297 536
298 rg_prof_end("bug_add");
537 rg_prof_end("bug_edit");
299 538 return $ret; return $ret;
300 539 } }
301 540
 
... ... function rg_bug_delete($db, $repo_id, $bug_id)
330 569 return $ret; return $ret;
331 570 } }
332 571
333 /*
334 * Update a bug
335 * TODO: check rights - also for create?
336 */
337 function rg_bug_update($db, $repo_id, $bug_id, $data)
338 {
339 rg_prof_start("bug_update");
340 rg_log("bug_update: repo_id=$repo_id bug_id=$bug_id data: "
341 . rg_array2string($data));
342
343 $ret = FALSE;
344 do {
345 // First, test if it already exists
346 $bi = rg_bug_info($db, $repoid, $bug_id);
347 if (($bi === FALSE) || ($bi['exists'] != 1))
348 break;
349
350 $e_data = $data;
351 $e_data['title'] = rg_sql_escape($db, $data['title']);
352 $e_data['body'] = rg_sql_escape($db, $data['body']);
353 $e_data['state'] = sprintf("%u", $data['state']);
354 // TODO: make a function to sanitize the input to be called from
355 // both update and insert.
356
357 $utime = time();
358
359 $sql = "UPDATE bugs SET utime = $now"
360 . ", title = '" . $e_data['title'] . "'"
361 . ", body = '" . $e_data['body'] . "'"
362 . ", state = " . $e_data['state']
363 . ", assigned_uid = " . $e_data['assigned_uid']
364 . " WHERE repo_id = $repo_id"
365 . " AND bug_id = $bug_id";
366 $res = rg_sql_query($db, $sql);
367 if ($res === FALSE) {
368 rg_bug_set_error("Cannot update bug (" . rg_sql_error() . ")");
369 break;
370 }
371 rg_sql_free_result($res);
372 $ret = TRUE;
373 } while (0);
374
375 rg_prof_end("bug_update");
376 return $ret;
377 }
378
379 572 /* /*
380 573 * List bugs * List bugs
381 574 */ */
 
... ... function rg_bug_search_remove($db, $repo_id, $uid, $name)
722 915 /* /*
723 916 * Add a note for a bug * Add a note for a bug
724 917 */ */
725 function rg_bug_note_add($db, $repo_id, $bug_id, $uid, $data)
918 function rg_bug_note_add($db, $repo_id, $bug_id, $login_uid, $data)
726 919 { {
727 920 rg_prof_start("bug_note_add"); rg_prof_start("bug_note_add");
728 921 rg_log("bug_note_add: repo_id=$repo_id bug_id=$bug_id" rg_log("bug_note_add: repo_id=$repo_id bug_id=$bug_id"
729 . " data: " . rg_array2string($data));
922 . " login_uid=$login_uid data: " . rg_array2string($data));
730 923
731 924 $ret = FALSE; $ret = FALSE;
732 925 do { do {
733 926 // TODO: test if user is allowed to add a note // TODO: test if user is allowed to add a note
734 927
735 928 $e_data = $data; $e_data = $data;
736 $e_data['note'] = rg_sql_escape($db, $data['note']);
929 $e_data['note'] = rg_sql_escape($db, trim($data['note']));
737 930
738 931 $itime = time(); $itime = time();
739 932 $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "?"; $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "?";
740 933
741 934 $sql = "INSERT INTO bug_notes (repo_id, bug_id, itime, uid, ip" $sql = "INSERT INTO bug_notes (repo_id, bug_id, itime, uid, ip"
742 935 . ", note)" . ", note)"
743 . " VALUES ($repo_id, $bug_id, $itime, $uid, '$ip'"
936 . " VALUES ($repo_id, $bug_id, $itime, $login_uid, '$ip'"
744 937 . ", '" . $e_data['note'] . "')"; . ", '" . $e_data['note'] . "')";
745 938 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
746 939 if ($res === FALSE) { if ($res === FALSE) {
 
... ... function rg_bug_note_add($db, $repo_id, $bug_id, $uid, $data)
748 941 break; break;
749 942 } }
750 943 rg_sql_free_result($res); rg_sql_free_result($res);
944
945 $_ri = rg_repo_info($db, $repo_id, 0, "");
946 if ($_ri['exists'] != 1) {
947 rg_bug_set_error("cannot lookup repo"
948 . " (" . rg_repo_error() . ")");
949 break;
950 }
951
952 $_bi = rg_bug_info($db, $repo_id, $bug_id);
953 if ($_bi === FALSE)
954 break;
955
956 $_ui = rg_user_info($db, $login_uid, "", "");
957 if ($_ui['exists'] != 1) {
958 rg_bug_set_error("cannot lookup user"
959 . " (" . rg_user_error() . ")");
960 break;
961 }
962
963 $event = array("category" => 4000, "prio" => 200,
964 "bug_id" => $bug_id,
965 "note.who_added" => $login_uid,
966 "repo.repo_id" => $repo_id,
967 "repo.name" => $_ri['name'],
968 "bug.title" => $_bi['title'],
969 "bug.url" => rg_base_url() . rg_re_bugpage($_ui, $_ri['name'], $bug_id),
970 "note" => $data['note'],
971 "note.who_added_text" => $_ui['username'],
972 "IP" => rg_var_str("REMOTE_ADDR"));
973 $r = rg_event_add($db, $event);
974 if ($r !== TRUE) {
975 rg_bug_set_error("cannot add event"
976 . " ( . rg_event_error() . )");
977 break;
978 }
979
751 980 $ret = TRUE; $ret = TRUE;
752 981 } while (0); } while (0);
753 982
 
... ... function rg_bug_note_list($db, $repo_id, $bug_id, $offset)
771 1000 . " WHERE repo_id = $repo_id" . " WHERE repo_id = $repo_id"
772 1001 . " AND bug_id = $bug_id" . " AND bug_id = $bug_id"
773 1002 . " ORDER BY itime" . " ORDER BY itime"
774 . " LIMIT 20 OFFSET $offset";
1003 . " OFFSET $offset";
775 1004 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
776 1005 if ($res === FALSE) { if ($res === FALSE) {
777 1006 rg_bug_set_error("Cannot select bug notes (" . rg_sql_error() . ")"); rg_bug_set_error("Cannot select bug notes (" . rg_sql_error() . ")");
 
... ... function rg_bug_label_insert($db, $repo_id, $bug_id, $labels)
932 1161 /* /*
933 1162 * Returns labels as HTML * Returns labels as HTML
934 1163 */ */
935 function rg_bug_label_html($db, $repo_id, $bug_id)
1164 function rg_bug_label_html($db, $labels)
936 1165 { {
937 1166 rg_prof_start("bug_label_html"); rg_prof_start("bug_label_html");
938 1167
939 $labels = rg_bug_label_get($db, $repo_id, $bug_id);
940
941 1168 $a = array(); $a = array();
942 1169 if (!empty($labels)) { if (!empty($labels)) {
943 1170 foreach ($labels as $label) foreach ($labels as $label)
File inc/fixes.inc.php changed (mode: 100644) (index e762e8c..1b70d8b)
7 7 include_once($INC . "/sql.inc.php"); include_once($INC . "/sql.inc.php");
8 8 include_once($INC . "/state.inc.php"); include_once($INC . "/state.inc.php");
9 9 include_once($INC . "/util.inc.php"); include_once($INC . "/util.inc.php");
10 include_once($INC . "/user.inc.php");
11 include_once($INC . "/repo.inc.php");
10 12
11 13 $rg_fixes = array(); $rg_fixes = array();
12 14 $rg_fixes[1] = array("rg_fixes_user_index_by_id"); $rg_fixes[1] = array("rg_fixes_user_index_by_id");
File inc/prof.inc.php changed (mode: 100644) (index 08b87ca..50383b4)
... ... function rg_prof_end($label)
38 38 global $rg_prof_main; global $rg_prof_main;
39 39
40 40 if (!isset($rg_prof_tmp[$label])) { if (!isset($rg_prof_tmp[$label])) {
41 rg_log("ERROR: rg_prof_start was not called for label [$label]!");
41 rg_internal_error("rg_prof_start was not called for label [$label]!");
42 42 return; return;
43 43 } }
44 44
File inc/repo.inc.php changed (mode: 100644) (index 0ad540d..91b720b)
... ... function rg_repo_event_storage_create($db, $e)
211 211 break; break;
212 212 } }
213 213 } else { } else {
214 $mi = rg_repo_info($db, $e['ui.uid'], $e['ri.master'], "");
214 $mi = rg_repo_info($db, $e['ri.master'], 0, "");
215 215 if ($mi['exists'] != 1) { if ($mi['exists'] != 1) {
216 216 rg_repo_set_error("cannot find master (" . rg_repo_error() . ")"); rg_repo_set_error("cannot find master (" . rg_repo_error() . ")");
217 217 break; break;
 
... ... function rg_repo_invalidate_cache($uid, $repo_id)
436 436
437 437 /* /*
438 438 * Return info about a repo * Return info about a repo
439 * If you want to lookup by repo_id or uid/repo_name
439 440 */ */
440 function rg_repo_info($db, $uid, $repo_id, $repo_name)
441 function rg_repo_info($db, $repo_id, $uid, $repo_name)
441 442 { {
442 443 global $rg_repo_info_cache; global $rg_repo_info_cache;
443 444
444 445 rg_prof_start("repo_info"); rg_prof_start("repo_info");
445 rg_log("repo_info: uid=$uid repo_id=$repo_id repo_name=$repo_name.");
446 rg_log("repo_info: repo_id=$repo_id uid=$uid repo_name=$repo_name.");
446 447
447 448 $ret['ok'] = 0; $ret['ok'] = 0;
448 449 $ret['exists'] = 0; $ret['exists'] = 0;
449 450 do { do {
450 451 if ($repo_id > 0) { if ($repo_id > 0) {
451 $key = $uid . " " . $repo_id;
452 $key = $repo_id;
452 453 if (isset($rg_repo_info_cache[$key])) { if (isset($rg_repo_info_cache[$key])) {
453 454 $ret = $rg_repo_info_cache[$key]; $ret = $rg_repo_info_cache[$key];
454 455 $ret['from_cache'] = 1; $ret['from_cache'] = 1;
 
... ... function rg_repo_info($db, $uid, $repo_id, $repo_name)
460 461 $add = " AND repo_id = $repo_id"; $add = " AND repo_id = $repo_id";
461 462 } else if (!empty($repo_name)) { } else if (!empty($repo_name)) {
462 463 $e_repo = rg_sql_escape($db, $repo_name); $e_repo = rg_sql_escape($db, $repo_name);
463 $add = " AND name = '$e_repo'";
464 $add = " AND uid = $uid AND name = '$e_repo'";
464 465 } else { } else {
465 466 rg_repo_set_error("no repo_id or user/repo specified!"); rg_repo_set_error("no repo_id or user/repo specified!");
466 467 break; break;
467 468 } }
468 469
469 $sql = "SELECT * FROM repos WHERE uid = $uid" . $add;
470 $sql = "SELECT * FROM repos WHERE 1 = 1" . $add;
470 471 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
471 472 if ($res === FALSE) { if ($res === FALSE) {
472 473 rg_repo_set_error("cannot query (" . rg_sql_error() . ")"); rg_repo_set_error("cannot query (" . rg_sql_error() . ")");
 
... ... function rg_repo_info($db, $uid, $repo_id, $repo_name)
485 486 break; break;
486 487 } }
487 488
488 $ret = rg_repo_info($db, $uid, $_repo_id, "");
489 $ret = rg_repo_info($db, $_repo_id, 0, "");
489 490 break; break;
490 491 } }
491 492
 
... ... function rg_repo_allow($db, $ri, $ui, $needed_rights)
554 555 * Add a repository * Add a repository
555 556 * @master - makes sense only for clones: who is the master repo. * @master - makes sense only for clones: who is the master repo.
556 557 * TODO: put all fields into an array! * TODO: put all fields into an array!
558 * TODO: unify this function with rg_repo_update.
557 559 */ */
558 560 function rg_repo_create($db, $master, $ui, $name, $max_commit_size, function rg_repo_create($db, $master, $ui, $name, $max_commit_size,
559 561 $description, $rights, $max_users) $description, $rights, $max_users)
 
... ... function rg_repo_create($db, $master, $ui, $name, $max_commit_size,
575 577 break; break;
576 578
577 579 // First, test if it already exists // First, test if it already exists
578 $ri = rg_repo_info($db, $ui['uid'], 0, $name);
580 $ri = rg_repo_info($db, 0, $ui['uid'], $name);
579 581 if ($ri['ok'] != 1) if ($ri['ok'] != 1)
580 582 break; break;
581 583 if ($ri['exists'] == 1) { if ($ri['exists'] == 1) {
 
... ... function rg_repo_create($db, $master, $ui, $name, $max_commit_size,
611 613 "ri.name" => $name, "ri.name" => $name,
612 614 "ri.master" => $master, "ri.master" => $master,
613 615 "ri.description" => $description, "ri.description" => $description,
614 "ri.rights_text" => implode("\n", rg_rights_text("repo", $rights)),
616 "ri.rights_text" => rg_implode("\t", rg_rights_text("repo", $rights), "\n"),
615 617 "ri.repo_id" => $row['repo_id'], "ri.repo_id" => $row['repo_id'],
618 "ri.url" => rg_base_url() . rg_re_repopage($ui, $name),
616 619 "IP" => rg_var_str("REMOTE_ADDR")); "IP" => rg_var_str("REMOTE_ADDR"));
617 620 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
618 621 if ($r !== TRUE) { if ($r !== TRUE) {
 
... ... function rg_repo_insert_rename($db, $uid, $repo_id, $old_name)
761 764 function rg_repo_update($db, $login_ui, &$new) function rg_repo_update($db, $login_ui, &$new)
762 765 { {
763 766 rg_prof_start("repo_update"); rg_prof_start("repo_update");
764 rg_log("repo_update: uid=" . $login_ui['uid']
767 rg_log("repo_update: login_uid=" . $login_ui['uid']
765 768 . " new=" . rg_array2string($new)); . " new=" . rg_array2string($new));
766 769
767 770 $ret = FALSE; $ret = FALSE;
 
... ... function rg_repo_update($db, $login_ui, &$new)
772 775
773 776 // TODO: Something is strange here, why we need to lookup the repo?! // TODO: Something is strange here, why we need to lookup the repo?!
774 777 // First, test if it already exists // First, test if it already exists
775 $ri = rg_repo_info($db, $login_ui['uid'], $new['repo_id'], $new['name']);
778 $ri = rg_repo_info($db, $new['repo_id'], $login_ui['uid'], $new['name']);
776 779 if ($ri['ok'] != 1) if ($ri['ok'] != 1)
777 780 break; break;
778 781 if (($ri['exists'] == 1) && ($ri['repo_id'] != $new['repo_id'])) { if (($ri['exists'] == 1) && ($ri['repo_id'] != $new['repo_id'])) {
 
... ... function rg_repo_update($db, $login_ui, &$new)
781 784 } }
782 785
783 786 // Second, test if repo_id is valid // Second, test if repo_id is valid
784 $ri = rg_repo_info($db, $login_ui['uid'], $new['repo_id'], "");
787 $ri = rg_repo_info($db, $new['repo_id'], $login_ui['uid'], "");
785 788 if ($ri['ok'] != 1) if ($ri['ok'] != 1)
786 789 break; break;
787 790 if ($ri['exists'] == 0) { if ($ri['exists'] == 0) {
 
... ... function rg_repo_update($db, $login_ui, &$new)
819 822 $event = array("category" => 3002, "prio" => 50, $event = array("category" => 3002, "prio" => 50,
820 823 "ui.uid" => $login_ui['uid'], "ui.uid" => $login_ui['uid'],
821 824 "ui.email" => $login_ui['email'], "ui.email" => $login_ui['email'],
825 "ri.url" => rg_base_url() . rg_re_repopage($login_ui, $new['name']),
822 826 "IP" => rg_var_str("REMOTE_ADDR")); "IP" => rg_var_str("REMOTE_ADDR"));
823 827 $event = rg_array_merge($event, "ri.old", $ri); $event = rg_array_merge($event, "ri.old", $ri);
824 828 $event = rg_array_merge($event, "ri", $new); $event = rg_array_merge($event, "ri", $new);
 
... ... function rg_repo_list_query($db, $url, $sql)
874 878 $master_repo = "-"; $master_repo = "-";
875 879 if ($row['master'] > 0) { if ($row['master'] > 0) {
876 880 $master_repo = "?"; $master_repo = "?";
877 $_mi = rg_repo_info($db, $_ui['uid'], $row['master'], "");
881 $_mi = rg_repo_info($db, $row['master'], 0, "");
878 882 if ($_mi['exists'] = 1) if ($_mi['exists'] = 1)
879 883 $master_repo = $_mi['name']; $master_repo = $_mi['name'];
880 884 } }
File inc/ssh.inc.php changed (mode: 100644) (index f7269c6..e9b2393)
... ... function rg_ssh_repo($db, $uid, $paras)
51 51
52 52 $repo_name = trim($paras[0]); $repo_name = trim($paras[0]);
53 53
54 $ri = rg_repo_info($db, $uid, 0, $repo_name);
54 $ri = rg_repo_info($db, 0, $uid, $repo_name);
55 55 if ($ri === FALSE) { if ($ri === FALSE) {
56 56 echo "Unknown repo!\n"; echo "Unknown repo!\n";
57 57 exit(0); exit(0);
 
... ... function rg_ssh_repo($db, $uid, $paras)
71 71 echo "Default rights: " . $rights . "\n"; echo "Default rights: " . $rights . "\n";
72 72
73 73 if ($ri['master'] > 0) { if ($ri['master'] > 0) {
74 $mri = rg_repo_info($db, $uid, $ri['master'], "");
74 $mri = rg_repo_info($db, $ri['master'], 0, "");
75 75 if ($mri !== FALSE) { if ($mri !== FALSE) {
76 76 echo "Master: " . $mri['name'] . "\n"; echo "Master: " . $mri['name'] . "\n";
77 77 } }
File inc/struct.inc.php changed (mode: 100644) (index 86026e9..5b0e4ac)
... ... $rg_sql_struct[14]['other'] = array(
261 261 ); );
262 262
263 263
264 $rg_sql_struct[15] = array();
265 $rg_sql_struct[15]['tables'] = array(
266 "watch_repo" => "CREATE TABLE watch_repo ("
267 . "uid INT NOT NULL"
268 . ", repo_id INT NOT NULL)",
269 "watch_bug" => "CREATE TABLE watch_bug ("
270 . "uid INT NOT NULL"
271 . ", repo_id INT NOT NULL"
272 . ", bug_id INT NOT NULL)"
273 );
274
275
264 276 // This must be the last line // This must be the last line
265 277 $rg_sql_schema_ver = count($rg_sql_struct); $rg_sql_schema_ver = count($rg_sql_struct);
266 278
File inc/user.inc.php changed (mode: 100644) (index fe23013..e9616f4)
... ... function rg_user_forgot_pass_mail($db, $email)
1005 1005
1006 1006 $headers = "From: $rg_admin_name <$rg_admin_email>"; $headers = "From: $rg_admin_name <$rg_admin_email>";
1007 1007
1008 if (isset($_SERVER['HTTPS']))
1009 $proto = "https";
1010 else
1011 $proto = "http";
1008 $base_url = rg_base_url();
1012 1009
1013 1010 if (!mail($email, if (!mail($email,
1014 1011 "Forgot password", "Forgot password",
1015 1012 "Hello!\n\n" "Hello!\n\n"
1016 1013 . "If you want to reset the password, follow:\n" . "If you want to reset the password, follow:\n"
1017 . $proto . "://"
1018 . @$_SERVER['HTTP_HOST']
1014 . $base_url
1019 1015 . rg_re_url("/op/forgot_link") . "&forgot_token=" . $r['token'] . rg_re_url("/op/forgot_link") . "&forgot_token=" . $r['token']
1020 1016 . "\n\nRocketGit team", . "\n\nRocketGit team",
1021 1017 $headers, $headers,
File inc/user/repo-page.php changed (mode: 100644) (index 86f6901..3231d1c)
... ... if (rg_repo_ok($repo) !== TRUE) {
15 15 return; return;
16 16 } }
17 17
18 $ri = rg_repo_info($db, $login_ui['uid'], 0, $repo);
19 if ($ri === FALSE) {
18 $ri = rg_repo_info($db, 0, $login_ui['uid'], $repo);
19 if ($ri['ok'] != 1) {
20 20 $_repo_page .= rg_warning("Internal error!"); $_repo_page .= rg_warning("Internal error!");
21 21 return; return;
22 22 } }
23 if ($ri['exists'] != 1) {
24 $_repo_page .= rg_warning("Non existing repo!");
25 return;
26 }
23 27
24 28 if ($ri['git_dir_done'] == 0) { if ($ri['git_dir_done'] == 0) {
25 29 // We will wait a little for the git dir to be done // We will wait a little for the git dir to be done
File inc/user/repo/bug/add/add.php changed (mode: 100644) (index 6d79e85..edef71e)
... ... $bug_add_more = $repo_bug_more;
5 5 $_bug_add = ""; $_bug_add = "";
6 6 $bug_errmsg = array(); $bug_errmsg = array();
7 7
8 $_x = array();
9 8 if ($doit == 0) { if ($doit == 0) {
10 9 // defaults // defaults
11 $_x['title'] = "";
12 $_x['body'] = "";
13 $_x['state'] = 1;
14 $_x['labels'] = "";
15 $_x['assigned_to'] = 0;
10 $_x = rg_bug_vars_defaults();
16 11 } else { } else {
17 $_x['title'] = rg_var_str("title");
18 $_x['body'] = rg_var_str("body");
19 $_x['state'] = rg_var_uint("state");
20 $_x['labels'] = rg_var_str("labels");
21 $_x['assigned_uid'] = 0;
12 $_x = rg_bug_vars();
22 13
23 14 do { do {
24 if (!rg_token_valid($db, $sid, rg_var_str("token"))) {
15 if (!rg_token_valid($db, $sid, $token)) {
25 16 $bug_errmsg[] = "Invalid token. Try again."; $bug_errmsg[] = "Invalid token. Try again.";
26 17 break; break;
27 18 } }
28 19
29 if (empty($_x['title'])) {
30 $bug_errmsg[] = "Title too short.";
31 break;
32 }
33
34 if (empty($_x['body'])) {
35 $bug_errmsg[] = "Description too short.";
36 break;
37 }
38
39 if (($_x['state'] < 1) || ($_x['state'] > 3)) {
40 $bug_errmsg[] = "State is not valid.";
41 break;
42 }
43
44 $bug_id = rg_bug_add($db, $ri['repo_id'], $login_ui['uid'], $_x);
20 $bug_id = rg_bug_edit($db, $ri, $login_ui, $_x);
45 21 if ($bug_id === FALSE) { if ($bug_id === FALSE) {
46 22 $bug_errmsg[] = "Cannot add bug (" . rg_bug_error() . ")."; $bug_errmsg[] = "Cannot add bug (" . rg_bug_error() . ").";
47 23 break; break;
48 24 } }
49 25
50 26 // redirect to bug home // redirect to bug home
51 $url = rg_re_bugpage($page_ui, $ri, $bug_id);
27 $url = rg_re_bugpage($page_ui, $ri['name'], $bug_id);
52 28 rg_redirect($url); rg_redirect($url);
53 29 } while (0); } while (0);
54 30 } }
55 31
56 32 $bug_add_more = array_merge($bug_add_more, $_x); $bug_add_more = array_merge($bug_add_more, $_x);
57 33 $bug_add_more['HTML:bug_errmsg'] = rg_template_errmsg($bug_errmsg); $bug_add_more['HTML:bug_errmsg'] = rg_template_errmsg($bug_errmsg);
58 $bug_add_more['bug_action'] = "Add bug";
59 34 $bug_add_more['rg_form_token'] = rg_token_get($db, $sid); $bug_add_more['rg_form_token'] = rg_token_get($db, $sid);
60 35 $_exclude = array(0); // exclude "Any" $_exclude = array(0); // exclude "Any"
61 36 $bug_add_more['HTML:state_select'] = rg_bug_state_select($_x['state'], $_exclude); $bug_add_more['HTML:state_select'] = rg_bug_state_select($_x['state'], $_exclude);
62 $_bug_add .= rg_template("repo/bug/bug_add.html", $bug_add_more);
37 $_bug_add .= rg_template("repo/bug/bug_add_edit.html", $bug_add_more);
63 38 ?> ?>
File inc/user/repo/bug/main.php changed (mode: 100644) (index a19b8f5..d8d059d)
... ... case 'list': /* list */
23 23
24 24 // Somebody pressed "Remove" button? // Somebody pressed "Remove" button?
25 25 if (rg_var_uint("remove") == 1) { if (rg_var_uint("remove") == 1) {
26 $token = rg_var_str("token");
27 26 if (!rg_token_valid($db, $sid, $token)) { if (!rg_token_valid($db, $sid, $token)) {
28 27 $_bug_body .= rg_warning("Error: invalid token. Try again."); // TODO $_bug_body .= rg_warning("Error: invalid token. Try again."); // TODO
29 28 exit(1); // security_violation! exit(1); // security_violation!
 
... ... case 'list': /* list */
59 58 $_bug_body .= rg_template_table("repo/bug/list", $r, $repo_bug_more); $_bug_body .= rg_template_table("repo/bug/list", $r, $repo_bug_more);
60 59
61 60 // Show remove for custom search // Show remove for custom search
61 // TODO: don't we check for uid also? Security problems?
62 62 if (isset($filter['standard']) && ($filter['standard'] == 0)) { if (isset($filter['standard']) && ($filter['standard'] == 0)) {
63 63 $_remove_more = $repo_bug_more; $_remove_more = $repo_bug_more;
64 64 $_remove_more['rg_form_token'] = rg_token_get($db, $sid); $_remove_more['rg_form_token'] = rg_token_get($db, $sid);
File inc/user/repo/bug/show/add_note.php added (mode: 100644) (index 0000000..1c96fbc)
1 <?php
2 rg_log("/inc/user/repo/bug/show/add_note");
3
4 $note_add_doit = rg_var_uint("note_add_doit");
5
6 $add_note_more = $repo_bug_show_more;
7 $note = "";
8
9 $note_errmsg = array();
10 if ($note_add_doit == 1) {
11 do {
12 $note = rg_var_str("note");
13
14 if (!rg_token_valid($db, $sid, $token)) {
15 $note_errmsg[] = "Invalid token. Try again.";
16 break;
17 }
18
19 if (empty($note)) {
20 $note_errmsg[] = "Cannot be empty";
21 break;
22 }
23
24 // add note
25 $_d = array();
26 $_d['note'] = $note;
27 $ret = rg_bug_note_add($db, $ri['repo_id'], $bug_id, $login_ui['uid'], $_d);
28 if ($ret === FALSE) {
29 $note_errmsg[] = "Cannot add note (" . rg_bug_error() . ")";
30 break;
31 }
32
33 // allow another note to be added
34 $note = "";
35 } while (0);
36 }
37
38 // add note form
39 $add_note_more['HTML:note_errmsg'] = rg_template_errmsg($note_errmsg);
40 $add_note_more['rg_form_token'] = rg_token_get($db, $sid);
41 $add_note_more['note'] = $note;
42 $repo_bug_show_more['HTML:note_add'] = rg_template("repo/bug/note_add.html", $add_note_more);
43 ?>
File inc/user/repo/bug/show/edit.php added (mode: 100644) (index 0000000..e939dfc)
1 <?php
2 rg_log("/inc/user/repo/bug/show/edit");
3
4 // TODO: check rights
5
6 $repo_bug_edit_more = $repo_bug_show_more;
7 $_bug_edit = "";
8
9 $bug_errmsg = array();
10
11 $_x = $ibug;
12 while ($doit == 1) {
13 $_x = rg_bug_vars();
14
15 if (!rg_token_valid($db, $sid, $token)) {
16 $bug_errmsg[] = "Invalid token. Try again.";
17 break;
18 }
19
20 $ret = rg_bug_edit($db, $ri, $login_ui, $_x);
21 if ($ret === FALSE) {
22 $bug_errmsg[] = "Cannot edit bug (" . rg_bug_error() . ")";
23 break;
24 }
25
26 // redirect to bug home
27 // TODO: Should we redirect, so user can press reload to refresh the bug?
28 //$url = rg_re_bugpage($page_ui, $ri['name'], $bug_id);
29 //rg_redirect($url);
30 }
31
32 // add note form
33 $repo_bug_edit_more = array_merge($repo_bug_edit_more, $_x);
34 $repo_bug_edit_more['HTML:bug_errmsg'] = rg_template_errmsg($bug_errmsg);
35 $_exclude = array(0); // exclude "Any"
36 $repo_bug_edit_more['HTML:state_select'] = rg_bug_state_select($_x['state'], $_exclude);
37 $_bug_edit .= rg_template("repo/bug/bug_add_edit.html", $repo_bug_edit_more);
38 ?>
File inc/user/repo/bug/show/show.php changed (mode: 100644) (index cfa6f1c..7d9d68f)
... ... $repo_bug_show_more = $repo_bug_more;
5 5 $_bug_show = ""; $_bug_show = "";
6 6
7 7 $repo_bug_show_more['bug_id'] = $bug_id; $repo_bug_show_more['bug_id'] = $bug_id;
8 $repo_bug_show_more['HTML:bug_edit'] = "";
8 9
9 10 $ibug = rg_bug_info($db, $ri['repo_id'], $bug_id); $ibug = rg_bug_info($db, $ri['repo_id'], $bug_id);
10 11 if ($ibug === FALSE) if ($ibug === FALSE)
 
... ... if ($ibug['exists'] != 1) {
14 15 return; return;
15 16 } }
16 17
17 $repo_bug_show_more = array_merge($repo_bug_show_more, $ibug);
18
19 // insert?
20 $doit = rg_var_uint("doit");
21 $note_errmsg = array();
22 if ($doit == 0) {
23 // default values
24 $note = "";
25 } else {
26 do {
27 $token = rg_var_str("token");
28 $note = rg_var_str("note");
18 // load labels
19 $labels = rg_bug_label_get($db, $ri['repo_id'], $bug_id);
20 if ($labels === FALSE)
21 $repo_bug_show_more['HTML:labels_html'] = "Cannot load labels!";
22 else
23 $repo_bug_show_more['HTML:labels_html'] = rg_bug_label_html($db, $labels);
24 $repo_bug_show_more['labels'] = implode(" ", $labels);
29 25
30 if (!rg_token_valid($db, $sid, $token)) {
31 $note_errmsg[] = "Invalid token. Try again.";
32 break;
33 }
26 // edit
27 $repo_bug_show_more['HTML:edit_form'] = rg_template("repo/bug/b_edit.html",
28 $repo_bug_show_more);
29 if (rg_var_uint("edit") == 1) {
30 include($INC . "/user/repo/bug/show/edit.php");
31 $repo_bug_show_more['HTML:bug_edit'] = $_bug_edit;
32 }
34 33
35 if (empty($note)) {
36 $note_errmsg[] = "Cannot be empty";
37 break;
38 }
34 // close/re-open
35 $close_reopen_error = "";
36 while (rg_var_uint("close_reopen") == 1) {
37 if (!rg_token_valid($db, $sid, $token)) {
38 $close_reopen_error = "Invalid token. Try again.";
39 break;
40 }
39 41
40 // add note
41 $_d = array();
42 $_d['note'] = $note;
43 $ret = rg_bug_note_add($db, $ri['repo_id'], $bug_id, $login_ui['uid'], $_d);
44 if ($ret === FALSE) {
45 $note_errmsg[] = "Cannot add note (" . rg_bug_error() . ")";
46 break;
47 }
42 $ibug['state'] = rg_var_uint("state");
43 $ibug['state_text'] = rg_bug_state($ibug['state']);
44 $ret = rg_bug_edit($db, $ri, $login_ui, $ibug);
45 if ($ret === FALSE) {
46 $close_reopen_error = "Cannot edit bug (" . rg_bug_error() . ")";
47 break;
48 }
48 49
49 // prepare form for other note
50 $note = "";
51 } while (0);
50 // TODO: do something with the error code
51 break;
52 52 } }
53
54 // load labels
55 $labels = rg_bug_label_get($db, $ri['repo_id'], $bug_id);
56 if ($labels === FALSE)
57 $repo_bug_show_more['HTML:labels'] = "Cannot load labels!";
53 if ($ibug['state'] == 1)
54 $t = "repo/bug/b_close.html";
58 55 else else
59 $repo_bug_show_more['HTML:labels'] = rg_bug_label_html($db, $ri['repo_id'], $bug_id);
56 $t = "repo/bug/b_reopen.html";
57 $repo_bug_show_more['HTML:close_form'] = rg_template($t, $repo_bug_show_more);
58 $repo_bug_show_more['HTML:button_error'] = rg_warning($close_reopen_error,
59 $repo_bug_show_more);
60
61 // add_note must be unconditionally included because we must insert the form
62 include($INC . "/user/repo/bug/show/add_note.php");
60 63
61 64 // load notes // load notes
62 65 $notes = rg_bug_note_list($db, $ri['repo_id'], $bug_id, 0); $notes = rg_bug_note_list($db, $ri['repo_id'], $bug_id, 0);
 
... ... if ($notes === FALSE)
65 68 else else
66 69 $repo_bug_show_more['HTML:notes'] = rg_template_table("repo/bug/list_note", $notes, $repo_bug_show_more); $repo_bug_show_more['HTML:notes'] = rg_template_table("repo/bug/list_note", $notes, $repo_bug_show_more);
67 70
68 // add note form
69 $repo_bug_show_more['HTML:note_errmsg'] = rg_template_errmsg($note_errmsg);
71 // watch
72 $watch_body = "";
73 $watch = rg_watch_load($db, "bug", $login_ui['uid'], $ri['repo_id'], $bug_id);
74 if ($watch === FALSE) {
75 $watch_body .= rg_warning("Internal error.");
76 } else {
77 if ($watch === 0) {
78 // user does not watch the bug, present 'watch' form
79 if (rg_var_uint("watch") == 1) {
80 // user pressed watch button
81 $r = rg_watch_add($db, "bug", $login_ui['uid'],
82 $ri['repo_id'], $bug_id);
83 if ($r === FALSE)
84 rg_internal_error("TODO: find something here");
85 $watch = 1;
86 }
87 } else {
88 // user is already watching the bug, present 'unwatch' option
89 if (rg_var_uint("unwatch") == 1) {
90 // user pressed unwatch button
91 $r = rg_watch_del($db, "bug", $login_ui['uid'],
92 $ri['repo_id'], $bug_id);
93 if ($r === FALSE)
94 rg_internal_error("TODO: find something here");
95 $watch = 0;
96 }
97 }
98
99 if ($watch == 0)
100 $t = "repo/bug/b_watch.html";
101 else
102 $t = "repo/bug/b_unwatch.html";
70 103
104 $r = rg_template($t, $repo_bug_show_more);
105 if ($r !== FALSE)
106 $watch_body .= $r;
107 }
108 $repo_bug_show_more['HTML:watch_form'] = $watch_body;
109
110 //rg_log_ml("DEBUG: ibug: " . print_r($ibug, TRUE));
111 $repo_bug_show_more = array_merge($repo_bug_show_more, $ibug);
71 112 $repo_bug_show_more['rg_form_token'] = rg_token_get($db, $sid); $repo_bug_show_more['rg_form_token'] = rg_token_get($db, $sid);
72 $repo_bug_show_more['note'] = $note;
73 $repo_bug_show_more['HTML:note_add'] = rg_template("repo/bug/note_add.html", $repo_bug_show_more);
74 113
75 114 $_bug_show .= rg_template("repo/bug/show.html", $repo_bug_show_more); $_bug_show .= rg_template("repo/bug/show.html", $repo_bug_show_more);
76 115 ?> ?>
File inc/util.inc.php changed (mode: 100644) (index bbe1d5c..78afc63)
... ... function rg_re_userpage($ui)
162 162 return $_SERVER['PHP_SELF'] . "?vv=$s"; return $_SERVER['PHP_SELF'] . "?vv=$s";
163 163 } }
164 164
165 function rg_re_repopage($ui, $repo)
165 function rg_re_repopage($ui, $repo_name)
166 166 { {
167 167 if (!isset($ui['organization'])) { if (!isset($ui['organization'])) {
168 168 rg_internal_error("rg_re_repopage called with wrong ui (no org)!"); rg_internal_error("rg_re_repopage called with wrong ui (no org)!");
169 169 exit(1); exit(1);
170 170 } }
171 171
172 $s = rg_re_userpage($ui) . "/" . $repo;
172 $s = rg_re_userpage($ui) . "/" . $repo_name;
173 173
174 174 if (isset($_REQUEST['rwe'])) if (isset($_REQUEST['rwe']))
175 175 return $s; return $s;
 
... ... function rg_re_repopage($ui, $repo)
177 177 return $_SERVER['PHP_SELF'] . "?vv=$s"; return $_SERVER['PHP_SELF'] . "?vv=$s";
178 178 } }
179 179
180 function rg_re_bugpage($ui, $ri, $bug_id)
180 function rg_re_bugpage($ui, $repo_name, $bug_id)
181 181 { {
182 182 if (!isset($ui['organization'])) { if (!isset($ui['organization'])) {
183 183 rg_internal_error("rg_re_repopage called with wrong ui (no org)!"); rg_internal_error("rg_re_repopage called with wrong ui (no org)!");
184 184 exit(1); exit(1);
185 185 } }
186 186
187 $s = rg_re_userpage($ui) . "/" . $ri['name'] . "/bug/" . $bug_id;
187 $s = rg_re_repopage($ui, $repo_name) . "/bug/" . $bug_id;
188 188
189 189 if (isset($_REQUEST['rwe'])) if (isset($_REQUEST['rwe']))
190 190 return $s; return $s;
 
... ... function rg_re_bugpage($ui, $ri, $bug_id)
192 192 return $_SERVER['PHP_SELF'] . "?vv=$s"; return $_SERVER['PHP_SELF'] . "?vv=$s";
193 193 } }
194 194
195 function rg_base_url()
196 {
197 $port = "";
198 if (isset($_SERVER['HTTPS'])) {
199 $proto = "https";
200 if ($_SERVER['SERVER_PORT'] != 443)
201 $port = ":" . $_SERVER['SERVER_PORT'];
202 } else {
203 $proto = "http";
204 if ($_SERVER['SERVER_PORT'] != 80)
205 $port = ":" . $_SERVER['SERVER_PORT'];
206 }
207
208 return $proto . "://" . $_SERVER['SERVER_NAME'] . $port;
209 }
210
195 211 function rg_re_repo_ssh($organization, $user, $repo) function rg_re_repo_ssh($organization, $user, $repo)
196 212 { {
197 213 global $rg_ssh_host; global $rg_ssh_host;
 
... ... function rg_prepare_replace(&$data, &$what, &$values)
448 464 if (!is_array($data)) if (!is_array($data))
449 465 rg_internal_error("invalid type passed"); rg_internal_error("invalid type passed");
450 466 foreach ($data as $k => $v) { foreach ($data as $k => $v) {
467 if (is_array($v)) {
468 rg_log_ml("value of key [$k] is array!"
469 . " data: " . print_r($data, TRUE));
470 exit(1);
471 }
451 472 if (strncmp($k, "HTML:", 5) == 0) { if (strncmp($k, "HTML:", 5) == 0) {
452 473 $k = substr($k, 5); $k = substr($k, 5);
453 474 } else { } else {
475 if (is_array($v))
476 rg_log_ml("DEBUG: Invalid type for [$k]: " . print_r($v, TRUE));
454 477 $v = htmlspecialchars($v); $v = htmlspecialchars($v);
455 478 } }
456 479 $what[$k] = "/@@" . $k . "@@/uU"; $what[$k] = "/@@" . $k . "@@/uU";
 
... ... function rg_prepare_replace(&$data, &$what, &$values)
470 493 } }
471 494
472 495 /* /*
473 * Lookup a var into data array, if needed
496 * Lookup a var into data array, if needed.
497 * It is used for conditionals.
474 498 */ */
475 499 function rg_replace_lookup(&$data, $var) function rg_replace_lookup(&$data, $var)
476 500 { {
 
... ... function rg_file_get_contents($f)
627 651
628 652 /* /*
629 653 * Builds a html output based on a template with header, footer and line * Builds a html output based on a template with header, footer and line
654 * @data - array of data for every line: index 0 is line 1, index 1 is line 2...
630 655 */ */
631 656 function rg_template_table($dir, &$data, $more) function rg_template_table($dir, &$data, $more)
632 657 { {
 
... ... function rg_template_table($dir, &$data, $more)
645 670
646 671 if (!is_array($data) || empty($data)) { if (!is_array($data) || empty($data)) {
647 672 $no_data = rg_file_get_contents($xdir . "/nodata.html"); $no_data = rg_file_get_contents($xdir . "/nodata.html");
648 $r = rg_replace_conditionals($no_data, $data);
673 $r = rg_replace_conditionals($no_data, $more);
649 674 return preg_replace($m_what, $m_values, $r); return preg_replace($m_what, $m_values, $r);
650 675 } }
651 676
 
... ... function rg_template_table($dir, &$data, $more)
654 679 $foot = rg_file_get_contents($xdir . "/footer.html"); $foot = rg_file_get_contents($xdir . "/footer.html");
655 680 $between = rg_file_get_contents($xdir . "/between.html"); $between = rg_file_get_contents($xdir . "/between.html");
656 681
657 $head = rg_replace_conditionals($head, $data);
658 $foot = rg_replace_conditionals($foot, $data);
659 $between = rg_replace_conditionals($between, $data);
682 $head = rg_replace_conditionals($head, $more);
683 $foot = rg_replace_conditionals($foot, $more);
684 $between = rg_replace_conditionals($between, $more);
660 685
661 686 $head = preg_replace($m_what, $m_values, $head); $head = preg_replace($m_what, $m_values, $head);
662 687 $foot = preg_replace($m_what, $m_values, $foot); $foot = preg_replace($m_what, $m_values, $foot);
 
... ... function rg_template_table($dir, &$data, $more)
677 702 $body .= $between; $body .= $between;
678 703 } }
679 704
680 $r = rg_replace_conditionals($line, $data);
705 $r = rg_replace_conditionals($line, $more);
681 706 $body .= preg_replace($what, $values, $r); $body .= preg_replace($what, $values, $r);
682 707 } }
683 708
 
... ... function rg_template_errmsg($a)
757 782 */ */
758 783 function rg_warning($msg) function rg_warning($msg)
759 784 { {
785 if (empty($msg))
786 return "";
787
760 788 $x = array("msg" => $msg); $x = array("msg" => $msg);
761 789 return rg_template("warning.html", $x); return rg_template("warning.html", $x);
762 790 } }
 
... ... function rg_warning($msg)
766 794 */ */
767 795 function rg_ok($msg) function rg_ok($msg)
768 796 { {
797 if (empty($msg))
798 return "";
799
769 800 $x = array("msg" => $msg); $x = array("msg" => $msg);
770 801 return rg_template("ok.html", $x); return rg_template("ok.html", $x);
771 802 } }
 
... ... function rg_array_merge($src, $namespace, $a)
1130 1161 return $ret; return $ret;
1131 1162 } }
1132 1163
1164 /*
1165 * Special implode, with prefix/postfix
1166 */
1167 function rg_implode($prefix, $a, $postfix)
1168 {
1169 if (!is_array($a))
1170 return $a;
1171
1172 if (empty($a))
1173 return "";
1174
1175 $ret = array();
1176 foreach ($a as $index => $data)
1177 $ret[] = $prefix . $data;
1178
1179 return implode($postfix, $ret);
1180 }
1181
1133 1182 ?> ?>
File inc/watch.inc.php added (mode: 100644) (index 0000000..355d1c8)
1 <?php
2 require_once($INC . "/util.inc.php");
3 require_once($INC . "/log.inc.php");
4 require_once($INC . "/sql.inc.php");
5 require_once($INC . "/user.inc.php");
6 require_once($INC . "/prof.inc.php");
7
8 $rg_watch_error = "";
9
10 function rg_watch_set_error($str)
11 {
12 global $rg_watch_error;
13 $rg_watch_error = $str;
14 }
15
16 function rg_watch_error()
17 {
18 global $rg_watch_error;
19 return $rg_watch_error;
20 }
21
22
23 /*
24 * Returns a watched entry
25 */
26 $rg_watch_load_cache = array();
27 function rg_watch_load($db, $type, $login_uid, $obj_id1, $obj_id2)
28 {
29 global $rg_watch_load_cache;
30
31 $key = $type . "-" . $login_uid . "-" . $obj_id1 . "-" . $obj_id2;
32 if (isset($rg_watch_load_cache[$key]))
33 return $rg_watch_load_cache[$key];
34
35 rg_prof_start("watch_load");
36 rg_log("watch_load: type=$type login_uid=$login_uid obj_id=$obj_id1/$obj_id2");
37
38 $ret = FALSE;
39 do {
40 if (strcmp($type, "bug") == 0) {
41 $sql = "SELECT 1 FROM watch_bug"
42 . " WHERE uid = $login_uid"
43 . " AND repo_id = $obj_id1"
44 . " AND bug_id = $obj_id2";
45 } else if (strcmp($type, "repo") == 0) {
46 $sql = "SELECT 1 FROM watch_repo"
47 . " WHERE uid = $login_uid"
48 . " AND repo_id = $obj_id1";
49 } else {
50 rg_internal_error("Invalid watch type!");
51 break;
52 }
53 $res = rg_sql_query($db, $sql);
54 if ($res === FALSE)
55 break;
56
57 $rows = rg_sql_num_rows($res);
58 rg_sql_free_result($res);
59
60 $ret = $rows > 0 ? 1 : 0;
61 $rg_watch_load_cache[$key] = $ret;
62 } while (0);
63
64 rg_prof_end("watch_load");
65 return $ret;
66 }
67
68 /*
69 * Add somebody to the watch list
70 */
71 $rg_watch_add_state = array();
72 function rg_watch_add($db, $type, $login_uid, $obj_id1, $obj_id2)
73 {
74 global $rg_watch_add_state;
75
76 // If watch already added, skip.
77 $key = $type . "-" . $login_uid . "-" . $obj_id1 . "-" . $obj_id2;
78 if (isset($rg_watch_add_state[$key]))
79 return $rg_watch_add_state[$key];
80
81 rg_prof_start("watch_add");
82 rg_log("watch_add type=$type, login_uid=$login_uid obj_id=$obj_id1/$obj_id2");
83
84 $ret = FALSE;
85 do {
86 $r = rg_watch_load($db, $type, $login_uid, $obj_id1, $obj_id2);
87 if ($r === FALSE)
88 break;
89 if ($r === 1) { // already in watch list
90 $ret = TRUE;
91 break;
92 }
93
94 if (strcmp($type, "bug") == 0) {
95 $sql = "INSERT INTO watch_bug (uid, repo_id, bug_id)"
96 . " VALUES ($login_uid, $obj_id1, $obj_id2)";
97 } else if (strcmp($type, "repo") == 0) {
98 $sql = "INSERT INTO watch_repo (uid, repo_id)"
99 . " VALUES ($login_uid, $obj_id1)";
100 } else {
101 rg_internal_error("Invalid watch type!");
102 break;
103 }
104 $res = rg_sql_query($db, $sql);
105 if ($res === FALSE)
106 break;
107 rg_sql_free_result($res);
108
109 $ret = TRUE;
110 } while (0);
111
112 $rg_watch_add_state[$key] = $ret;
113
114 rg_prof_end("watch_add");
115 return $ret;
116 }
117
118 /*
119 * Delete somebody from the watch list
120 */
121 function rg_watch_del($db, $type, $login_uid, $obj_id1, $obj_id2)
122 {
123 rg_prof_start("watch_del");
124 rg_log("watch_del type=$type, login_uid=$login_uid obj_id=$obj_id1/$obj_id2");
125
126 $ret = FALSE;
127 do {
128 if (strcmp($type, "bug") == 0) {
129 $sql = "DELETE FROM watch_bug"
130 . " WHERE uid = $login_uid"
131 . " AND repo_id = $obj_id1"
132 . " AND bug_id = $obj_id2";
133 } else if (strcmp($type, "repo") == 0) {
134 $sql = "DELETE FROM watch_repo"
135 . " WHERE uid = $login_uid"
136 . " AND repo_id = $obj_id1";
137 } else {
138 rg_internal_error("Invalid watch type!");
139 break;
140 }
141 $res = rg_sql_query($db, $sql);
142 if ($res === FALSE)
143 break;
144 rg_sql_free_result($res);
145
146 $ret = TRUE;
147 } while (0);
148
149 rg_prof_end("watch_del");
150 return $ret;
151 }
152
153 /*
154 * Returns a list of uids by type and obj_id
155 */
156 function rg_watch_load_by_obj_id($db, $type, $obj_id1, $obj_id2)
157 {
158 rg_prof_start("watch_load_by_obj_id");
159 rg_log("watch_load_by_obj_id: type=$type obj_id=$obj_id1/$obj_id2");
160
161 $ret = FALSE;
162 do {
163 if (strcmp($type, "bug") == 0) {
164 $sql = "SELECT uid FROM watch_bug"
165 . " WHERE repo_id = $obj_id1"
166 . " AND bug_id = $obj_id2";
167 } else if (strcmp($type, "repo") == 0) {
168 $sql = "SELECT uid FROM watch_repo"
169 . " WHERE repo_id = $obj_id1";
170 } else {
171 rg_internal_error("Invalid watch type!");
172 break;
173 }
174 $res = rg_sql_query($db, $sql);
175 if ($res === FALSE)
176 break;
177
178 $ret = array();
179 while (($row = rg_sql_fetch_array($res))) {
180 $ret[] = $row['uid'];
181 }
182
183 rg_sql_free_result($res);
184 } while (0);
185
186 rg_prof_end("watch_load_by_obj_id");
187 return $ret;
188 }
189
190 ?>
File rocketgit.spec.in changed (mode: 100644) (index e492886..c750c1e)
1 %global selinux_types %(%{__awk} '/^#[[:space:]]*SELINUXTYPE=/,/^[^#]/ { if ($3 == "-") printf "%s ", $2 }' /etc/selinux/config 2>/dev/null)
2 %global selinux_variants %([ -z "%{selinux_types}" ] && echo mls strict targeted || echo %{selinux_types})
3 %global selinux_policyver %(%{__sed} -e 's,.*selinux-policy-\\([^/]*\\)/.*,\\1,' /usr/share/selinux/devel/policyhelp || echo 0.0.0)
4
1 5 Summary: Light and fast Git hosting solution Summary: Light and fast Git hosting solution
2 6 Name: @PRJ@ Name: @PRJ@
3 7 Version: @VER@ Version: @VER@
 
... ... URL: http://kernel.embedromix.ro/us/
9 13 BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
10 14 BuildArch: noarch BuildArch: noarch
11 15 Requires: httpd, php, php-cli, php-pgsql, php-gd, xinetd Requires: httpd, php, php-cli, php-pgsql, php-gd, xinetd
12 Requires: shadow-utils, git, postgresql-server, policycoreutils-python
16 Requires(pre): shadow-utils
17 Requires: git, postgresql-server
13 18 Requires: util-linux Requires: util-linux
14
19 # SELinux stuff
20 # https://fedoraproject.org/wiki/SELinux_Policy_Modules_Packaging_Draft?rd=PackagingDrafts/SELinux/PolicyModules
21 BuildRequires: checkpolicy, selinux-policy-devel, hardlink
22 BuildRequires: /usr/share/selinux/devel/policyhelp
23 %if "%{selinux_policyver}" != ""
24 Requires: selinux-policy >= %{selinux_policyver}
25 %endif
26 Requires(post): /usr/sbin/semodule, /sbin/restorecon, /sbin/fixfiles
27 Requires(postun): /usr/sbin/semodule, /sbin/restorecon, /sbin/fixfiles
15 28
16 29 %description %description
17 Light and fast Git hosting solution, similar with Gitorious/GitHub/etc.
30 Light and fast Git hosting solution, similar with Gitorious/etc.
18 31
19 32 %pre %pre
20 33 getent group rocketgit >/dev/null || groupadd -r rocketgit getent group rocketgit >/dev/null || groupadd -r rocketgit
21 34 getent passwd rocketgit >/dev/null || useradd -r -g rocketgit -s /bin/bash -m -d /home/rocketgit -c "RocketGit user" rocketgit getent passwd rocketgit >/dev/null || useradd -r -g rocketgit -s /bin/bash -m -d /home/rocketgit -c "RocketGit user" rocketgit
22 semanage fcontext -a -t httpd_log_t "/var/log/rocketgit-web(/.*)?" || :
23 semanage fcontext -a -t public_content_rw_t "/var/lib/rocketgit(/.*)?" || :
24 35
25 36 %post %post
37 for type in %{selinux_variants}
38 do
39 /usr/sbin/semodule -s ${type} -i \
40 @USR_SHARE@/selinux/${type}/@PRJ@.pp &> /dev/null || :
41 done
42 /sbin/fixfiles -R @PRJ@ restore || :
43
26 44 if [ $1 -ne 0 ]; then if [ $1 -ne 0 ]; then
27 45 /sbin/service xinetd reload &>/dev/null || : /sbin/service xinetd reload &>/dev/null || :
28 46 /sbin/service httpd reload &>/dev/null || : /sbin/service httpd reload &>/dev/null || :
 
... ... fi
30 48
31 49 %postun %postun
32 50 if [ $1 = 0 ]; then if [ $1 = 0 ]; then
33 userdel rocketgit
34 semanage fcontext -d "/var/lib/rocketgit(/.*)?" || :
35 semanage fcontext -d "/var/log/rocketgit-web(/.*)?" || :
51 for type in %{selinux_variants}
52 do
53 /usr/sbin/semodule -s ${type} -r @PRJ@.pp &> /dev/null || :
54 done
55 /sbin/fixfiles -R @PRJ@ restore || :
36 56 fi fi
37 57
38 58 %prep %prep
 
... ... fi
40 60
41 61 %build %build
42 62 %configure %configure
43 make
63 # TODO: should we do this in configure?!
64 make selinux_variants="%{selinux_variants}"
44 65
45 66 %install %install
46 67 rm -rf ${RPM_BUILD_ROOT} rm -rf ${RPM_BUILD_ROOT}
 
... ... make install DESTDIR=${RPM_BUILD_ROOT}
51 72 rm -rf ${RPM_BUILD_ROOT} rm -rf ${RPM_BUILD_ROOT}
52 73
53 74 %files %files
54 %attr (-,root,root)
55 %attr(0755,root,root) %dir @USR_SHARE@/@PRJ@
56 %attr(0755,root,root) %doc README LICENSE Changelog TODO
57 %attr(0755,root,root) %dir @ETC@/@PRJ@
58 %attr(0755,root,root) %config(noreplace) @ETC@/@PRJ@/config.php
59 %attr(0755,root,root) @ETC@/@PRJ@/config.php.sample
60 %attr(0755,root,root) @ETC@/cron.d/rocketgit
61 %attr(0755,root,root) @ETC@/logrotate.d/rocketgit
62 %attr(0755,roor,root) %config(noreplace) @ETC@/xinetd.d/rocketgit
63 %attr(0755,root,root) %config(noreplace) @ETC@/httpd/conf.d/rocketgit.conf
75 %defattr (-,root,root,0755)
76 %dir @USR_SHARE@/@PRJ@
77 %doc README LICENSE Changelog TODO selinux/@PRJ@.*
78 %dir @ETC@/@PRJ@
79 %config(noreplace) @ETC@/@PRJ@/config.php
80 @ETC@/@PRJ@/config.php.sample
81 @ETC@/cron.d/rocketgit
82 @ETC@/logrotate.d/rocketgit
83 %config(noreplace) @ETC@/xinetd.d/rocketgit
84 %config(noreplace) @ETC@/httpd/conf.d/rocketgit.conf
64 85 %attr(0700,rocketgit,rocketgit) %dir @VAR_LOG@/@PRJ@ %attr(0700,rocketgit,rocketgit) %dir @VAR_LOG@/@PRJ@
65 86 %attr(0700,apache,apache) %dir @VAR_LOG@/@PRJ@-web %attr(0700,apache,apache) %dir @VAR_LOG@/@PRJ@-web
66 87 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@ %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@
 
... ... rm -rf ${RPM_BUILD_ROOT}
68 89 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/repos %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/repos
69 90 %attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/q_merge_requests %attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/q_merge_requests
70 91 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/sockets %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/sockets
92 @USR_SHARE@/@PRJ@/*
93 @USR_SHARE@/selinux/*/@PRJ@.pp
71 94
72 95 %changelog %changelog
73 96 * Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dor ro> 0.10 * Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dor ro> 0.10
File root/index.php changed (mode: 100644) (index b4f0b6a..179d76d)
... ... if ($login_ui['uid'] > 0) {
123 123 // Some variables from the database // Some variables from the database
124 124 $r = rg_state_get_uint($db, "first_install"); $r = rg_state_get_uint($db, "first_install");
125 125 if ($r > 0) { if ($r > 0) {
126 $more['first_install_text'] = gmdate("Y-m-d H:i", $r);
126 $more['first_install_text'] = gmdate("Y-m-d", $r);
127 127 } else { } else {
128 128 $more['first_install_text'] = "?"; $more['first_install_text'] = "?";
129 129 } }
File root/themes/default/mail/user/repo/bug/new.body.txt added (mode: 100644) (index 0000000..9971814)
1 Hello!
2
3 A new bug was added to repo '@@repo.name@@':
4 '@@bug.title@@'.
5
6 Description:
7 @@bug.body@@
8
9 The bug was added by '@@bug.who_added_text@@'.
10 It is assigned to '@@bug.assigned_to_text@@'.
11 State: @@bug.state_text@@
12
13 Link to bug: @@bug.url@@
14
15 Thank you!
16
17 --
18 RocketGit Team
19 http://rocketgit.net
File root/themes/default/mail/user/repo/bug/new.head.txt copied from file root/themes/default/mail/user/key/new.head.txt (similarity 100%)
File root/themes/default/mail/user/repo/bug/new.subj.txt added (mode: 100644) (index 0000000..846e469)
1 New bug: '@@bug.title@@' (@@repo.name@@)
File root/themes/default/mail/user/repo/bug/new_note.body.txt added (mode: 100644) (index 0000000..99a04fb)
1 Hello!
2
3 A new note was added to bug
4 '@@bug.title@@',
5 repo '@@repo.name@@'.
6 The note was added by '@@note.who_added_text@@'.
7
8 @@note@@
9
10 Link to bug: @@bug.url@@
11
12 Thank you!
13
14 --
15 RocketGit Team
16 http://rocketgit.net
File root/themes/default/mail/user/repo/bug/new_note.head.txt copied from file root/themes/default/mail/user/key/del.head.txt (similarity 100%)
File root/themes/default/mail/user/repo/bug/new_note.subj.txt added (mode: 100644) (index 0000000..7099617)
1 New note for '@@bug.title@@' (@@repo.name@@)
File root/themes/default/mail/user/repo/new.body.txt changed (mode: 100644) (index 5cef38c..4befc1e)
... ... Anonymous rights:
8 8 Description: Description:
9 9 @@ri.description@@ @@ri.description@@
10 10
11 Link to repository: @@ri.url@@.
11 12 IP: @@IP@@ IP: @@IP@@
12 13
13 14 Thank you! Thank you!
File root/themes/default/mail/user/repo/update.body.txt changed (mode: 100644) (index ab12058..3da201f)
... ... Description changed to:
8 8 New anonymous rights: New anonymous rights:
9 9 @@ri.rights_text@@ @@ri.rights_text@@
10 10 }}{{}} }}{{}}
11 Link to repository: @@ri.url@@.
12
11 13 IP: @@IP@@ IP: @@IP@@
12 14
13 15 Thank you! Thank you!
File root/themes/default/main.css changed (mode: 100644) (index 2c8ef73..b32c882)
... ... form input[type="submit"] {
43 43 color: #FF0000; color: #FF0000;
44 44 display: inline-block; display: inline-block;
45 45 font-weight: bold; font-weight: bold;
46 font-size: 11pt;
47 padding: 2px 6px 2px 6px;
46 font-size: 10pt;
47 padding: 2px 4px 2px 4px;
48 48 cursor: pointer; cursor: pointer;
49 49 border: 2px solid #DDDDDD; border: 2px solid #DDDDDD;
50 50 background-image: -moz-linear-gradient(top, #EEEEEE, #CCCCCC); background-image: -moz-linear-gradient(top, #EEEEEE, #CCCCCC);
 
... ... form input[type="submit"] {
122 122 } }
123 123 #header table td { #header table td {
124 124 padding: 0 10px 0 0; padding: 0 10px 0 0;
125 border: 0px;
125 border: 0;
126 126 } }
127 127
128 128
 
... ... form input[type="submit"] {
149 149 } }
150 150 #footer table td { #footer table td {
151 151 padding: 3px 40px 3px 0; padding: 3px 40px 3px 0;
152 border: 0px;
152 border: 0;
153 153 font-size: 10pt; font-size: 10pt;
154 154 line-height: 120%; line-height: 120%;
155 155 background-color: #DDDDDD; background-color: #DDDDDD;
156 156 } }
157 157
158 .horizontal_buttons {
159 margin-top: 2px;
160 margin-bottom: 2px;
161 }
162 .horizontal_buttons table {
163 border-collapse: collapse;
164 border: 0;
165 border-spacing: 0;
166 }
167 .horizontal_buttons table td {
168 padding: 0;
169 border: 0;
170 }
171
158 172 .formarea { .formarea {
159 173 margin-top: 5px; margin-top: 5px;
160 174 border: 1px solid #CCCCCC; border: 1px solid #CCCCCC;
 
... ... form input[type="submit"] {
166 180 .formarea_title { .formarea_title {
167 181 font-weight: bold; font-weight: bold;
168 182 font-size: 13pt; font-size: 13pt;
169 border: 0px;
183 border: 0;
170 184 border-bottom: 2px solid #CCCCCC; border-bottom: 2px solid #CCCCCC;
171 185 } }
172 186
 
... ... form input[type="submit"] {
308 322
309 323
310 324 .bug { .bug {
311 margin-top: 10px;
325 margin-top: 5px;
312 326 } }
313 327 .bug_body { .bug_body {
314 328 margin-top: 3px; margin-top: 3px;
315 329 background-color: #A0FFA0; background-color: #A0FFA0;
316 padding: 5px;
330 padding: 3px;
317 331 border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px;
318 332 border: 1px solid #cccccc; border: 1px solid #cccccc;
319 333 line-height: 120%; line-height: 120%;
320 334 display: table; display: table;
321 335 } }
322 336
337 .bug_description {
338 margin-top: 5px;
339 }
340
341 .bug_title {
342 font-size: 12pt;
343 font-weight: bold;
344 }
345
323 346 .notes { .notes {
324 margin-top: 10px;
347 margin-top: 5px;
325 348 display: table; display: table;
326 349 } }
327 350
File root/themes/default/repo/bug/b_close.html added (mode: 100644) (index 0000000..99ddaef)
1 <form method="post" action="@@url@@">
2 <input type="hidden" name="close_reopen" value="1" />
3 <input type="hidden" name="state" value="2" />
4 <input type="hidden" name="token" value="@@rg_form_token@@" />
5
6 <input type="submit" name="button" value="Close" />
7 </form>
File root/themes/default/repo/bug/b_edit.html added (mode: 100644) (index 0000000..03d1a29)
1 <form method="post" action="@@url@@">
2 <input type="hidden" name="edit" value="1" />
3 <!-- no need for token -->
4
5 <input type="submit" name="button" value="Edit" />
6 </form>
File root/themes/default/repo/bug/b_reopen.html added (mode: 100644) (index 0000000..0359587)
1 <form method="post" action="@@url@@">
2 <input type="hidden" name="close_reopen" value="1" />
3 <input type="hidden" name="state" value="1" />
4 <input type="hidden" name="token" value="@@rg_form_token@@" />
5
6 <input type="submit" name="button" value="Re-open" />
7 </form>
File root/themes/default/repo/bug/b_unwatch.html added (mode: 100644) (index 0000000..7348f81)
1 <form method="post" action="@@url@@">
2 <input type="hidden" name="unwatch" value="1" />
3 <input type="hidden" name="token" value="@@rg_form_token@@" />
4
5 <input type="submit" name="button" value="Unwatch" />
6 </form>
File root/themes/default/repo/bug/b_watch.html added (mode: 100644) (index 0000000..9b7e138)
1 <form method="post" action="@@url@@">
2 <input type="hidden" name="watch" value="1" />
3 <input type="hidden" name="token" value="@@rg_form_token@@" />
4
5 <input type="submit" name="button" value="Watch" />
6 </form>
File root/themes/default/repo/bug/bug_add_edit.html renamed from root/themes/default/repo/bug/bug_add.html (similarity 65%) (mode: 100644) (index a415abe..9f3e560)
1 1 <div class="formarea"> <div class="formarea">
2 2
3 <div class="formarea_title">Add a bug</div><br />
3 <div class="formarea_title">@@if(@@bug_id == 0){{Add bug}}{{Edit bug}}</div><br />
4 4
5 5 @@bug_errmsg@@ @@bug_errmsg@@
6 6
7 7 <form method="post" action="@@url@@"> <form method="post" action="@@url@@">
8 8 <input type="hidden" name="doit" value="1" /> <input type="hidden" name="doit" value="1" />
9 <input type="hidden" name="bug_id" value="@@bug_id@@" />
9 10 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
10 11
11 12 <label for="title" class="form_item_title">Title</label><br /> <label for="title" class="form_item_title">Title</label><br />
 
23 24 <br /> <br />
24 25 <br /> <br />
25 26
27 <label for="assigned_to" class="form_item_title">Assign to</label><br />
28 <input type="text" name="assigned_to" value="@@assigned_to@@" size="80" />
29 <br />
30 <br />
31
26 32 <label for="labels" class="form_item_title">Labels (comma or Enter separated)</label><br /> <label for="labels" class="form_item_title">Labels (comma or Enter separated)</label><br />
27 33 <textarea name="labels" rows="3" cols="80">@@labels@@</textarea> <textarea name="labels" rows="3" cols="80">@@labels@@</textarea>
28 34 <br /> <br />
29 35 <br /> <br />
30 36
31 <input type="submit" name="button" value="@@bug_action@@" />
37 <input type="submit" name="button" value="@@if(@@bug_id@@ == 0){{Add bug}}{{Update}}" />
32 38
33 39 </form> </form>
34 40 </div> </div>
File root/themes/default/repo/bug/list/line.html changed (mode: 100644) (index 7608c3d..568a5f8)
2 2 <td><a href="@@url_repo@@/bug/@@bug_id@@">@@bug_id@@</a></td> <td><a href="@@url_repo@@/bug/@@bug_id@@">@@bug_id@@</a></td>
3 3 <td>@@creation@@</td> <td>@@creation@@</td>
4 4 <td><a href="@@url_repo@@/bug/@@bug_id@@">@@title@@</a></td> <td><a href="@@url_repo@@/bug/@@bug_id@@">@@title@@</a></td>
5 <td>@@state@@</td>
5 <td>@@state_text@@</td>
6 6 <td>@@owner@@</td> <td>@@owner@@</td>
7 <td>@@assigned_to@@</td>
7 <td>@@if(@@assigned_to@@ == ){{-}}{{@@assigned_to@@}}</td>
8 8 <td>@@updated@@</td> <td>@@updated@@</td>
9 9 </tr> </tr>
10 10
File root/themes/default/repo/bug/note_add.html changed (mode: 100644) (index 0f2c978..05fb9dc)
5 5 @@note_errmsg@@ @@note_errmsg@@
6 6
7 7 <form method="post" action="@@url@@"> <form method="post" action="@@url@@">
8 <input type="hidden" name="doit" value="1" />
8 <input type="hidden" name="note_add_doit" value="1" />
9 9 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
10 10
11 11 <label for="note" class="form_item_title">Note</label><br /> <label for="note" class="form_item_title">Note</label><br />
File root/themes/default/repo/bug/show.html changed (mode: 100644) (index cc276f2..6f16b69)
1 <!-- @@DUMP-DISABLED@@ -->
2
3 1 <div class="bug"> <div class="bug">
4 <b>#@@bug_id@@ - @@title@@</b><br />
2 <!-- some buttons: watch/unwatch/etc. -->
3 <div class="horizontal_buttons">
4 <table>
5 <tbody>
6 <tr>
7 <td>@@edit_form@@</td>
8 <td>@@watch_form@@</td>
9 <td>@@close_form@@</td>
10 </tr>
11 </tbody>
12 </table>
13 </div>
14 @@button_error@@
15
16 @@bug_edit@@
17
18 <div class="bug_description">
19 <div class="bug_title">#@@bug_id@@ - @@title@@</div>
20 State: @@state_text@@<br />
5 21 Insertion date (UTC): @@creation@@<br /> Insertion date (UTC): @@creation@@<br />
6 22 Last update (UTC): @@updated@@<br /> Last update (UTC): @@updated@@<br />
7 23 Reporter: <b>@@owner@@</b><br /> Reporter: <b>@@owner@@</b><br />
8 Assigned to: <b>@@assigned_to@@</b><br />
24 Assigned to: <b>@@if(@@assigned_to@@ == ){{-}}{{@@assigned_to@@}}</b><br />
25 </div>
26
9 27 <div class="bug_body"> <div class="bug_body">
10 28 @@body@@ @@body@@
11 29 </div> </div>
12 30
13 @@labels@@
31 @@labels_html@@
14 32
15 33 @@notes@@ @@notes@@
16 34
File samples/cron changed (mode: 100644) (index f423640..72f6e23)
1 * * * * * rocketgit php /usr/share/rocketgit/scripts/cron.php
2 * * * * * rocketgit php /usr/share/rocketgit/scripts/q.php
1 * * * * * rocketgit /usr/share/rocketgit/scripts/cron.sh
2 * * * * * rocketgit /usr/share/rocketgit/scripts/q.sh
3 3 * * * * * rocketgit /usr/share/rocketgit/scripts/events.sh * * * * * rocketgit /usr/share/rocketgit/scripts/events.sh
File samples/rg.conf changed (mode: 100644) (index a56d1b2..9401ad7)
10 10 AllowOverride All AllowOverride All
11 11 Order allow,deny Order allow,deny
12 12 Allow from all Allow from all
13 Require all granted
13 14 </Directory> </Directory>
14 15
15 16 RewriteEngine On RewriteEngine On
16 17 #RewriteLog /var/log/httpd/rg-Rewrite.log #RewriteLog /var/log/httpd/rg-Rewrite.log
17 18 #RewriteLogLevel 3 #RewriteLogLevel 3
18 19
19 # Allow .ico and 'themes' folder
20 RewriteCond %{REQUEST_URI} ^/(favicon\.ico|themes)
20 # Allow .ico, 'themes' folder and any txt file (think robots.txt)
21 RewriteCond %{REQUEST_URI} ^/(favicon\.ico|themes|.*\.txt)
21 22 RewriteRule .* - [L] RewriteRule .* - [L]
22 23
23 24 # index.php is special # index.php is special
File scripts/cron.sh added (mode: 100755) (index 0000000..14e2433)
1 #!/bin/bash
2
3 # This is a wrapper for cron.php, to not wait a lot after it exits
4
5 exec 100<>/var/lib/rocketgit/locks/cron.lock
6
7 flock --exclusive --nonblock 100
8 if [ "${?}" != "0" ]; then
9 exit 0
10 fi
11
12 php /usr/share/rocketgit/scripts/cron.php
13
14 flock --unlock 100
File scripts/events.php changed (mode: 100644) (index 226d58b..550012b)
... ... require_once($INC . "/prof.inc.php");
22 22 require_once($INC . "/mr.inc.php"); require_once($INC . "/mr.inc.php");
23 23 require_once($INC . "/keys.inc.php"); require_once($INC . "/keys.inc.php");
24 24 require_once($INC . "/user.inc.php"); require_once($INC . "/user.inc.php");
25 require_once($INC . "/bug.inc.php");
25 26 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
26 27
27 28 rg_prof_start("MAIN"); rg_prof_start("MAIN");
File scripts/events.sh changed (mode: 100755) (index 640f032..a131a71)
1 1 #!/bin/bash #!/bin/bash
2 2
3 # This is a wrapper for events.php, to not wait a lot after it exists
3 # This is a wrapper for events.php, to not wait a lot after it exits
4 4
5 5 exec 100<>/var/lib/rocketgit/locks/events.lock exec 100<>/var/lib/rocketgit/locks/events.lock
6 6
File scripts/q.sh copied from file scripts/events.sh (similarity 59%) (mode: 100755) (index 640f032..95705f8)
1 1 #!/bin/bash #!/bin/bash
2 2
3 # This is a wrapper for events.php, to not wait a lot after it exists
3 # This is a wrapper for q.php, to not wait a lot after it exits
4 4
5 exec 100<>/var/lib/rocketgit/locks/events.lock
5 exec 100<>/var/lib/rocketgit/locks/q.lock
6 6
7 7 flock --exclusive --nonblock 100 flock --exclusive --nonblock 100
8 8 if [ "${?}" != "0" ]; then if [ "${?}" != "0" ]; then
 
... ... if [ "${?}" != "0" ]; then
10 10 fi fi
11 11
12 12 while [ 1 ]; do while [ 1 ]; do
13 php /usr/share/rocketgit/scripts/events.php
13 php /usr/share/rocketgit/scripts/q.php
14 14
15 15 # in case of errors, we will wait, to not go into an infinite loop # in case of errors, we will wait, to not go into an infinite loop
16 16 if [ "${?}" != "0" ]; then if [ "${?}" != "0" ]; then
File scripts/remote.php changed (mode: 100644) (index acebfa6..fd6ea17)
... ... if ($owner_ui['exists'] != 1)
168 168 // Loading info about the repository // Loading info about the repository
169 169 if (rg_repo_ok($repo) !== TRUE) if (rg_repo_ok($repo) !== TRUE)
170 170 fatal("Repo is invalid (" . rg_repo_error() . ")"); fatal("Repo is invalid (" . rg_repo_error() . ")");
171 $ri = rg_repo_info($db, $owner_ui['uid'], 0, $repo);
171 $ri = rg_repo_info($db, 0, $owner_ui['uid'], $repo);
172 172 if ($ri['ok'] != 1) if ($ri['ok'] != 1)
173 173 fatal("Internal problems. Try again later, please."); fatal("Internal problems. Try again later, please.");
174 174 if ($ri['exists'] != 1) if ($ri['exists'] != 1)
File selinux/.gitignore added (mode: 100644) (index 0000000..4e9f08c)
1 out
2 restore.sh
File selinux/build.sh added (mode: 100755) (index 0000000..6d3b1a8)
1 #!/bin/bash
2
3 if [ -z "${selinux_variants}" ]; then
4 selinux_variants="mls targeted minimum"
5 fi
6
7 if [ -z "${PRJ}" ]; then
8 echo "Define PRJ first!"
9 exit 1
10 fi
11
12 for type in ${selinux_variants}; do
13 make NAME=${type} -f /usr/share/selinux/devel/Makefile
14 mkdir -p out
15 mv ${PRJ}.pp out/${PRJ}-${type}.pp
16 make NAME=${type} -f /usr/share/selinux/devel/Makefile clean
17 done
18
19 # Hard link identical policies (thanks, crossfire)
20 /usr/sbin/hardlink -cv out
File selinux/rocketgit.fc added (mode: 100644) (index 0000000..255b678)
1 # rocketgit executable will have:
2 # label: system_u:object_r:rocketgit_exec_t
3 # MLS sensitivity: s0
4 # MCS categories: <none>
5
6 /etc/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_conf_t,s0)
7
8 /var/log/rocketgit(/.*)? -- gen_context(system_u:object_r:rocketgit_log_t,s0)
9 /var/log/rocketgit-web(/.*)? gen_context(system_u:object_r:httpd_log_t,s0)
10
11 /var/lib/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_var_t,s0)
12 /var/lib/rocketgit/locks(/.*)? gen_context(system_u:object_r:rocketgit_lock_t,s0)
13 /var/lib/rocketgit/sockets(/.*)? gen_context(system_u:object_r:rocketgit_socket_t,s0)
14
15 /usr/share/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_usr_t,s0)
16 /usr/share/rocketgit/scripts(/.*)? -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
File selinux/rocketgit.if copied from file root/themes/default/errmsg/nodata.html (similarity 100%)
File selinux/rocketgit.te added (mode: 100644) (index 0000000..b6afa0c)
1 policy_module(rocketgit,1.0.51)
2
3 ########################################
4 #
5 # Declarations
6 #
7
8 gen_require(`
9 # really needed httpd_log_t?
10 type httpd_t;
11 type httpd_log_t;
12 ')
13
14 type rocketgit_t;
15 domain_type(rocketgit_t)
16
17 apache_content_template(rocketgit)
18 # Allow httpd to access php scripts:
19 read_files_pattern(httpd_t, rocketgit_usr_t, rocketgit_usr_t)
20
21 type rocketgit_exec_t;
22 domain_entry_file(rocketgit_t, rocketgit_exec_t)
23
24 # When cron executes rocketgit_exec_t, we transition to rocketgit_t
25 cron_system_entry(rocketgit_t, rocketgit_exec_t)
26
27 # Allow event.sh to access /home/rocketgit
28 userdom_list_user_home_content(rocketgit_t)
29
30 # Allow PHP to read /proc/meminfo, probably other files
31 # Seems a little bit too much. TODO
32 kernel_read_system_state(rocketgit_t)
33
34 dev_read_urand(rocketgit_t)
35
36 # Allow rocketgit_t to execute flock.
37 # Seems a little bit too much to allow all execution. TODO
38 application_exec_all(rocketgit_t)
39
40 # Allow rocketgit_t to use tcp sockets
41 allow rocketgit_t self:tcp_socket { connect getopt getattr create setopt };
42
43
44 # php files
45 type rocketgit_usr_t;
46 files_type(rocketgit_usr_t)
47 read_files_pattern(rocketgit_t, rocketgit_usr_t, rocketgit_usr_t)
48
49
50 # log files
51 type rocketgit_log_t;
52 files_type(rocketgit_log_t)
53 manage_files_pattern(rocketgit_t, rocketgit_log_t, rocketgit_log_t)
54 logging_log_filetrans(rocketgit_t, rocketgit_log_t, file)
55
56
57 # content (repos)
58 type rocketgit_var_t;
59 files_type(rocketgit_var_t)
60 admin_pattern(rocketgit_t, rocketgit_var_t, rocketgit_var_t)
61 filetrans_pattern(rocketgit_t, rocketgit_var_t, rocketgit_var_t, { file dir })
62
63
64 # sockets
65 type rocketgit_socket_t;
66 files_type(rocketgit_socket_t)
67 manage_sock_files_pattern(rocketgit_t, rocketgit_socket_t, rocketgit_socket_t)
68 filetrans_pattern(rocketgit_t, rocketgit_socket_t, rocketgit_socket_t, file)
69 rw_sock_files_pattern(httpd_t, rocketgit_socket_t, rocketgit_socket_t)
70 # Allow httpd to connect to _domain_ rocketgit_t for event.sock
71 allow httpd_t rocketgit_t:unix_stream_socket connectto;
72
73
74 # locks
75 type rocketgit_lock_t;
76 files_lock_file(rocketgit_lock_t)
77 manage_files_pattern(rocketgit_t, rocketgit_lock_t, rocketgit_lock_t)
78 #read_files_pattern(httpd_t, rocketgit_lock_t, rocketgit_lock_t)
79 filetrans_pattern(rocketgit_t, rocketgit_lock_t, rocketgit_lock_t, file)
80
81
82 # conf
83 type rocketgit_conf_t;
84 files_type(rocketgit_conf_t)
85 read_files_pattern(rocketgit_t, rocketgit_conf_t, rocketgit_conf_t)
86 filetrans_pattern(rocketgit_t, rocketgit_conf_t, rocketgit_conf_t, file)
87 read_files_pattern(httpd_t, rocketgit_conf_t, rocketgit_conf_t)
88
89
90 # Permit PHP to use nscd socket
91 optional_policy(`
92 nscd_socket_use(rocketgit_t)
93 ')
94
95 # Allow connection to database
96 postgresql_tcp_connect(rocketgit_t)
97 postgresql_stream_connect(rocketgit_t)
98
99 # httpd
100 # Allow apache to read the conf file
101 #allow httpd_t rocketgit_t:dir { getattr search };
102 #allow httpd_t rocketgit_t:file { getattr read open };
103 #allow httpd_t rocketgit_t:sock_file { write };
104 #allow httpd_t rocketgit_t:unix_stream_socket { connectto };
105
106 # mail
107 sendmail_domtrans(rocketgit_t)
108
109 # self
110 allow rocketgit_t self:unix_stream_socket { connectto };
111 allow rocketgit_t self:process { setsched };
112
113 # PHP needs getattr to /var/lib
114 files_getattr_var_lib_dirs(rocketgit_t)
115
116 # Some common macros (you might be able to remove some)
117 #files_read_etc_files(rocketgit_t)
118 ## internal communication is often done using fifo and unix sockets.
119 #allow rocketgit_t self:fifo_file { read write };
120 #allow rocketgit_t self:unix_stream_socket create_stream_socket_perms;
121
122 # We leak log and lock fds, ignore for now
123 allow sendmail_t rocketgit_lock_t:file { read write };
124 allow sendmail_t rocketgit_log_t:file append;
File tests/Makefile changed (mode: 100644) (index 63c50dc..552bef5)
... ... hook_update_anon:
48 48
49 49 .PHONY: clean .PHONY: clean
50 50 clean: clean:
51 @rm -f *.log
51 @rm -f *.log *.strace *.out
File tests/bug.php changed (mode: 100644) (index 4fa4747..b59d51a)
... ... if ($r !== TRUE) {
50 50 $repo_id = 100; $repo_id = 100;
51 51 $uid = 1; $uid = 1;
52 52
53 $data = array("title" => "Bug title",
53 $data = array("bug_id" => 0,
54 "title" => "Bug title",
54 55 "body" => "This is the body\nof the\nbug. <>", "body" => "This is the body\nof the\nbug. <>",
55 56 "labels" => "label1,label2,label3", "labels" => "label1,label2,label3",
56 57 "state" => 1, "state" => 1,
57 58 "assigned_uid" => 6); "assigned_uid" => 6);
58 $r = rg_bug_add($db, $repo_id, $uid, $data);
59 $ri = array("repo_id" => $repo_id);
60 $ui = array("uid" => $uid);
61 $r = rg_bug_edit($db, $ri, $ui, $data);
59 62 if ($r === FALSE) { if ($r === FALSE) {
60 63 rg_log("Cannot insert a bug (" . rg_bug_error() . ")!"); rg_log("Cannot insert a bug (" . rg_bug_error() . ")!");
61 64 exit(1); exit(1);
File tests/repo.php changed (mode: 100644) (index 0f497be..0620aae)
... ... if ($repo_id === FALSE) {
137 137 exit(1); exit(1);
138 138 } }
139 139
140 $ri = rg_repo_info($db, $rg_ui['uid'], $repo_id, "");
140 $ri = rg_repo_info($db, $repo_id, 0, "");
141 141 if ($ri['exists'] != 1) { if ($ri['exists'] != 1) {
142 142 rg_log("ri: " . print_r($ri, TRUE)); rg_log("ri: " . print_r($ri, TRUE));
143 143 rg_log("Cannot lookup repo_id $repo_id!"); rg_log("Cannot lookup repo_id $repo_id!");
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master