List of commits:
Subject Hash Author Date (UTC)
Checkpoint - mostly fixes for tests and switch to sql_params 28830fcf28cf8f3ae0f59bf1205281820df1307a Catalin(ux) M. BOIE 2013-07-16 19:42:15
Bulk changes all over the place. 69bd7667ac66a02ae3734ddb2f1eb8eec526e3bf Catalin(ux) M. BOIE 2013-04-21 06:40:27
Fixed repo search: ui['admin'] may not be defined 48794821cb9a4ea8fa793144256ac916b1554bf2 Catalin(ux) M. BOIE 2013-02-18 19:37:31
Several changes. Bump version to 0.18 57269df7b88cd6cbb0c2569c6e14d94887c6ca40 Catalin(ux) M. BOIE 2013-02-17 10:10:48
Bump the version 753abba3b1f6caac8f96d801e5a5d1786023aa2f Catalin(ux) M. BOIE 2013-02-05 19:40:38
Checkpoint 16a893cae9b7754a3e9ff9a0f380c00ccc52a907 Catalin(ux) M. BOIE 2013-02-05 19:35:48
Bulk fixes 30f559c9d7701b0a06344f286f113e154a39805b Catalin(ux) M. BOIE 2013-01-06 00:24:33
Removed some debug stuff. d17e0d454e7e1cad1b350139e0770e7450ee9331 Catalin(ux) M. BOIE 2012-12-02 21:00:30
Apply conditionals before replacing variables! 3d5b7d5fcc11734f9623a3d6ff0aaa8a332b6bdb Catalin(ux) M. BOIE 2012-12-02 20:58:43
More fixes for 'fixes' infrastructure 831af837ca9e7fcf56bef81d1831c3150afa7de8 Catalin(ux) M. BOIE 2012-12-01 21:58:30
Fixes infrastructure; bug fixing c282b19dcb975b1e90a4eaacfe4c126364f6e054 Catalin(ux) M. BOIE 2012-12-01 21:01:23
First round of notifications 561943c9bfd37fcf2b3c53724af2c8145d76d664 Catalin(ux) M. BOIE 2012-11-18 12:03:28
Repo history added 888934152ff5c2f2dafae9e598cf93ab6f377dba Catalin(ux) M. BOIE 2012-11-09 22:39:08
git clone fixes and other stuff dbe6ddaddfc735c8a6fef126ba90cdb2a98fe631 Catalin(ux) M. BOIE 2012-11-07 19:19:38
Allow duplicate repo names. Allow same key (db pov). 146d1de07369f1e3270a6cdca1f1bead2d076f30 Catalin(ux) M. BOIE 2012-11-05 19:47:06
Bulk e15b8500a1ba4d1a84631287b234a661aa366cd6 Catalin(ux) M. BOIE 2012-11-05 18:39:16
Bulk updates - search, rights \!own fd52a1454efb598538244ac8b1117ee074d818cd Catalin(ux) M. BOIE 2012-10-31 22:08:29
Fix delete repo function 63e34cf9032bb7b108b51c97ccbd1efbd1e5cd7b Catalin(ux) M. BOIE 2012-10-29 20:45:40
Bulk 2ccd4da309196c89d776950b3b2e9efec32a6c60 Catalin(ux) M. BOIE 2012-10-29 18:30:20
Small changes all over the place: CSS, keys etc. ea67645051e11f3ef9ba3a115ccecb8e1f8cfee0 Catalin(ux) M. BOIE 2012-10-24 21:48:39
Commit 28830fcf28cf8f3ae0f59bf1205281820df1307a - Checkpoint - mostly fixes for tests and switch to sql_params
Author: Catalin(ux) M. BOIE
Author date (UTC): 2013-07-16 19:42
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2013-07-16 19:42
Parent(s): 69bd7667ac66a02ae3734ddb2f1eb8eec526e3bf
Signing key:
Tree: e12cf2e9e25e6221c093bed67b00e6ac2c534aba
File Lines added Lines deleted
Certs.txt 36 0
Makefile.in 25 11
TODO 153 69
admin/init.php 0 1
hooks/post-receive 5 6
hooks/pre-commit 7 1
hooks/pre-receive 6 1
hooks/update 6 1
inc/admin/admin.php 11 1
inc/admin/plans/plans.php 32 0
inc/admin/users/add.php 0 82
inc/admin/users/edit.php 0 87
inc/admin/users/user.form.php 0 93
inc/admin/users/users.php 33 9
inc/bug.inc.php 84 82
inc/cache.inc.php 81 6
inc/dispatch/dispatch.php 2 2
inc/events.inc.php 27 87
inc/feedback/suggestion.php 26 26
inc/fixes.inc.php 22 4
inc/git.inc.php 3 1
inc/keys.inc.php 114 110
inc/log.inc.php 109 29
inc/login/login.php 2 2
inc/mr.inc.php 14 10
inc/plan.inc.php 192 1061
inc/repo.inc.php 126 99
inc/rights.inc.php 57 42
inc/sess.inc.php 121 68
inc/sql.inc.php 141 39
inc/ssh.inc.php 4 5
inc/state.inc.php 58 32
inc/struct.inc.php 64 14
inc/token.inc.php 15 9
inc/user.inc.php 537 278
inc/user/confirm.php 4 3
inc/user/create.php 0 84
inc/user/forgot.php 6 3
inc/user/home-page.php 2 2
inc/user/info/info.php 0 60
inc/user/keys/keys.php 1 1
inc/user/pass/pass.php 27 26
inc/user/repo-page.php 9 7
inc/user/repo/admin/delete/delete.php 20 18
inc/user/repo/admin/rights/rights.php 23 11
inc/user/repo/bug/show/add_note.php 29 27
inc/user/repo/bug/show/edit.php 5 2
inc/user/repo/bug/show/show.php 5 3
inc/user/settings.php 4 2
inc/util.inc.php 222 89
inc/watch.inc.php 19 13
rocketgit.spec.in 4 4
root/index.php 36 10
root/themes/default/access_denied.html 1 1
root/themes/default/admin/plans/add_edit.html 37 6
root/themes/default/admin/plans/list/header.html 2 1
root/themes/default/admin/plans/list/line.html 5 4
root/themes/default/admin/plans/list/nodata.html 1 1
root/themes/default/admin/plans/list_err.html 1 1
root/themes/default/admin/users/bad_admin.html 3 0
root/themes/default/admin/users/bad_remove.html 3 0
root/themes/default/admin/users/bad_suspend.html 3 0
root/themes/default/admin/users/bad_unadmin.html 3 0
root/themes/default/admin/users/bad_unsuspend.html 3 0
root/themes/default/hints/ssh/key.html 3 2
root/themes/default/mail/user/key/del.body.txt 1 1
root/themes/default/mail/user/key/del.subj.txt 1 1
root/themes/default/mail/user/repo/del.body.txt 1 1
root/themes/default/mail/user/welcome.body.txt 6 0
root/themes/default/main.css 3 2
root/themes/default/menu/line.html 1 1
root/themes/default/msg/internal.txt 1 1
root/themes/default/repo/bug/bug_add_edit.html 1 1
root/themes/default/repo/invalid.html 1 1
root/themes/default/repo/list/header.html 1 3
root/themes/default/repo/list/line.html 0 2
root/themes/default/user/add_edit.html 68 0
root/themes/default/user/bad_token.html 1 1
root/themes/default/user/create_na.html 3 0
root/themes/default/user/create_ok.html 8 0
root/themes/default/user/edit_ok.html 3 0
root/themes/default/user/forgot.html 5 0
root/themes/default/user/invalid.html 1 1
root/themes/default/user/keys/list/header.html 2 0
root/themes/default/user/keys/list/line.html 2 0
root/themes/default/user/login.html 7 4
root/themes/default/user/repo/rights/form.html 26 0
samples/config.php 6 0
samples/cron 1 0
samples/rg.conf 4 4
scripts/cache.php 222 76
scripts/cache.sh 12 0
scripts/cachec.php 1 1
scripts/common.sh 13 0
scripts/cron.php 21 24
scripts/cron.sh 3 1
scripts/events.php 17 10
scripts/events.sh 4 0
scripts/q.php 4 2
scripts/q.sh 4 0
scripts/remote.php 14 6
scripts/wake.php 1 1
selinux/rocketgit.te 7 1
tests/.gitignore 2 0
tests/Makefile 8 2
tests/bug.php 29 9
tests/cache.php 65 8
tests/common.php 32 0
tests/email.php 1 4
tests/event.php 1 3
tests/git.php 1 4
tests/git2.php 1 4
tests/hook_update.sh 2 17
tests/hook_update_anon.sh 2 0
tests/hook_update_anon_nm.sh 2 0
tests/keys.php 7 7
tests/log.php 1 5
tests/prof.php 1 3
tests/repo.php 16 30
tests/rights.php 1 0
tests/size/dir/b 1 0
tests/sql.php 1 3
tests/state.php 1 3
tests/themes/util/t1/nodata.html 0 0
tests/themes/util/t2/footer.html 0 0
tests/themes/util/t2/header.html 0 0
tests/themes/util/t2/line.html 0 0
tests/themes/util/t3/c1 0 0
tests/themes/util/t3/c2 0 0
tests/themes/util/t3/c3 0 0
tests/themes/util/t3/c4 0 0
tests/themes/util/t3/c5 0 0
tests/themes/util/t3/c6 0 0
tests/themes/util/t3/c7 0 0
tests/themes/util/t3/c8 0 0
tests/user.php 8 4
tests/util.php 31 5
tests/util/dir_pattern/err-asasasas 0 0
File Certs.txt added (mode: 100644) (index 0000000..87c7a41)
1 This document tries to find a way to get rid of authorized_keys file.
2
3 Certificates may be used for user (auth user to serv) or host authentication
4 (auth servers to users).
5
6 Certificate has a public key, identity information zero or more principal
7 (user or host) names and a set of options signed by CA key.
8
9 Generate a user cerificate:
10 ssh-keygen -f ~/.ssh/key1
11 ssh-keygen -s CA.key -I key_id ~/.ssh/key1.pub
12 Output will be in ~/.ssh/key1-cert.pub
13
14 Host certificates:
15 ssh-keygen -f ~/ssh/host1
16 ssh-keygen -s CA.key -I key_id -h ~/.ssh/host1.pub
17 Output will be in ~/.ssh/host1-cert.pub
18
19 Lets see how we generate CA.key. Seems that is a normal key, but, in
20 authorized_keys file is marked with option cert-authority.
21
22
23 Plan:
24 Create a user (A).
25 Create a CA key.
26 Add it to authorized_keys file and mark it as cert-authority.
27 Generate a key for a connection user (B) and sign it with the CA key.
28 Add the cert to B's ~/.ssh/
29 Try to connect with user B to userA@host.
30
31 Seems we can specify "-z serial" to ssh-keygen. But ssh-keygen crashes.
32
33 Questions:
34 - How to revoke a key?
35 - Seems the key_id is not exported in environment. :(
36
File Makefile.in changed (mode: 100644) (index f273734..a13fbd1)
... ... install: all
29 29 cp -vd samples/config.php $(I_ETC)/$(PRJ)/config.php.sample cp -vd samples/config.php $(I_ETC)/$(PRJ)/config.php.sample
30 30 @mkdir -p $(I_ETC)/logrotate.d @mkdir -p $(I_ETC)/logrotate.d
31 31 cp -vd samples/logrotate $(I_ETC)/logrotate.d/$(PRJ) cp -vd samples/logrotate $(I_ETC)/logrotate.d/$(PRJ)
32 @mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ)
33 @-chown rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ)
34 @chmod 0700 $(I_VAR_LOG)/$(PRJ)
35 @mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ)-web
36 @-chown apache:apache $(I_VAR_LOG)/$(PRJ)-web
37 @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)
38 @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/locks
39 @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/repos
40 @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/q_merge_requests
41 @mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/qstats
42 @mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/sockets
32 @
33 @echo "Installing log stuff..."
34 @mkdir -p $(I_VAR_LOG)/$(PRJ)
35 @-chown -R rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ)
36 @-find $(I_VAR_LOG)/$(PRJ) -type d -exec chmod -R 0755 {} \;
37 @-find $(I_VAR_LOG)/$(PRJ) -type f -exec chmod -R 0600 {} \;
38 @
39 @mkdir -p $(I_VAR_LOG)/$(PRJ)-web
40 @-chown -R apache:apache $(I_VAR_LOG)/$(PRJ)-web
41 @-find $(I_VAR_LOG)/$(PRJ)-web -type d -exec chmod -R 0755 {} \;
42 @-find $(I_VAR_LOG)/$(PRJ)-web -type f -exec chmod -R 0600 {} \;
43 @
44 @echo "Installing varlib stuff..."
45 @mkdir -p $(I_VAR_LIB)/$(PRJ)
46 @mkdir -p $(I_VAR_LIB)/$(PRJ)/locks
47 @mkdir -p $(I_VAR_LIB)/$(PRJ)/repos
48 @mkdir -p $(I_VAR_LIB)/$(PRJ)/q_merge_requests
49 @mkdir -p $(I_VAR_LIB)/$(PRJ)/qstats
50 @mkdir -p $(I_VAR_LIB)/$(PRJ)/sockets
51 @echo "Fixing rights..."
43 52 @-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ) @-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ)
53 @-find $(I_VAR_LIB)/$(PRJ) -type d -exec chmod 0755 {} \;
54 @-find $(I_VAR_LIB)/$(PRJ) -type f -exec chmod 0600 {} \;
55 @
56 @echo "Installing SELinux stuff..."
44 57 @mkdir -p --mode=0755 $(I_USR_SHARE)/selinux/targeted @mkdir -p --mode=0755 $(I_USR_SHARE)/selinux/targeted
45 58 cp -vd selinux/out/$(PRJ)-targeted.pp $(I_USR_SHARE)/selinux/targeted/$(PRJ).pp cp -vd selinux/out/$(PRJ)-targeted.pp $(I_USR_SHARE)/selinux/targeted/$(PRJ).pp
59 @echo "Done!"
File TODO changed (mode: 100644) (index a4f9b6d..cdb786f)
1 1 == BEFORE NEXT RELEASE == == BEFORE NEXT RELEASE ==
2 [ ] Seems that an annotated tag cannot be overwritten, even with rights.
3 [ ] Test bug.php is not working. Seems that repo_info is not working right for
4 an inexistent repo_id!
5 [ ] From arora I cannot login! See a tcpdump.
6 [ ] Rights management
7 - A user is trying to push some commits in a branch B, for a file F
8 - The set of rights may be:
9 Branch File/dir Rights
10 B2 dir/*.png FPA
11 * dir2 A
12 * * F
13 refs/heads/x/ * ??? - allow to push in private "ns" 'x'
14 x/ * ??? - same as above.
15 refs/tags/v[0-9] ??? - allow tags that starts with v.
16 USER/ * ??? - give rights to any user to a
17 private branch (refs/heads/USER/...).
18 * USER/ ??? - give rights to any user to a
19 private dir.
20 - Also limit by IP and by time.
21 - We have a problem: some rights do not map correctly to the plan above.
22 For example, A(admin)
23 - Also, we will have problems classifying a project as public or private.
24 Maybe we can compute the rights as an event after any rights change.
25 Maybe we should let the user what type of project it is, and, if is
26 public, to grant fetch right.
27 - Should I add "Create users right"?
2 28
3 == BEFORE FIRST RELEASE! ==
4 [ ] Increment usage on keys should be done by events, with a predefined interval
5 to not kill the database.
6 [ ] Uploading/deleting a key will generate an event.
7 [ ] Add first usage of ssh keys.
8 [ ] Add count of usage for ssh keys.
9 [ ] Reorder ssh keys by usage to speed up ssh login.
10 [ ] In documentation, because of SELinux, we may want to restart some services.
11 At least: xinetd, cron etc. Probably not, but I must test this.
29 == BEFORE NEXT RELEASE ==
30 [ ] Does it makes sense to have a local cache (user/repo/etc.) when we have
31 another local cache (cache.inc.php).
32 [ ] Search for "parmas" and "$e_".
33 [ ] Remove all db escaping after switching to params!
34 [ ] keys.inc.php - convert to params!
35 [ ] Switch from pg_query to pg_query_params.
36 [ ] Finish high level sql function.
37 [ ] When we escape, it will try to connect to database, that may fail.
38 This is not good at all and it seems a little bit hard to fix.
39 Maybe switch to prepared statements?
40 [ ] pg_fetch_assoc returns FALSE if error or no more rows.
41 We must know the difference!
42 [ ] Check "suspend"/"make admin"/etc. in admin area. Maybe use a checkbox and
43 an operation to avoid CSRF and to be consistent with ssh keys forms?
44 [ ] Fix rights saga on user side. We may remove user_allow and replace with
45 rights_check?
46 [ ] Riths use-cases:
47 [ ] An admin may not have "Remove" access.
48 [ ] An admin may not have "Suspend" access.
49 [ ] An admin may have only add/edit rights.
50 [ ] "Reset password" in admin area?
51 [ ] "Make admin" will be replaced by "Edit"?
52 [ ] Problems trying to push to rg1 because of SELinux:
53 type=SELINUX_ERR msg=audit(1366526640.307:1449979): security_compute_sid:
54 invalid context unconfined_u:unconfined_r:rocketgit_t:s0-s0:c0.c1023
55 for scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
56 tcontext=system_u:object_r:rocketgit_exec_t:s0 tclass=process
12 57 [ ] Check if adding/editing a bug generates notifications correctly. [ ] Check if adding/editing a bug generates notifications correctly.
13 58 Maybe use a global function for notify_one. Maybe use a global function for notify_one.
14 59 [ ] When we cannot process an event, mark it as failed and do not touch it again. [ ] When we cannot process an event, mark it as failed and do not touch it again.
 
19 64 [ ] Checking for "rg_ui['uid'] == 0" may not be enough. [ ] Checking for "rg_ui['uid'] == 0" may not be enough.
20 65 Maybe rg_ui[['uid'] = repo['uid']? Maybe rg_ui[['uid'] = repo['uid']?
21 66 Or, everywhere add 'uid = ?' in queries. Or, everywhere add 'uid = ?' in queries.
22 [ ] All operations must be verified with tokens.
67 Scenario: a user pass a list of ids to be del but s/he's not the owner.
23 68 [ ] Check if we can give rights for a non-owning repo! [ ] Check if we can give rights for a non-owning repo!
24 69 We should check if the user that gives rights is the owner or has admin We should check if the user that gives rights is the owner or has admin
25 70 rights! rights!
71 [ ] Add "lock ip" to settings and use them as default.
72 Also use it for confirmation.
73 But, if the IP changes, the user will have to relogin. Hm.
74 [ ] The rights should be stored on different rows? Probably not.
75 [ ] Adding an account seems to just show "Account was created".
76 Maybe redirect to user page? Only if there is no need to confirm.
77 What about lock_ip?
78 [ ] Where to check if plan exists (rg_user_edit_high_level).
26 79
27 80 == Medium == == Medium ==
81 [ ] Allow user to change timezone!
82 [ ] Prea mult spatiu gol la notificarea de schimbare repo.
83 [ ] @@if: if after {{/}} follows a \n, just remove it?
84 [ ] Think about moving unused tokens to a new session after login.
85 [ ] Security: Edit info: user can chage the uid behind my back in form!
86 This is fixed with rg_user_allow_access. It should be used everywhere.
87 [ ] Maybe do not deny account creation, but put them on a special state
88 and ask admin to allow it?
89 [ ] $sid to be masked behind a function (rg_user_get_sid).
90 [ ] Use curl to auto test all web functionality fast.
91 [ ] info.php shouldn't be converted to high-level function?!
92 [ ] Move sending e-mails to event.
93 [ ] Think about renaming repositories to projects. Because they contain also
94 the bug tracker. Maybe in the future the admin would want to disable
95 some modules (git/bug tracket/etc.).
96 [ ] When a push/etc. taskes places, add an event to recompute disk size!
97 Then, remove this from cron.
98 [ ] If user applies for open-source type account, do not allow private repos.
99 [ ] Move rg_account_allow_creation and other configuration stuff into admin area.
100 [ ] How to set default rights for new users? Maybe a section in admin area?
101 [ ] Computing disk size must invalidate the user cache. Or update it?
102 [ ] Check in remote.php that for the user connecting we are updating stats.
103 Better, update stats for both connecting user and repo is connecting to.
104 As an event?
105 [ ] Allow user to change the plan somehow.
106 [ ] In documentation, because of SELinux, we may want to restart some services.
107 At least: xinetd, cron etc. Probably not, but I must test this.
108 [ ] Think about generating more tokens. Maybe just sign them to not be forced
109 to save them in database. At least generate more than one and cache them.
110 [ ] There is a small possibility for files that are called from cron to not
111 have correct context (cron instead rocketgit_t). Seems I fixed it
112 with check_context function.
113 [ ] Allow upload a ssh key as a file, not only paste it in textarea.
114 [ ] Merge $more in all places where we add events.
115 [ ] Invite a friend.
116 [ ] In a lot of places seems I use rg_log instead of rg_*_set_error!
117 [ ] Auto login after account creation? What about locking by IP? Maybe just redirect to
118 login page with (at least) username pre-filled? Or ask only about "lock ip"?
119 [ ] sess: just mark it as invalid and store it in cache to not connect to
120 database? Cron will clean them up.
121 [ ] Transaction for bugs_max should be shorter. Now is very long. Hm.
122 [ ] Protect sh scripts to be run as rocletgit user and not other.
123 [ ] To not have too many keys in authorized_keys, investigate certificates.
124 [ ] Add cache in:
125 - rg_keys_count
126 - etc.
127 [ ] Add transaction in all places where event_add is called.
128 Maybe also in other places. Do an audit.
129 [ ] Remove 'repo/dirty' stuff and replace with events.
130 [ ] When we delete a user, should we remove from cache the name_to_id/email_to_id?
131 [ ] Delete repo - check if all is deleted. Seems not.
132 [ ] Audit all operations to be verified with tokens.
133 [ ] Create repo on demand when a user pushes.
134 [ ] Compute how many users are per plan, as an event when a user is
135 added/deleted/changed plans. Better, from cron.
136 [ ] Increment usage on keys should be done by events, with a predefined interval
137 to not kill the database.
138 [ ] Allow user management by ssh:
139 ssh rocketgit@host create-account --ssh-key `cat key.pub` <name>.
140 ssh rocketgit@host disable-account <name>.
141 Of course, check rights.
142 [ ] Add unit testing for high level functions.
143 [ ] Add unit testing for plans and rg_user_over_limit.
144 [ ] Switch to *_high_level functions.
145 [ ] When user press submit in a form and session expired, save in a cookie all
146 data, invite user to login and redirect to old page will all fields
147 filled in! But if the user is in a cafe, s/he will lose that info.
148 Better store locally.
149 [ ] Add rights for "Transform merge request in e-mail".
150 [ ] Check if all forms keep old values in case of an error.
151 [ ] Limit the number of e-mails to not flood the inbox.
152 [ ] Record in some stats how long took a push in terms of cpu/time/etc.
153 [ ] We should have a log with logins, not only last_login per user.
154 So, we should have an event on login and explode it in several queries.
155 Also session may be updated from this event, but still with a 1 min gap.
156 [ ] Max number of users must be removed from repo. No need for it.
157 [ ] Max commit size must be added per repo.
158 [ ] A script to check if all CSS classes in templates are present in css file.
159 [ ] Export/import a repo (xml maybe).
28 160 [ ] Add groups. [ ] Add groups.
29 161 [ ] We should warn the user if some users have lower rights than the default! [ ] We should warn the user if some users have lower rights than the default!
30 162 [ ] Auto-create repos at clonse phase, not only at push phase. [ ] Auto-create repos at clonse phase, not only at push phase.
 
39 171 [ ] SELinux: what about rocketgit_t access to postgresql through apache? [ ] SELinux: what about rocketgit_t access to postgresql through apache?
40 172 [ ] Check why only 'tageted' policy is installed. [ ] Check why only 'tageted' policy is installed.
41 173 [ ] Should I move the socket to /var/run (using tmp.d)? [ ] Should I move the socket to /var/run (using tmp.d)?
42 [ ] Use (organization, user, repo) instead of user/repo only.
43 174 [ ] Bug:List: saved searches with spaces inside the name are not correctly escaped. [ ] Bug:List: saved searches with spaces inside the name are not correctly escaped.
44 175 Use _ instead of space, or properly escape it (ugly: %20 etc.)? Use _ instead of space, or properly escape it (ugly: %20 etc.)?
45 176 [ ] "if ($res === FALSE) break" must set the error message! [ ] "if ($res === FALSE) break" must set the error message!
46 177 [ ] Carefull order the events. We do not want to build list notifications [ ] Carefull order the events. We do not want to build list notifications
47 178 before adding a user to the watch list. before adding a user to the watch list.
48 179 [ ] If description is empty, do not insert a \n in 'new repo' e-mail. [ ] If description is empty, do not insert a \n in 'new repo' e-mail.
49 [ ] Remove last form in PHP: user.form.php.
50 180 [ ] Current menu is not correctly shown as selected. [ ] Current menu is not correctly shown as selected.
51 181 [ ] If the confirmation code is truncated, an internal error is generated [ ] If the confirmation code is truncated, an internal error is generated
52 182 instead of a user error! instead of a user error!
 
85 215 [ ] We have a little problem: we need the ssh keyring to regenerate fast but [ ] We have a little problem: we need the ssh keyring to regenerate fast but
86 216 we may have a big events queue. We may want to signal directly we may have a big events queue. We may want to signal directly
87 217 the regeneration script and to not store mark-dirty state. Hm. the regeneration script and to not store mark-dirty state. Hm.
88 [ ] Optimize keyring invalidation.
89 [ ] Put "create user" on login page!
218 [ ] Optimize keyring invalidation. Store in cache the ts of last regenerate and
219 ignore request before that timestamp.
90 220 [ ] We should make stuff more robust. For example: CREATE REPO + HISTORY_INSERT. [ ] We should make stuff more robust. For example: CREATE REPO + HISTORY_INSERT.
91 [ ] What happens if we unlock an unlocked resource?
92 221 [ ] We have to record the renaming in the repo history. [ ] We have to record the renaming in the repo history.
93 222 [ ] What happends if a user is doing a downgrade? Must not allow it. [ ] What happends if a user is doing a downgrade? Must not allow it.
94 223 [ ] Use another home page for logged in users. [ ] Use another home page for logged in users.
 
96 225 No. But use some combinations of paras. No. But use some combinations of paras.
97 226 [ ] Why we use "FOR UPDATE" on 'events' table?! events.php is the only user. [ ] Why we use "FOR UPDATE" on 'events' table?! events.php is the only user.
98 227 [ ] We need to parallelize the event processing. [ ] We need to parallelize the event processing.
99 [ ] We need to add organization parameters next to repo_name!
100 228 [ ] Check if there are unused parameters after name2base(_path). [ ] Check if there are unused parameters after name2base(_path).
101 229 [ ] Remove any trace of $rr. [ ] Remove any trace of $rr.
102 [ ] After the switch from username to uid, should we pass uid into forms?
103 230 [ ] How to deal with browser accessing an old name (after rename)? [ ] How to deal with browser accessing an old name (after rename)?
104 231 [ ] repo.php tests does not say "ok". [ ] repo.php tests does not say "ok".
105 232 [ ] Functions from util.inc.php set rg_util_error(). Use it. [ ] Functions from util.inc.php set rg_util_error(). Use it.
 
... ... them after processing is done.
125 252 [ ] Profiling in not reentrant. We should use a stack! [ ] Profiling in not reentrant. We should use a stack!
126 253 [ ] We should not store repo_id0 into cache! [ ] We should not store repo_id0 into cache!
127 254 [ ] We are redirecting the user to history page. Do not wait for git dir! [ ] We are redirecting the user to history page. Do not wait for git dir!
128 [ ] Implement a cache like event.php.
129 255 [ ] Set a policy in config.php and do the cleaning/compress of the log files. [ ] Set a policy in config.php and do the cleaning/compress of the log files.
130 256 [ ] Fix the mail headers (+dkim) to avoid spam. [ ] Fix the mail headers (+dkim) to avoid spam.
131 257 [ ] http://joeyh.name/blog/entry/git_push_over_XMPP/ (ialbescu) [ ] http://joeyh.name/blog/entry/git_push_over_XMPP/ (ialbescu)
 
... ... them after processing is done.
133 259 [ ] Add history also for user. [ ] Add history also for user.
134 260 [ ] template_table can deal with a FALSE para: load error.html file in list/ [ ] template_table can deal with a FALSE para: load error.html file in list/
135 261 [ ] Put in history how many visitors received. [ ] Put in history how many visitors received.
136 Maybe only whn hitting some limits?
262 Maybe only when hitting some limits?
137 263 [ ] Run shaX 1000 times for login? [ ] Run shaX 1000 times for login?
138 264 [ ] There is no back button in tree browsing. [ ] There is no back button in tree browsing.
139 265 [ ] Allow users to have templates repo to be used when creating a new repo. [ ] Allow users to have templates repo to be used when creating a new repo.
140 266 Also define global templates. Also define global templates.
141 [ ] In logs we should log the version!
142 267 [ ] GeoIP [ ] GeoIP
143 268 [ ] Specify a timeout for push/fetch. [ ] Specify a timeout for push/fetch.
144 269 [ ] Describe also the instalation. [ ] Describe also the instalation.
 
... ... them after processing is done.
147 272 [ ] Detect hexa strings and link them to commits. [ ] Detect hexa strings and link them to commits.
148 273 [ ] Any user on a machine can look at repositories. [ ] Any user on a machine can look at repositories.
149 274 Any user can connect to database. Fix also the README after fixing this. Any user can connect to database. Fix also the README after fixing this.
150 [ ] Provide OpenVPN tunnels.
275 [ ] (Commercially) Provide OpenVPN tunnels to be sure you can push/fetch safely.
151 276 [ ] Errors should signal what field is not ok. [ ] Errors should signal what field is not ok.
152 [ ] Replace all *.form.php with templates.
153 277 [ ] Also log errmsg[] array! [ ] Also log errmsg[] array!
154 278 [ ] Do we need subop=1 into login.html? [ ] Do we need subop=1 into login.html?
155 [ ] Add possibility to donload the "CV" of a user.
279 [ ] Add possibility to download the "CV" of a user.
156 280 [ ] Happy birthday for projects/users/etc. [ ] Happy birthday for projects/users/etc.
157 [ ] Check if if we remove rocketgit, the repos stay!
281 [ ] Check if we remove rocketgit, the repos stay!
158 282 [ ] Bug rights: add note, anonymous add note, add label, add global search. [ ] Bug rights: add note, anonymous add note, add label, add global search.
159 283 [ ] Allow user to specify if is on windows/linux/etc. to be able to give [ ] Allow user to specify if is on windows/linux/etc. to be able to give
160 specific hints. Hm. THe user may have multiple OSs.
161 [ ] The selected menu is not colored different.
284 specific hints. Hm. The user may have multiple OSs.
162 285 [ ] http://rg.embedromix.ro:8000/user/catab/a13/admin/rights?edit_uid=19 [ ] http://rg.embedromix.ro:8000/user/catab/a13/admin/rights?edit_uid=19
163 286 should give an error! should give an error!
164 287 [ ] Pay attention to: https://github.com/sitaramc/gitolite/wiki: [ ] Pay attention to: https://github.com/sitaramc/gitolite/wiki:
 
... ... them after processing is done.
188 311 [ ] When repo is empty, we should not show the Log/Tree menu. [ ] When repo is empty, we should not show the Log/Tree menu.
189 312 [ ] @@branch@@ is not defined for merge requests. Should it? Probably yes, to filter them. [ ] @@branch@@ is not defined for merge requests. Should it? Probably yes, to filter them.
190 313 [ ] Fix diff output. Cannot deal with renames/removes/etc. [ ] Fix diff output. Cannot deal with renames/removes/etc.
191 [ ] Check admin creatin of an account.
314 [ ] Check admin creating of an account.
192 315 [ ] Add possibility to reject merge requests, to apply, to delete etc. [ ] Add possibility to reject merge requests, to apply, to delete etc.
193 316 [ ] Do we need to escape some chars in console (ssh rocketgit@host repo X)? [ ] Do we need to escape some chars in console (ssh rocketgit@host repo X)?
194 317 [ ] We need to switch to a template for the user form to get rid of a lot of [ ] We need to switch to a template for the user form to get rid of a lot of
195 318 mambo-jumbo with the _u array passed! mambo-jumbo with the _u array passed!
196 319 [ ] Show the API on the webpage, exactly like Blender. [ ] Show the API on the webpage, exactly like Blender.
197 [ ] We can pass in authorized_keys aslo the key id. Maybe for usage?
198 320 [ ] Migrate to a single function to deal with a request so we can do better [ ] Migrate to a single function to deal with a request so we can do better
199 321 unit testing. unit testing.
200 322 [ ] We should have a 'policy' table where we have something like: [ ] We should have a 'policy' table where we have something like:
 
... ... them after processing is done.
203 325 Example: user X paid some money, and we assign it to level 2 Example: user X paid some money, and we assign it to level 2
204 326 Level 2 has 4 users, max 100MiB disk space, 1Mbit/s speed. Level 2 has 4 users, max 100MiB disk space, 1Mbit/s speed.
205 327 He creates a repo and assigns 2 users to it. He creates a repo and assigns 2 users to it.
206 [ ] Notifications when disk space is low.
328 [ ] Notifications when disk space is low.
207 329 [ ] Check webSSO for authentification. [ ] Check webSSO for authentification.
208 330 [ ] Check http://gitlist.org/ [ ] Check http://gitlist.org/
209 [ ] use do {} while(0) to respect profiling!
210 331 [ ] Enforce Signoff-by lines per project (a new permission) [ ] Enforce Signoff-by lines per project (a new permission)
211 332 = reject commits without signoff! = reject commits without signoff!
212 333 Maybe, do it generic, allow a text field to enumerate what should be in a commit! Maybe, do it generic, allow a text field to enumerate what should be in a commit!
 
... ... them after processing is done.
218 339 [ ] Merge requests e-mail: explanation of why to pull, diffstat! Maybe also the [ ] Merge requests e-mail: explanation of why to pull, diffstat! Maybe also the
219 340 patch if is small. patch if is small.
220 341 [ ] Check git-request-pull [ ] Check git-request-pull
221 [ ] Show the size of a repository. Also when you ssh from terminal.
222 See git-count-objects and http://stackoverflow.com/questions/8185276/find-size-of-git-repo.
223 342 [ ] Logo for project. Blender? [ ] Logo for project. Blender?
224 343 [ ] Default branch per project[/user]. [ ] Default branch per project[/user].
225 344 [ ] Main language of the project. [ ] Main language of the project.
 
... ... them after processing is done.
228 347
229 348 == Normal priority == == Normal priority ==
230 349 [ ] [ ]
231 [ ] Show last time use of a ssh key, or how many times was used, or both.
232 350 [ ] Add hint about "ssh rocketgit@server" to quickly find status etc. [ ] Add hint about "ssh rocketgit@server" to quickly find status etc.
233 351 [ ] rg_redirect does not record profiling information! [ ] rg_redirect does not record profiling information!
234 352 [ ] git bundle [ ] git bundle
235 353 [ ] How to sign merge requests?! [ ] How to sign merge requests?!
236 [ ] Signal, with red, if a key was uploaded in the last X days.
237 354 [ ] 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
238 355 forgot password e-mail field. Not good. An attacker may iterate over all forgot password e-mail field. Not good. An attacker may iterate over all
239 356 uids. But, with a token will be nice! uids. But, with a token will be nice!
240 357 [ ] 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.
241 358 [ ] Permit "log" to see more rows. [ ] Permit "log" to see more rows.
242 [ ] Allow admin to upload keys for a user.
243 359 [ ] Make an option to not allow a client to upload keys. Why? [ ] Make an option to not allow a client to upload keys. Why?
244 360 To restrict this to admin? To restrict this to admin?
245 361 [ ] Can we bypass ssh auth to allow pushes? [ ] Can we bypass ssh auth to allow pushes?
246 362 This way maybe we can identify client by fingerprint. This way maybe we can identify client by fingerprint.
247 [ ] Use rg_git_diff_tree to test for path based restrictions. Also, take care of renmaes, copies etc.
363 [ ] Use rg_git_diff_tree to test for path based restrictions. Also, take care of renames, copies etc.
248 364 [ ] See Gerrit: https://codereview.qt-project.org/#change,22764 [ ] See Gerrit: https://codereview.qt-project.org/#change,22764
249 365 [ ] user-conf: option: auto-create-repo-on-push [ ] user-conf: option: auto-create-repo-on-push
250 366 [ ] 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.
251 [ ] Allow user to create a template for repositories.
252 367 [ ] Optionally init a repo with some files (README, TODO etc.) [ ] Optionally init a repo with some files (README, TODO etc.)
253 368 [ ] 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
254 369 [ ] 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.
257 372 [ ] Statistics (number, tool etc.) for project access. [ ] Statistics (number, tool etc.) for project access.
258 373 [ ] For bugtracker use BerliOS as a starting point. [ ] For bugtracker use BerliOS as a starting point.
259 374 [ ] Allow (anonymous) editing files on web and transform them in merge request. [ ] Allow (anonymous) editing files on web and transform them in merge request.
375 How to bundle multiple edits in a single commit?
260 376 [ ] On the first page no search form! It is useless! [ ] On the first page no search form! It is useless!
261 377 [ ] Add stats for a repo. Some stuff is already in git.inc.php. [ ] Add stats for a repo. Some stuff is already in git.inc.php.
262 378 [ ] Anti-spam: hide e-mail addresses! [ ] Anti-spam: hide e-mail addresses!
 
... ... them after processing is done.
267 383 [ ] Order tags by mtime desc. [ ] Order tags by mtime desc.
268 384 [ ] rg_repos should be split in rg_repos and rg_var_lib. [ ] rg_repos should be split in rg_repos and rg_var_lib.
269 385 [ ] $blocks = explode("@@left@@-=ROCKETGIT=-@@left@@", $a) - seems that \0 is replaced! [ ] $blocks = explode("@@left@@-=ROCKETGIT=-@@left@@", $a) - seems that \0 is replaced!
270 [ ] Changing repo name probably is not working right.
271 386 [ ] Check XSRF attacks and other types. [ ] Check XSRF attacks and other types.
272 387 [ ] Validate e-mails. [ ] Validate e-mails.
273 388 [ ] Take care of PHP's time limit to not interfere with the rest. [ ] Take care of PHP's time limit to not interfere with the rest.
274 [ ] Run update.php before rpm upgrade the scripts.
275 [ ] Store by uid the repos, and make links to them. Make a function to rename
276 a username. We have to keep track of renames so old links will
277 still work.
278 389 [ ] Differentiate between owner of a repository, currently logged in user and admin. [ ] Differentiate between owner of a repository, currently logged in user and admin.
279 390 [ ] Warn before deleting a repo! [ ] Warn before deleting a repo!
280 391 [ ] Switch all menus to templates. [ ] Switch all menus to templates.
 
... ... them after processing is done.
285 396 [ ] admin: "Lock all accounts" and "Reset password for all accounts and send mail". [ ] admin: "Lock all accounts" and "Reset password for all accounts and send mail".
286 397 [ ] rg_repo_allow seems to not be used. [ ] rg_repo_allow seems to not be used.
287 398 [ ] Get memory statistics from /proc. [ ] Get memory statistics from /proc.
288 [ ] Delay connection to database.
289 399 [ ] Add support for refs/notes/ pushes. [ ] Add support for refs/notes/ pushes.
290 400 [ ] When logging _SERVER variables, log only the ones prefixed by ROCKETGIT_. [ ] When logging _SERVER variables, log only the ones prefixed by ROCKETGIT_.
291 401 [ ] 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.
292 [ ] Add commercial posibility for VPNs to be sure you can push/fetch safely.
293 402 [ ] Add a possibility (link shown in push message) to delete/update/etc. the [ ] Add a possibility (link shown in push message) to delete/update/etc. the
294 403 merge request. merge request.
295 404 [ ] Allow a nonstandard port for web. [ ] Allow a nonstandard port for web.
 
... ... them after processing is done.
306 415 Only owner will have access. Only owner will have access.
307 416 We may add also a text that will be output to clients. We may add also a text that will be output to clients.
308 417 [ ] List chages introduced by a merge: git diff-tree --always [--cc] -m -p f7d5b5770f4c6b5a124dad6358bed310d56bf909 [ ] List chages introduced by a merge: git diff-tree --always [--cc] -m -p f7d5b5770f4c6b5a124dad6358bed310d56bf909
309 [ ] ACL per IP (only for private repos).
310 418 [ ] Check pack-protocol.txt! [ ] Check pack-protocol.txt!
311 419 [ ] When push is executed with success, show a nice message from RocketGit. [ ] When push is executed with success, show a nice message from RocketGit.
312 420 [ ] Move is_private member in repo array, not test for empty on default rights [ ] Move is_private member in repo array, not test for empty on default rights
 
... ... them after processing is done.
318 426 Disk space accounting? Disk space accounting?
319 427 [ ] We should make a repo dirty only if user pushed something with success. [ ] We should make a repo dirty only if user pushed something with success.
320 428 [ ] <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"/>
321 [ ] "Add key" form may be joined with list keys command!
322 429 [ ] Allow to recover a deleted repository. [ ] Allow to recover a deleted repository.
323 430 [ ] Deny access in all functions to deleted repositories. [ ] Deny access in all functions to deleted repositories.
324 431 [ ] Count the numbers of clones/pushes/pulls. [ ] Count the numbers of clones/pushes/pulls.
325 [ ] Add memcache caching for all database lookups.
326 432 [ ] Allow to configure the limit of the patch size to prevent abuses. [ ] Allow to configure the limit of the patch size to prevent abuses.
327 433 [ ] Allow to configure to refuse binary files. [ ] Allow to configure to refuse binary files.
328 [ ] Add a repo_prop_set/get function that will set/get a file in .git folder.
329 This way we can speed up some lookups (no need for database). Hm.
330 [ ] When we delete a repository, we will do repo_prop_set(repo, disabled) and we will
331 return OK, in the background we will do the removing.
332 Do not forget to also remove clones. Hm.
333 434 [ ] E-mail aliases section. [ ] E-mail aliases section.
334 435 [ ] User details section (blog, avatar, mail notifications). [ ] User details section (blog, avatar, mail notifications).
335 [ ] Check if user is over-quota on push.
336 [ ] The cron will have to:
337 [ ] Compute disk usage, ignoring hard links. Hm. Probably we will add
338 only the owner, even if the files have multiple links. TBD.
339 [ ]
340 436 [ ] UTF-8 checks of patches. [ ] UTF-8 checks of patches.
341 437 [ ] W3C validation on all pages. [ ] W3C validation on all pages.
342 438 [ ] Validate user and repo names. Probably other things. [ ] Validate user and repo names. Probably other things.
 
... ... them after processing is done.
354 450 [ ] Check http://plathrop.tertiusfamily.net/blog/2010/05/11/git-hooks-branch-acls-and-more/ to block updates that have not pull - a la SVN [ ] Check http://plathrop.tertiusfamily.net/blog/2010/05/11/git-hooks-branch-acls-and-more/ to block updates that have not pull - a la SVN
355 451 [ ] Maybe we should mark the repository as dirty, only in the post-receive hook? Or update is the best place? [ ] Maybe we should mark the repository as dirty, only in the post-receive hook? Or update is the best place?
356 452 [ ] Limit number of commits per push. [ ] Limit number of commits per push.
357 [ ] Compute disk_used_mb per user.
358 [ ] Enforce disk quota.
359 453 [ ] RSS [ ] RSS
360 454 [ ] Config file must be able to be set from a env var, to be able to run [ ] Config file must be able to be set from a env var, to be able to run
361 455 multiple instances of rocketgit on the same server. multiple instances of rocketgit on the same server.
 
... ... them after processing is done.
371 465 [ ] git-notes may be used to attach messages to commits. Nice. [ ] git-notes may be used to attach messages to commits. Nice.
372 466 [ ] Store also the size of the patch along history/commit info. [ ] Store also the size of the patch along history/commit info.
373 467 [ ] Check SELinux MLS [ ] Check SELinux MLS
374 [ ] Test if 'first_install' state is working correctly.
375 468 [ ] Deal with empty repositories (rg_git_ls_tree etc.). [ ] Deal with empty repositories (rg_git_ls_tree etc.).
376 469 [ ] 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.
377 470 [ ] The rewrite engine should pass a single op for user and for org, but with [ ] The rewrite engine should pass a single op for user and for org, but with
 
... ... them after processing is done.
398 491 automatically to the specified queues. automatically to the specified queues.
399 492 [ ] At push time we may generate some nice informative output (commits, [ ] At push time we may generate some nice informative output (commits,
400 493 last time when current user commited etc.) last time when current user commited etc.)
401 [ ] Team suports
402 494 [ ] Bulk add users/teams/repos/bugs/etc. [ ] Bulk add users/teams/repos/bugs/etc.
403 495
404 496 == Low priority == == Low priority ==
 
... ... them after processing is done.
422 514 * *
423 515
424 516
425 == Rights management - to be implemented ==
426
427 - A user is trying to push some commits in a branch B, for a file F
428 - The set of rights may be:
429 Branch File Rights
430 B2 dir/*.png FPA
431 * dir2 A
432 * * F
File admin/init.php changed (mode: 100644) (index 45832cb..343a3cf)
... ... $_u['username'] = "admin";
42 42 $_u['realname'] = "Master admin"; $_u['realname'] = "Master admin";
43 43 $_u['email'] = $rg_admin_email; $_u['email'] = $rg_admin_email;
44 44 $_u['is_admin'] = 1; $_u['is_admin'] = 1;
45 $_u['disk_quota_mb'] = 0;
46 45 $_u['rights'] = rg_rights_all("user"); $_u['rights'] = rg_rights_all("user");
47 46 $_u['session_time'] = 3600; $_u['session_time'] = 3600;
48 47 $_u['confirm_token'] = ""; $_u['confirm_token'] = "";
File hooks/post-receive changed (mode: 100755) (index 72701e2..f3094ab)
... ... ini_set("track_errors", "On");
16 16
17 17 $_start = microtime(TRUE); $_start = microtime(TRUE);
18 18
19 require_once("/etc/rocketgit/config.php");
19 $conf = getenv("ROCKETGIT_CONF_FILE");
20 if (empty($conf))
21 $conf = "/etc/rocketgit/config.php";
22 require_once($conf);
20 23
21 24 $INC = $rg_scripts . "/inc"; $INC = $rg_scripts . "/inc";
22 25 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
 
... ... while (($set = fgets($f))) {
58 61 } }
59 62 fclose($f); fclose($f);
60 63
61
62 // Mark repository dirty for disk statistics and other stuff
63 // TODO: deal with the case when is not possible to write that file.
64 @file_put_contents($repo_path . "/rocketgit/dirty", "");
65
64 //TODO: replace with event - do not forget to dirty the repo
66 65 $a = array( $a = array(
67 66 "op" => "push", "op" => "push",
68 67 "itime" => getenv("ROCKETGIT_ITIME"), "itime" => getenv("ROCKETGIT_ITIME"),
File hooks/pre-commit changed (mode: 100755) (index ccef4c4..afb9431)
... ... ini_set("track_errors", "On");
7 7
8 8 $_start = microtime(TRUE); $_start = microtime(TRUE);
9 9
10 require_once("/etc/rocketgit/config.php");
10 $conf = getenv("ROCKETGIT_CONF_FILE");
11 if (empty($conf))
12 $conf = "/etc/rocketgit/config.php";
13 require_once($conf);
11 14
12 15 $INC = $rg_scripts . "/inc"; $INC = $rg_scripts . "/inc";
13 16 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
 
... ... else
38 41 $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000);
39 42 rg_log("Took " . $diff . "ms."); rg_log("Took " . $diff . "ms.");
40 43
44 /*TODO: replace with event
41 45 @file_put_contents($repo_path . "/rocketgit/hook-pre-commit", @file_put_contents($repo_path . "/rocketgit/hook-pre-commit",
42 46 "repo: " . $repo . " ($repo_path)" "repo: " . $repo . " ($repo_path)"
43 47 . "\nat: " . sprintf("%u", $_start) . "\nat: " . sprintf("%u", $_start)
44 48 . "\nuid: " . $uid . "\nuid: " . $uid
45 49 . "\ncmd: against=$against" . "\ncmd: against=$against"
46 50 . "\nTook: " . $diff . "ms"); . "\nTook: " . $diff . "ms");
51 */
52
47 53 ?> ?>
File hooks/pre-receive changed (mode: 100755) (index 785f8b8..0676a5e)
... ... ini_set("track_errors", "On");
13 13
14 14 $_start = microtime(TRUE); $_start = microtime(TRUE);
15 15
16 require_once("/etc/rocketgit/config.php");
16 $conf = getenv("ROCKETGIT_CONF_FILE");
17 if (empty($conf))
18 $conf = "/etc/rocketgit/config.php";
19 require_once($conf);
17 20
18 21 $INC = $rg_scripts . "/inc"; $INC = $rg_scripts . "/inc";
19 22 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
 
... ... fclose($f);
58 61 $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000);
59 62 rg_log("Took " . $diff . "ms."); rg_log("Took " . $diff . "ms.");
60 63
64 /*TODO: replace with event
61 65 @file_put_contents($repo_path . "/rocketgit/hook-pre-receive", @file_put_contents($repo_path . "/rocketgit/hook-pre-receive",
62 66 "repo: " . $repo . " ($repo_path)" "repo: " . $repo . " ($repo_path)"
63 67 . "\nat: " . sprintf("%u", $_start) . "\nat: " . sprintf("%u", $_start)
 
... ... rg_log("Took " . $diff . "ms.");
65 69 . "\npara: $refname $old_rev $new_rev" . "\npara: $refname $old_rev $new_rev"
66 70 . "\nTook: " . $diff . "ms" . "\nTook: " . $diff . "ms"
67 71 . "\n_SERVER: " . rg_array2string($_SERVER)); . "\n_SERVER: " . rg_array2string($_SERVER));
72 */
68 73
69 74 ?> ?>
File hooks/update changed (mode: 100755) (index 7765def..b229745)
... ... ini_set("track_errors", "On");
14 14
15 15 $_start = microtime(TRUE); $_start = microtime(TRUE);
16 16
17 require_once("/etc/rocketgit/config.php");
17 $conf = getenv("ROCKETGIT_CONF_FILE");
18 if (empty($conf))
19 $conf = "/etc/rocketgit/config.php";
20 require_once($conf);
18 21
19 22 $INC = $rg_scripts . "/inc"; $INC = $rg_scripts . "/inc";
20 23 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
 
... ... if (strncmp($a['refname'], "refs/tags/", 10) == 0) {
69 72 rg_git_fatal("Unknown refname type provided [" . $a['refname'] . "]"); rg_git_fatal("Unknown refname type provided [" . $a['refname'] . "]");
70 73 } }
71 74
75 /*TODO: replace with event
72 76 @file_put_contents($a['repo_path'] . "/rocketgit/hook-update", @file_put_contents($a['repo_path'] . "/rocketgit/hook-update",
73 77 "repo: " . $a['repo_path'] "repo: " . $a['repo_path']
74 78 . "\nat: " . sprintf("%u", $_start) . "\nat: " . sprintf("%u", $_start)
 
... ... if (strncmp($a['refname'], "refs/tags/", 10) == 0) {
76 80 . "\npara: " . $a['refname'] . " " . $a['old_rev'] . " " . $a['new_rev'] . "\npara: " . $a['refname'] . " " . $a['old_rev'] . " " . $a['new_rev']
77 81 . "\nProfiling:\n" . rg_prof_text() . "\nProfiling:\n" . rg_prof_text()
78 82 . "\n_SERVER: " . rg_array2string($_SERVER)); . "\n_SERVER: " . rg_array2string($_SERVER));
83 */
79 84
80 85 rg_prof_end("hook-update"); rg_prof_end("hook-update");
81 86 rg_prof_log("rg_log"); rg_prof_log("rg_log");
File inc/admin/admin.php changed (mode: 100644) (index 27d63e7..195b1a8)
1 1 <?php <?php
2 2 rg_log("/inc/admin/admin"); rg_log("/inc/admin/admin");
3 3
4 $admin_more = $more;
4 5 $_admin = ""; $_admin = "";
5 6
6 7 if ($login_ui['is_admin'] != 1) { if ($login_ui['is_admin'] != 1) {
 
... ... if ($login_ui['is_admin'] != 1) {
8 9 return; return;
9 10 } }
10 11
11 $_subop = empty($paras) ? "users" : array_shift($paras);
12 $_subop = empty($paras) ? "" : array_shift($paras);
12 13
13 14 // menu // menu
14 15 $_m = array( $_m = array(
16 "plans" => array(
17 "text" => "Plans",
18 "op" => "plans"
19 ),
15 20 "users" => array( "users" => array(
16 21 "text" => "Users", "text" => "Users",
17 22 "op" => "users" "op" => "users"
 
... ... $_m = array(
24 29 rg_menu_add($rg_menu, $_m, $_subop); rg_menu_add($rg_menu, $_m, $_subop);
25 30
26 31 switch ($_subop) { switch ($_subop) {
32 case 'plans':
33 include($INC . "/admin/plans/plans.php");
34 $_admin .= $_admin_plans;
35 break;
36
27 37 case 'users': // users case 'users': // users
28 38 include($INC . "/admin/users/users.php"); include($INC . "/admin/users/users.php");
29 39 $_admin .= $_admin_users; $_admin .= $_admin_users;
File inc/admin/plans/plans.php changed (mode: 100644) (index e69de29..8c8874a)
1 <?php
2 rg_log("/inc/admin/plans/plans");
3
4 $_admin_plans = "";
5
6 $_op = empty($paras) ? "list" : array_shift($paras);
7
8 // menu
9 $_m = array(
10 "list" => array(
11 "text" => "List plans",
12 "op" => "list"
13 ),
14 "add" => array(
15 "text" => "Add plan",
16 "op" => "add"
17 )
18 );
19 rg_menu_add($rg_menu, $_m, $_op);
20
21 switch ($_op) {
22 case 'list': // list
23 $_admin_plans .= rg_plan_list_high_level($db, $sid, $admin_more);
24 break;
25
26 case 'add': // add
27 case 'edit': // edit
28 $_admin_plans .= rg_plan_edit_high_level($db, $sid, $admin_more);
29 break;
30 }
31
32 ?>
File inc/admin/users/add.php deleted (index 57dfea0..0000000)
1 <?php
2 rg_log("/inc/admin/users/add");
3
4 $uid = 0;
5 $_user_add = "";
6 $errmsg = array();
7
8 if ($doit == 1) {
9 if (!rg_token_valid($db, $sid, $token)) {
10 $_user_add .= "Invalid token. Try again.";
11 return;
12 }
13
14 $xuser = rg_var_str("xuser");
15 $realname = rg_var_str("realname");
16 $email = rg_var_str("email");
17 $xpass = rg_var_str("xpass");
18 $is_admin = rg_var_uint("is_admin");
19 $disk_quota_mb = rg_var_uint("disk_quota_mb");
20 $rights = rg_rights_a2s(rg_var_str("rights"));
21 $session_time = rg_var_uint("session_time");
22
23 do {
24 if (rg_user_ok($xuser) !== TRUE) {
25 $errmsg[] = "invalid user name (" . rg_user_error() . ")";
26 break;
27 }
28
29 if (rg_user_pass_ok($xpass) !== TRUE) {
30 $errmsg[] = "invalid password (" . rg_user_error() . ")";
31 break;
32 }
33
34 $_ui = rg_user_info($db, 0, $xuser, "");
35 if ($_ui['ok'] != 1) {
36 $errmsg[] = "internal error";
37 break;
38 }
39
40 if ($_ui['exists'] == 1) {
41 $errmsg[] = "user already exists";
42 break;
43 }
44
45 $_u = array();
46 $_u['uid'] = 0;
47 $_u['username'] = $xuser;
48 $_u['realname'] = $realname;
49 $_u['email'] = $email;
50 $_u['pass'] = $xpass;
51 $_u['is_admin'] = $is_admin;
52 $_u['disk_quota_mb'] = $disk_quota_mb;
53 $_u['rights'] = $rights;
54 $_u['session_time'] = $session_time;
55 $_u['confirm_token'] = "";
56 if (!rg_user_edit($db, $_u)) {
57 $errmsg[] = "cannot add user (" . rg_user_error() . ")";
58 break;
59 }
60
61 // TODO: Send a confirmation e-mail with the password
62
63 $_user_add .= "OK!<br />";
64 } while (0);
65 } else {
66 $xuser = "";
67 $realname = "";
68 $email = "";
69 $xpass = "";
70 $is_admin = 0;
71 $disk_quota_mb = 0;
72 $rights = "";
73 $session_time = $rg_session_time;
74 }
75
76 $create_mode = 1;
77 $admin_mode = 1;
78 $pass_mode = 1;
79 include($INC . "/admin/users/user.form.php");
80 $_user_add .= $_form;
81
82 ?>
File inc/admin/users/edit.php deleted (index 92dc201..0000000)
1 <?php
2 rg_log("/inc/admin/users/edit");
3
4 $uid = rg_var_str("uid");
5
6 $_user_edit = "";
7
8 $show_form = 1;
9 $errmsg = array();
10
11 if ($doit == 1) {
12 if (!rg_token_valid($db, $sid, $token)) {
13 $_user_edit .= "Invalid token. Try again.";
14 return;
15 }
16
17 $xuser = rg_var_str("xuser");
18 $realname = rg_var_str("realname");
19 $email = rg_var_str("email");
20 $xpass = rg_var_str("xpass");
21 $is_admin = rg_var_uint("is_admin");
22 $disk_quota_mb = rg_var_uint("disk_quota_mb");
23 $rights = rg_rights_a2s(rg_var_str("rights"));
24 $session_time = rg_var_uint("session_time");
25
26 do {
27 $_ui = rg_user_info($db, 0, $xuser, "");
28 if ($_ui['ok'] == 0) {
29 $errmsg[] = "internal error";
30 break;
31 }
32
33 if ($_ui['exists'] == 0) {
34 $errmsg[] = "user does not exists";
35 break;
36 }
37
38 $_u = array();
39 $_u['uid'] = $uid;
40 $_u['username'] = $xuser;
41 $_u['realname'] = $realname;
42 $_u['email'] = $email;
43 $_u['pass'] = $xpass;
44 $_u['is_admin'] = $is_admin;
45 $_u['disk_quota_mb'] = $disk_quota_mb;
46 $_u['rights'] = $rights;
47 $_u['session_time'] = $session_time;
48 $_u['confirm_token'] = "";
49 if (!rg_user_edit($db, $_u)) {
50 $errmsg[] = "cannot change info (" . rg_user_error() . ")";
51 break;
52 }
53
54 $_user_edit .= "OK!<br />";
55 $show_form = 0;
56 } while (0);
57 } else {
58 // TODO: Check if user has the right to edit this info!
59
60 $_ui = rg_user_info($db, $uid, "", "");
61 if ($_ui['ok'] == 0) {
62 $_user_edit .= "internal error";
63 $show_form = 0;
64 } else if ($_ui['exists'] == 0) {
65 $_user_edit .= "user does not exist";
66 $show_form = 0;
67 } else {
68 $xuser = $_ui['username'];
69 $realname = $_ui['realname'];
70 $email = $_ui['email'];
71 $xpass = "";
72 $is_admin = $_ui['is_admin'];
73 $disk_quota_mb = $_ui['disk_quota_mb'];
74 $rights = $_ui['rights'];
75 $session_time = $_ui['session_time'];
76 }
77 }
78
79 if ($show_form == 1) {
80 $create_mode = 0;
81 $admin_mode = 1;
82 $pass_mode = 1;
83 include($INC . "/admin/users/user.form.php");
84 $_user_edit .= $_form;
85 }
86
87 ?>
File inc/admin/users/user.form.php deleted (index 08f947c..0000000)
1 <?php
2 $_form = '<div class="formarea">' . "\n";
3
4 if ($create_mode == 1)
5 $_title = "Create a new account";
6 else
7 $_title = "Change details";
8 $_form .= "<div class=\"formarea_title\">$_title</div><br />\n";
9
10 if ($admin_mode == 1) {
11 $sel_is_admin = array(0 => "", 1 => "");
12 $sel_is_admin[$is_admin] = " selected=\"selected\"";
13 }
14
15 $_form .= rg_template_errmsg($errmsg);
16
17 $_form .= '
18 <form method="post" action="' . rg_re_post($sparas) . '">
19 <input type="hidden" name="doit" value="1" />
20 <input type="hidden" name="token" value="' . rg_token_get($db, $sid) . '" />
21 ';
22
23 if ($admin_mode == 1)
24 $_form .= '<input type="hidden" name="uid" value="' . $uid . '" />';
25
26 $_form .= '
27 <label for="xuser" class="form_item_title">User name</label><br />
28 <input type="text" name="xuser" value="' . $xuser . '" />
29 <br />
30 <br />
31
32 <label for="realname" class="form_item_title">Name</label><br />
33 <input type="text" name="realname" value="' . $realname . '" />
34 <br />
35 <br />
36
37 <label for="email" class="form_item_title">E-mail</label><br />
38 <input type="text" name="email" value="' . $email . '" />
39 <br />
40 <br />
41 ';
42
43 if ($pass_mode > 0) {
44 $_form .= '
45 <label for="xpass" class="form_item_title">Password</label><br />
46 <input type="password" name="xpass" value="' . $xpass . '" />
47 <br />
48 <br />
49 ';
50 }
51
52 if ($pass_mode > 1) {
53 $_form .= '
54 <label for="xpass2" class="form_item_title">Password (confirmation)</label><br />
55 <input type="password" name="xpass2" value="' . $xpass2 . '" />
56 <br />
57 <br />
58 ';
59 }
60
61 if ($admin_mode == 1) {
62 $_form .= '
63 <label for="is_admin" class="form_item_title">Admin?</label><br />
64 <select name="is_admin">
65 <option value="0"' . $sel_is_admin[0] . '>No</option>
66 <option value="1"' . $sel_is_admin[1] . '>Yes</option>
67 </select>
68 <br />
69 <br />
70
71 <label for="disk_quota_mb" class="form_item_title">Disk quota (MiB)</label><br />
72 <input type="text" name="disk_quota_mb" value="' . $disk_quota_mb . '" />
73 <br />
74 <br />
75
76 <label for="rights" class="form_item_title">Rights</label><br />
77 ' . rg_rights_checkboxes("user", $rights) . '
78 <br />
79 <br />
80 ';
81 }
82
83 $_form .= '
84 <label for="session_time" class="form_item_title">Preferred session time (in seconds)</label><br />
85 <input type="text" name="session_time" value="' . $session_time . '" />
86 <br />
87 <br />
88
89 <input type="submit" value="Do" />
90 </form>
91 </div>
92 ';
93 ?>
File inc/admin/users/users.php changed (mode: 100644) (index 2c4a863..92ac5e2)
... ... rg_log("/inc/admin/users/users");
4 4 $_admin_users = ""; $_admin_users = "";
5 5
6 6 $_op = empty($paras) ? "list" : array_shift($paras); $_op = empty($paras) ? "list" : array_shift($paras);
7 $target = empty($paras) ? "" : array_shift($paras);
8 $target_ui = rg_user_info($db, 0, $target, "");
7 9
8 10 // menu // menu
9 11 $_m = array( $_m = array(
 
... ... $_m = array(
18 20 ); );
19 21 rg_menu_add($rg_menu, $_m, $_op); rg_menu_add($rg_menu, $_m, $_op);
20 22
23 // TODO: security: CSRF!
24 $_show_list = 1;
21 25 switch ($_op) { switch ($_op) {
22 case 'list': // list
23 // TODO: load template!
24 $_admin_users .= rg_user_list($db, $_admin_users_url);
26 case 'add': // add
27 case 'edit': // edit
28 $more['ask_for_pass'] = 1;
29 $_admin_users .= rg_user_edit_high_level($db, $sid, $more);
30 $_show_list = 0;
25 31 break; break;
26 32
27 case 'add': // add
28 include($INC . "/admin/users/add.php");
29 $_admin_users .= $_user_add;
33 case 'suspend':
34 if (!rg_user_suspend($db, $target_ui, 1))
35 $_admin_users .= rg_template("admin/users/bad_suspend.html");
30 36 break; break;
31 37
32 case 'edit': // edit
33 include($INC . "/admin/users/edit.php");
34 $_admin_users .= $_user_edit;
38 case 'unsuspend':
39 if (!rg_user_suspend($db, $target_ui, 0))
40 $_admin_users .= rg_template("admin/users/bad_unsuspend.html");
41 break;
42
43 case 'make_admin':
44 if (!rg_user_make_admin($db, $target_ui, 1))
45 $_admin_users .= rg_template("admin/users/bad_admin.html");
46 break;
47
48 case 'remove_admin':
49 if (!rg_user_make_admin($db, $target_ui, 0))
50 $_admin_users .= rg_template("admin/users/bad_unadmin.html");
51 break;
52
53 case 'remove':
54 if (!rg_user_remove($db, $target_ui))
55 $_admin_users .= rg_template("admin/users/bad_remove.html");
35 56 break; break;
36 57 } }
37 58
59 if ($_show_list == 1)
60 $_admin_users .= rg_user_list($db);
61
38 62 ?> ?>
File inc/bug.inc.php changed (mode: 100644) (index 679ef0d..1cb7d2c)
... ... function rg_bug_next_id($db, $repo_id)
210 210
211 211 $next_bug_id = FALSE; $next_bug_id = FALSE;
212 212 do { do {
213 $params = array($repo_id);
213 214 $sql = "UPDATE bugs_max SET last_bug_id = last_bug_id + 1" $sql = "UPDATE bugs_max SET last_bug_id = last_bug_id + 1"
214 . " WHERE repo_id = $repo_id"
215 . " WHERE repo_id = $1"
215 216 . " RETURNING last_bug_id AS next_bug_id"; . " RETURNING last_bug_id AS next_bug_id";
216 $res = rg_sql_query($db, $sql);
217 $res = rg_sql_query_params($db, $sql, $params);
217 218 if ($res === FALSE) { if ($res === FALSE) {
218 219 rg_bug_set_error("cannot get/update max (" . rg_sql_error() . ")"); rg_bug_set_error("cannot get/update max (" . rg_sql_error() . ")");
219 220 break; break;
 
... ... function rg_bug_next_id($db, $repo_id)
244 245 * 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
245 246 * took place. * took place.
246 247 */ */
247 $sql = "SELECT 1 FROM bugs_max WHERE repo_id = $repo_id";
248 $res = rg_sql_query($db, $sql);
248 $params = array($repo_id);
249 $sql = "SELECT 1 FROM bugs_max WHERE repo_id = $1";
250 $res = rg_sql_query_params($db, $sql, $params);
249 251 if ($res === FALSE) { if ($res === FALSE) {
250 252 rg_bug_set_error("cannot select 1 from max table (" . rg_sql_error() . ")"); rg_bug_set_error("cannot select 1 from max table (" . rg_sql_error() . ")");
251 253 break; break;
 
... ... function rg_bug_next_id($db, $repo_id)
255 257
256 258 if ($rows == 0) { if ($rows == 0) {
257 259 // We were faster, just insert. // We were faster, just insert.
260 $params = array($repo_id);
258 261 $sql = "INSERT INTO bugs_max (repo_id, last_bug_id)" $sql = "INSERT INTO bugs_max (repo_id, last_bug_id)"
259 . " VALUES ($repo_id, 1)";
260 $res = rg_sql_query($db, $sql);
262 . " VALUES ($1, 1)";
263 $res = rg_sql_query_params($db, $sql, $params);
261 264 if ($res === FALSE) { if ($res === FALSE) {
262 265 rg_bug_set_error("cannot insert into max table (" . rg_sql_error() . ")"); rg_bug_set_error("cannot insert into max table (" . rg_sql_error() . ")");
263 266 break; break;
 
... ... function rg_bug_info($db, $repo_id, $bug_id)
358 361 break; break;
359 362 } }
360 363
364 $params = array($repo_id, $bug_id);
361 365 $sql = "SELECT * FROM bugs" $sql = "SELECT * FROM bugs"
362 . " WHERE repo_id = " . $repo_id
363 . " AND bug_id = " . $bug_id;
364 $res = rg_sql_query($db, $sql);
366 . " WHERE repo_id = $1"
367 . " AND bug_id = $2";
368 $res = rg_sql_query_params($db, $sql, $params);
365 369 if ($res === FALSE) { if ($res === FALSE) {
366 370 rg_bug_set_error("cannot list bugs (" . rg_sql_error() . ")"); rg_bug_set_error("cannot list bugs (" . rg_sql_error() . ")");
367 371 break; break;
 
... ... function rg_bug_edit($db, $ri, $login_ui, $data)
396 400
397 401 // TODO: test if user is allowed to add/edit a bug // TODO: test if user is allowed to add/edit a bug
398 402
399 $e_data = $data;
400 $e_data['title'] = rg_sql_escape($db, $data['title']);
401 $e_data['body'] = rg_sql_escape($db, $data['body']);
402 $e_data['state'] = sprintf("%u", $data['state']);
403 $e_data['labels'] = isset($data['labels']) ? rg_sql_escape($db, $data['labels']) : "";
403 $data['labels'] = isset($data['labels']) ? $data['labels'] : "";
404 404
405 405 $itime = time(); $itime = time();
406 406 $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ""; $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "";
 
... ... function rg_bug_edit($db, $ri, $login_ui, $data)
458 458 } }
459 459
460 460 if ($data['bug_id'] == 0) { if ($data['bug_id'] == 0) {
461 $params = array($bug_id, $itime, $ri['repo_id'],
462 $login_ui['uid'], $ip, $data['title'],
463 $data['body'], $data['state'], $assigned_uid);
461 464 $sql = "INSERT INTO bugs (bug_id, itime, utime, repo_id" $sql = "INSERT INTO bugs (bug_id, itime, utime, repo_id"
462 465 . ", uid, ip, title, body, state, assigned_uid" . ", uid, ip, title, body, state, assigned_uid"
463 466 . ", deleted)" . ", 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)";
467 . " VALUES ($1, $2, 0, $3, $4, $5, $6, $7, $8, $9, 0)";
472 468 } else { } 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";
469 $params = array($itime, $data['title'], $data['body'],
470 $data['state'], $assigned_uid, $ri['repo_id'],
471 $bug_id);
472 $sql = "UPDATE bugs SET utime = $1"
473 . ", title = $2"
474 . ", body = $3"
475 . ", state = $4"
476 . ", assigned_uid = $5"
477 . " WHERE repo_id = $6"
478 . " AND bug_id = $7";
480 479 } }
481 $res = rg_sql_query($db, $sql);
480 $res = rg_sql_query_params($db, $sql, $params);
482 481 if ($res === FALSE) { if ($res === FALSE) {
483 482 rg_bug_set_error("cannot insert bug (" . rg_sql_error() . ")"); rg_bug_set_error("cannot insert bug (" . rg_sql_error() . ")");
484 483 break; break;
 
... ... function rg_bug_delete($db, $repo_id, $bug_id)
553 552 $now = time(); $now = time();
554 553
555 554 // Only mark it as such, deletion will happen in background // Only mark it as such, deletion will happen in background
556 $sql = "UPDATE bugs SET deleted = $now"
557 . " WHERE repo_id = $repo_id"
558 . " AND bug_id = $bug_id";
559 $res = rg_sql_query($db, $sql);
555 $params = array($now, $repo_id, $bug_id);
556 $sql = "UPDATE bugs SET deleted = $1"
557 . " WHERE repo_id = $2"
558 . " AND bug_id = $3";
559 $res = rg_sql_query_params($db, $sql, $params);
560 560 if ($res === FALSE) { if ($res === FALSE) {
561 561 rg_bug_set_error("Cannot delete bug (" . rg_sql_error() . ")"); rg_bug_set_error("Cannot delete bug (" . rg_sql_error() . ")");
562 562 break; break;
 
... ... function rg_bug_delete($db, $repo_id, $bug_id)
572 572 /* /*
573 573 * List bugs * List bugs
574 574 */ */
575 function rg_bug_list_query($db, $sql)
575 function rg_bug_list_query($db, $sql, $params)
576 576 { {
577 577 rg_prof_start("bug_list_query"); rg_prof_start("bug_list_query");
578 578 rg_log("bug_list_query: sql=$sql..."); rg_log("bug_list_query: sql=$sql...");
579 579
580 580 $ret = FALSE; $ret = FALSE;
581 581 do { do {
582 $res = rg_sql_query($db, $sql);
582 $res = rg_sql_query_params($db, $sql, $params);
583 583 if ($res === FALSE) { if ($res === FALSE) {
584 584 rg_bug_set_error("cannot list by query (" . rg_sql_error() . ")"); rg_bug_set_error("cannot list by query (" . rg_sql_error() . ")");
585 585 break; break;
 
... ... function rg_bug_search_load_all($db, $repo_id, $uid)
608 608
609 609 $ret = FALSE; $ret = FALSE;
610 610 do { do {
611 $params = array($repo_id, $uid);
611 612 $sql = "SELECT name FROM bug_search" $sql = "SELECT name FROM bug_search"
612 . " WHERE (repo_id = $repo_id OR repo_id = 0)"
613 . " AND uid = $uid"
613 . " WHERE (repo_id = $1 OR repo_id = 0)"
614 . " AND uid = $2"
614 615 . " ORDER BY repo_id, name"; . " ORDER BY repo_id, name";
615 $res = rg_sql_query($db, $sql);
616 $res = rg_sql_query_params($db, $sql, $params);
616 617 if ($res === FALSE) { if ($res === FALSE) {
617 618 rg_bug_set_error("cannot load searches (" . rg_sql_error() . ")"); rg_bug_set_error("cannot load searches (" . rg_sql_error() . ")");
618 619 break; break;
 
... ... function rg_bug_search_load($db, $repo_id, $uid, $name)
682 683 break; break;
683 684 } }
684 685
685 $e_name = rg_sql_escape($db, $name);
686
686 $params = array($repo_id, $uid, $name);
687 687 $sql = "SELECT uid, name, data, for_all_users" $sql = "SELECT uid, name, data, for_all_users"
688 688 . " FROM bug_search" . " FROM bug_search"
689 . " WHERE (repo_id = $repo_id OR repo_id = 0)"
690 . " AND (uid = $uid OR for_all_users = 1)"
691 . " AND name = '$e_name'"
689 . " WHERE (repo_id = $1 OR repo_id = 0)"
690 . " AND (uid = $2 OR for_all_users = 1)"
691 . " AND name = $3"
692 692 . " ORDER BY name"; . " ORDER BY name";
693 $res = rg_sql_query($db, $sql);
693 $res = rg_sql_query_params($db, $sql, $params);
694 694 if ($res === FALSE) { if ($res === FALSE) {
695 695 rg_bug_set_error("cannot search load (" . rg_sql_error() . ")"); rg_bug_set_error("cannot search load (" . rg_sql_error() . ")");
696 696 break; break;
 
... ... function rg_bug_search_save($db, $repo_id, $uid, $q)
739 739 if ($old === FALSE) if ($old === FALSE)
740 740 break; break;
741 741
742 $s = serialize($q);
743 $e_data = rg_sql_escape($db, $s);
744 $e_name = rg_sql_escape($db, $name);
742 $data = serialize($q);
745 743
746 744 // Global? // Global?
747 745 if (isset($q['global']) && (strcmp($q['global'], "on") == 0)) if (isset($q['global']) && (strcmp($q['global'], "on") == 0))
748 $e_repo_id = 0;
746 $repo_id = 0;
749 747 else else
750 $e_repo_id = $repo_id;
748 $repo_id = $repo_id;
751 749
752 750 if (isset($q['for_all_users']) && (strcmp($q['for_all_users'], "on") == 0)) if (isset($q['for_all_users']) && (strcmp($q['for_all_users'], "on") == 0))
753 $e_for_all_users = 1;
751 $for_all_users = 1;
754 752 else else
755 $e_for_all_users = 0;
753 $for_all_users = 0;
756 754
757 755 // We will not overwrite somebody else's search // We will not overwrite somebody else's search
756 // TODO: race?
758 757 rg_log("DEBUG: old: " . rg_array2string($old)); rg_log("DEBUG: old: " . rg_array2string($old));
759 758 if (empty($old) || ($old['uid'] != $uid)) { if (empty($old) || ($old['uid'] != $uid)) {
759 $params = array($repo_id, $uid, $name, $data, $for_all_users);
760 760 $sql = "INSERT INTO bug_search (repo_id, uid, name" $sql = "INSERT INTO bug_search (repo_id, uid, name"
761 761 . ", data, for_all_users)" . ", data, for_all_users)"
762 . " VALUES ($e_repo_id, $uid, '$e_name'"
763 . ", '$e_data', $e_for_all_users)";
762 . " VALUES ($1, $2, $3, $4, $5)";
764 763 } else { } else {
764 $params = array($data, $for_all_users, $repo_id, $uid, $name);
765 765 $sql = "UPDATE bug_search" $sql = "UPDATE bug_search"
766 . " SET data = '$e_data'"
767 . ", for_all_users = $e_for_all_users"
768 . " WHERE repo_id = $e_repo_id"
769 . " AND uid = $uid"
770 . " AND name = '$e_name'";
766 . " SET data = $1"
767 . ", for_all_users = $2"
768 . " WHERE repo_id = $3"
769 . " AND uid = $4"
770 . " AND name = $5";
771 771 } }
772 $res = rg_sql_query($db, $sql);
772 $res = rg_sql_query_params($db, $sql, $params);
773 773 if ($res === FALSE) { if ($res === FALSE) {
774 774 rg_bug_set_error("cannot save search (" . rg_sql_error() . ")"); rg_bug_set_error("cannot save search (" . rg_sql_error() . ")");
775 775 break; break;
 
... ... function rg_bug_search($db, $repo_id, $uid, $q)
802 802 rg_bug_set_error("cannot lookup user (reported_by)"); rg_bug_set_error("cannot lookup user (reported_by)");
803 803 break; break;
804 804 } }
805 $add[] = "uid = " . $_ui['uid'];
805 $add[] = "AND uid = " . $_ui['uid'];
806 806 } }
807 807
808 808 // assigned to // assigned to
 
... ... function rg_bug_search($db, $repo_id, $uid, $q)
862 862 break; break;
863 863 } }
864 864
865 $params = array($repo_id);
865 866 $sql = "SELECT * FROM bugs" $sql = "SELECT * FROM bugs"
866 . " WHERE repo_id = $repo_id"
867 . " WHERE repo_id = $1"
867 868 . " AND deleted = 0" . " AND deleted = 0"
868 869 . " " . implode(" ", $add) . " " . implode(" ", $add)
869 870 . " ORDER BY itime" . " ORDER BY itime"
 
... ... function rg_bug_search($db, $repo_id, $uid, $q)
871 872
872 873 // TODO: order // TODO: order
873 874
874 $ret = rg_bug_list_query($db, $sql);
875 $ret = rg_bug_list_query($db, $sql, $params);
875 876 if ($ret === FALSE) if ($ret === FALSE)
876 877 break; break;
877 878 } while (0); } while (0);
 
... ... function rg_bug_search_remove($db, $repo_id, $uid, $name)
891 892
892 893 $ret = FALSE; $ret = FALSE;
893 894 do { do {
894 $e_name = rg_sql_escape($db, $name);
895
895 $params = array($repo_id, $uid, $name);
896 896 $sql = "DELETE FROM bug_search" $sql = "DELETE FROM bug_search"
897 . " WHERE repo_id = $repo_id"
898 . " AND uid = $uid"
899 . " AND name = '$e_name'";
900 $res = rg_sql_query($db, $sql);
897 . " WHERE repo_id = $1"
898 . " AND uid = $2"
899 . " AND name = $3";
900 $res = rg_sql_query_params($db, $sql, $params);
901 901 if ($res === FALSE) { if ($res === FALSE) {
902 902 rg_bug_set_error("cannot remove search (" . rg_sql_error() . ")"); rg_bug_set_error("cannot remove search (" . rg_sql_error() . ")");
903 903 break; break;
 
... ... function rg_bug_note_add($db, $repo_id, $bug_id, $login_uid, $data)
925 925 do { do {
926 926 // TODO: test if user is allowed to add a note // TODO: test if user is allowed to add a note
927 927
928 $e_data = $data;
929 $e_data['note'] = rg_sql_escape($db, trim($data['note']));
930
931 928 $itime = time(); $itime = time();
932 929 $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "?"; $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "?";
933 930
931 $params = array($repo_id, $bug_id, $itime, $login_uid, $ip,
932 $data['note']);
934 933 $sql = "INSERT INTO bug_notes (repo_id, bug_id, itime, uid, ip" $sql = "INSERT INTO bug_notes (repo_id, bug_id, itime, uid, ip"
935 934 . ", note)" . ", note)"
936 . " VALUES ($repo_id, $bug_id, $itime, $login_uid, '$ip'"
937 . ", '" . $e_data['note'] . "')";
938 $res = rg_sql_query($db, $sql);
935 . " VALUES ($1, $2, $3, $4, $5, $6)";
936 $res = rg_sql_query_params($db, $sql, $params);
939 937 if ($res === FALSE) { if ($res === FALSE) {
940 938 rg_bug_set_error("Cannot insert bug note (" . rg_sql_error() . ")"); rg_bug_set_error("Cannot insert bug note (" . rg_sql_error() . ")");
941 939 break; break;
 
... ... function rg_bug_note_add($db, $repo_id, $bug_id, $login_uid, $data)
948 946 . " (" . rg_repo_error() . ")"); . " (" . rg_repo_error() . ")");
949 947 break; break;
950 948 } }
949 rg_log_ml("_ri: " . print_r($_ri, TRUE));
951 950
952 951 $_bi = rg_bug_info($db, $repo_id, $bug_id); $_bi = rg_bug_info($db, $repo_id, $bug_id);
953 952 if ($_bi === FALSE) if ($_bi === FALSE)
 
... ... function rg_bug_note_list($db, $repo_id, $bug_id, $offset)
996 995 do { do {
997 996 // TODO: test if user is allowed to see a note // TODO: test if user is allowed to see a note
998 997
998 $params = array($repo_id, $bug_id);
999 999 $sql = "SELECT * FROM bug_notes" $sql = "SELECT * FROM bug_notes"
1000 . " WHERE repo_id = $repo_id"
1001 . " AND bug_id = $bug_id"
1000 . " WHERE repo_id = $1"
1001 . " AND bug_id = $2"
1002 1002 . " ORDER BY itime" . " ORDER BY itime"
1003 1003 . " OFFSET $offset"; . " OFFSET $offset";
1004 $res = rg_sql_query($db, $sql);
1004 $res = rg_sql_query_params($db, $sql, $params);
1005 1005 if ($res === FALSE) { if ($res === FALSE) {
1006 1006 rg_bug_set_error("Cannot select bug notes (" . rg_sql_error() . ")"); rg_bug_set_error("Cannot select bug notes (" . rg_sql_error() . ")");
1007 1007 break; break;
 
... ... function rg_bug_label_get($db, $repo_id, $bug_id)
1090 1090
1091 1091 $ret = FALSE; $ret = FALSE;
1092 1092 do { do {
1093 $params = array($repo_id, $bug_id);
1093 1094 $sql = "SELECT DISTINCT label FROM bug_labels" $sql = "SELECT DISTINCT label FROM bug_labels"
1094 . " WHERE repo_id = $repo_id"
1095 . " AND bug_id = $bug_id"
1095 . " WHERE repo_id = $1"
1096 . " AND bug_id = $2"
1096 1097 . " ORDER BY label"; . " ORDER BY label";
1097 $res = rg_sql_query($db, $sql);
1098 $res = rg_sql_query_params($db, $sql, $params);
1098 1099 if ($res === FALSE) { if ($res === FALSE) {
1099 1100 rg_bug_set_error("Cannot select labels (" . rg_sql_error() . ")"); rg_bug_set_error("Cannot select labels (" . rg_sql_error() . ")");
1100 1101 break; break;
 
... ... function rg_bug_label_insert($db, $repo_id, $bug_id, $labels)
1138 1139 break; break;
1139 1140 } }
1140 1141
1142 // TODO: switch to params
1141 1143 $list = array(); $list = array();
1142 1144 foreach ($diff as $label) { foreach ($diff as $label) {
1143 1145 $e_label = rg_sql_escape($db, $label); $e_label = rg_sql_escape($db, $label);
1144 1146 $list[] = "($repo_id, $bug_id, '$e_label')"; $list[] = "($repo_id, $bug_id, '$e_label')";
1145 1147 } }
1146 1148 $sql = "INSERT INTO bug_labels (repo_id, bug_id, label)" $sql = "INSERT INTO bug_labels (repo_id, bug_id, label)"
1147 . " VALUES " . implode(",", $list);
1149 . " VALUES " . implode(", ", $list);
1148 1150 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
1149 1151 if ($res === FALSE) { if ($res === FALSE) {
1150 1152 rg_bug_set_error("Cannot insert labels (" . rg_sql_error() . ")"); rg_bug_set_error("Cannot insert labels (" . rg_sql_error() . ")");
File inc/cache.inc.php changed (mode: 100644) (index 9625809..3bbeb44)
1 1 <?php <?php
2 2 // //
3 // This functions are used for background tasks: the tasks that the user should
4 // not wait to happen in the browser: e-mails, keyring regeneration etc.
3 // memcache alike daemon
5 4 // //
6 5 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
7 require_once($INC . "/log.inc.php");
8 6 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
9 7 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
10 8
9 // Client side can disable the cache for various reasons (unit testing etc.)
10 $rg_cache_enable = TRUE;
11
11 12 // timeout in miliseconds // timeout in miliseconds
12 13 $rg_cache_timeout = 100; $rg_cache_timeout = 100;
13 14
 
... ... function rg_cache_set_error($str)
24 25 { {
25 26 global $rg_cache_error; global $rg_cache_error;
26 27 $rg_cache_error = $str; $rg_cache_error = $str;
27 rg_log($str);
28 28 } }
29 29
30 30 function rg_cache_error() function rg_cache_error()
 
... ... function rg_cache_server_dump()
40 40 { {
41 41 global $rg_cache; global $rg_cache;
42 42
43 rg_log_ml("rg_cache:\n" . print_r($rg_cache, TRUE));
43 return "rg_cache:\n" . print_r($rg_cache, TRUE);
44 44 } }
45 45
46 46 /* /*
47 * Returns the pointer to a tree
47 * Sets a variable
48 48 * TODO: Prevent cache to grow and grow. * TODO: Prevent cache to grow and grow.
49 49 */ */
50 50 function rg_cache_server_set($ns_var, $value) function rg_cache_server_set($ns_var, $value)
 
... ... function rg_cache_server_set($ns_var, $value)
64 64 $tree[$var] = $value; $tree[$var] = $value;
65 65 } }
66 66
67 /*
68 * Increments a variable
69 */
70 function rg_cache_server_inc($ns_var)
71 {
72 global $rg_cache;
73
74 $tree = &$rg_cache;
75 $t = explode("::", $ns_var);
76 $var = array_pop($t);
77 foreach ($t as $token) {
78 if (!isset($tree[$token]))
79 $tree[$token] = array();
80
81 $tree = &$tree[$token];
82 }
83
84 if (!isset($tree[$var]))
85 $ret = 1;
86 else
87 $ret = $tree[$var] + 1;
88
89 $tree[$var] = $ret;
90
91 return $ret;
92 }
93
67 94 /* /*
68 95 * Retrieve a variable from cache * Retrieve a variable from cache
69 96 */ */
 
... ... function rg_cache_get($ns_var)
228 255 global $rg_cache_socket; global $rg_cache_socket;
229 256 global $rg_cache_timeout; global $rg_cache_timeout;
230 257 global $rg_cache_local; global $rg_cache_local;
258 global $rg_cache_enable;
259
260 if ($rg_cache_enable === FALSE)
261 return FALSE;
231 262
232 263 rg_prof_start("cache_get"); rg_prof_start("cache_get");
233 264
 
... ... function rg_cache_set($ns_var, $value)
266 297 global $rg_cache_socket; global $rg_cache_socket;
267 298 global $rg_cache_timeout; global $rg_cache_timeout;
268 299 global $rg_cache_local; global $rg_cache_local;
300 global $rg_cache_enable;
301
302 if ($rg_cache_enable === FALSE)
303 return FALSE;
269 304
270 305 rg_prof_start("cache_set"); rg_prof_start("cache_set");
271 306
 
... ... function rg_cache_set($ns_var, $value)
287 322 return $ret; return $ret;
288 323 } }
289 324
325 /*
326 * Increments a variable in the cache daemon
327 */
328 function rg_cache_inc($ns_var)
329 {
330 global $rg_cache_socket;
331 global $rg_cache_timeout;
332 global $rg_cache_local;
333 global $rg_cache_enable;
334
335 if ($rg_cache_enable === FALSE)
336 return FALSE;
337
338 rg_prof_start("cache_inc");
339
340 $ret = FALSE;
341 do {
342 $c = rg_socket($rg_cache_socket,
343 "INC " . $ns_var . "\n", $rg_cache_timeout);
344 if ($c === FALSE)
345 break;
346
347 if (strncmp($c, "OK", 2) != 0)
348 break;
349
350 $v = strstr($c, " v=");
351 if ($v === FALSE)
352 break;
353
354 $ret = intval($v);
355 } while (0);
356
357 rg_prof_end("cache_inc");
358 return $ret;
359 }
360
290 361 /* /*
291 362 * Unsets a variable in the cache daemon * Unsets a variable in the cache daemon
292 363 */ */
 
... ... function rg_cache_unset($ns_var)
295 366 global $rg_cache_socket; global $rg_cache_socket;
296 367 global $rg_cache_timeout; global $rg_cache_timeout;
297 368 global $rg_cache_local; global $rg_cache_local;
369 global $rg_cache_enable;
370
371 if ($rg_cache_enable === FALSE)
372 return FALSE;
298 373
299 374 rg_prof_start("cache_unset"); rg_prof_start("cache_unset");
300 375
File inc/dispatch/dispatch.php changed (mode: 100644) (index cf1a781..cc670b5)
... ... case 'forgot_send': // forgot pass - send mail
41 41 break; break;
42 42
43 43 case 'create_account': case 'create_account':
44 include($INC . "/user/create.php");
45 $body .= $_create;
44 $more['ask_for_pass'] = 1;
45 $body .= rg_user_edit_high_level($db, $sid, $more);
46 46 break; break;
47 47
48 48 case 'confirm': case 'confirm':
File inc/events.inc.php changed (mode: 100644) (index 9a17fef..a334332)
... ... function rg_event_register_functions($functions)
48 48
49 49 /* /*
50 50 * Signals the daemon that there is some work to do * Signals the daemon that there is some work to do
51 * if @event_id > 0, we will wait for the finish of the event
51 * @timeout == NULL, do not wait, 0 = wait forever, else, wait @timeout miliseconds.
52 52 */ */
53 53 function rg_event_signal_daemon($ev_id, $timeout) function rg_event_signal_daemon($ev_id, $timeout)
54 54 { {
55 55 global $rg_event_socket; global $rg_event_socket;
56 56
57 rg_prof_start("event_signal_daemon");
58 rg_log("event_signal_daemon: event_id=[$ev_id] timeout=$timeout");
59
60 $ret = FALSE;
61 do {
62 $socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
63 if ($socket === FALSE) {
64 rg_log("Could not create socket!");
65 break;
66 }
67
68 // try 3 times
69 $tries = 3;
70 while ($tries > 0) {
71 $r = socket_connect($socket, $rg_event_socket);
72 if ($r === FALSE) {
73 $tries--;
74 usleep(200000);
75 continue;
76 }
57 if (empty($rg_event_socket))
58 return TRUE;
77 59
78 break;
79 }
80 if ($r === FALSE) {
81 rg_log("Could not connect the socket!");
82 break;
83 }
84
85 if (empty($ev_id))
86 $buf = "W";
87 else
88 $buf = "NOTIFY " . $ev_id;
89 $len = strlen($buf);
90 $r = socket_send($socket, $buf, $len, 0);
91 if ($r !== $len) {
92 rg_log("Could not send!");
93 break;
94 }
95
96 if (empty($ev_id)) {
97 rg_log("We do not have to wait. Exit.");
98 $ret = TRUE;
99 socket_close($socket);
100 break;
101 }
102
103 $reads = array($socket); $writes = array(); $ex = array();
104 $r = socket_select($reads, $writes, $ex, $timeout, 0);
105 if ($r === FALSE) {
106 rg_log("Cannot select!");
107 socket_close($socket);
108 break;
109 }
110
111 if ($r === 0) { // timeout
112 rg_log("Timeout!");
113 socket_close($socket);
114 break;
115 }
116
117 if (!in_array($socket, $reads)) {
118 rg_log("Select returned > 0 and my socket is not in reads");
119 socket_close($socket);
120 break;
121 }
60 rg_prof_start("event_signal_daemon");
61 rg_log("event_signal_daemon: event_id=[$ev_id] timeout=" . $timeout . "ms");
122 62
123 $r = socket_recv($socket, $buf, 1024, 0);
124 if ($r === FALSE) {
125 rg_log("Cannot receive!");
126 break;
127 }
128 rg_log("Received [$buf]");
63 if (empty($ev_id))
64 $buf = "W";
65 else
66 $buf = "NOTIFY " . $ev_id;
129 67
130 socket_close($socket);
131 $ret = TRUE;
132 } while (0);
133
134 return $ret;
68 return rg_socket($rg_event_socket, $buf, $timeout);
135 69 } }
136 70
137 71 /* /*
 
... ... function rg_event_add($db, $event)
146 80 $ret = FALSE; $ret = FALSE;
147 81 do { do {
148 82 $now = time(); $now = time();
149 $prio = $event['prio'];
150 $e_data = rg_sql_escape($db, serialize($event));
83 $prio = $event['prio']; unset($event['prio']);
84 $params = array($now, $prio, serialize($event));
151 85 $sql = "INSERT INTO events (itime, prio, data)" $sql = "INSERT INTO events (itime, prio, data)"
152 . " VALUES ($now, $prio, '$e_data')";
153 $res = rg_sql_query($db, $sql);
86 . " VALUES ($1, $2, $3)";
87 $res = rg_sql_query_params($db, $sql, $params);
154 88 if ($res === FALSE) { if ($res === FALSE) {
155 89 rg_event_set_error("Could not add event (" . rg_sql_error() . ")"); rg_event_set_error("Could not add event (" . rg_sql_error() . ")");
156 90 break; break;
157 91 } }
158 92 rg_sql_free_result($res); rg_sql_free_result($res);
159 93
160 rg_event_signal_daemon("", 0);
94 rg_event_signal_daemon("", NULL);
161 95
162 96 $ret = TRUE; $ret = TRUE;
163 97 } while (0); } while (0);
 
... ... function rg_event_notify_clean(&$notify_list)
246 180 /* /*
247 181 * Tries to notify a client if requested * Tries to notify a client if requested
248 182 */ */
249 function rg_event_notify(&$notify_list, $ev_id)
183 function rg_event_notify(&$notify_list, $ev_id, $misc)
250 184 { {
251 185 if (!isset($notify_list[$ev_id])) if (!isset($notify_list[$ev_id]))
252 186 return; return;
253 187
254 $buf = "DONE $ev_id\n";
188 $buf = "DONE $ev_id\n" . $misc;
255 189 $buf_len = strlen($buf); $buf_len = strlen($buf);
256 190 foreach ($notify_list[$ev_id] as $index => $info) { foreach ($notify_list[$ev_id] as $index => $info) {
257 191 $fd = $info['fd']; $fd = $info['fd'];
258 192 rg_log("\tNotify [$ev_id] [fd=$fd]..."); rg_log("\tNotify [$ev_id] [fd=$fd]...");
259 socket_send($fd, $buf, $buf_len, 0);
193 $r = @socket_send($fd, $buf, $buf_len, 0);
194 if ($r === FALSE)
195 rg_log("Error in sending.");
260 196 socket_shutdown($fd, 1); socket_shutdown($fd, 1);
261 197 } }
262 198
 
... ... function rg_event_process_queue($db, &$notify_list)
306 242 rg_internal_error("Cannot unserialize data"); rg_internal_error("Cannot unserialize data");
307 243 break; break;
308 244 } }
245 $ev['prio'] = $row['prio'];
246 $ev['itime'] = $row['itime'];
247
309 248 $r = rg_event_process($db, $ev); $r = rg_event_process($db, $ev);
310 249 if ($r !== TRUE) { if ($r !== TRUE) {
311 250 $all_good = FALSE; $all_good = FALSE;
 
... ... function rg_event_process_queue($db, &$notify_list)
313 252 } }
314 253
315 254 if (isset($ev['notification'])) if (isset($ev['notification']))
316 rg_event_notify($notify_list, $ev['notification']);
255 rg_event_notify($notify_list, $ev['notification'], "");
317 256
318 $sql = "DELETE FROM events WHERE id = " . $row['id'];
319 $res2 = rg_sql_query($db, $sql);
257 $params = array($row['id']);
258 $sql = "DELETE FROM events WHERE id = $1";
259 $res2 = rg_sql_query_params($db, $sql, $params);
320 260 rg_sql_free_result($res2); rg_sql_free_result($res2);
321 261 } }
322 262 rg_sql_free_result($res); rg_sql_free_result($res);
File inc/feedback/suggestion.php changed (mode: 100644) (index 7b73329..c77d9f1)
... ... $_suggestion = "";
7 7 $errmsg = array(); $errmsg = array();
8 8 $show_form = 1; $show_form = 1;
9 9
10 if ($doit == 1) {
10 do {
11 if ($doit != 1) {
12 // defaults
13 $suggestion = "";
14 break;
15 }
16
11 17 $suggestion = rg_var_str("suggestion"); $suggestion = rg_var_str("suggestion");
12 18
13 do {
14 if (!rg_token_valid($db, $sid, $token)) {
15 $errmsg[] = "invalid token; try again";
16 break;
17 }
18
19 if (empty($suggestion)) {
20 $errmsg[] = "empty suggestion";
21 break;
22 }
23
24 $r = rg_user_suggestion($db, $login_ui['uid'], $suggestion);
25 if ($r === FALSE) {
26 $errmsg[] = "could not add suggestion (" . rg_user_error() . ")!";
27 break;
28 }
29
30 $show_form = 0;
31 $_suggestion .= "Thank you very much!";
32 } while (0);
33 } else {
34 // defaults for form
35 $suggestion = "";
36 }
19 if (!rg_token_valid($db, $sid, $token)) {
20 $errmsg[] = "invalid token; try again";
21 break;
22 }
23
24 if (empty($suggestion)) {
25 $errmsg[] = "empty suggestion";
26 break;
27 }
28
29 $r = rg_user_suggestion($db, $login_ui['uid'], $suggestion);
30 if ($r === FALSE) {
31 $errmsg[] = "could not add suggestion (" . rg_user_error() . ")!";
32 break;
33 }
34
35 $show_form = 0;
36 $_suggestion .= "Thank you very much!";
37 } while (0);
37 38
38 39 if ($show_form == 1) { if ($show_form == 1) {
39 40 $suggestion_more['suggestion'] = $suggestion; $suggestion_more['suggestion'] = $suggestion;
 
... ... if ($show_form == 1) {
43 44 } }
44 45
45 46 ?> ?>
46
File inc/fixes.inc.php changed (mode: 100644) (index 1b70d8b..6e3f8f8)
1 1 <?php <?php
2 2 // //
3 3 // This is a set of fixes that must be applied when the software is upgraded. // This is a set of fixes that must be applied when the software is upgraded.
4 // If the structure of authorized_keys may change, we must add a fix to mark
5 // the stat dirty.
4 // If the structure of authorized_keys may change, we must add a fix to
5 // regenerate the keys.
6 6 // //
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 10 include_once($INC . "/user.inc.php"); include_once($INC . "/user.inc.php");
11 11 include_once($INC . "/repo.inc.php"); include_once($INC . "/repo.inc.php");
12 include_once($INC . "/keys.inc.php");
12 13
13 14 $rg_fixes = array(); $rg_fixes = array();
14 15 $rg_fixes[1] = array("rg_fixes_user_index_by_id"); $rg_fixes[1] = array("rg_fixes_user_index_by_id");
15 16 $rg_fixes[2] = array("rg_fixes_repo_index_by_id"); $rg_fixes[2] = array("rg_fixes_repo_index_by_id");
17 $rg_fixes[3] = array("rg_fixes_keys_regen");
16 18
17 19 // This must be the last line // This must be the last line
18 20 $rg_fixes_ver = count($rg_fixes); $rg_fixes_ver = count($rg_fixes);
19 21
22 /*
23 * Just regenerate the keys
24 */
25 function rg_fixes_keys_regen($db)
26 {
27 rg_log("fixes_keys_regen");
28 $ret = rg_keys_regen($db);
29 if ($ret === FALSE) {
30 rg_log("Could not regenerate keys: " . rg_keys_error() . "!");
31 }
32
33 return $ret;
34 }
35
20 36 /* /*
21 37 * Fix one repo (make the names as relative links to ids) * Fix one repo (make the names as relative links to ids)
22 38 */ */
23 39 function rg_fixes_repo_index_by_id_one($uid, $repo_id, $repo_name) function rg_fixes_repo_index_by_id_one($uid, $repo_id, $repo_name)
24 40 { {
25 rg_log("Fix repo path: uid=$uid repo_id=$repo_id repo_name=$repo_name");
41 rg_log("fixes_repo_index_by_id_one:"
42 . " uid=$uid repo_id=$repo_id repo_name=$repo_name");
26 43
27 44 $ret = FALSE; $ret = FALSE;
28 45 do { do {
 
... ... function rg_fixes_run($db, $old_ver)
240 257 } }
241 258
242 259 /* /*
243 * Tests if fixes are needed. Return old version
260 * Tests if fixes are needed.
261 * Returns old version or FALSE if fixes are not needed.
244 262 */ */
245 263 function rg_fixes_needed($db) function rg_fixes_needed($db)
246 264 { {
File inc/git.inc.php changed (mode: 100644) (index e0261f2..602e361)
... ... $rg_git_error = "";
11 11 function rg_git_set_error($str) function rg_git_set_error($str)
12 12 { {
13 13 global $rg_git_error; global $rg_git_error;
14
15 rg_log($str);
14 16 $rg_git_error = $str; $rg_git_error = $str;
15 17 } }
16 18
 
... ... function rg_git_install_hooks($dst)
71 73
72 74 } }
73 75
74 rg_log("\tRemoving wrong hooks dir...");
76 rg_log("\tRemoving original hooks dir...");
75 77 if (!rg_rmdir($dst . "/hooks")) { if (!rg_rmdir($dst . "/hooks")) {
76 78 rg_git_set_error("cannot remove hooks dir" rg_git_set_error("cannot remove hooks dir"
77 79 . " (" . rg_util_error() . ")"); . " (" . rg_util_error() . ")");
File inc/keys.inc.php changed (mode: 100644) (index 6265587..8636b86)
... ... function rg_keys_error()
24 24 $rg_keys_functions = array( $rg_keys_functions = array(
25 25 1000 => "rg_keys_event_new", 1000 => "rg_keys_event_new",
26 26 1001 => "rg_keys_event_del", 1001 => "rg_keys_event_del",
27 1002 => "rg_keys_event_mark_dirty",
27 1002 => "rg_keys_event_regen",
28 28 1003 => "rg_keys_event_notify_user" 1003 => "rg_keys_event_notify_user"
29 29 ); );
30 30 rg_event_register_functions($rg_keys_functions); rg_event_register_functions($rg_keys_functions);
 
... ... function rg_keys_event_del($db, $event)
61 61 } }
62 62
63 63 /* /*
64 * Notify user that a new key was added/deleted to/from the keyring
65 * TODO: Do not mark keys dirty from another place in this file
64 * Regenrate keyring.
65 * We ignore requests that were inserted in queue after we already
66 * regenerated the keys.
67 * We must regenerate now to not let the user wait too much.
68 * TODO: When we will have support in sshd for key lookup, we will not need to regenerate.
66 69 */ */
67 function rg_keys_event_mark_dirty($db, $event)
70 function rg_keys_event_regen($db, $event)
68 71 { {
69 $r = rg_keys_mark_dirty($db);
70 if ($r === FALSE)
71 return FALSE;
72 rg_log("keys_event_regen");
73
74 $last = rg_cache_get("key::last_regen_time");
75 if ($last === FALSE)
76 $last = 0;
77
78 if ($event['itime'] < $last) {
79 rg_log("DEBUG: event itime(" . $event['itime'] . ") < last($last)."
80 . " Skip regeneration of keys.");
81 } else {
82 $r = rg_keys_regen($db);
83 if ($r === FALSE)
84 return FALSE;
85 }
72 86
73 87 return array(); return array();
74 88 } }
 
... ... function rg_keys_event_notify_user($db, $event)
84 98 // TODO: load info about the keys and put the fingerprint in e-mail // TODO: load info about the keys and put the fingerprint in e-mail
85 99 // TODO: Maybe put also the body in the e-mail, so it can be re-uploaded. // TODO: Maybe put also the body in the e-mail, so it can be re-uploaded.
86 100 // TODO: Maybe add also the statistics. // TODO: Maybe add also the statistics.
101 // TODO: Do not forget that here we have a list
102 // TODO: Take care: we already deleted the keys. We cannot inspect
103 // them anymore! Maybe put info in the event.
87 104
88 105 $r = rg_mail("mail/user/key/" . $event['op'], $event); $r = rg_mail("mail/user/key/" . $event['op'], $event);
89 106 if ($r === FALSE) if ($r === FALSE)
 
... ... function rg_keys_info($key)
115 132 } }
116 133
117 134 $ret['type'] = $t[0]; $ret['type'] = $t[0];
118 $ret['key'] = isset($t[1]) ? $t[1] : "";
135 $ret['key'] = $t[1];
119 136 $ret['comment'] = isset($t[2]) ? $t[2] : ""; $ret['comment'] = isset($t[2]) ? $t[2] : "";
120 137
121 138 $d = base64_decode($ret['key']); $d = base64_decode($ret['key']);
 
... ... function rg_keys_info($key)
128 145 $a = array(); $a = array();
129 146 for ($i = 0; $i < 16; $i++) for ($i = 0; $i < 16; $i++)
130 147 $a[] = substr($digest, $i * 2, 2); $a[] = substr($digest, $i * 2, 2);
131
132 148 $ret['fingerprint'] = implode(":", $a); $ret['fingerprint'] = implode(":", $a);
133 149
134 150 $ret['ok'] = 1; $ret['ok'] = 1;
 
... ... function rg_keys_info($key)
139 155 } }
140 156
141 157 /* /*
142 * Mark state as dirty
143 */
144 function rg_keys_mark_dirty($db)
145 {
146 rg_prof_start("keys_mark_dirty");
147
148 $ret = TRUE;
149 if (rg_state_set($db, "authorized_keys", 1) === FALSE) {
150 rg_keys_set_error("cannot make state dirty (" . rg_state_error() . ")!");
151 $ret = FALSE;
152 }
153
154 rg_prof_end("keys_mark_dirty");
155 return $ret;
156 }
157
158 /*
159 * Remove a key from database for user 'ui'
160 * TODO: Remove "multi" function and make this accepts an array of keys.
161 * TODO: Here we must have a transaction!
158 * Remove keys from database for user 'ui'
162 159 */ */
163 function rg_keys_remove($db, $ui, $key_id, $flags)
160 function rg_keys_remove($db, $ui, $list)
164 161 { {
165 162 rg_prof_start("keys_remove"); rg_prof_start("keys_remove");
166 rg_log("keys_remove: key_id=$key_id flags=" . rg_array2string($flags));
163 rg_log("keys_remove: list=" . rg_array2string($list));
167 164
168 165 $ret = FALSE; $ret = FALSE;
169 166 do { do {
170 // Do not move this to caller.
171 // TODO: Do rg_var_array that will enforce index to be numeric?
172 $e_key_id = sprintf("%u", $key_id);
167 $my_list = array();
168 foreach ($list as $key_id => $junk)
169 $my_list[] = sprintf("%u", $key_id);
173 170
171 $params = array($ui['uid']);
172 $sql_list = implode(", ", $my_list);
174 173 $sql = "DELETE FROM keys" $sql = "DELETE FROM keys"
175 . " WHERE uid = " . $ui['uid']
176 . " AND key_id = $e_key_id";
177 $res = rg_sql_query($db, $sql);
174 . " WHERE uid = $1"
175 . " AND key_id IN (" . $sql_list . ")";
176 $res = rg_sql_query_params($db, $sql, $params);
178 177 if ($res === FALSE) { if ($res === FALSE) {
179 rg_keys_set_error("cannot delete key $key_id (" . rg_sql_error() . ")");
178 rg_keys_set_error("cannot delete keys"
179 . " (" . rg_sql_error() . ")");
180 180 break; break;
181 181 } }
182 182 rg_sql_free_result($res); rg_sql_free_result($res);
183 183
184 184 $event = array("category" => 1001, "prio" => 50, $event = array("category" => 1001, "prio" => 50,
185 "email" => $ui['email'],
185 "ui.email" => $ui['email'],
186 186 "IP" => rg_var_str("REMOTE_ADDR"), "IP" => rg_var_str("REMOTE_ADDR"),
187 "key_id" => $key_id);
187 "keys" => implode(",", $my_list));
188 188 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
189 189 if ($r !== TRUE) { if ($r !== TRUE) {
190 190 rg_keys_set_error("cannot add event" rg_keys_set_error("cannot add event"
 
... ... function rg_keys_remove($db, $ui, $key_id, $flags)
199 199 return $ret; return $ret;
200 200 } }
201 201
202 /*
203 * Remove multiple keys from database
204 */
205 function rg_keys_remove_multi($db, $ui, $list)
206 {
207 rg_prof_start("keys_remove_multi");
208 rg_log("keys_remove_multi: list=" . rg_array2string($list));
209
210 $ret = FALSE;
211 do {
212 if (empty($list)) {
213 rg_keys_set_error("no keys provided");
214 break;
215 }
216
217 $flags = array("no_dirty" => 1);
218 foreach ($list as $key_id => $junk) {
219 $r = rg_keys_remove($db, $ui, $key_id, $flags);
220 if ($r !== TRUE)
221 break;
222 }
223
224 if (rg_keys_mark_dirty($db) != TRUE)
225 break;
226
227 $ret = TRUE;
228 } while (0);
229
230 rg_prof_end("keys_remove_multi");
231 return $ret;
232 }
233
234 202 /* /*
235 203 * Count the number of keys per user * Count the number of keys per user
236 204 */ */
 
... ... function rg_keys_count($db, $uid)
240 208
241 209 $ret = FALSE; $ret = FALSE;
242 210 do { do {
243 $sql = "SELECT COUNT(*) AS count FROM keys WHERE uid = $uid";
244 $res = rg_sql_query($db, $sql);
211 $params = array($uid);
212 $sql = "SELECT COUNT(*) AS count FROM keys"
213 . " WHERE uid = $1";
214 $res = rg_sql_query_params($db, $sql, $params);
245 215 if ($res === FALSE) { if ($res === FALSE) {
246 216 rg_keys_set_error("cannot query (" . rg_sql_error() . ")"); rg_keys_set_error("cannot query (" . rg_sql_error() . ")");
247 217 break; break;
 
... ... function rg_keys_count($db, $uid)
259 229 /* /*
260 230 * Add a key * Add a key
261 231 * Returns the key_id of the key. * Returns the key_id of the key.
262 * TODO: Transaction!
263 232 */ */
264 233 function rg_keys_add($db, $ui, $key) function rg_keys_add($db, $ui, $key)
265 234 { {
 
... ... function rg_keys_add($db, $ui, $key)
269 238 rg_log("keys_add: $key=$key"); rg_log("keys_add: $key=$key");
270 239
271 240 $ret = FALSE; $ret = FALSE;
241 $do_rollback = 0;
272 242 do { do {
273 243 $itime = time(); $itime = time();
274 $e_key = rg_sql_escape($db, $key);
275 244
276 245 $ki = rg_keys_info($key); $ki = rg_keys_info($key);
277 246 if ($ki['ok'] != 1) if ($ki['ok'] != 1)
 
... ... function rg_keys_add($db, $ui, $key)
286 255 break; break;
287 256
288 257 if ($no_of_keys >= $rg_max_ssh_keys) { if ($no_of_keys >= $rg_max_ssh_keys) {
289 rg_keys_set_error("too many keys; please delete some");
258 rg_keys_set_error("too many keys"
259 . " (" . $no_of_keys . "); please delete some");
260 break;
261 }
262
263 $r = rg_sql_begin($db);
264 if ($r !== TRUE) {
265 rg_keys_set_error("cannot start transaction"
266 . " (" . rg_sql_error() . ")");
290 267 break; break;
291 268 } }
269 $do_rollback = 1;
292 270
271 $params = array($itime, $ui['uid'], $key);
293 272 $sql = "INSERT INTO keys (itime, uid, key)" $sql = "INSERT INTO keys (itime, uid, key)"
294 . " VALUES ($itime, " . $ui['uid'] . ", '$e_key')"
273 . " VALUES ($1, $2, $3)"
295 274 . " RETURNING key_id"; . " RETURNING key_id";
296 $res = rg_sql_query($db, $sql);
275 $res = rg_sql_query_params($db, $sql, $params);
297 276 if ($res === FALSE) { if ($res === FALSE) {
298 rg_keys_set_error("cannot insert key (" . rg_sql_error() . ")");
277 rg_keys_set_error("cannot insert key"
278 . " (" . rg_sql_error() . ")");
299 279 break; break;
300 280 } }
301 281 $row = rg_sql_fetch_array($res); $row = rg_sql_fetch_array($res);
 
... ... function rg_keys_add($db, $ui, $key)
303 283 rg_sql_free_result($res); rg_sql_free_result($res);
304 284
305 285 $event = array("category" => 1000, "prio" => 50, $event = array("category" => 1000, "prio" => 50,
306 "email" => $ui['email'],
286 "ui.email" => $ui['email'],
307 287 "IP" => rg_var_str("REMOTE_ADDR"), "IP" => rg_var_str("REMOTE_ADDR"),
308 288 "key_id" => $key_id); "key_id" => $key_id);
309 289 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
 
... ... function rg_keys_add($db, $ui, $key)
313 293 break; break;
314 294 } }
315 295
296 $r = rg_sql_commit($db);
297 if ($r !== TRUE) {
298 rg_keys_set_error("cannot commit transaction"
299 . " (" . rg_sql_error() . ")");
300 break;
301 }
302 $do_rollback = 0;
303
316 304 $ret = $key_id; $ret = $key_id;
317 305 } while (0); } while (0);
318 306
307 if ($do_rollback == 1)
308 rg_sql_rollback($db);
309
319 310 rg_prof_end("keys_add"); rg_prof_end("keys_add");
320 311 return $ret; return $ret;
321 312 } }
322 313
323 314 /* /*
324 * Update last_use and last_ip
315 * Update first_use, last_use, last_ip and count
325 316 */ */
326 317 function rg_keys_update_use($db, $key_id, $ip) function rg_keys_update_use($db, $key_id, $ip)
327 318 { {
 
... ... function rg_keys_update_use($db, $key_id, $ip)
332 323 do { do {
333 324 $now = time(); $now = time();
334 325
335 $e_ip = rg_sql_escape($db, $ip);
326 $params = array($now, $key_id);
327 $sql = "UPDATE keys SET first_use = $1"
328 . " WHERE first_use = 0"
329 . " AND key_id = $2";
330 $res = rg_sql_query_params($db, $sql, $params);
331 if ($res === FALSE) {
332 rg_keys_set_error("cannot update key's first use"
333 . " (" . rg_sql_error() . ")");
334 break;
335 }
336 336
337 $sql = "UPDATE keys SET last_use = $now, last_ip = '$e_ip'"
338 . " WHERE key_id = $key_id";
339 $res = rg_sql_query($db, $sql);
337 $params = array($now, $ip, $key_id);
338 $sql = "UPDATE keys SET last_use = $1"
339 . ", last_ip = $2"
340 . ", count = count + 1"
341 . " WHERE key_id = $3";
342 $res = rg_sql_query_params($db, $sql, $params);
340 343 if ($res === FALSE) { if ($res === FALSE) {
341 rg_keys_set_error("cannot update key (" . rg_sql_error() . ")");
344 rg_keys_set_error("cannot update key"
345 . " (" . rg_sql_error() . ")");
342 346 break; break;
343 347 } }
344 348 rg_sql_free_result($res); rg_sql_free_result($res);
 
... ... function rg_keys_regen($db)
360 364
361 365 rg_prof_start("keys_regen"); rg_prof_start("keys_regen");
362 366
367 $now = time();
363 368 $ret = FALSE; $ret = FALSE;
364 369 do { do {
365 $dirty = rg_state_get($db, "authorized_keys");
366 if (!file_exists($rg_keys_file)) {
367 rg_log("Keys file does not exists, force dirty 1.");
368 $dirty = 1;
369 }
370 if ($dirty == 0) {
371 // Skip generation because is not dirty
372 $ret = TRUE;
373 break;
374 }
375
376 370 // create .ssh folder if does not exists // create .ssh folder if does not exists
377 371 $dir = dirname($rg_keys_file); $dir = dirname($rg_keys_file);
378 372 if (!file_exists($dir)) { if (!file_exists($dir)) {
379 373 if (!@mkdir($dir, 0700, TRUE)) { if (!@mkdir($dir, 0700, TRUE)) {
380 rg_keys_set_error("cannot create dir $dir ($php_errormsg)");
374 rg_keys_set_error("cannot create dir [$dir] ($php_errormsg)");
381 375 break; break;
382 376 } }
383 377 } }
 
... ... function rg_keys_regen($db)
395 389 break; break;
396 390 } }
397 391
398 // mark file as clean
399 rg_state_set($db, "authorized_keys", 0);
400
401 $sql = "SELECT key_id, uid, key FROM keys";
392 $sql = "SELECT key_id, uid, key FROM keys ORDER BY count DESC";
402 393 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
403 394 if ($res === FALSE) { if ($res === FALSE) {
404 395 rg_keys_set_error("cannot query (" . rg_sql_error() . ")"); rg_keys_set_error("cannot query (" . rg_sql_error() . ")");
405 396 break; break;
406 397 } }
398 $errors = 0;
407 399 while (($row = rg_sql_fetch_array($res))) { while (($row = rg_sql_fetch_array($res))) {
408 rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']);
400 //rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']);
409 401 $buf = "command=\"" $buf = "command=\""
410 402 . $rg_scripts . "/scripts/remote.sh" . $rg_scripts . "/scripts/remote.sh"
411 403 . " " . $row['uid'] . " " . $row['uid']
 
... ... function rg_keys_regen($db)
413 405 . "," . $rg_ssh_paras . "," . $rg_ssh_paras
414 406 . " " . $row['key'] . "\n"; . " " . $row['key'] . "\n";
415 407 if (@fwrite($f, $buf) === FALSE) { if (@fwrite($f, $buf) === FALSE) {
416 rg_keys_set_error("cannot write. Disk space problems? ($php_errormsg)");
417 fclose($f);
418 unlink($tmp);
419 rg_sql_free_result($res);
408 rg_keys_set_error("cannot write; disk space problems? ($php_errormsg)");
409 $errors = 1;
420 410 break; break;
421 411 } }
422 412 } }
423 413 rg_sql_free_result($res); rg_sql_free_result($res);
424 414
425 415 fclose($f); fclose($f);
416 if ($errors == 1) {
417 unlink($tmp);
418 break;
419 }
426 420
427 421 if (@rename($tmp, $rg_keys_file) === FALSE) { if (@rename($tmp, $rg_keys_file) === FALSE) {
428 422 rg_keys_set_error("cannot rename $tmp to $rg_keys_file ($php_errormsg)"); rg_keys_set_error("cannot rename $tmp to $rg_keys_file ($php_errormsg)");
 
... ... function rg_keys_regen($db)
430 424 break; break;
431 425 } }
432 426
427 rg_cache_set("key::last_regen_time", $now);
428
433 429 $ret = TRUE; $ret = TRUE;
434 430 } while (0); } while (0);
435 431
 
... ... function rg_keys_list($db, $ui)
447 443
448 444 $ret = FALSE; $ret = FALSE;
449 445 do { do {
450 $sql = "SELECT * FROM keys WHERE uid = " . $ui['uid']
446 $params = array($ui['uid']);
447 $sql = "SELECT * FROM keys WHERE uid = $1"
451 448 . " ORDER BY itime DESC"; . " ORDER BY itime DESC";
452 $res = rg_sql_query($db, $sql);
449 $res = rg_sql_query_params($db, $sql, $params);
453 450 if ($res === FALSE) { if ($res === FALSE) {
454 451 rg_keys_set_error("Cannot query (" . rg_sql_error() . ")"); rg_keys_set_error("Cannot query (" . rg_sql_error() . ")");
455 452 break; break;
 
... ... function rg_keys_list($db, $ui)
467 464 $t['key_id'] = $row['key_id']; $t['key_id'] = $row['key_id'];
468 465 $t['itime'] = gmdate("Y-m-d H:i", $row['itime']); $t['itime'] = gmdate("Y-m-d H:i", $row['itime']);
469 466
467 if ($row['first_use'] == 0)
468 $t['first_use'] = "-";
469 else
470 $t['first_use'] = gmdate("Y-m-d H:i", $row['first_use']);
471
470 472 if (empty($row['last_ip'])) if (empty($row['last_ip']))
471 473 $t['last_ip'] = "-"; $t['last_ip'] = "-";
472 474 else else
 
... ... function rg_keys_list($db, $ui)
477 479 else else
478 480 $t['last_use'] = gmdate("Y-m-d H:i", $row['last_use']); $t['last_use'] = gmdate("Y-m-d H:i", $row['last_use']);
479 481
482 $t['count'] = $row['count'];
483
480 484 $ret[] = $t; $ret[] = $t;
481 485 } }
482 486 rg_sql_free_result($res); rg_sql_free_result($res);
File inc/log.inc.php changed (mode: 100644) (index 59ac935..30cafe9)
1 1 <?php <?php
2 2 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
3 require_once($INC . "/cache.inc.php");
3 4
4 5 if (!isset($rg_log_dir)) if (!isset($rg_log_dir))
5 6 $rg_log_dir = "/var/log/rocketgit"; $rg_log_dir = "/var/log/rocketgit";
 
... ... if (!isset($rg_log_dir))
7 8 if (!isset($rg_web_log_dir)) if (!isset($rg_web_log_dir))
8 9 $rg_web_log_dir = "/var/log/rocketgit-web"; $rg_web_log_dir = "/var/log/rocketgit-web";
9 10
10 $rg_log_file = $rg_log_dir . "/fallback.log";
11 if (isset($_SERVER['REMOTE_ADDR']))
12 $rg_log_file = $rg_web_log_dir . "/fallback.log";
13 else
14 $rg_log_file = $rg_log_dir . "/fallback.log";
11 15 $rg_log_fd = FALSE; $rg_log_fd = FALSE;
12 16 $rg_log_sid = rg_id(6); $rg_log_sid = rg_id(6);
13 17 $rg_log_buf = ""; $rg_log_buf = "";
14 18 $rg_log_last_date = ""; $rg_log_last_date = "";
15 19
20 /*
21 * Clears 'rg_log_buf' to not send a big log in case of errors
22 */
23 function rg_log_buffer_clear()
24 {
25 global $rg_log_buf;
26
27 $rg_log_buf = "";
28 }
29
16 30 /* /*
17 31 * Allow forcing sid, so we can spread the logs to multiple file * Allow forcing sid, so we can spread the logs to multiple file
18 32 * or to supress the output of it. * or to supress the output of it.
 
... ... function rg_log($str)
55 69 $rg_log_fd = fopen($lf, "a"); $rg_log_fd = fopen($lf, "a");
56 70 if ($rg_log_fd === FALSE) if ($rg_log_fd === FALSE)
57 71 return; return;
72
73 // Set correct rights
74 chmod($lf, 0600);
75
58 76 // write an empty line // write an empty line
59 77 fwrite($rg_log_fd, "\n"); fwrite($rg_log_fd, "\n");
60 78 $rg_log_last_date = $date; $rg_log_last_date = $date;
 
... ... function rg_log_ml($str)
96 114 rg_log($line); rg_log($line);
97 115 } }
98 116
99 function rg_fatal($msg)
117 /*
118 * This function will log fatal errors.
119 */
120 $rg_error_core_seen = array();
121 function rg_error_core($msg)
100 122 { {
123 global $rg_web_log_dir;
124 global $rg_log_dir;
101 125 global $rg_admin_email; global $rg_admin_email;
102 global $rg_log_buf;
126 global $rg_error_core_seen;
103 127
104 rg_log("FATAL: $msg");
128 rg_log($msg);
105 129
106 $bt = debug_backtrace();
107 rg_log_ml("Backtrace: " . print_r($bt, TRUE));
108 mail("rg_fatal@embedromix.ro", "FATAL ERROR",
109 $msg
110 . "\n" . rg_log_buffer()
111 . "\n" . print_r($bt, TRUE), "", "-f $rg_admin_email");
112 exit(1);
130 $me = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : "?";
131
132 $bt = print_r(debug_backtrace(), TRUE);
133 $bt = substr($bt, 0, 1024 * 1024);
134
135 if (isset($_SERVER['REMOTE_ADDR']))
136 $dir = $rg_web_log_dir;
137 else
138 $dir = $rg_log_dir;
139
140 $key = md5($msg);
141 if (isset($rg_error_core_seen[$key]))
142 return;
143
144 $r = file_put_contents($dir . "/err-" . $key,
145 "Script: " . $me . "\n" . rg_log_buffer() . "\n\n" . $bt);
146 if ($r === FALSE)
147 return;
148 chmod($dir . "/err-" . $key, 0600);
149
150 $rg_error_core_seen[$key] = 1;
113 151 } }
114 152
115 function rg_internal_error($msg)
153 /*
154 * This function is run from cron and will signal pending fatal errors.
155 */
156 function rg_log_cron()
116 157 { {
158 global $rg_web_log_dir;
159 global $rg_log_dir;
117 160 global $rg_admin_email; global $rg_admin_email;
161 global $rg_state_dir;
118 162
119 rg_log("Internal error: $msg");
163 $wd = rg_dir_load_pattern($rg_web_log_dir, "err-.*");
164 if ($wd === FALSE)
165 $wcount = "?";
166 else
167 $wcount = count($wd);
120 168
121 $bt = debug_backtrace();
122 rg_log_ml("Backtrace: " . print_r($bt, TRUE));
123 mail("rg_ie@embedromix.ro", "INTERNAL ERROR",
124 $msg
125 . "\n" . rg_log_buffer()
126 . "\n" . print_r($bt, TRUE), "", "-f $rg_admin_email");
169 $nd = rg_dir_load_pattern($rg_log_dir, "err-.*");
170 if ($nd === FALSE)
171 $ncount = "?";
172 else
173 $ncount = count($nd);
174
175 if ($wcount + $ncount == 0)
176 return;
177
178 // Do not send less than 1 per 4 hours
179 $last_ts = 0;
180 if (file_exists($rg_state_dir . "/log_cron_last"))
181 $last_ts = filemtime($rg_state_dir . "/log_cron_last");
182
183 if ($last_ts + 4 * 3600 > time())
184 return 0;
185
186 mail($rg_admin_email, $wcount . " + " . $ncount
187 . " errors are waiting...",
188 "Please forward the content of /var/log/rocketgit.*/err-.*"
189 . " to RocketGit developers at bugs@embedromix.ro.\n\n"
190 . "Thank you!\n\n",
191 "", "-f $rg_admin_email");
192
193 file_put_contents($rg_state_dir . "/log_cron_last", time());
127 194 } }
128 195
129 // TODO: send mail or store all data in database
130 function rg_security_violation($msg)
196 function rg_fatal($msg)
131 197 { {
132 global $rg_admin_email;
198 rg_error_core("FATAL: $msg");
199 exit(1);
200 }
133 201
134 rg_log("Security violation: $msg");
202 function rg_fatal_web($msg, $url)
203 {
204 rg_error_core("FATAL: $msg");
205 header("Location: " . $url);
206 exit(1);
207 }
208
209 function rg_internal_error($msg)
210 {
211 rg_error_core("Internal error: $msg");
212 }
135 213
136 $bt = debug_backtrace();
137 rg_log_ml("Backtrace: " . print_r($bt, TRUE));
138 mail("rg_sec@embedromix.ro", "SECURITY VIOLATION",
139 $msg
140 . "\n" . rg_log_buffer()
141 . "\n" . print_r($bt, TRUE), "", "-f $rg_admin_email");
214 function rg_security_violation_no_exit($msg)
215 {
216 rg_error_core("Security violation: $msg");
217 }
218
219 function rg_security_violation($msg)
220 {
221 rg_error_core("Security violation: $msg");
142 222 exit(1); exit(1);
143 223 } }
144 224
File inc/login/login.php changed (mode: 100644) (index f114b72..da927b1)
... ... $login_more = $more;
5 5
6 6 $user = rg_var_str("user"); $user = rg_var_str("user");
7 7 $pass = rg_var_str("pass"); $pass = rg_var_str("pass");
8 $lock_ip = rg_var_uint("lock_ip");
8 9
9 10 $_login = ""; $_login = "";
10 11
11 12 $errmsg = array(); $errmsg = array();
12 13
13 14 if ($doit == 1) { if ($doit == 1) {
14 $r = rg_user_login_by_user_pass($db, $user, $pass, $login_ui);
15 $r = rg_user_login_by_user_pass($db, $user, $pass, $lock_ip, $login_ui);
15 16 if ($r === FALSE) { if ($r === FALSE) {
16 17 $errmsg[] = rg_user_error(); $errmsg[] = rg_user_error();
17 18 } else { } else {
 
... ... $login_more['pass'] = $pass;
26 27 $login_more['HTML:errmsg'] = rg_template_errmsg($errmsg); $login_more['HTML:errmsg'] = rg_template_errmsg($errmsg);
27 28 $login_more['forgot_send'] = rg_re_url("/op/forgot_send"); $login_more['forgot_send'] = rg_re_url("/op/forgot_send");
28 29 $login_more['create_account'] = rg_re_url("/op/create_account"); $login_more['create_account'] = rg_re_url("/op/create_account");
29 $login_more['allow_creation'] = $rg_account_allow_creation;
30 30 $_login .= rg_template("user/login.html", $login_more); $_login .= rg_template("user/login.html", $login_more);
31 31 ?> ?>
File inc/mr.inc.php changed (mode: 100644) (index a459c51..c0afc90)
... ... function rg_mr_create($db, $repo_id, $namespace, $old_rev, $new_rev, $refname,
69 69 . " ip=$ip"); . " ip=$ip");
70 70
71 71 $now = time(); $now = time();
72 $params = array($repo_id, $now, $namespace, $refname, $old_rev, $new_rev,
73 $ip);
72 74 $sql = "INSERT INTO merge_requests (repo_id, itime, namespace" $sql = "INSERT INTO merge_requests (repo_id, itime, namespace"
73 75 . ", refname, old_rev, new_rev, done, ip)" . ", refname, old_rev, new_rev, done, ip)"
74 . " VALUES ($repo_id, $now, '$namespace'"
75 . ", '$refname', '$old_rev', '$new_rev', 0, '$ip')";
76 $res = rg_sql_query($db, $sql);
76 . " VALUES ($1, $2, $3, $4, $5, $6, 0, $7)";
77 $res = rg_sql_query_params($db, $sql, $params);
77 78 if ($res === FALSE) { if ($res === FALSE) {
78 79 rg_mr_set_error("cannot insert merge request" rg_mr_set_error("cannot insert merge request"
79 80 . " (" . rg_sql_error() . ")"); . " (" . rg_sql_error() . ")");
 
... ... function rg_mr_queue_process($db)
116 117 { {
117 118 global $rg_mr_queue; global $rg_mr_queue;
118 119
119 rg_log("mr_queue_process...");
120 rg_prof_start("mr_queue_process");
120 121
121 122 $ret = TRUE; $ret = TRUE;
122 123 $dir = @opendir($rg_mr_queue); $dir = @opendir($rg_mr_queue);
 
... ... function rg_mr_queue_process($db)
149 150 } }
150 151 closedir($dir); closedir($dir);
151 152
153 rg_prof_end("mr_queue_process");
152 154 return $ret; return $ret;
153 155 } }
154 156
 
... ... function rg_mr_load($db, $repo_id, $limit)
169 171 { {
170 172 rg_log("rg_mr_load: repo_id=$repo_id limit=$limit"); rg_log("rg_mr_load: repo_id=$repo_id limit=$limit");
171 173
174 $params = array($repo_id, $limit);
172 175 $sql = "SELECT * FROM merge_requests" $sql = "SELECT * FROM merge_requests"
173 . " WHERE repo_id = $repo_id"
176 . " WHERE repo_id = $1"
174 177 . " AND done = 0" . " AND done = 0"
175 178 . " ORDER BY itime" . " ORDER BY itime"
176 . " LIMIT $limit";
177 $res = rg_sql_query($db, $sql);
179 . " LIMIT $2";
180 $res = rg_sql_query_params($db, $sql, $params);
178 181 if ($res === FALSE) { if ($res === FALSE) {
179 182 rg_mr_set_error("Cannot load merge requests (" . rg_sql_error() . ")"); rg_mr_set_error("Cannot load merge requests (" . rg_sql_error() . ")");
180 183 return FALSE; return FALSE;
 
... ... function rg_mr_load_one($db, $repo_id, $namespace)
197 200 { {
198 201 rg_log("rg_mr_load_one: repo_id=$repo_id namespace=$namespace"); rg_log("rg_mr_load_one: repo_id=$repo_id namespace=$namespace");
199 202
203 $params = array($repo_id, $namespace);
200 204 $sql = "SELECT * FROM merge_requests" $sql = "SELECT * FROM merge_requests"
201 . " WHERE repo_id = $repo_id"
202 . " AND namespace = '$namespace'";
203 $res = rg_sql_query($db, $sql);
205 . " WHERE repo_id = $1"
206 . " AND namespace = $2";
207 $res = rg_sql_query_params($db, $sql, $params);
204 208 if ($res === FALSE) { if ($res === FALSE) {
205 209 rg_mr_set_error("cannot load a merge request" rg_mr_set_error("cannot load a merge request"
206 210 . " (" . rg_sql_error() . ")"); . " (" . rg_sql_error() . ")");
File inc/plan.inc.php changed (mode: 100644) (index 180476b..21c662b)
2 2 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
3 3 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
4 4 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
5 require_once($INC . "/sess.inc.php");
6 require_once($INC . "/rights.inc.php");
7 5 require_once($INC . "/events.inc.php"); require_once($INC . "/events.inc.php");
8 6 require_once($INC . "/cache.inc.php"); require_once($INC . "/cache.inc.php");
9 7
10 $rg_user_rights = array(
11 "C" => "Create repositories",
12 "U" => "Add users"
13 );
8 $rg_plan_error = "";
14 9
15 rg_rights_register("user", $rg_user_rights);
16
17 $rg_user_error = "";
18
19 function rg_user_set_error($str)
10 function rg_plan_set_error($str)
20 11 { {
21 global $rg_user_error;
22 $rg_user_error = $str;
12 global $rg_plan_error;
13 $rg_plan_error = $str;
23 14 } }
24 15
25 function rg_user_error()
26 {
27 global $rg_user_error;
28 return $rg_user_error;
29 }
30
31 /*
32 * Event functions
33 */
34 $rg_user_functions = array(
35 2000 => "rg_user_event_new",
36 2002 => "rg_user_event_notify_user",
37 2005 => "rg_user_event_rename",
38 2006 => "rg_user_link_by_name"
39 );
40 rg_event_register_functions($rg_user_functions);
41
42 /*
43 * Event for adding a new user
44 */
45 function rg_user_event_new($db, $event)
16 function rg_plan_error()
46 17 { {
47 $ret = array();
48
49 $event['op'] = "new";
50 // create link by name
51 $ret[] = array_merge($event, array("category" => 2006, "prio" => 200));
52 // notify user
53 $ret[] = array_merge($event, array("category" => 2002, "prio" => 100));
54
55 return $ret;
18 global $rg_plan_error;
19 return $rg_plan_error;
56 20 } }
57 21
58 22 /* /*
59 * Notify user: welcome
23 * Validates plan name
60 24 */ */
61 function rg_user_event_notify_user($db, $event)
25 function rg_plan_ok($name)
62 26 { {
63 rg_log("user_event_notify_user: event=" . rg_array2string($event));
64
65 if (strcmp($event['op'], "rename") == 0) {
66 $r = rg_mail("mail/user/rename", $event);
67 if ($r === FALSE)
68 return FALSE;
69 }
70
71 $r = rg_mail("mail/user/welcome", $event);
72 if ($r === FALSE)
27 if (empty($name))
73 28 return FALSE; return FALSE;
74 29
75 return array();
76 }
77
78 /*
79 * Event for renaming an user
80 */
81 function rg_user_event_rename($db, $event)
82 {
83 $ret = array();
84
85 $event['op'] = "rename";
86 // notify user
87 $ret[] = array_merge($event, array("category" => 2002, "prio" => 100));
88 // TODO: notify watchers
89
90 return $ret;
91 }
92
93 /*
94 * Event for creating a link by name to the uid
95 */
96 function rg_user_link_by_name($db, $event)
97 {
98 rg_log("user_link_by_name: event=" . rg_array2string($event));
99
100 $by_id = rg_user_path_by_id($event['uid']);
101 if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) {
102 rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)");
103 return FALSE;
104 }
105
106 $by_name = rg_user_path_by_name($event['username']);
107 $by_name_parent = dirname($by_name);
108 if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) {
109 rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)");
110 return FALSE;
111 }
112
113 $by_id_rel = rg_user_path_by_id_rel($event['uid']);
114 if (symlink($by_id_rel, $by_name) === FALSE) {
115 rg_user_set_error("cannot symlink $by_id_rel <- $by_name ($php_errormsg)!");
116 return FALSE;
117 }
118
119 return array();
120 }
121
122 /*
123 * Returns the relative path to user home based on uid
124 */
125 function rg_user_path_by_id_rel($uid)
126 {
127 $xuid = sprintf("%08X", $uid);
128 $uid_path = array();
129 for ($i = 0; $i < 8; $i += 2)
130 $uid_path[] = $xuid[$i] . $xuid[$i + 1];
131 $uid_path = implode("/", $uid_path);
132
133 return "../../../../by_id/" . $uid_path . "/" . $xuid;
134 }
135
136 /*
137 * Returns the path to user home based on uid
138 */
139 function rg_user_path_by_id($uid)
140 {
141 global $rg_repos;
142
143 $xuid = sprintf("%08X", $uid);
144 $uid_path = array();
145 for ($i = 0; $i < 8; $i += 2)
146 $uid_path[] = $xuid[$i] . $xuid[$i + 1];
147 $uid_path = implode("/", $uid_path);
148
149 return $rg_repos . "/by_id/" . $uid_path . "/" . $xuid;
150 }
151
152 /*
153 * Returns the path to user home based on name
154 */
155 function rg_user_path_by_name($name)
156 {
157 global $rg_repos;
158
159 $x = $name . "__";
160
161 return $rg_repos . "/by_name/"
162 . $x[0] . "/" . $x[1] . "/" . $x[2] . "/" . $name;
163 }
164
165 /*
166 * Returns the URL to a user home based on $ui
167 */
168 function rg_user_url($ui)
169 {
170 $prefix = "";
171 if ($ui['organization'] == 0)
172 $prefix = "/user";
173
174 return $prefix . "/" . $ui['username'];
175 }
176
177 /*
178 * Computes password hash
179 */
180 function rg_user_pass($salt, $pass)
181 {
182 return sha1($salt . "===" . $pass);
183 }
184
185 /*
186 * Validates a password
187 */
188 function rg_user_pass_ok($pass)
189 {
190 if (strlen($pass) < 5) {
191 rg_user_set_error("password is too short (less than 5 chars)");
192 return FALSE;
193 }
194
195 return TRUE;
196 }
197
198 /*
199 * Returns true if the user is ok
200 */
201 function rg_user_ok($user)
202 {
203 global $rg_user_allow;
204 global $rg_user_min_len;
205 global $rg_user_max_len;
206
207 if (rg_chars_allow($user, $rg_user_allow) !== TRUE) {
208 rg_user_set_error("invalid user name (invalid chars [$user] [$rg_user_allow])");
209 return FALSE;
210 }
211
212 if (strlen($user) < $rg_user_min_len) {
213 rg_user_set_error("user name too short (shorter than $rg_user_min_len)");
214 return FALSE;
215 }
216
217 if (strlen($user) > $rg_user_max_len) {
218 rg_user_set_error("user name too long (longer than $rg_user_max_len)");
219 return FALSE;
220 }
221
222 30 return TRUE; return TRUE;
223 31 } }
224 32
225 33 /* /*
226 * Lookup in db the old names, so we can redirect the user to the new name
34 * Add/edit a plan
35 * If uid > 0 - edit, else, add
227 36 */ */
228 function rg_user_lookup_by_old_name($db, $old_name)
37 function rg_plan_edit($db, $d)
229 38 { {
230 rg_prof_start("user_lookup_by_old_name");
231 rg_log("user_lookup_by_old_name: old_name=$old_name");
39 rg_prof_start("plan_edit");
40 rg_log("plan_edit: d: " . rg_array2string($d));
232 41
233 42 $ret = FALSE; $ret = FALSE;
234 43 do { do {
235 $x = rg_cache_get("old_name::" . $old_name);
236 if ($x !== FALSE) {
237 $ret = $x;
44 if (rg_plan_ok($d['name']) !== TRUE)
238 45 break; break;
46
47 $params = array($d['name'], $d['description'], $d['disk_mb'],
48 $d['users'], $d['bw'], $d['speed'], $d['position'],
49 $d['id']);
50 if ($d['id'] == 0) { // add
51 $sql = "INSERT INTO plans (name, description, disk_mb"
52 . ", users, bw, speed, position)"
53 . " VALUES ($1, $2, $3, $4, $5, $6, $7)"
54 . " RETURNING id";
55 } else { // edit
56 $sql = "UPDATE plans"
57 . " SET name = $1"
58 . ", description = $2"
59 . ", disk_mb = $3"
60 . ", users = $4"
61 . ", bw = $5"
62 . ", speed = $6"
63 . ", position = $7"
64 . " WHERE id = $8"
65 . " RETURNING id";
239 66 } }
240 67
241 $e_old_name = rg_sql_escape($db, $old_name);
242 $sql = "SELECT uid FROM users_renames"
243 . " WHERE old_name = '$e_old_name'";
244 $res = rg_sql_query($db, $sql);
68 $res = rg_sql_query_params($db, $sql, $params);
245 69 if ($res === FALSE) { if ($res === FALSE) {
246 rg_user_set_error("cannot lookup old name ("
247 . rg_sql_error() . ")");
70 rg_plan_set_error("cannot insert/update plan"
71 . " (" . rg_sql_error() . ")");
248 72 break; break;
249 73 } }
250 $rows = rg_sql_num_rows($res);
251 if ($rows > 0)
252 $row = rg_sql_fetch_array($res);
74 $row = rg_sql_fetch_array($res);
253 75 rg_sql_free_result($res); rg_sql_free_result($res);
254 if ($rows == 0)
255 $ret = 0;
256 else
257 $ret = $row['uid'];
258 76
259 rg_cache_set("old_name::" . $old_name, $ret);
77 $d['id'] = $row['id'];
78
79 // invalidate cache
80 rg_cache_unset("plan::list");
81
82 $ret = $row['id'];
260 83 } while (0); } while (0);
261 84
262 rg_prof_end("user_lookup_by_old_name");
85 rg_prof_end("plan_edit");
263 86 return $ret; return $ret;
264 87 } }
265 88
266 89 /* /*
267 * Add a rename to the database
90 * Delete plans; list is array("<id>" => "<junk>, ...)
268 91 */ */
269 function rg_user_insert_rename($db, $uid, $old_name)
92 function rg_plan_remove($db, $list)
270 93 { {
271 rg_prof_start("user_insert_rename");
272 rg_log("user_insert_rename: uid=$uid old_name=$old_name");
94 rg_prof_start("plan_remove");
95 rg_log("plan_remove: list=" . rg_array2string($list));
273 96
274 97 $ret = FALSE; $ret = FALSE;
275 98 do { do {
276 $e_old_name = rg_sql_escape($db, $old_name);
99 $my_list = array();
100 foreach ($list as $id => $junk)
101 $my_list[] = sprintf("%u", $id);
277 102
278 // Check if already exists in the database
279 $r = rg_user_lookup_by_old_name($db, $old_name);
280 if ($r === FALSE)
281 break;
282 if ($r > 0) {
283 $sql = "UPDATE users_renames"
284 . " SET uid = $uid"
285 . " WHERE old_name = '$e_old_name'";
286 } else {
287 $now = time();
288 $sql = "INSERT INTO users_renames (uid, old_name"
289 . ", itime)"
290 . " VALUES (" . $uid
291 . ", '$e_old_name'"
292 . ", $now"
293 . ")";
294 }
103 $sql_list = implode(", ", $my_list);
104 $sql = "DELETE FROM plans WHERE id IN (" . $sql_list . ")";
295 105 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
296 106 if ($res === FALSE) { if ($res === FALSE) {
297 rg_user_set_error("cannot link with old_name in db"
107 rg_plan_set_error("cannot remove plan $id"
298 108 . " (" . rg_sql_error() . ")"); . " (" . rg_sql_error() . ")");
299 109 break; break;
300 110 } }
111 rg_sql_free_result($res);
301 112
302 rg_cache_set("old_name::" . $old_name, $uid);
303
304 $ret = TRUE;
305 } while (0);
306
307 rg_prof_end("user_insert_rename");
308 return $ret;
309 }
310
311 /*
312 * Rename a user
313 * We keep the old name around, so the clients do not break.
314 */
315 function rg_user_rename($db, $ui, $new_name)
316 {
317 rg_prof_start("user_rename");
318 rg_log("user_rename: from=[" . $ui['username'] . "]"
319 . " to=[" . $new_name . "]...");
320
321 $user_path = rg_user_path_by_id($ui['uid']);
322 $old_path = rg_user_path_by_id_rel($ui['uid']);
323 $new_path = rg_user_path_by_name($new_name);
324 rg_log("old_path=$old_path new_path=$new_path");
325
326 $ret = FALSE;
327 do {
328 $do_link = TRUE;
329
330 // Check if we already did the rename
331 if (file_exists($new_path)) {
332 if (!is_link($new_path)) {
333 rg_internal_error("$new_path is not a link!");
334 break;
335 }
336
337 $v = readlink($new_path);
338 if ($v === FALSE) {
339 rg_internal_error("Cannot read link $new_path!");
340 break;
341 }
342 rg_log("new_path points to [$v]");
343
344 if (strcmp($old_path, $v) == 0) {
345 // Link already done
346 $do_link = FALSE;
347 } else {
348 // Seems that new_path points to other place
349 $r = rename($new_path, $new_path . ".BOGUS." . time());
350 if ($r !== TRUE) {
351 rg_internal_error("Cannot rename bogus!");
352 break;
353 }
354 }
355 }
356
357 if ($do_link === TRUE) {
358 // Now, the new name is free, do the link
359 $r = symlink($old_path, $new_path);
360 if ($r !== TRUE) {
361 rg_internal_error("Cannot symlink $old_path -> $new_path ($php_errormsg)!");
362 break;
363 }
364 }
365
366 // TOOD: transaction?
367 $r = rg_user_insert_rename($db, $ui['uid'], $new_name);
368 if ($r !== TRUE)
369 break;
370
371 // TODO: Check if all parameters are used.
372 $event = array("category" => 2005, "prio" => 50,
373 "ui.rename_from" => $ui['username'],
374 "ui.rename_to" => $new_name,
375 "IP" => rg_var_str("REMOTE_ADDR"),
376 "ui.uid" => $ui['uid']);
377 $r = rg_event_add($db, $event);
378 if ($r !== TRUE) {
379 rg_repo_set_error("cannot add event"
380 . " (" . rg_event_error() . ")");
381 break;
382 }
113 // invalidate cache
114 rg_cache_unset("plan::list");
383 115
384 116 $ret = TRUE; $ret = TRUE;
385 117 } while (0); } while (0);
386 118
387 rg_prof_end("user_rename");
119 rg_prof_end("plan_remove");
388 120 return $ret; return $ret;
389 121 } }
390 122
391 123 /* /*
392 * Add/edit a user
393 * If uid > 0 - edit, else, add
124 * Return the list of plans
394 125 */ */
395 function rg_user_edit($db, $d)
126 function rg_plan_list($db)
396 127 { {
397 rg_prof_start("user_edit");
398 rg_log("user_edit: data: " . rg_array2string($d));
128 rg_prof_start("plan_list");
399 129
400 130 $ret = FALSE; $ret = FALSE;
401 131 do { do {
402 // DEBUG
403 if (!isset($d['username'])) {
404 rg_internal_error("username not passed");
132 $c = rg_cache_get("plan::list");
133 if ($c !== FALSE) {
134 $ret = unserialize($c);
405 135 break; break;
406 136 } }
407 137
408 if (rg_user_ok($d['username']) !== TRUE)
409 break;
410
411 $now = time();
412 $e_username = rg_sql_escape($db, $d['username']);
413 $e_realname = rg_sql_escape($db, $d['realname']);
414 $e_salt = rg_id(40);
415 $e_pass = rg_user_pass($e_salt, $d['pass']);
416 $e_email = rg_sql_escape($db, $d['email']);
417 $e_rights = rg_sql_escape($db, $d['rights']);
418 $e_is_admin = $d['is_admin'];
419 $e_disk_quota_mb = $d['disk_quota_mb'];
420 $e_session_time = $d['session_time'];
421 $e_confirm_token = isset($d['confirm_token']) ? $d['confirm_token'] : "";
422
423 if (empty($d['confirm_token'])) {
424 // no need to confirm account
425 $e_confirmed = $now;
426 } else {
427 $e_confirmed = 0;
428 }
429
430 if ($d['uid'] == 0) { // add
431 if (rg_user_pass_ok($d['pass']) !== TRUE)
432 break;
433
434 $sql = "INSERT INTO users (username, realname, salt, pass"
435 . ", email, itime"
436 . ", is_admin, disk_quota_mb, rights, session_time"
437 . ", confirmed, confirm_token)"
438 . " VALUES ('$e_username', '$e_realname', '$e_salt', '$e_pass'"
439 . ", '$e_email', $now, $e_is_admin, $e_disk_quota_mb"
440 . ", '$e_rights', $e_session_time"
441 . ", $e_confirmed, '$e_confirm_token')"
442 . " RETURNING uid";
443 } else { // edit
444 $salt_pass_add = "";
445 if (!empty($d['pass']))
446 $salt_pass_add = ", pass = '$e_pass', salt = '$e_salt'";
447
448 $sql = "UPDATE users"
449 . " SET username = '$e_username'"
450 . ", realname = '$e_realname'"
451 . $salt_pass_add
452 . ", email = '$e_email'"
453 . ", is_admin = $e_is_admin"
454 . ", disk_quota_mb = $e_disk_quota_mb"
455 . ", rights = '$e_rights'"
456 . ", session_time = $e_session_time"
457 . " WHERE uid = " . $d['uid']
458 . " RETURNING uid";
459 }
460
138 $sql = "SELECT * FROM plans ORDER BY position";
461 139 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
462 140 if ($res === FALSE) { if ($res === FALSE) {
463 rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")");
141 rg_plan_set_error("cannot get plan list"
142 . " (" . rg_sql_error() . ")");
464 143 break; break;
465 144 } }
466 $row = rg_sql_fetch_array($res);
467 rg_sql_free_result($res);
468 145
469 // invalidate cache
470 rg_cache_unset("user::" . $d['uid']);
471
472 if ($d['uid'] == 0) { // add
473 $event = array("category" => 2000, "prio" => 50,
474 "ui.uid" => $d['uid'],
475 "ui.username" => $d['username'],
476 "ui.email" => $d['email']
477 );
478 $r = rg_event_add($db, $event);
479 if ($r === FALSE) {
480 rg_user_set_error("Canot add event!");
481 break;
482 }
483 }
484
485 $ret = $row['uid'];
486 } while (0);
487
488 rg_prof_end("user_edit");
489 return $ret;
490 }
491
492 /*
493 * Delete a user
494 */
495 function rg_user_remove($db, $uid)
496 {
497 rg_prof_start("user_remove");
498 rg_log("user_remove: uid=$uid");
499
500 $ret = FALSE;
501 do {
502 $uid = sprintf("%u", $uid);
503
504 $sql = "DELETE FROM users WHERE uid = $uid";
505 $res = rg_sql_query($db, $sql);
506 if ($res === FALSE) {
507 rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")");
508 break;
146 $ret = array();
147 while (($row = rg_sql_fetch_array($res))) {
148 $row['exists'] = 1;
149 $id = $row['id'];
150 $ret[$id] = $row;
509 151 } }
510 152 rg_sql_free_result($res); rg_sql_free_result($res);
511 153
512 // invalidate cache
513 rg_cache_unset("user::" . $uid);
514
515 $ret = TRUE;
154 rg_cache_set("plan::list", serialize($ret));
516 155 } while (0); } while (0);
517 156
518 rg_prof_end("user_remove");
157 rg_prof_end("plan_list");
519 158 return $ret; return $ret;
520 159 } }
521 160
522 161 /* /*
523 * Returns info about a user (by uid, user or e-mail)
162 * Returns info about a plan (by id)
524 163 */ */
525 function rg_user_info($db, $uid, $user, $email)
164 function rg_plan_info($db, $id)
526 165 { {
527 rg_prof_start("user_info");
166 rg_prof_start("plan_info");
528 167
529 168 $ret = array(); $ret = array();
530 169 $ret['ok'] = 0; $ret['ok'] = 0;
531 170 $ret['exists'] = 0; $ret['exists'] = 0;
532 $ret['uid'] = 0;
533 $ret['is_admin'] = 0;
534
535 $set_cache = FALSE;
536 $set_cache_user = FALSE;
537 $set_cache_email = FALSE;
538 while (1) {
539 //rg_log("user_info: uid=$uid user=$user email=$email.");
540 171
541 if ($uid > 0) {
542 $c = rg_cache_get("user::" . $uid);
543 if ($c !== FALSE) {
544 $ret = unserialize($c);
545 if ($ret !== FALSE)
546 break;
547 }
548 $add = " AND uid = " . sprintf("%u", $uid);
549 $set_cache = TRUE;
550 } else if (!empty($user)) {
551 if (rg_user_ok($user) !== TRUE)
552 break;
553
554 $c = rg_cache_get("username_to_uid::" . $user);
555 if ($c !== FALSE) {
556 $uid = $c;
557 continue;
558 }
559
560 $e_user = rg_sql_escape($db, $user);
561 $add = " AND username = '$e_user'";
562 $set_cache_user = TRUE;
563 } else if (!empty($email)) {
564 $c = rg_cache_get("email_to_uid::" . $email);
565 if ($c != FALSE) {
566 $uid = $c;
567 continue;
568 }
569
570 $e_email = rg_sql_escape($db, $email);
571 $add = " AND email = '$e_email'";
572 $set_cache_email = TRUE;
573 }
574
575 $sql = "SELECT * FROM users WHERE 1 = 1" . $add;
576 $res = rg_sql_query($db, $sql);
577 if ($res === FALSE) {
578 rg_user_set_error("cannot get info (" . rg_sql_error() . ")");
172 do {
173 $list = rg_plan_list($db);
174 if ($list === FALSE) {
175 rg_plan_set_error("cannot load plans"
176 . " (" . rg_sql_error() . ")");
579 177 break; break;
580 178 } }
581 179
582 180 $ret['ok'] = 1; $ret['ok'] = 1;
583 $rows = rg_sql_num_rows($res);
584 if ($rows > 0)
585 $row = rg_sql_fetch_array($res);
586 rg_sql_free_result($res);
587 if ($rows == 0) {
588 rg_user_set_error("user not found");
589 break;
590 }
591
592 $row['ok'] = 1;
593 $row['exists'] = 1;
594
595 $ret = $row;
596 break;
597 };
598 181
599 if ($ret['exists'] == 1) {
600 if ($set_cache)
601 rg_cache_set("user::" . $ret['uid'], serialize($ret));
602 }
603
604 if ($ret['exists'] == 1) {
605 if ($set_cache_user)
606 rg_cache_set("username_to_uid::" . $ret['username'], $ret['uid']);
182 $id = sprintf("%u", $id);
183 if (!isset($list[$id]))
184 break;
607 185
608 if ($set_cache_email)
609 rg_cache_set("email_to_uid::" . $ret['email'], $ret['uid']);
610 }
186 $ret = array_merge($ret, $list[$id]);
187 } while (0);
611 188
612 rg_prof_end("user_info");
189 rg_prof_end("plan_info");
613 190 return $ret; return $ret;
614 191 } }
615 192
616 193 /* /*
617 * Loads ui based on sid, if possible
194 * Returns a select list
618 195 */ */
619 function rg_user_login_by_sid($db, $sid, &$ui)
196 function rg_plan_select($db, $plan_id)
620 197 { {
621 rg_log("user_login_by_sid: sid=$sid...");
198 $list = rg_plan_list($db);
199 if ($list === FALSE)
200 return rg_warning("Could not load plans.");
622 201
623 // Make sure it is not passed by client
624 $ui = array();
625 $ui['uid'] = 0;
626 $ui['is_admin'] = 0;
627 $ui['username'] = "";
628
629 if (empty($sid)) {
630 rg_log("\tNo sid!");
631 return FALSE;
202 $ret = "<select name=\"plan_id\">\n";
203 foreach ($list as $row) {
204 $add = "";
205 if ($row['id'] == $plan_id)
206 $add = " selected";
207 $ret .= "<option value=\"" . htmlspecialchars($row['id'])
208 . "\"" . $add . ">"
209 . htmlspecialchars($row['name']) . "</option>\n";
632 210 } }
633 211
634 $sess = rg_sess_valid($db, $sid);
635 if ($sess == FALSE)
636 return FALSE;
637
638 $uid = $sess['uid'];
639 $ui = rg_user_info($db, $uid, "", "");
640 if ($ui['exists'] != 1) {
641 rg_log("\tUid $uid does not exists (" . rg_user_error() . ")!");
642 rg_user_set_error("invalid uid");
643 return FALSE;
644 }
645
646 rg_sess_update($db, $sess);
647
648 rg_user_set_last_seen($db, $ui['uid']);
649
650 return TRUE;
651 }
652
653 /*
654 * Test if a password is valid
655 */
656 function rg_user_pass_valid($db, $uid, $pass)
657 {
658 rg_log("user_pass_valid: uid=$uid, pass=$pass...");
659
660 if (empty($pass)) {
661 rg_user_set_error("password is empty");
662 return FALSE;
663 }
212 $ret .= "</select>\n";
664 213
665 $ui = rg_user_info($db, $uid, "", "");
666 if ($ui['exists'] != 1) {
667 rg_user_set_error("user does not exists");
668 return FALSE;
669 }
670
671 $sha1pass = rg_user_pass($ui['salt'], $pass);
672 if (strcmp($sha1pass, $ui['pass']) != 0) {
673 rg_user_set_error("password is not ok");
674 return FALSE;
675 }
676
677 rg_log("\tPass is valid.");
678 return TRUE;
679 }
680
681 /*
682 * Auto login the user
683 */
684 function rg_user_auto_login($db, $uid, $lock_ip, &$ui)
685 {
686 $ui = rg_user_info($db, $uid, "", "");
687 if ($ui['ok'] != 1)
688 return FALSE;
689
690 if ($ui['exists'] != 1)
691 return FALSE;
692
693 $secure = FALSE;
694 if (isset($_SERVER['HTTPS']))
695 $secure = TRUE;
696
697 $sid = rg_id(40);
698 rg_sess_add($db, $uid, $sid, $ui['session_time'], $lock_ip);
699 setcookie("sid", $sid, 0, "/", $_SERVER['SERVER_NAME'],
700 $secure, TRUE /* httponly */);
701
702 return TRUE;
703 }
704
705 /*
706 * Test if login is OK
707 */
708 function rg_user_login_by_user_pass($db, $user, $pass, $lock_ip, &$ui)
709 {
710 rg_log("user_login_by_user_pass: user=$user, pass=$pass lock_ip=$lock_ip");
711
712 $ui = array();
713 $ui['uid'] = 0;
714 $ui['is_admin'] = 0;
715
716 if (empty($user) || empty($pass)) {
717 rg_user_set_error("invalid user or pass");
718 return FALSE;
719 }
720
721 $ui0 = rg_user_info($db, 0, $user, "");
722 if ($ui0['ok'] != 1) {
723 rg_user_set_error("internal error");
724 return FALSE;
725 }
726 if ($ui0['exists'] != 1) {
727 rg_user_set_error("invalid user or pass");
728 return FALSE;
729 }
730
731 if ($ui0['suspended'] > 0) {
732 rg_user_set_error("invalid user or pass");
733 return FALSE;
734 }
735
736 if ($ui0['confirmed'] == 0) {
737 rg_user_set_error("invalid user or pass");
738 return FALSE;
739 }
740
741 $sha1pass = rg_user_pass($ui0['salt'], $pass);
742 if (strcmp($sha1pass, $ui0['pass']) != 0) {
743 rg_user_set_error("invalid user or pass");
744 return FALSE;
745 }
746
747 $ui = $ui0;
748 rg_user_auto_login($db, $ui['uid'], $lock_ip, $ui);
749
750 rg_user_set_last_seen($db, $ui['uid']);
751
752 return TRUE;
753 }
754
755 /*
756 * Suspend an account
757 * 1=suspend, 0=unsuspend
758 */
759 function rg_user_suspend($db, $uid, $op)
760 {
761 rg_log("user_suspend: uid=$uid, op=$op");
762
763 $now = time();
764
765 if ($op == 1)
766 $v = $now;
767 else
768 $v = 0;
769
770 $sql = "UPDATE users SET suspended = $v WHERE uid = $uid";
771 $res = rg_sql_query($db, $sql);
772 if ($res === FALSE) {
773 rg_user_set_error("cannot suspend (" . rg_sql_error() . ")");
774 return FALSE;
775 }
776 rg_sql_free_result($res);
777
778 // Invalidate cache.
779 rg_cache_unset("user::" . $uid);
780
781 return TRUE;
782 }
783
784 /*
785 * Make/remove admin
786 * 1=make, 0=remove
787 */
788 function rg_user_make_admin($db, $uid, $op)
789 {
790 rg_log("user_make_admin: uid=$uid, op=$op");
791
792 $sql = "UPDATE users SET is_admin = $op WHERE uid = $uid";
793 $res = rg_sql_query($db, $sql);
794 if ($res === FALSE) {
795 rg_user_set_error("cannot make admin (" . rg_sql_error() . ")");
796 return FALSE;
797 }
798 rg_sql_free_result($res);
799
800 // Invalidate cache.
801 rg_cache_unset("user::" . $uid);
802
803 return TRUE;
804 }
805
806 /*
807 * Update last_seen field
808 */
809 function rg_user_set_last_seen($db, $uid)
810 {
811 rg_log("user_set_last_seen: uid=$uid");
812
813 $now = time();
814
815 $sql = "UPDATE users SET last_seen = $now WHERE uid = $uid";
816 $res = rg_sql_query($db, $sql);
817 if ($res === FALSE) {
818 rg_user_set_error("cannot update last seen (" . rg_sql_error() . ")");
819 return FALSE;
820 }
821 rg_sql_free_result($res);
822
823 // TODO: check if we need to invalidate cache
824
825 return TRUE;
214 return $ret;
826 215 } }
827 216
828 217 /* /*
829 * List users
218 * High-level function for rg_plan_list
830 219 */ */
831 function rg_user_list($db, $url)
220 function rg_plan_list_high_level($db, $sid, $more)
832 221 { {
833 rg_log("user_list, url=$url...");
834
835 222 $ret = ""; $ret = "";
836 223
837 $uid = rg_var_uint("uid");
838
839 $suspend = rg_var_uint("suspend");
840 if ($suspend == 1) {
841 if (!rg_user_suspend($db, $uid, 1))
842 $ret .= "<font color=red>Cannot suspend!</font><br />";
843 }
844
845 $unsuspend = rg_var_uint("unsuspend");
846 if ($unsuspend == 1) {
847 if (!rg_user_suspend($db, $uid, 0))
848 $ret .= "<font color=red>Cannot unsuspend!</font><br />";
849 }
850
851 $make_admin = rg_var_uint("make_admin");
852 if ($make_admin == 1) {
853 if (!rg_user_make_admin($db, $uid, 1))
854 $ret .= "<font color=red>Cannot make admin!</font><br />";
855 }
856
857 $remove_admin = rg_var_uint("remove_admin");
858 if ($remove_admin == 1) {
859 if (!rg_user_make_admin($db, $uid, 0))
860 $ret .= "<font color=red>Cannot remove admin!</font><br />";
861 }
224 $list_errmsg = array();
225 $del_errmsg = array();
862 226
863 $remove = rg_var_uint("remove");
864 if ($remove > 0) {
865 if (!rg_user_remove($db, $uid))
866 $ret .= "<font color=red>Cannot remove!</font><br />";
867 }
868
869 $sql = "SELECT * FROM users ORDER BY username";
870 $res = rg_sql_query($db, $sql);
871 if ($res === FALSE) {
872 rg_user_set_error("cannot get info (" . rg_sql_error() . ")!");
873 return FALSE;
874 }
875
876 $ret .= "<table>\n";
877 $ret .= "<tr>\n";
878 $ret .= " <th>User name</th>\n";
879 $ret .= " <th>Name</th>\n";
880 $ret .= " <th>E-mail</th>\n";
881 $ret .= " <th>Admin?</th>\n";
882 $ret .= " <th>Creation date (UTC)</th>\n";
883 $ret .= " <th>Quota</th>\n";
884 $ret .= " <th>Suspended?</th>\n";
885 $ret .= " <th>Confirmed?</th>\n";
886 $ret .= " <th>Session time</th>\n";
887 $ret .= " <th>Last seen (UTC)</th>\n";
888 $ret .= " <th>Rights</th>\n";
889 $ret .= " <th>Operations</th>\n";
890 $ret .= "</tr>\n";
891 while (($row = rg_sql_fetch_array($res))) {
892 $ret .= "<tr>\n";
893 $ret .= " <td>" . $row['username'] . "</td>\n";
894 $ret .= " <td>" . $row['realname'] . "</td>\n";
895 $ret .= " <td>" . $row['email'] . "</td>\n";
896 $ret .= " <td>" . ($row['is_admin'] == 1 ? "Yes" : "No") . "</td>\n";
897 $ret .= " <td>" . gmdate("Y-m-d", $row['itime']) . "</td>\n";
898 if ($row['disk_quota_mb'] > 0)
899 $_v = rg_1024($row['disk_quota_mb'] * 1024 * 1024);
900 else
901 $_v = "unlimited";
902 $ret .= " <td>" . $_v . "</td>\n";
903 $ret .= " <td>" . ($row['suspended'] == 0 ? "No" : "Yes") . "</th>\n";
904 $ret .= " <td>" . ($row['confirmed'] == 0 ? "No" : gmdate("Y-m-d", $row['confirmed'])) . "</th>\n";
905 $ret .= " <td>" . $row['session_time'] . "s</td>\n";
906 $v = $row['last_seen'] == 0 ? "-" : gmdate("Y-m-d", $row['last_seen']);
907 $ret .= " <td>" . $v . "</td>\n";
908 $v = implode(", ", rg_rights_text("user", $row['rights']));
909 $ret .= " <td>" . $v . "</td>\n";
910
911 // operations
912 $_url = $url . "&amp;uid=" . $row['uid'];
913 $ret .= " <td>";
914
915 // edit
916 $ret .= "[<a href=\"$_url&amp;subsubop=3\">Edit</a>]";
227 $delete = rg_var_uint("delete");
228 do {
229 if ($delete != 1)
230 break;
917 231
918 // suspend
919 $v = "suspend=1"; $t = "Suspend";
920 if ($row['suspended'] > 0) {
921 $t = "Unsuspend";
922 $v = "unsuspend=1";
232 $token = rg_var_str("token");
233 if (!rg_token_valid($db, $sid, $token)) {
234 $del_errmsg[] = "Invalid token. Try again.";
235 break;
923 236 } }
924 $ret .= "[<a href=\"$_url&amp;subsubop=1&amp;$v\">$t</a>]";
925 237
926 // admin
927 $v = "make_admin=1"; $t = "Make admin";
928 if ($row['is_admin'] == 1) {
929 $t = "Remove admin";
930 $v = "remove_admin=1";
238 $list = rg_var_str("delete_list");
239 $r = rg_plan_remove($db, $list);
240 if ($r !== TRUE) {
241 $more['errmsg'] = rg_plan_error();
242 $del_errmsg[] = rg_template("admin/plans/delete_err.html", $more);
243 break;
931 244 } }
932 $ret .= "[<a href=\"$_url&amp;subsubop=1&amp;$v\">$t</a>]";
933
934 // remove
935 if ($row['suspended'] > 0)
936 $ret .= "[<a href=\"$_url&amp;subsubop=1&amp;remove=1\">Remove!</a>]";
937
938 $ret .= " </td>";
939 $ret .= "</tr>\n";
940 }
941 $ret .= "</table>\n";
942 rg_sql_free_result($res);
943
944 return $ret;
945 }
946
947 /*
948 * Returns uid by token, if not expired
949 */
950 function rg_user_forgot_pass_uid($db, $token)
951 {
952 $ret = array();
953 $ret['ok'] = 0;
954 $ret['uid'] = 0;
955
956 rg_log("user_forgot_pass_uid: token=$token");
957
958 $now = time();
959 $e_token = rg_sql_escape($db, $token);
245 } while (0);
960 246
961 $sql = "SELECT uid FROM forgot_pass"
962 . " WHERE token = '$e_token'"
963 . " AND expire > $now";
964 $res = rg_sql_query($db, $sql);
965 if ($res === FALSE) {
966 rg_user_set_error("cannot lookup token (" . rg_sql_error() . ")");
967 return $ret;
247 $list = rg_plan_list($db);
248 if ($list === FALSE) {
249 $more['errmsg'] = rg_plan_error();
250 return rg_template("admin/plans/list_err.html", $more);
968 251 } }
969 252
970 $ret['ok'] = 1;
971
972 $rows = rg_sql_num_rows($res);
973 if ($rows > 0)
974 $row = rg_sql_fetch_array($res);
975 rg_sql_free_result($res);
976 if ($rows == 0)
977 return $ret;
978
979 $ret['uid'] = $row['uid'];
980
253 $more['rg_form_token'] = rg_token_get($db, $sid);
254 $more['HTML:del_errmsg'] = rg_template_errmsg($del_errmsg);
255 $ret .= rg_template_table("admin/plans/list", $list, $more);
981 256 return $ret; return $ret;
982 257 } }
983 258
984 259 /* /*
985 * Reset password function (send mail) - helper
260 * High-level function for rg_plan_edit.
986 261 */ */
987 function rg_user_forgot_pass_mail_prepare($db, $email)
262 function rg_plan_edit_high_level($db, $sid, $more)
988 263 { {
989 rg_log("user_forgot_pass_mail_prepare: email=$email");
264 rg_log("plan_edit_high_level");
990 265
991 $ret = array();
992 $ret['ok'] = 0;
993 $ret['exists'] = 0;
994
995 $expire = time() + 24 * 3600;
996 $token = rg_id(20);
266 $doit = rg_var_uint("doit");
267 $plan_id = rg_var_uint("id");
997 268
998 $r = rg_user_info($db, 0, "", $email);
999 if ($r['ok'] == 0) {
1000 rg_log("\tInternal error.");
1001 return $ret;
1002 }
1003 if ($r['exists'] == 0) {
1004 rg_log("\tUser does not exists.");
1005 $ret['ok'] = 1;
1006 return $ret;
1007 }
1008 $uid = $r['uid'];
1009
1010 // store token in database
1011 $sql = "INSERT INTO forgot_pass (token, uid, expire)"
1012 . " VALUES ('$token', $uid, $expire)";
1013 $res = rg_sql_query($db, $sql);
1014 if ($res === FALSE) {
1015 rg_user_set_error("cannot query (" . rg_sql_error() . ")");
1016 return $ret;
269 $ret = "";
270 $pi = array();
271
272 if ($doit == 0) {
273 if ($plan_id > 0) {
274 $pi = rg_plan_info($db, $plan_id);
275 if ($pi['exists'] != 1) {
276 $ret .= rg_warning("Invalid plan.");
277 return $ret;
278 }
279 } else {
280 // Defaults.
281 $pi['id'] = 0;
282 $pi['name'] = "";
283 $pi['description'] = "";
284 $pi['disk_mb'] = "0";
285 $pi['users'] = "0";
286 $pi['bw'] = "0";
287 $pi['speed'] = "0";
288 $pi['position'] = "100";
289 }
1017 290 } }
1018 rg_sql_free_result($res);
1019
1020 $ret['ok'] = 1;
1021 $ret['exists'] = 1;
1022 $ret['token'] = $token;
1023 291
1024 rg_log("DEBUG: user_forgot_pass_mail_prepare: ret=" . rg_array2string($ret));
1025
1026 return $ret;
1027 }
1028
1029 /*
1030 * Reset password function (send mail)
1031 */
1032 function rg_user_forgot_pass_mail($db, $email)
1033 {
1034 global $rg_admin_name, $rg_admin_email;
1035
1036 rg_log("user_forgot_pass_mail: email=$email");
1037
1038 $ret = array();
1039 $ret['ok'] = 0;
1040 $ret['exists'] = 0;
1041
1042 $r = rg_user_forgot_pass_mail_prepare($db, $email);
1043 if ($r['exists'] != 1) {
1044 rg_log("\tUser does not exists.");
1045 return $r;
1046 }
292 $errmsg = array();
293 $load_form = TRUE;
294 do {
295 if ($doit != 1)
296 break;
1047 297
1048 $ret['exists'] = 1;
298 $pi = array();
299 $pi['id'] = $plan_id;
300 $pi['name'] = rg_var_str("name");
301 $pi['description'] = rg_var_str("description");
302 $pi['disk_mb'] = rg_var_uint("disk_mb");
303 $pi['users'] = rg_var_uint("users");
304 $pi['bw'] = rg_var_uint("bw");
305 $pi['speed'] = rg_var_uint("speed");
306 $pi['position'] = rg_var_uint("position");
307 $token = rg_var_str("token");
308
309 if (!rg_token_valid($db, $sid, $token)) {
310 $errmsg[] = "Invalid token. Try again.";
311 break;
312 }
1049 313
1050 $headers = "From: $rg_admin_name <$rg_admin_email>";
314 $r = rg_plan_edit($db, $pi);
315 if ($r === FALSE) {
316 $errmsg[] = "cannot add/edit plan: " . rg_plan_error();
317 break;
318 }
1051 319
1052 $base_url = rg_base_url();
320 // TODO: move to template.
321 $ret = rg_ok("Plan was added with success.");
322 $load_form = FALSE;
323 } while (0);
1053 324
1054 if (!mail($email,
1055 "Forgot password",
1056 "Hello!\n\n"
1057 . "If you want to reset the password, follow:\n"
1058 . $base_url
1059 . rg_re_url("/op/forgot_link") . "&forgot_token=" . $r['token']
1060 . "\n\nRocketGit team",
1061 $headers,
1062 "-f $rg_admin_email")) {
1063 rg_user_set_error("cannot send mail ($php_errormsg)!");
1064 return $ret;
325 if ($load_form) {
326 $more = array_merge($more, $pi);
327 $more['HTML:errmsg'] = rg_template_errmsg($errmsg);
328 $more['rg_form_token'] = rg_token_get($db, $sid);
329 $ret .= rg_template("admin/plans/add_edit.html", $more);
1065 330 } }
1066 331
1067 $ret['ok'] = 1;
1068
1069 rg_log("DEBUG: user_forgot_pass_mail: ret=" . rg_array2string($ret) . ".");
1070 332 return $ret; return $ret;
1071 333 } }
1072 334
1073 /*
1074 * After reseting the pass, we have to destroy all 'reset pass' requests
1075 */
1076 function rg_user_forgot_pass_destroy($db, $uid)
1077 {
1078 rg_log("user_forgot_pass_destroy: uid=$uid");
1079
1080 $sql = "DELETE FROM forgot_pass WHERE uid = $uid";
1081 $res = rg_sql_query($db, $sql);
1082 if ($res === FALSE) {
1083 rg_user_set_error("cannot query (" . rg_sql_error() . ")");
1084 return FALSE;
1085 }
1086 rg_sql_free_result($res);
1087
1088 return TRUE;
1089 }
1090
1091 function rg_user_set_pass($db, $uid, $pass)
1092 {
1093 rg_log("user_set_pass: uid=$uid pass=$pass");
1094
1095 $e_salt = rg_id(40);
1096 $e_sha1pass = rg_user_pass($e_salt, $pass);
1097
1098 $sql = "UPDATE users SET"
1099 ." salt = '$e_salt'"
1100 . ", pass = '$e_sha1pass'"
1101 . " WHERE uid = " . $uid;
1102 $res = rg_sql_query($db, $sql);
1103 if ($res === FALSE) {
1104 rg_user_set_error("cannot update pass (" . rg_sql_error() . ")");
1105 return FALSE;
1106 }
1107 rg_sql_free_result($res);
1108
1109 // Invalidate cache.
1110 rg_cache_unset("user::" . $uid);
1111
1112 return TRUE;
1113 }
1114
1115 /*
1116 * Confirm account creation (send mail)
1117 */
1118 function rg_user_confirm_send($email, $token)
1119 {
1120 global $rg_admin_name, $rg_admin_email;
1121
1122 rg_log("user_confirm_send: email=$email, token=$token");
1123
1124 $headers = "From: $rg_admin_name <$rg_admin_email>";
1125
1126 $proto = "http://";
1127 if (isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'], "on") == 0))
1128 $proto = "https://";
1129
1130 if (!mail($email,
1131 "Account creation confirmation",
1132 "Hello!\n\n"
1133 . "Please confirm your account creation following:\n"
1134 . $proto
1135 . @$_SERVER['HTTP_HOST']
1136 . rg_re_url("/op/confirm") . "&token=" . $token
1137 . "\n\nRocketGit team",
1138 $headers,
1139 "-f $rg_admin_email")) {
1140 rg_user_set_error("cannot send mail ($php_errormsg)!");
1141 return FALSE;
1142 }
1143
1144 return TRUE;
1145 }
1146
1147 /*
1148 * Confirm account creation
1149 */
1150 function rg_user_confirm($db, $token)
1151 {
1152 $now = time();
1153
1154 $sql = "SELECT uid FROM users WHERE confirm_token = '$token'";
1155 $res = rg_sql_query($db, $sql);
1156 if ($res === FALSE) {
1157 rg_user_set_error("cannot search for token (" . rg_sql_error() . ")");
1158 return FALSE;
1159 }
1160 $rows = rg_sql_num_rows($res);
1161 if ($rows > 0)
1162 $row = rg_sql_fetch_array($res);
1163 rg_sql_free_result($res);
1164 if ($rows == 0) {
1165 rg_user_set_error("cannot find token (" . rg_sql_error() . ")");
1166 return FALSE;
1167 }
1168 $uid = $row['uid'];
1169
1170 $sql = "UPDATE users SET confirmed = $now"
1171 . " WHERE uid = $uid";
1172 $res = rg_sql_query($db, $sql);
1173 if ($res === FALSE) {
1174 rg_user_set_error("cannot update confirmed (" . rg_sql_error() . ")");
1175 return FALSE;
1176 }
1177 rg_sql_free_result($res);
1178
1179 // TODO: invalidate cache?
1180
1181 return $uid;
1182 }
1183
1184 /*
1185 * Add a suggestion to database
1186 */
1187 function rg_user_suggestion($db, $uid, $email, $suggestion)
1188 {
1189 $e_email = rg_sql_escape($db, $email);
1190 $e_suggestion = rg_sql_escape($db, $suggestion);
1191
1192 $sql = "INSERT INTO suggestions (uid, email, suggestion)"
1193 . " VALUES ($uid, '$e_email', '$e_suggestion')";
1194 $res = rg_sql_query($db, $sql);
1195 if ($res === FALSE) {
1196 rg_user_set_error("cannot add suggestion (" . rg_sql_error() . ")");
1197 return FALSE;
1198 }
1199 rg_sql_free_result($res);
1200
1201 return TRUE;
1202 }
1203
1204 335 ?> ?>
File inc/repo.inc.php changed (mode: 100644) (index eba96e5..f566a7f)
... ... $rg_repo_rights = array(
14 14 "P" => "Push", "P" => "Push",
15 15 "H" => "Anonymous push", "H" => "Anonymous push",
16 16 "S" => "Create annotated tag", "S" => "Create annotated tag",
17 "N" => "Modify annotated tag",
18 17 "n" => "Delete annotated tag", "n" => "Delete annotated tag",
19 18 "Y" => "Create un-annotated tag", "Y" => "Create un-annotated tag",
20 19 "U" => "Modify un-annotated tag", "U" => "Modify un-annotated tag",
 
... ... function rg_repo_history_insert($db, $repo_id, $category, $message)
290 289 $ret = FALSE; $ret = FALSE;
291 290 do { do {
292 291 $now = time(); $now = time();
293 $e_message = rg_sql_escape($db, $message);
292 $params = array($now, $repo_id, $category, $message);
294 293 $sql = "INSERT INTO repo_history_" . gmdate("Y_m", $now) $sql = "INSERT INTO repo_history_" . gmdate("Y_m", $now)
295 294 . " (itime, repo_id, category, message)" . " (itime, repo_id, category, message)"
296 . " VALUES ($now, $repo_id, $category, '$e_message')";
297 $res = rg_sql_query($db, $sql);
295 . " VALUES ($1, $2, $3, $4)";
296 $res = rg_sql_query_params($db, $sql, $params);
298 297 if ($res === FALSE) if ($res === FALSE)
299 298 break; break;
300 299
 
... ... function rg_repo_invalidate_cache($uid, $repo_id)
435 434 } }
436 435
437 436 /* /*
438 * Return info about a repo
437 * Returns info about a repo
439 438 * If you want to lookup by repo_id or uid/repo_name * If you want to lookup by repo_id or uid/repo_name
440 439 */ */
441 440 function rg_repo_info($db, $repo_id, $uid, $repo_name) function rg_repo_info($db, $repo_id, $uid, $repo_name)
 
... ... function rg_repo_info($db, $repo_id, $uid, $repo_name)
449 448 $ret['exists'] = 0; $ret['exists'] = 0;
450 449 do { do {
451 450 if ($repo_id > 0) { if ($repo_id > 0) {
452 $key = $repo_id;
451 +$key = $repo_id;
453 452 if (isset($rg_repo_info_cache[$key])) { if (isset($rg_repo_info_cache[$key])) {
454 453 $ret = $rg_repo_info_cache[$key]; $ret = $rg_repo_info_cache[$key];
455 454 $ret['from_cache'] = 1; $ret['from_cache'] = 1;
 
... ... function rg_repo_info($db, $repo_id, $uid, $repo_name)
458 457 } }
459 458
460 459 if ($repo_id > 0) { if ($repo_id > 0) {
461 $add = " AND repo_id = $repo_id";
460 $params = array($repo_id);
461 $sql = "SELECT * FROM repos WHERE repo_id = $1";
462 462 } else if (!empty($repo_name)) { } else if (!empty($repo_name)) {
463 $e_repo = rg_sql_escape($db, $repo_name);
464 $add = " AND uid = $uid AND name = '$e_repo'";
463 $params = array($uid, $repo_name);
464 $sql = "SELECT * FROM repos WHERE uid = $1 AND name = $2";
465 465 } else { } else {
466 466 rg_repo_set_error("no repo_id or user/repo specified!"); rg_repo_set_error("no repo_id or user/repo specified!");
467 467 break; break;
468 468 } }
469 469
470 $sql = "SELECT * FROM repos WHERE 1 = 1" . $add;
471 $res = rg_sql_query($db, $sql);
470 $res = rg_sql_query_params($db, $sql, $params);
472 471 if ($res === FALSE) { if ($res === FALSE) {
473 472 rg_repo_set_error("cannot query (" . rg_sql_error() . ")"); rg_repo_set_error("cannot query (" . rg_sql_error() . ")");
474 473 break; break;
475 474 } }
476 $ret['ok'] = 1;
477 475 $rows = rg_sql_num_rows($res); $rows = rg_sql_num_rows($res);
478 476 if ($rows > 0) if ($rows > 0)
479 477 $ret = rg_sql_fetch_array($res); $ret = rg_sql_fetch_array($res);
480 478 rg_sql_free_result($res); rg_sql_free_result($res);
479 $ret['ok'] = 1;
480
481 481 if (($rows == 0) && ($repo_id == 0)) { if (($rows == 0) && ($repo_id == 0)) {
482 482 // Repo not found, maybe it was renamed // Repo not found, maybe it was renamed
483 483 $_repo_id = rg_repo_lookup_by_old_name($db, $uid, $repo_name); $_repo_id = rg_repo_lookup_by_old_name($db, $uid, $repo_name);
 
... ... function rg_repo_info($db, $repo_id, $uid, $repo_name)
491 491 } }
492 492
493 493 // small fixes // small fixes
494 if ($rows > 0)
494 if ($rows > 0) {
495 $ret['exists'] = 1;
495 496 $ret['HTML:description'] = nl2br($ret['description']); $ret['HTML:description'] = nl2br($ret['description']);
496
497 $ret['exists'] = 1;
498 $ret['ok'] = 1;
497 }
499 498 } while (0); } while (0);
500 499
501 500 if (($repo_id > 0) && !isset($ret['from_cache'])) if (($repo_id > 0) && !isset($ret['from_cache']))
 
... ... function rg_repo_create($db, $master, $ui, $name, $max_commit_size,
585 584 break; break;
586 585 } }
587 586
588 $e_name = rg_sql_escape($db, $name);
589 587 $description = trim($description); $description = trim($description);
590 $e_description = rg_sql_escape($db, $description);
591
592 588 $itime = time(); $itime = time();
593 589
590 $params = array($ui['uid'], $master, $name, $itime,
591 $max_commit_size, $description, $rights, $max_users);
594 592 $sql = "INSERT INTO repos (uid, master, name" $sql = "INSERT INTO repos (uid, master, name"
595 593 . ", itime, max_commit_size, description, git_dir_done" . ", itime, max_commit_size, description, git_dir_done"
596 594 . ", default_rights, max_users)" . ", default_rights, max_users)"
597 . " VALUES (" . $ui['uid'] . ", $master, '$e_name'"
598 . ", $itime, $max_commit_size, '$e_description', 0"
599 . ", '$rights', $max_users)"
595 . " VALUES ($1, $2, $3, $4, $5, $6, 0, $7, $8)"
600 596 . " RETURNING repo_id"; . " RETURNING repo_id";
601 $res = rg_sql_query($db, $sql);
597 $res = rg_sql_query_params($db, $sql, $params);
602 598 if ($res === FALSE) { if ($res === FALSE) {
603 599 rg_repo_set_error("Cannot insert (" . rg_sql_error() . ")"); rg_repo_set_error("Cannot insert (" . rg_sql_error() . ")");
604 600 break; break;
 
... ... function rg_repo_delete($db, $repo_id, $ui)
648 644 // TODO: Check rights // TODO: Check rights
649 645 // TODO: Transaction? // TODO: Transaction?
650 646
647 $ri = rg_repo_info($db, $repo_id, 0, "");
648 if ($ri['ok'] != 1)
649 break;
650 if ($ri['exists'] != 1) {
651 rg_repo_set_error("Repository does not exists.");
652 break;
653 }
654
651 655 // Only mark it as such, deletion will happen in background // Only mark it as such, deletion will happen in background
652 $sql = "UPDATE repos SET deleted = 1 WHERE repo_id = $repo_id";
653 $res = rg_sql_query($db, $sql);
656 $params = array($repo_id);
657 $sql = "UPDATE repos SET deleted = 1 WHERE repo_id = $1";
658 $res = rg_sql_query_params($db, $sql, $params);
654 659 if ($res === FALSE) { if ($res === FALSE) {
655 660 rg_repo_set_error("Cannot delete (" . rg_sql_error() . ")"); rg_repo_set_error("Cannot delete (" . rg_sql_error() . ")");
656 661 break; break;
 
... ... function rg_repo_delete($db, $repo_id, $ui)
660 665 $event = array("category" => 3001, "prio" => 50, $event = array("category" => 3001, "prio" => 50,
661 666 "IP" => rg_var_str("REMOTE_ADDR"), "IP" => rg_var_str("REMOTE_ADDR"),
662 667 "ui.email" => $ui['email'], "ui.email" => $ui['email'],
663 "ri.name" => $name,
668 "ri.name" => $ri['name'],
664 669 "ri.repo_id" => $repo_id); "ri.repo_id" => $repo_id);
665 670 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
666 671 if ($r !== TRUE) { if ($r !== TRUE) {
 
... ... function rg_repo_delete($db, $repo_id, $ui)
681 686 */ */
682 687 function rg_repo_lookup_by_old_name($db, $uid, $old_name) function rg_repo_lookup_by_old_name($db, $uid, $old_name)
683 688 { {
684 rg_prof_start("rg_repo_lookup_by_old_name");
689 rg_prof_start("repo_lookup_by_old_name");
685 690 rg_log("repo_lookup_by_old_name: uid=$uid old_name=$old_name"); rg_log("repo_lookup_by_old_name: uid=$uid old_name=$old_name");
686 691
687 692 $ret = FALSE; $ret = FALSE;
688 693 do { do {
689 $e_old_name = rg_sql_escape($db, $old_name);
694 $params = array($uid, $old_name);
690 695 $sql = "SELECT repo_id FROM repos_renames" $sql = "SELECT repo_id FROM repos_renames"
691 . " WHERE uid = " . $uid
692 . " AND old_name = '$e_old_name'";
693 $res = rg_sql_query($db, $sql);
696 . " WHERE uid = $1"
697 . " AND old_name = $2";
698 $res = rg_sql_query_params($db, $sql, $params);
694 699 if ($res === FALSE) { if ($res === FALSE) {
695 700 rg_repo_set_error("cannot lookup old name (" rg_repo_set_error("cannot lookup old name ("
696 701 . rg_sql_error() . ")"); . rg_sql_error() . ")");
 
... ... function rg_repo_lookup_by_old_name($db, $uid, $old_name)
706 711 $ret = $row['repo_id']; $ret = $row['repo_id'];
707 712 } while (0); } while (0);
708 713
709 rg_prof_end("rg_repo_lookup_by_old_name");
714 rg_prof_end("repo_lookup_by_old_name");
710 715 return $ret; return $ret;
711 716 } }
712 717
 
... ... function rg_repo_insert_rename($db, $uid, $repo_id, $old_name)
720 725
721 726 $ret = FALSE; $ret = FALSE;
722 727 do { do {
723 $e_old_name = rg_sql_escape($db, $old_name);
724
725 728 // Check if already exists in the database // Check if already exists in the database
726 729 $r = rg_repo_lookup_by_old_name($db, $uid, $old_name); $r = rg_repo_lookup_by_old_name($db, $uid, $old_name);
727 730 if ($r === FALSE) if ($r === FALSE)
728 731 break; break;
729 732 if ($r > 0) { if ($r > 0) {
733 $params = array($repo_id, $uid, $old_name);
730 734 $sql = "UPDATE repos_renames" $sql = "UPDATE repos_renames"
731 . " SET repo_id = $repo_id"
732 . " WHERE uid = " . $uid
733 . " AND old_name = '$e_old_name'";
735 . " SET repo_id = $1"
736 . " WHERE uid = $2"
737 . " AND old_name = $3";
734 738 } else { } else {
735 739 $now = time(); $now = time();
740 $params = array($uid, $old_name, $repo_id, $now);
736 741 $sql = "INSERT INTO repos_renames (uid, old_name" $sql = "INSERT INTO repos_renames (uid, old_name"
737 742 . ", repo_id, itime)" . ", repo_id, itime)"
738 . " VALUES (" . $uid
739 . ", '$e_old_name'"
740 . ", " . $repo_id
741 . ", $now"
742 . ")";
743 . " VALUES ($1, $2, $3, $4)";
743 744 } }
744 $res = rg_sql_query($db, $sql);
745 $res = rg_sql_query_params($db, $sql, $params);
745 746 if ($res === FALSE) { if ($res === FALSE) {
746 747 rg_repo_set_error("cannot link with old_name in db" rg_repo_set_error("cannot link with old_name in db"
747 748 . " (" . rg_sql_error() . ")"); . " (" . rg_sql_error() . ")");
 
... ... function rg_repo_update($db, $login_ui, &$new)
802 803 break; break;
803 804 } }
804 805
805 $e_name = rg_sql_escape($db, $new['name']);
806 $new['description'] = trim($new['description']);
807 $e_description = rg_sql_escape($db, $new['description']);
808
809 $sql = "UPDATE repos SET name = '$e_name'"
810 . ", max_commit_size = " . $new['max_commit_size']
811 . ", description = '$e_description'"
812 . ", default_rights = '" . $new['default_rights'] . "'"
813 . ", max_users = " . $new['max_users']
814 . " WHERE repo_id = " . $new['repo_id'];
815 $res = rg_sql_query($db, $sql);
806 $params = array($new['name'], $new['max_commit_size'],
807 trim($new['description']), $new['default_rights'],
808 $new['max_users'], $new['repo_id']);
809 $sql = "UPDATE repos SET name = $1"
810 . ", max_commit_size = $2"
811 . ", description = $3"
812 . ", default_rights = $4"
813 . ", max_users = $5"
814 . " WHERE repo_id = $6";
815 $res = rg_sql_query_params($db, $sql, $params);
816 816 if ($res === FALSE) { if ($res === FALSE) {
817 817 rg_repo_set_error("Cannot update (" . rg_sql_error() . ")"); rg_repo_set_error("Cannot update (" . rg_sql_error() . ")");
818 818 break; break;
 
... ... function rg_repo_update($db, $login_ui, &$new)
846 846 /* /*
847 847 * List repositories * List repositories
848 848 */ */
849 function rg_repo_list_query($db, $url, $sql)
849 function rg_repo_list_query($db, $url, $sql, $params)
850 850 { {
851 851 rg_prof_start("repo_list_query"); rg_prof_start("repo_list_query");
852 852 rg_log("repo_list_query: url=$url, sql=$sql..."); rg_log("repo_list_query: url=$url, sql=$sql...");
853 853
854 $res = rg_sql_query($db, $sql);
854 $res = rg_sql_query_params($db, $sql, $params);
855 855 if ($res === FALSE) { if ($res === FALSE) {
856 856 rg_repo_set_error("cannot list by query (" . rg_sql_error() . ")"); rg_repo_set_error("cannot list by query (" . rg_sql_error() . ")");
857 857 return FALSE; return FALSE;
 
... ... function rg_repo_list_query($db, $url, $sql)
888 888 // rights // rights
889 889 $_line['rights'] = implode(", ", rg_rights_text("repo", $row['default_rights'])); $_line['rights'] = implode(", ", rg_rights_text("repo", $row['default_rights']));
890 890
891 $_max = "unlimited";
892 if ($row['disk_quota_mb'] > 0)
893 $_max = rg_1024($row['disk_quota_mb'] * 1024 * 1024);
894 $_line['disk_used'] = $row['disk_used_mb'] . "/" . $_max;
895
896 $_line['max_commit_size'] = "unlimited";
897 if ($row['max_commit_size'] > 0)
898 $_line['max_commit_size'] = rg_1024($row['max_commit_size']);
899
900 $_line['max_users'] = "unlimited";
901 if ($row['max_users'] > 0)
902 $_line['max_users'] = $row['max_users'];
891 $_line['disk_used'] = rg_1024($row['disk_used_mb'] * 1024 * 1024);
903 892
904 893 $d[] = $_line; $d[] = $_line;
905 894 } }
 
... ... function rg_repo_list($db, $url, $ui)
918 907
919 908 $add = ""; $add = "";
920 909 if ($ui['uid'] > 0) if ($ui['uid'] > 0)
921 $add = " AND uid = " . $ui['uid'];
910 $add = " AND uid = $1";
922 911
912 $params = array($ui['uid']);
923 913 $sql = "SELECT * FROM repos" $sql = "SELECT * FROM repos"
924 914 . " WHERE deleted = 0" . " WHERE deleted = 0"
925 915 . $add . $add
926 916 . " ORDER BY name"; . " ORDER BY name";
927 917
928 return rg_repo_list_query($db, $url, $sql);
918 return rg_repo_list_query($db, $url, $sql, $params);
929 919 } }
930 920
931 921 /* /*
 
... ... function rg_repo_search($db, $login_ui, $q)
937 927 rg_prof_start("repo_search"); rg_prof_start("repo_search");
938 928 rg_log("repo_search: q=[$q]"); rg_log("repo_search: q=[$q]");
939 929
940 $e_q = rg_sql_escape($db, $q);
941
942 930 $admin = 0; $admin = 0;
943 931 if (isset($login_ui['admin']) && ($login_ui['admin'] == 1)) if (isset($login_ui['admin']) && ($login_ui['admin'] == 1))
944 932 $admin = 1; $admin = 1;
945 933
934 $params = array($q, $login_ui['uid']);
946 935 $sql = "SELECT * FROM repos" $sql = "SELECT * FROM repos"
947 936 . " WHERE deleted = 0" . " WHERE deleted = 0"
948 . " AND (name ILIKE '%$e_q%' OR description ILIKE '%$e_q%')"
949 . " AND (uid = " . $login_ui['uid'] . " OR default_rights LIKE '%F%'"
937 . " AND (name ILIKE '%$1%' OR description ILIKE '%$1%')"
938 . " AND (uid = $2 OR default_rights LIKE '%F%'"
950 939 . " OR " . $admin . " = 1)" . " OR " . $admin . " = 1)"
951 940 . " ORDER BY master, name" . " ORDER BY master, name"
952 941 . " LIMIT 10"; . " LIMIT 10";
953 942
954 $r = rg_repo_list_query($db, "", $sql);
943 $r = rg_repo_list_query($db, "", $sql, $params);
955 944
956 945 rg_prof_end("repo_search"); rg_prof_end("repo_search");
957 946 return $r; return $r;
 
... ... function rg_repo_search($db, $login_ui, $q)
959 948
960 949 /* /*
961 950 * Computes the size of a repository * Computes the size of a repository
951 * @all - if TRUE, take in account all files. If FALSE, ignore the files with
952 * many links (a clone).
962 953 */ */
963 function rg_repo_disk_mb($path)
954 function rg_repo_size($path, $all)
964 955 { {
965 rg_log("repo_disk_mb: path=$path...");
956 //rg_log("repo_disk_mb: path=$path");
966 957
967 // TODO
958 $ret = FALSE;
959 do {
960 $dir = @opendir($path);
961 if ($dir === FALSE) {
962 rg_repo_set_error("Cannot open $path!");
963 break;
964 }
965
966 $total = 0;
967 $error = FALSE;
968 while (($f = readdir($dir)) !== FALSE) {
969 if (strcmp($f, ".") == 0)
970 continue;
971
972 if (strcmp($f, "..") == 0)
973 continue;
974
975 if (is_dir($path . "/" . $f)) {
976 $r = rg_repo_size($path . "/" . $f, $all);
977 if ($r === FALSE) {
978 $error = TRUE;
979 break;
980 }
981 $total += $r;
982 }
983
984 if (is_file($path . "/" . $f)) {
985 $s = stat($path . "/" . $f);
986 if ($s === FALSE) {
987 $error = TRUE;
988 break;
989 }
990
991 $r = $s['size'];
992 if ($all === FALSE) {
993 if ($s['nlink'] > 1)
994 $r = 0;
995 }
996
997 $total += $r;
998 }
999 }
1000 closedir($dir);
1001
1002 if ($error === FALSE)
1003 $ret = $total;
1004 } while (0);
968 1005
969 return 10;
1006 return $ret;
970 1007 } }
971 1008
972 1009 /* /*
 
... ... function rg_repo_git_done($db, $repo_id)
979 1016
980 1017 $ret = FALSE; $ret = FALSE;
981 1018 do { do {
1019 $params = array($repo_id);
982 1020 $sql = "UPDATE repos SET git_dir_done = 1" $sql = "UPDATE repos SET git_dir_done = 1"
983 . " WHERE repo_id = $repo_id";
984 $res = rg_sql_query($db, $sql);
1021 . " WHERE repo_id = $1";
1022 $res = rg_sql_query_params($db, $sql, $params);
985 1023 if ($res === FALSE) { if ($res === FALSE) {
986 1024 rg_repo_set_error("Cannot query (" . rg_sql_error() . ")"); rg_repo_set_error("Cannot query (" . rg_sql_error() . ")");
987 1025 break; break;
 
... ... function rg_repo_rights_get($db, $ri, $uid, $flags)
1038 1076 . $r['rights'] . ")=" . $ret['rights']); . $r['rights'] . ")=" . $ret['rights']);
1039 1077 $ret['ok'] = 1; $ret['ok'] = 1;
1040 1078
1079 // add misc stuff
1080 $ret = array_merge($ret, $r['misc']);
1081
1041 1082 rg_prof_end("repo_rights_get"); rg_prof_end("repo_rights_get");
1042 1083
1043 1084 return $ret; return $ret;
 
... ... function rg_repo_rights_get($db, $ri, $uid, $flags)
1046 1087 /* /*
1047 1088 * Add rights for a repo * Add rights for a repo
1048 1089 */ */
1049 function rg_repo_rights_set($db, $ri, $uid, $rights)
1090 function rg_repo_rights_set($db, $ri, $uid, $rights, $misc)
1050 1091 { {
1051 1092 if (!isset($ri['repo_id'])) { if (!isset($ri['repo_id'])) {
1052 1093 rg_internal_error("repo_id is not defined!"); rg_internal_error("repo_id is not defined!");
 
... ... function rg_repo_rights_set($db, $ri, $uid, $rights)
1054 1095 } }
1055 1096
1056 1097 rg_log("rg_repo_rights_set: repo_id=" . $ri['repo_id'] rg_log("rg_repo_rights_set: repo_id=" . $ri['repo_id']
1057 . ", uid=$uid, rights=$rights...");
1098 . " uid=$uid rights=$rights misc=" . rg_array2string($misc));
1058 1099
1059 $r = rg_rights_set($db, "repo", $ri['repo_id'], $uid, $rights);
1100 $r = rg_rights_set($db, "repo", $ri['repo_id'], $uid, $rights, $misc);
1060 1101 if ($r !== TRUE) { if ($r !== TRUE) {
1061 1102 rg_repo_set_error("cannot alter rights (" . rg_rights_error() . ")!"); rg_repo_set_error("cannot alter rights (" . rg_rights_error() . ")!");
1062 1103 return FALSE; return FALSE;
 
... ... function rg_repo_rights_load($db, $ri)
1081 1122 return $r; return $r;
1082 1123 } }
1083 1124
1084 /*
1085 * Returns TRUE if a repo is over limit
1086 */
1087 function rg_repo_over_limit($ri)
1088 {
1089 if ($ri['disk_quota_mb'] == 0)
1090 return FALSE;
1091
1092 if ($ri['disk_used_mb'] >= $ri['disk_quota_mb'])
1093 return TRUE;
1094
1095 return FALSE;
1096 }
1097
1098 1125 /* /*
1099 1126 * Add in queue a statistic file * Add in queue a statistic file
1100 1127 */ */
 
... ... function rg_repo_stats_push2file($a)
1106 1133 if (!is_dir($q)) { if (!is_dir($q)) {
1107 1134 $r = @mkdir($q, 0700); $r = @mkdir($q, 0700);
1108 1135 if ($r !== TRUE) { if ($r !== TRUE) {
1109 rg_internal_error("Cannot create dir $q ($php_errormsg)!");
1136 rg_internal_error("Cannot create dir [$q] ($php_errormsg)!");
1110 1137 return FALSE; return FALSE;
1111 1138 } }
1112 1139 } }
File inc/rights.inc.php changed (mode: 100644) (index 90aa7bb..8873b5a)
... ... function rg_rights_a2s($a)
127 127 { {
128 128 $rights = ""; $rights = "";
129 129
130 // TODO - log backtrace instead being silent
131 if (is_array($a))
132 foreach ($a as $right => $junk)
133 $rights .= $right;
130 if (!is_array($a)) {
131 rg_internal_error("Para is not an array");
132 return "";
133 }
134
135 foreach ($a as $right => $junk)
136 $rights .= $right;
134 137
135 138 return rg_rights_fix($rights); return rg_rights_fix($rights);
136 139 } }
 
... ... function rg_rights_get($db, $type, $obj_id, $uid)
144 147 global $rg_rights; global $rg_rights;
145 148
146 149 rg_log("rg_rights_get: type=$type obj_id=$obj_id uid=$uid..."); rg_log("rg_rights_get: type=$type obj_id=$obj_id uid=$uid...");
150 rg_prof_start("rights_get");
147 151
148 152 $ret = array(); $ret = array();
149 153 $ret['ok'] = 0; $ret['ok'] = 0;
150 154 $ret['rights'] = ""; $ret['rights'] = "";
155 do {
156 if ($uid == 0) {
157 $ret['ok'] = 1;
158 break;
159 }
151 160
152 if ($uid == 0) {
153 $ret['ok'] = 1;
154 return $ret;
155 }
161 $params = array($type, $uid, $obj_id);
162 $sql = "SELECT itime, rights, misc FROM rights"
163 . " WHERE type = $1"
164 . " AND uid = $2"
165 . " AND obj_id = $3"
166 . " LIMIT 1";
167 $res = rg_sql_query_params($db, $sql, $params);
168 if ($res === FALSE) {
169 rg_rights_set_error("cannot get info (" . rg_sql_error() . ")!");
170 break;
171 }
156 172
157 $sql = "SELECT itime, rights FROM rights"
158 . " WHERE type = '$type'"
159 . " AND uid = $uid"
160 . " AND obj_id = $obj_id"
161 . " LIMIT 1";
162 $res = rg_sql_query($db, $sql);
163 if ($res === FALSE) {
164 rg_rights_set_error("cannot get info (" . rg_sql_error() . ")!");
165 return $ret;
166 }
173 $ret['ok'] = 1;
174 $ret['exists'] = 0;
175 $rows = rg_sql_num_rows($res);
176 if ($rows > 0)
177 $row = rg_sql_fetch_array($res);
178 rg_sql_free_result($res);
179 if ($rows == 0)
180 break;
167 181
168 $ret['ok'] = 1;
169 $ret['exists'] = 0;
170 $rows = rg_sql_num_rows($res);
171 if ($rows > 0)
172 $row = rg_sql_fetch_array($res);
173 rg_sql_free_result($res);
174 if ($rows > 0) {
175 182 $ret['itime'] = $row['itime']; $ret['itime'] = $row['itime'];
176 183 $ret['rights'] = $row['rights']; $ret['rights'] = $row['rights'];
184 $ret['misc'] = empty($row['misc']) ? array() : unserialize($row['misc']);
177 185 $ret['exists'] = 1; $ret['exists'] = 1;
178 }
186 } while (0);
179 187
180 188 rg_log("\tdb rights: [" . $ret['rights'] . "]."); rg_log("\tdb rights: [" . $ret['rights'] . "].");
181 189
190 rg_prof_end("rights_get");
182 191 return $ret; return $ret;
183 192 } }
184 193
185 194 /* /*
186 195 * Set rights for an object * Set rights for an object
187 196 */ */
188 function rg_rights_set($db, $type, $obj_id, $uid, $rights)
197 function rg_rights_set($db, $type, $obj_id, $uid, $rights, $misc)
189 198 { {
190 199 rg_log("rg_rights_set: type=$type obj_id=$obj_id" rg_log("rg_rights_set: type=$type obj_id=$obj_id"
191 . ", uid=$uid, rights=$rights...");
192
193 $cond = " type = '$type' AND uid = $uid AND obj_id = $obj_id";
200 . " uid=$uid rights=$rights misc=" . rg_array2string($misc));
194 201
195 202 if (empty($rights)) { if (empty($rights)) {
203 $params = array($type, $uid, $obj_id);
196 204 $sql = "DELETE FROM rights" $sql = "DELETE FROM rights"
197 . " WHERE $cond";
205 . " WHERE type = $1"
206 . " AND uid = $2"
207 . " AND obj_id = $3";
198 208 } else { } else {
199 209 $r = rg_rights_get($db, $type, $obj_id, $uid); $r = rg_rights_get($db, $type, $obj_id, $uid);
200 210 if ($r['ok'] != 1) if ($r['ok'] != 1)
 
... ... function rg_rights_set($db, $type, $obj_id, $uid, $rights)
202 212 rg_log("r: " . rg_array2string($r)); rg_log("r: " . rg_array2string($r));
203 213
204 214 if ($r['exists'] == 1) { if ($r['exists'] == 1) {
215 $params = array($rights, serialize($misc), $type, $uid,
216 $obj_id);
205 217 $sql = "UPDATE rights" $sql = "UPDATE rights"
206 . " SET rights = '$rights'"
207 . " WHERE $cond";
218 . " SET rights = $1"
219 . ", misc = $2"
220 . " WHERE type = $3"
221 . " AND uid = $4"
222 . " AND obj_id = $5";
208 223 } else { } else {
209 $itime = time();
210
224 $params = array($type, $uid, $obj_id, $rights,
225 serialize($misc), time());
211 226 $sql = "INSERT INTO rights (type, uid, obj_id, rights" $sql = "INSERT INTO rights (type, uid, obj_id, rights"
212 . ", itime)"
213 . " VALUES ('$type', $uid, $obj_id, '$rights'"
214 . ", $itime)";
227 . ", misc, itime)"
228 . " VALUES ($1, $2, $3, $4, $5, $6)";
215 229 } }
216 230 } }
217 231
218 $res = rg_sql_query($db, $sql);
232 $res = rg_sql_query_params($db, $sql, $params);
219 233 if ($res === FALSE) { if ($res === FALSE) {
220 234 rg_rights_set_error("cannot alter rights (" . rg_sql_error() . ")!"); rg_rights_set_error("cannot alter rights (" . rg_sql_error() . ")!");
221 235 return FALSE; return FALSE;
 
... ... function rg_rights_load($db, $type, $obj_id)
237 251
238 252 $ret = FALSE; $ret = FALSE;
239 253 do { do {
254 $params = array($type, $obj_id);
240 255 $sql = "SELECT * FROM rights" $sql = "SELECT * FROM rights"
241 . " WHERE type = '$type'"
242 . " AND obj_id = $obj_id";
243 $res = rg_sql_query($db, $sql);
256 . " WHERE type = $1"
257 . " AND obj_id = $2";
258 $res = rg_sql_query_params($db, $sql, $params);
244 259 if ($res === FALSE) { if ($res === FALSE) {
245 260 rg_rights_set_error("cannot get info (" . rg_sql_error() . ")!"); rg_rights_set_error("cannot get info (" . rg_sql_error() . ")!");
246 261 break; break;
File inc/sess.inc.php changed (mode: 100644) (index 7a8451b..44cfcb4)
... ... require_once($INC . "/prof.inc.php");
7 7 /* /*
8 8 * Add a session * Add a session
9 9 */ */
10 function rg_sess_add($db, $uid, $sid, $session_time)
10 function rg_sess_add($db, $uid, $sid, $session_time, $lock_ip)
11 11 { {
12 12 rg_prof_start("sess_add"); rg_prof_start("sess_add");
13 rg_log("sess_add: uid=$uid, sid=$sid, session_time=$session_time"
14 . " lock_ip=$lock_ip");
13 15
14 rg_log("sess_add: uid=$uid, sid=$sid, session_time=$session_time.");
15
16 $ip = @$_SERVER['REMOTE_ADDR'];
16 if ($lock_ip == 1)
17 $ip = @$_SERVER['REMOTE_ADDR'];
18 else
19 $ip = "";
17 20 $now = time(); $now = time();
18 21
19 $sql = "INSERT INTO sess (sid, uid, expire, session_time, ip)"
20 . " VALUES ('$sid', $uid"
21 . ", " . ($now + $session_time) . ", $session_time, '$ip')";
22 $res = rg_sql_query($db, $sql);
23 if ($res === FALSE) {
24 rg_log("\tCannot insert (" . rg_sql_error() . ")!");
25 return FALSE;
26 }
27 rg_sql_free_result($res);
22 $ret = FALSE;
23 do {
24 $params = array($sid, $uid, $now + $session_time, $session_time, $ip);
25 $sql = "INSERT INTO sess (sid, uid, expire, session_time, ip)"
26 . " VALUES ($1, $2, $3, $4, $5)";
27 $res = rg_sql_query_params($db, $sql, $params);
28 if ($res === FALSE) {
29 rg_log("\tCannot insert (" . rg_sql_error() . ")!");
30 break;
31 }
32 rg_sql_free_result($res);
28 33
29 rg_prof_end("sess_add");
34 $row = array("sid" => $sid, "uid" => $uid,
35 "expire" => $now + $session_time,
36 "session_time" => $session_time, "ip" => $ip,
37 "last_db_write" => $now);
38 rg_cache_set("sess::" . $sid, serialize($row));
30 39
31 return TRUE;
40 $ret = TRUE;
41 } while (0);
42
43 rg_prof_end("sess_add");
44 return $ret;
32 45 } }
33 46
34 47 /* /*
35 * Returns if a session is still valid. Will return FALSE or uid
48 * Tests if a session is still valid. Will return FALSE on error or session
49 * info.
36 50 */ */
37 51 function rg_sess_valid($db, $sid) function rg_sess_valid($db, $sid)
38 52 { {
39 53 rg_prof_start("sess_valid"); rg_prof_start("sess_valid");
40
41 54 rg_log("sess_valid: sid=$sid..."); rg_log("sess_valid: sid=$sid...");
42 55
43 $uid = FALSE;
56 $ret = FALSE;
57 do {
58 $r = rg_cache_get("sess::" . $sid);
59 if ($r !== FALSE)
60 $r = unserialize($r);
61
62 if ($r === FALSE) {
63 $params = array($sid);
64 $sql = "SELECT * FROM sess WHERE sid = $1";
65 $res = rg_sql_query_params($db, $sql, $params);
66 if ($res === FALSE) {
67 rg_log("\tCannot select (" . rg_sql_error() . ")!");
68 break;
69 }
70 $rows = rg_sql_num_rows($res);
71 if ($rows > 0) {
72 $r = rg_sql_fetch_array($res);
73 $r['last_db_write'] = $r['expire'] - $r['session_time'];
74 rg_cache_set("sess::" . $sid, serialize($r));
75 }
76 rg_sql_free_result($res);
77 }
44 78
45 $e_sid = rg_sql_escape($db, $sid);
79 if ($r === FALSE) {
80 rg_log("\tSession not found.");
81 break;
82 }
46 83
47 $sql = "SELECT uid, expire FROM sess WHERE sid = '$e_sid'";
48 $res = rg_sql_query($db, $sql);
49 if ($res === FALSE) {
50 rg_log("\tCannot select (" . rg_sql_error() . ")!");
51 return FALSE;
52 }
53 $row = rg_sql_fetch_array($res);
54 rg_sql_free_result($res);
55 if (isset($row['uid'])) {
56 84 $now = time(); $now = time();
57 if ($row['expire'] >= $now) {
58 $uid = $row['uid'];
59 rg_log("\tSession valid, uid=$uid, expire=+" . ($row['expire'] - $now));
60 } else {
61 rg_log("\tSession too old (" . ($now - $row['expire']) . "s)");
85 if ($r['expire'] < $now) {
86 rg_log("\tSession too old (" . ($now - $r['expire']) . "s).");
87 break;
62 88 } }
63 } else {
64 rg_log("\tSession not found!");
65 }
66 89
67 rg_prof_end("sess_valid");
90 $ip = @$_SERVER['REMOTE_ADDR'];
91 if (!empty($r['ip']) && (strcmp($r['ip'], $ip) != 0)) {
92 rg_log("\tSession invalid because of IP"
93 . " login=" . $r['ip'] . " now=$ip.");
94 break;
95 }
68 96
69 return $uid;
97 $uid = $r['uid'];
98 rg_log("\tSession valid, uid=$uid, expire=+" . ($r['expire'] - $now));
99 $ret = $r;
100 } while (0);
101
102 rg_prof_end("sess_valid");
103 return $ret;
70 104 } }
71 105
72 106 /* /*
73 * Refresh a session
107 * Refreshes a session.
108 * Because of performance reasons, we will not update database
109 * every time.
74 110 */ */
75 function rg_sess_update($db, $sid)
111 function rg_sess_update($db, $sess)
76 112 { {
77 113 rg_prof_start("sess_update"); rg_prof_start("sess_update");
114 rg_log("sess_update: sess=" . rg_array2string($sess));
115
116 $ret = FALSE;
117 do {
118 if ($sess['last_db_write'] + 60 > time()) {
119 $_diff = time() - $sess['last_db_write'];
120 rg_log("DEBUG: last_db_write is fresh enough ($_diff).");
121 $ret = TRUE;
122 break;
123 }
78 124
79 rg_log("sess_update: sid=$sid...");
125 $params = array(time(), $sid);
126 $sql = "UPDATE sess SET expire = $1 + session_time"
127 . " WHERE sid = $2";
128 $res = rg_sql_query_params($db, $sql, $params);
129 if ($res === FALSE) {
130 rg_log("\tCannot update (" . rg_sql_error() . ")!");
131 break;
132 }
133 rg_sql_free_result($res);
80 134
81 $e_sid = rg_sql_escape($db, $sid);
135 $sess['last_db_write'] = time();
136 rg_cache_set("sess::" . $sess['sid'], serialize($sess));
82 137
83 $sql = "UPDATE sess SET expire = " . time() . " + session_time"
84 . " WHERE sid = '$e_sid'";
85 $res = rg_sql_query($db, $sql);
86 if ($res === FALSE) {
87 rg_log("\tCannot update (" . rg_sql_error() . ")!");
88 return FALSE;
89 }
90 rg_sql_free_result($res);
138 $ret = TRUE;
139 } while (0);
91 140
92 141 rg_prof_end("sess_update"); rg_prof_end("sess_update");
93
94 return TRUE;
142 return $ret;
95 143 } }
96 144
97 145 /* /*
 
... ... function rg_sess_update($db, $sid)
100 148 function rg_sess_destroy($db, $sid, &$ui) function rg_sess_destroy($db, $sid, &$ui)
101 149 { {
102 150 rg_prof_start("sess_destroy"); rg_prof_start("sess_destroy");
103
104 151 rg_log("sess_destroy: sid=$sid..."); rg_log("sess_destroy: sid=$sid...");
105 152
106 $e_sid = rg_sql_escape($db, $sid);
153 $ret = FALSE;
154 do {
155 $params = array($sid);
156 $sql = "DELETE FROM sess WHERE sid = $1";
157 $res = rg_sql_query_params($db, $sql, $params);
158 if ($res === FALSE) {
159 rg_log("\tCannot delete (" . rg_sql_error() . ")!");
160 break;
161 }
162 rg_sql_free_result($res);
163
164 // Delete all tokens associated with this session
165 rg_token_delete($db, $sid, "");
107 166
108 $sql = "DELETE FROM sess WHERE sid = '$e_sid'";
109 $res = rg_sql_query($db, $sql);
110 if ($res === FALSE) {
111 rg_log("\tCannot delete (" . rg_sql_error() . ")!");
112 return FALSE;
113 }
114 rg_sql_free_result($res);
167 $ui = array();
168 $ui['uid'] = 0;
169 $ui['is_admin'] = 0;
170 $ui['rights'] = "";
115 171
116 // Delete all tokens associated with this session
117 rg_token_delete($db, $sid, "");
172 rg_cache_unset("sess::" . $sid);
118 173
119 $ui = array();
120 $ui['uid'] = 0;
121 $ui['is_admin'] = 0;
174 $ret = TRUE;
175 } while (0);
122 176
123 177 rg_prof_end("sess_destroy"); rg_prof_end("sess_destroy");
124
125 return TRUE;
178 return $ret;
126 179 } }
127 180
128 181 ?> ?>
File inc/sql.inc.php changed (mode: 100644) (index dbbd92b..d8fe504)
... ... function rg_sql_error()
27 27 /* /*
28 28 * Connect to database * Connect to database
29 29 */ */
30 function rg_sql_open($str)
30 function rg_sql_open_nodelay($h)
31 31 { {
32 32 global $rg_sql_debug; global $rg_sql_debug;
33 33 global $rg_sql_conn; global $rg_sql_conn;
34 34
35 if (isset($rg_sql_conn[$str]))
36 return $rg_sql_conn[$str];
37
38 if ($rg_sql_debug > 0)
39 rg_log("DB: opening [$str]...");
40
41 rg_prof_set(array("db_conn" => 1));
35 $ret = FALSE;
36 do {
37 if (!isset($rg_sql_conn[$h])) {
38 rg_internal_error("Handler $h not present!");
39 break;
40 }
41
42 if (isset($rg_sql_conn[$h]['db'])) {
43 $ret = $rg_sql_conn[$h]['db'];
44 break;
45 }
46
47 $str = $rg_sql_conn[$h]['str'];
48 if ($rg_sql_debug > 0)
49 rg_log("DB: opening [$str]...");
50
51 // TODO: I do not remember what this is doing. Bad!
52 rg_prof_set(array("db_conn" => 1));
53
54 $_s = microtime(TRUE);
55
56 $tries = 5;
57 while ($tries > 0) {
58 $db = @pg_pconnect($str);
59 if ($db === FALSE) {
60 rg_log("Cannot connect to db. Sleep 1 second and try again.");
61 sleep(1);
62 $tries--;
63 continue;
64 }
65 break;
66 }
67 $diff = sprintf("%u", (microtime(TRUE) - $_s) * 1000);
68 rg_prof_set(array("db_conn_time_ms" => $diff));
69 if ($db === FALSE) {
70 rg_log("Cannot connect to database (" . $php_errormsg . ").");
71 rg_sql_set_error("cannot connect to database (" . $php_errormsg . ")");
72 rg_prof_set(array("db_conn_errors" => 1));
73 break;
74 }
75
76 rg_log("Connect OK to database.");
77 $rg_sql_conn[$h]['db'] = $db;
78 $ret = $db;
79 } while (0);
80
81 return $ret;
82 }
42 83
43 $_s = microtime(TRUE);
44 $db = @pg_pconnect($str);
45 $diff = sprintf("%u", (microtime(TRUE) - $_s) * 1000);
46 rg_prof_set(array("db_conn_time_ms" => $diff));
47 if ($db === FALSE) {
48 rg_sql_set_error("cannot connect to database (" . $php_errormsg . ")");
49 rg_prof_set(array("db_conn_errors" => 1));
50 return FALSE;
51 }
84 /*
85 * Prepare to connect to database (delayed connection).
86 * Returns a special handler.
87 */
88 function rg_sql_open($str)
89 {
90 global $rg_sql_conn;
52 91
53 $rg_sql_conn[$str] = $db;
92 $free_index = count($rg_sql_conn);
93 $rg_sql_conn[$free_index] = array();
94 $rg_sql_conn[$free_index]['str'] = $str;
54 95
55 return $db;
96 //rg_log("Delay connection to [$str], index $free_index.");
97 return $free_index;
56 98 } }
57 99
58 100 /* /*
59 101 * Escaping * Escaping
60 102 */ */
61 function rg_sql_escape($db, $str)
103 function rg_sql_escape($h, $str)
62 104 { {
105 $db = rg_sql_open_nodelay($h);
106 if ($db === FALSE)
107 return FALSE;
108
63 109 return pg_escape_string($db, $str); return pg_escape_string($db, $str);
64 110 } }
65 111
66 112 /* /*
67 * Do a query
113 * Helper for sql_query and sql_query_params
68 114 */ */
69 function rg_sql_query($db, $sql)
115 function rg_sql_query0($db, $sql, $res, $_s)
70 116 { {
71 117 global $rg_sql_debug; global $rg_sql_debug;
72 118
73 if ($rg_sql_debug > 0)
74 rg_log("\tDB: running [$sql]...");
75
76 $_s = microtime(TRUE);
77 $res = @pg_query($db, $sql);
78 119 if ($res === FALSE) { if ($res === FALSE) {
79 120 rg_sql_set_error("$sql: " . @pg_last_error($db)); rg_sql_set_error("$sql: " . @pg_last_error($db));
80 121 rg_prof_set(array("query_errors" => 1)); rg_prof_set(array("query_errors" => 1));
 
... ... function rg_sql_query($db, $sql)
97 138 "query_time_ms" => $diff)); "query_time_ms" => $diff));
98 139
99 140 return $res; return $res;
141
142 }
143
144 /*
145 * Do a query
146 */
147 function rg_sql_query($h, $sql)
148 {
149 global $rg_sql_debug;
150
151 if ($rg_sql_debug > 0)
152 rg_log("\tDB: running [$sql]...");
153
154 $db = rg_sql_open_nodelay($h);
155 if ($db === FALSE)
156 return FALSE;
157
158 $_s = microtime(TRUE);
159 $res = @pg_query($db, $sql);
160 return rg_sql_query0($db, $sql, $res, $_s);
161 }
162
163 /*
164 * Queries using params
165 */
166 function rg_sql_query_params($h, $sql, $params)
167 {
168 global $rg_sql_debug;
169
170 if ($rg_sql_debug > 0)
171 rg_log("\tDB: running [$sql] with [" . rg_array2string($params) . "]...");
172
173 $db = rg_sql_open_nodelay($h);
174 if ($db === FALSE)
175 return FALSE;
176
177 $_s = microtime(TRUE);
178 $res = @pg_query_params($db, $sql, $params);
179 return rg_sql_query0($db, $sql, $res, $_s);
100 180 } }
101 181
102 182 /* /*
103 183 * Close database * Close database
104 184 */ */
105 function rg_sql_close($db)
185 function rg_sql_close($h)
106 186 { {
107 pg_close($db);
187 $db = rg_sql_open_nodelay($h);
188 if ($db === FALSE)
189 return FALSE;
190
191 return pg_close($db);
108 192 } }
109 193
110 194 /* /*
 
... ... function rg_sql_close($db)
112 196 */ */
113 197 function rg_sql_free_result($res) function rg_sql_free_result($res)
114 198 { {
115 if (!is_resource($res))
116 rg_fatal("res is not resource!");
199 if (!is_resource($res)) {
200 rg_internal_error("res is not resource!");
201 return;
202 }
203
117 204 pg_free_result($res); pg_free_result($res);
118 205 } }
119 206
 
... ... function rg_sql_free_result($res)
122 209 */ */
123 210 function rg_sql_fetch_array($res) function rg_sql_fetch_array($res)
124 211 { {
212 if (!is_resource($res)) {
213 rg_internal_error("res is not resource!");
214 return FALSE;
215 }
216
125 217 return pg_fetch_assoc($res); return pg_fetch_assoc($res);
126 218 } }
127 219
128 function rg_sql_last_id($db)
220 function rg_sql_last_id($h)
129 221 { {
130 222 $sql = "SELECT lastval() AS id"; $sql = "SELECT lastval() AS id";
131 $res = rg_sql_query($db, $sql);
223 $res = rg_sql_query($h, $sql);
132 224 if ($res === FALSE) if ($res === FALSE)
133 225 return FALSE; return FALSE;
134 226
 
... ... function rg_sql_last_id($db)
139 231
140 232 function rg_sql_num_rows($res) function rg_sql_num_rows($res)
141 233 { {
234 if (!is_resource($res)) {
235 rg_internal_error("res is not resource!");
236 return FALSE;
237 }
238
142 239 return pg_num_rows($res); return pg_num_rows($res);
143 240 } }
144 241
145 242 function rg_sql_affected_rows($res) function rg_sql_affected_rows($res)
146 243 { {
244 if (!is_resource($res)) {
245 rg_internal_error("res is not resource!");
246 return FALSE;
247 }
248
147 249 return pg_affected_rows($res); return pg_affected_rows($res);
148 250 } }
149 251
150 function rg_sql_begin($db)
252 function rg_sql_begin($h)
151 253 { {
152 $res = rg_sql_query($db, "BEGIN");
254 $res = rg_sql_query($h, "BEGIN");
153 255 if ($res === FALSE) if ($res === FALSE)
154 256 return FALSE; return FALSE;
155 257
 
... ... function rg_sql_begin($db)
157 259 return TRUE; return TRUE;
158 260 } }
159 261
160 function rg_sql_commit($db)
262 function rg_sql_commit($h)
161 263 { {
162 $res = rg_sql_query($db, "COMMIT");
264 $res = rg_sql_query($h, "COMMIT");
163 265 if ($res === FALSE) if ($res === FALSE)
164 266 return FALSE; return FALSE;
165 267
 
... ... function rg_sql_commit($db)
167 269 return TRUE; return TRUE;
168 270 } }
169 271
170 function rg_sql_rollback($db)
272 function rg_sql_rollback($h)
171 273 { {
172 $res = rg_sql_query($db, "ROLLBACK");
274 $res = rg_sql_query($h, "ROLLBACK");
173 275 if ($res === FALSE) if ($res === FALSE)
174 276 return FALSE; return FALSE;
175 277
File inc/ssh.inc.php changed (mode: 100644) (index e9b2393..5d75c18)
... ... function rg_ssh_repos($db, $uid)
22 22 { {
23 23 rg_log("ssh_repos"); rg_log("ssh_repos");
24 24
25 echo "Repositories (name, creation, disk used/quota):\n";
25 echo "Repositories (name, creation, disk used):\n";
26 26 $sql = "SELECT * FROM repos" $sql = "SELECT * FROM repos"
27 27 . " WHERE uid = $uid" . " WHERE uid = $uid"
28 28 . " AND deleted = 0" . " AND deleted = 0"
 
... ... function rg_ssh_repos($db, $uid)
31 31 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
32 32 while (($row = rg_sql_fetch_array($res))) { while (($row = rg_sql_fetch_array($res))) {
33 33 echo substr(substr($row['name'], 0, 40) . $pad, 0, 32) echo substr(substr($row['name'], 0, 40) . $pad, 0, 32)
34 . "\t" . gmdate("Y-m-d", $row['itime'])
35 . "\t" . rg_1024($row['disk_used_mb']) . "/" . rg_1024($row['disk_quota_mb'])
34 . " " . gmdate("Y-m-d", $row['itime'])
35 . " " . rg_1024($row['disk_used_mb'])
36 36 . "\n"; . "\n";
37 37 } }
38 38 rg_sql_free_result($res); rg_sql_free_result($res);
 
... ... function rg_ssh_repo($db, $uid, $paras)
65 65 echo " " . $_line . "\n"; echo " " . $_line . "\n";
66 66 } }
67 67 echo "Creation time: " . gmdate("Y-m-d", $ri['itime']) . " UTC\n"; echo "Creation time: " . gmdate("Y-m-d", $ri['itime']) . " UTC\n";
68 echo "Disk used: " . rg_1024($ri['disk_used_mb']) . " MiB\n";
69 echo "Disk quota: " . rg_1024($ri['disk_quota_mb']) . " MiB\n";
68 echo "Disk used: " . rg_1024($ri['disk_used_mb']) . "\n";
70 69 $rights = implode(", ", rg_rights_text("repo", $ri['default_rights'])); $rights = implode(", ", rg_rights_text("repo", $ri['default_rights']));
71 70 echo "Default rights: " . $rights . "\n"; echo "Default rights: " . $rights . "\n";
72 71
File inc/state.inc.php changed (mode: 100644) (index 3cd1821..0850743)
1 1 <?php <?php
2 2 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
3 require_once($INC . "/cache.inc.php");
4 require_once($INC . "/prof.inc.php");
3 5
4 6 $rg_state_error = ""; $rg_state_error = "";
5 7
 
... ... function rg_state_set_error($str)
7 9 { {
8 10 global $rg_state_error; global $rg_state_error;
9 11 $rg_state_error = $str; $rg_state_error = $str;
12 rg_log($str);
10 13 } }
11 14
12 15 function rg_state_error() function rg_state_error()
 
... ... function rg_state_error()
20 23 */ */
21 24 function rg_state_get($db, $var) function rg_state_get($db, $var)
22 25 { {
23 $e_var = rg_sql_escape($db, $var);
26 rg_prof_start("state_get");
24 27
25 $sql = "SELECT value FROM state WHERE var = '$e_var'";
26 $res = rg_sql_query($db, $sql);
27 if ($res === FALSE) {
28 rg_state_set_error("state: " . rg_sql_error());
29 return FALSE;
30 }
28 $ret = FALSE;
29 do {
30 // Try cache first
31 $r = rg_cache_get("state::" . $var);
32 if ($r !== FALSE) {
33 $ret = $r;
34 break;
35 }
36
37 $params = array($var);
38 $sql = "SELECT value FROM state WHERE var = $1 LIMIT 1";
39 $res = rg_sql_query_params($db, $sql, $params);
40 if ($res === FALSE) {
41 rg_state_set_error(rg_sql_error());
42 break;
43 }
44
45 $rows = rg_sql_num_rows($res);
46 if ($rows == 0) {
47 $ret = "";
48 } else {
49 $row = rg_sql_fetch_array($res);
50 $ret = $row['value'];
51 }
52 rg_sql_free_result($res);
31 53
32 $rows = rg_sql_num_rows($res);
33 if ($rows == 0) {
34 $ret = "";
35 } else {
36 $row = rg_sql_fetch_array($res);
37 $ret = $row['value'];
38 }
39 rg_sql_free_result($res);
54 rg_cache_set("state::" . $var, $ret);
55 } while (0);
40 56
57 rg_prof_end("state_get");
41 58 return $ret; return $ret;
42 59 } }
43 60
 
... ... function rg_state_get_uint($db, $var)
58 75 */ */
59 76 function rg_state_set($db, $var, $value) function rg_state_set($db, $var, $value)
60 77 { {
61 $e_var = rg_sql_escape($db, $var);
62 $e_value = rg_sql_escape($db, $value);
63
64 if (rg_state_get($db, $var) === "") {
65 $sql = "INSERT INTO state (var, value)"
66 . " VALUES('$e_var', '$e_value')";
67 } else {
68 $sql = "UPDATE state SET value = '$e_value'"
69 . " WHERE var = '$e_var'";
70 }
71 $res = rg_sql_query($db, $sql);
72 if ($res === FALSE) {
73 rg_state_set_error("state: " . rg_sql_error());
74 return FALSE;
75 }
76 rg_sql_free_result($res);
78 rg_prof_start("state_set");
79
80 $ret = FALSE;
81 do {
82 $params = array($var, $value);
83 if (rg_state_get($db, $var) === "") {
84 $sql = "INSERT INTO state (var, value)"
85 . " VALUES ($1, $2)";
86 } else {
87 $sql = "UPDATE state SET value = $2"
88 . " WHERE var = $1";
89 }
90 $res = rg_sql_query_params($db, $sql, $params);
91 if ($res === FALSE) {
92 rg_state_set_error(rg_sql_error());
93 break;
94 }
95 rg_sql_free_result($res);
77 96
78 return TRUE;
97 rg_cache_set("state::" . $var, $value);
98
99 $ret = TRUE;
100 } while (0);
101
102 rg_prof_end("state_set");
103 return $ret;
79 104 } }
105
80 106 ?> ?>
File inc/struct.inc.php changed (mode: 100644) (index 5b0e4ac..4b0a720)
... ... $rg_sql_struct[15]['tables'] = array(
273 273 ); );
274 274
275 275
276 $rg_sql_struct[16] = array();
277 $rg_sql_struct[16]['other'] = array(
278 "ssh_usage_count" => "ALTER TABLE keys"
279 . " ADD count INT NOT NULL DEFAULT 0"
280 );
281
282
283 $rg_sql_struct[17] = array();
284 $rg_sql_struct[17]['other'] = array(
285 "misc_field_for_rights" => "ALTER TABLE rights"
286 . " ADD misc TEXT NOT NULL DEFAULT ''"
287 );
288
289
290 $rg_sql_struct[18] = array();
291 $rg_sql_struct[18]['tables'] = array(
292 "plans" => "CREATE TABLE plans (id SERIAL PRIMARY KEY"
293 . ", name TEXT NOT NULL DEFAULT ''"
294 . ", disk_mb INT NOT NULL DEFAULT 0"
295 . ", users INT NOT NULL DEFAULT 0"
296 . ", bw INT NOT NULL DEFAULT 0"
297 . ", position INT NOT NULL DEFAULT 0"
298 . ")"
299 );
300 $rg_sql_struct[18]['other'] = array(
301 "plan_id" => "ALTER TABLE users ADD plan_id INT NOT NULL DEFAULT 0",
302 "commit_size" => "ALTER TABLE plans ADD commit_size INT NOT NULL DEFAULT 0",
303 "disk_quota" => "ALTER TABLE users DROP disk_quota_mb",
304 "plan_desc" => "ALTER TABLE plans ADD description TEXT NOT NULL DEFAULT ''",
305 "plan_speed" => "ALTER TABLE plans ADD speed INT NOT NULL DEFAULT 0",
306 "unlimited" => "INSERT INTO plans (id, name, disk_mb, users, bw"
307 . ", speed, commit_size, description, position)"
308 . " VALUES (0, 'Unlimited', 0, 0, 0, 0, 0, 'Unlimited plan', 1000)",
309 "key_first" => "ALTER TABLE keys ADD first_use INT NOT NULL DEFAULT 0"
310 );
311
312
276 313 // This must be the last line // This must be the last line
277 314 $rg_sql_schema_ver = count($rg_sql_struct); $rg_sql_schema_ver = count($rg_sql_struct);
278 315
 
... ... function rg_sql_struct_run($db, $flags, $old_schema_ver)
332 369 } }
333 370
334 371 /* /*
335 * Tests if schema update is needed. Return old version
372 * Returns current version of the schema.
336 373 */ */
337 function rg_sql_struct_update_needed($db)
374 function rg_sql_struct_get_current_ver($db)
338 375 { {
339 376 global $rg_sql_schema_ver; global $rg_sql_schema_ver;
340 377
341 rg_log("sql_struct_update_needed:");
378 rg_log("sql_struct_get_current_ver:");
342 379
343 380 $old = rg_state_get($db, "schema_version"); $old = rg_state_get($db, "schema_version");
344 if ($old === FALSE) {
345 //TODO: error rg_log("\tDEBUG: schema is up to date!");
381 if ($old === FALSE)
346 382 return FALSE; return FALSE;
347 }
348 383
349 384 if (empty($old)) if (empty($old))
350 385 $old = 0; $old = 0;
351 386
352 rg_log("\tDEBUG: old=$old new=$rg_sql_schema_ver");
353 if ($old == $rg_sql_schema_ver) {
354 rg_log("\tDEBUG: schema is up to date!");
387 return $old;
388 }
389
390 /*
391 * Tests if an update of the structure is needed.
392 * Returns FALSE on error, 0 if update is not needed, else 1.
393 */
394 function rg_sql_struct_update_needed($db)
395 {
396 global $rg_sql_schema_ver;
397
398 $old = rg_sql_struct_get_current_ver($db);
399 if ($old === FALSE)
355 400 return FALSE; return FALSE;
356 }
357 401
358 return $old;
402 if ($rg_sql_schema_ver == $old)
403 return 0;
404
405 return 1;
359 406 } }
360 407
361 408 /* /*
362 409 * Update schema if needed * Update schema if needed
363 * Returns FALSE in case of error
364 * This must not be run by web user because of the owner of the locking file.
410 * Returns FALSE in case of error.
411 * This must _not_ be run by web user because of the owner of the locking file.
365 412 */ */
366 413 function rg_sql_struct_update($db, $flags) function rg_sql_struct_update($db, $flags)
367 414 { {
 
... ... function rg_sql_struct_update($db, $flags)
369 416
370 417 rg_log("sql_struct_update: flags=$flags"); rg_log("sql_struct_update: flags=$flags");
371 418
372 $old = rg_sql_struct_update_needed($db);
419 $old = rg_sql_struct_get_current_ver($db);
373 420 if ($old === FALSE) if ($old === FALSE)
421 return FALSE;
422
423 if ($rg_sql_schema_ver == $old)
374 424 return TRUE; return TRUE;
375 425
376 426 // If we cannot lock, return error // If we cannot lock, return error
File inc/token.inc.php changed (mode: 100644) (index 2d3eb1b..07e94a1)
... ... function rg_token_set_error($str)
9 9 { {
10 10 global $rg_token_error; global $rg_token_error;
11 11 $rg_token_error = $str; $rg_token_error = $str;
12 rg_log($str);
12 13 } }
13 14
14 15 function rg_token_error() function rg_token_error()
 
... ... function rg_token_delete($db, $sid, $token)
27 28 $ret = array(); $ret = array();
28 29 $ret['ok'] = 0; $ret['ok'] = 0;
29 30
31 $params = array($sid);
30 32 $add_token = ""; $add_token = "";
31 if (!empty($token))
32 $add_token = " AND token = '$token'";
33 if (!empty($token)) {
34 $params[] = $token;
35 $add_token = " AND token = $2";
36 }
33 37
34 38 $sql = "DELETE FROM tokens" $sql = "DELETE FROM tokens"
35 . " WHERE sid = '$sid'"
39 . " WHERE sid = $1"
36 40 . $add_token; . $add_token;
37 $res = rg_sql_query($db, $sql);
41 $res = rg_sql_query_parmas($db, $sql, $params);
38 42 if ($res === FALSE) { if ($res === FALSE) {
39 43 rg_token_set_error("cannot delete token (" . rg_sql_error() . ")"); rg_token_set_error("cannot delete token (" . rg_sql_error() . ")");
40 44 return $ret; return $ret;
 
... ... function rg_token_valid($db, $sid, $token)
53 57 { {
54 58 rg_log("rg_token_get: sid=$sid token=$token"); rg_log("rg_token_get: sid=$sid token=$token");
55 59
60 $params = array($token, $sid);
56 61 $sql = "SELECT 1 AS junk FROM tokens" $sql = "SELECT 1 AS junk FROM tokens"
57 . " WHERE token = '$token'"
58 . " AND sid = '$sid'";
59 $res = rg_sql_query($db, $sql);
62 . " WHERE token = $1"
63 . " AND sid = $2";
64 $res = rg_sql_query_params($db, $sql, $params);
60 65 if ($res === FALSE) { if ($res === FALSE) {
61 66 rg_token_set_error("cannot get token (" . rg_sql_error() . ")"); rg_token_set_error("cannot get token (" . rg_sql_error() . ")");
62 67 return FALSE; return FALSE;
 
... ... function rg_token_insert($db, $sid, $token)
84 89
85 90 $now = time(); $now = time();
86 91
92 $params = array($sid, $token, $now + 24 * 3600);
87 93 $sql = "INSERT INTO tokens (sid, token, expire)" $sql = "INSERT INTO tokens (sid, token, expire)"
88 . " VALUES ('$sid', '$token', $now + 24 * 3600)";
89 $res = rg_sql_query($db, $sql);
94 . " VALUES ($1, $2, $3)";
95 $res = rg_sql_query_params($db, $sql, $params);
90 96 if ($res === FALSE) { if ($res === FALSE) {
91 97 rg_token_set_error("cannot insert token (" . rg_sql_error() . ")!"); rg_token_set_error("cannot insert token (" . rg_sql_error() . ")!");
92 98 return $ret; return $ret;
File inc/user.inc.php changed (mode: 100644) (index e9616f4..ffb18bf)
... ... require_once($INC . "/sql.inc.php");
5 5 require_once($INC . "/sess.inc.php"); require_once($INC . "/sess.inc.php");
6 6 require_once($INC . "/rights.inc.php"); require_once($INC . "/rights.inc.php");
7 7 require_once($INC . "/events.inc.php"); require_once($INC . "/events.inc.php");
8 require_once($INC . "/cache.inc.php");
9 require_once($INC . "/plan.inc.php");
8 10
9 11 $rg_user_rights = array( $rg_user_rights = array(
10 12 "C" => "Create repositories", "C" => "Create repositories",
11 "U" => "Add users"
13 "U" => "Add/edit users",
14 "S" => "Suspend accounts",
15 "A" => "Up/downgrade to admin level",
16 "R" => "Remove account"
12 17 ); );
13 18
14 19 rg_rights_register("user", $rg_user_rights); rg_rights_register("user", $rg_user_rights);
 
... ... function rg_user_link_by_name($db, $event)
96 101 { {
97 102 rg_log("user_link_by_name: event=" . rg_array2string($event)); rg_log("user_link_by_name: event=" . rg_array2string($event));
98 103
99 $by_id = rg_user_path_by_id($event['uid']);
104 $by_id = rg_user_path_by_id($event['ui.uid']);
100 105 if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) { if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) {
101 106 rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)"); rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)");
102 107 return FALSE; return FALSE;
103 108 } }
104 109
105 $by_name = rg_user_path_by_name($event['username']);
110 $by_name = rg_user_path_by_name($event['ui.username']);
106 111 $by_name_parent = dirname($by_name); $by_name_parent = dirname($by_name);
107 112 if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) { if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) {
108 113 rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)"); rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)");
109 114 return FALSE; return FALSE;
110 115 } }
111 116
112 $by_id_rel = rg_user_path_by_id_rel($event['uid']);
117 $by_id_rel = rg_user_path_by_id_rel($event['ui.uid']);
113 118 if (symlink($by_id_rel, $by_name) === FALSE) { if (symlink($by_id_rel, $by_name) === FALSE) {
114 119 rg_user_set_error("cannot symlink $by_id_rel <- $by_name ($php_errormsg)!"); rg_user_set_error("cannot symlink $by_id_rel <- $by_name ($php_errormsg)!");
115 120 return FALSE; return FALSE;
 
... ... function rg_user_ok($user)
226 231 */ */
227 232 function rg_user_lookup_by_old_name($db, $old_name) function rg_user_lookup_by_old_name($db, $old_name)
228 233 { {
229 rg_prof_start("rg_user_lookup_by_old_name");
234 rg_prof_start("user_lookup_by_old_name");
230 235 rg_log("user_lookup_by_old_name: old_name=$old_name"); rg_log("user_lookup_by_old_name: old_name=$old_name");
231 236
232 237 $ret = FALSE; $ret = FALSE;
233 238 do { do {
234 $e_old_name = rg_sql_escape($db, $old_name);
239 $x = rg_cache_get("old_name::" . $old_name);
240 if ($x !== FALSE) {
241 $ret = $x;
242 break;
243 }
244
245 $params = array($old_name);
235 246 $sql = "SELECT uid FROM users_renames" $sql = "SELECT uid FROM users_renames"
236 . " WHERE old_name = '$e_old_name'";
237 $res = rg_sql_query($db, $sql);
247 . " WHERE old_name = $1";
248 $res = rg_sql_query_params($db, $sql, $params);
238 249 if ($res === FALSE) { if ($res === FALSE) {
239 250 rg_user_set_error("cannot lookup old name (" rg_user_set_error("cannot lookup old name ("
240 251 . rg_sql_error() . ")"); . rg_sql_error() . ")");
 
... ... function rg_user_lookup_by_old_name($db, $old_name)
248 259 $ret = 0; $ret = 0;
249 260 else else
250 261 $ret = $row['uid']; $ret = $row['uid'];
262
263 rg_cache_set("old_name::" . $old_name, $ret);
251 264 } while (0); } while (0);
252 265
253 rg_prof_end("rg_user_lookup_by_old_name");
266 rg_prof_end("user_lookup_by_old_name");
254 267 return $ret; return $ret;
255 268 } }
256 269
 
... ... function rg_user_insert_rename($db, $uid, $old_name)
264 277
265 278 $ret = FALSE; $ret = FALSE;
266 279 do { do {
267 $e_old_name = rg_sql_escape($db, $old_name);
268
269 280 // Check if already exists in the database // Check if already exists in the database
270 281 $r = rg_user_lookup_by_old_name($db, $old_name); $r = rg_user_lookup_by_old_name($db, $old_name);
271 282 if ($r === FALSE) if ($r === FALSE)
272 283 break; break;
273 284 if ($r > 0) { if ($r > 0) {
285 $params = array($uid, $old_name);
274 286 $sql = "UPDATE users_renames" $sql = "UPDATE users_renames"
275 . " SET uid = $uid"
276 . " WHERE old_name = '$e_old_name'";
287 . " SET uid = $1"
288 . " WHERE old_name = $2";
277 289 } else { } else {
278 $now = time();
290 $params = array($uid, $old_name, time());
279 291 $sql = "INSERT INTO users_renames (uid, old_name" $sql = "INSERT INTO users_renames (uid, old_name"
280 292 . ", itime)" . ", itime)"
281 . " VALUES (" . $uid
282 . ", '$e_old_name'"
283 . ", $now"
284 . ")";
293 . " VALUES ($1, $2, $3)";
285 294 } }
286 $res = rg_sql_query($db, $sql);
295 $res = rg_sql_query_params($db, $sql, $params);
287 296 if ($res === FALSE) { if ($res === FALSE) {
288 297 rg_user_set_error("cannot link with old_name in db" rg_user_set_error("cannot link with old_name in db"
289 298 . " (" . rg_sql_error() . ")"); . " (" . rg_sql_error() . ")");
290 299 break; break;
291 300 } }
292 301
302 rg_cache_set("old_name::" . $old_name, $uid);
303
293 304 $ret = TRUE; $ret = TRUE;
294 305 } while (0); } while (0);
295 306
 
... ... function rg_user_rename($db, $ui, $new_name)
383 394 */ */
384 395 function rg_user_edit($db, $d) function rg_user_edit($db, $d)
385 396 { {
386 global $rg_user_info_cache; // TODO: what we do with this?
397 global $rg_account_email_confirm;
387 398
388 399 rg_prof_start("user_edit"); rg_prof_start("user_edit");
389 rg_log("user_edit: data: " . rg_array2string($d));
400 rg_log("user_edit: d: " . rg_array2string($d));
390 401
391 402 $ret = FALSE; $ret = FALSE;
392 403 do { do {
393 // DEBUG
394 if (!isset($d['username'])) {
395 rg_internal_error("username not passed");
396 break;
397 }
398
399 404 if (rg_user_ok($d['username']) !== TRUE) if (rg_user_ok($d['username']) !== TRUE)
400 405 break; break;
401 406
402 $now = time();
403 $e_username = rg_sql_escape($db, $d['username']);
404 $e_realname = rg_sql_escape($db, $d['realname']);
405 $e_salt = rg_id(40);
406 $e_pass = rg_user_pass($e_salt, $d['pass']);
407 $e_email = rg_sql_escape($db, $d['email']);
408 $e_rights = rg_sql_escape($db, $d['rights']);
409 $e_is_admin = $d['is_admin'];
410 $e_disk_quota_mb = $d['disk_quota_mb'];
411 $e_session_time = $d['session_time'];
412 $e_confirm_token = isset($d['confirm_token']) ? $d['confirm_token'] : "";
413
414 if (empty($d['confirm_token'])) {
407 // TODO: check rights
408 // TODO - check if user is allowed to give passed rights
409
410 if ($rg_account_email_confirm == 0) {
415 411 // no need to confirm account // no need to confirm account
416 $e_confirmed = $now;
412 $confirmed = 1; // signals "no-need-to-confirm"
417 413 } else { } else {
418 $e_confirmed = 0;
414 $confirmed = 0;
415 }
416
417 if (!empty($d['pass'])) {
418 if (strcmp($d['pass'], $d['pass2']) != 0) {
419 rg_user_set_error("passwords are not the same");
420 break;
421 }
419 422 } }
420 423
424 $now = time();
425 $d['salt'] = rg_id(40);
426 $d['pass_crypted'] = rg_user_pass($d['salt'], $d['pass']);
427
421 428 if ($d['uid'] == 0) { // add if ($d['uid'] == 0) { // add
422 429 if (rg_user_pass_ok($d['pass']) !== TRUE) if (rg_user_pass_ok($d['pass']) !== TRUE)
423 430 break; break;
424 431
432 $params = array($d['username'], $d['realname'], $d['salt'],
433 $d['pass_crypted'], $d['email'], $now, $d['is_admin'],
434 $d['rights'], $d['session_time'], $confirmed,
435 $d['confirm_token'], $d['plan_id']);
425 436 $sql = "INSERT INTO users (username, realname, salt, pass" $sql = "INSERT INTO users (username, realname, salt, pass"
426 437 . ", email, itime" . ", email, itime"
427 . ", is_admin, disk_quota_mb, rights, session_time"
428 . ", confirmed, confirm_token)"
429 . " VALUES ('$e_username', '$e_realname', '$e_salt', '$e_pass'"
430 . ", '$e_email', $now, $e_is_admin, $e_disk_quota_mb"
431 . ", '$e_rights', $e_session_time"
432 . ", $e_confirmed, '$e_confirm_token')"
438 . ", is_admin, rights, session_time"
439 . ", confirmed, confirm_token, plan_id)"
440 . " VALUES ($1, $2, $3, $4, $5, $6, $7"
441 . ", $8, $9, $10, $11, $12)"
433 442 . " RETURNING uid"; . " RETURNING uid";
434 443 } else { // edit } else { // edit
444 $params = array($d['username'], $d['realname'],
445 $d['email'], $d['is_admin'], $d['rights'],
446 $d['session_time'], $d['uid']);
447
435 448 $salt_pass_add = ""; $salt_pass_add = "";
436 if (!empty($d['pass']))
437 $salt_pass_add = ", pass = '$e_pass', salt = '$e_salt'";
449 if (!empty($d['pass'])) {
450 $params[] = $d['pass_crypted'];
451 $params[] = $d['salt'];
452 $salt_pass_add = ", pass = $8, salt = $9";
453 }
438 454
439 455 $sql = "UPDATE users" $sql = "UPDATE users"
440 . " SET username = '$e_username'"
441 . ", realname = '$e_realname'"
456 . " SET username = $1"
457 . ", realname = $2"
458 . ", email = $3"
459 . ", is_admin = $4"
460 . ", rights = $5"
461 . ", session_time = $6"
442 462 . $salt_pass_add . $salt_pass_add
443 . ", email = '$e_email'"
444 . ", is_admin = $e_is_admin"
445 . ", disk_quota_mb = $e_disk_quota_mb"
446 . ", rights = '$e_rights'"
447 . ", session_time = $e_session_time"
448 . " WHERE uid = " . $d['uid']
463 . " WHERE uid = $7"
449 464 . " RETURNING uid"; . " RETURNING uid";
450 465 } }
451 466
452 $res = rg_sql_query($db, $sql);
467 $res = rg_sql_query_params($db, $sql, $params);
453 468 if ($res === FALSE) { if ($res === FALSE) {
454 469 rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")"); rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")");
455 470 break; break;
 
... ... function rg_user_edit($db, $d)
457 472 $row = rg_sql_fetch_array($res); $row = rg_sql_fetch_array($res);
458 473 rg_sql_free_result($res); rg_sql_free_result($res);
459 474
460 // invalidate cache
461 $rg_user_info_cache = array();
475 // invalidate cache (because we may not have the password)
476 if ($d['uid'] > 0)
477 rg_cache_unset("user::" . $d['uid']);
462 478
463 479 if ($d['uid'] == 0) { // add if ($d['uid'] == 0) { // add
464 480 $event = array("category" => 2000, "prio" => 50, $event = array("category" => 2000, "prio" => 50,
465 481 "ui.uid" => $d['uid'], "ui.uid" => $d['uid'],
466 482 "ui.username" => $d['username'], "ui.username" => $d['username'],
467 "ui.email" => $d['email']
483 "ui.email" => $d['email'],
484 "ui.confirm_token" => $d['confirm_token'],
485 "rg_account_email_confirm" => $rg_account_email_confirm,
486 "url" => rg_base_url()
468 487 ); );
469 488 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
470 489 if ($r === FALSE) { if ($r === FALSE) {
 
... ... function rg_user_edit($db, $d)
485 504 */ */
486 505 function rg_user_remove($db, $uid) function rg_user_remove($db, $uid)
487 506 { {
488 global $rg_user_info_cache;
489
490 507 rg_prof_start("user_remove"); rg_prof_start("user_remove");
491 508 rg_log("user_remove: uid=$uid"); rg_log("user_remove: uid=$uid");
492 509
493 510 $ret = FALSE; $ret = FALSE;
494 511 do { do {
495 $uid = sprintf("%u", $uid);
512 $login_ui = rg_get_login_ui();
513 if (!rg_rights_allow($login_ui['rights'], "R"))
514 break;
496 515
497 $sql = "DELETE FROM users WHERE uid = $uid";
498 $res = rg_sql_query($db, $sql);
516 $params = array($uid);
517 $sql = "DELETE FROM users WHERE uid = $1";
518 $res = rg_sql_query_params($db, $sql, $params);
499 519 if ($res === FALSE) { if ($res === FALSE) {
500 520 rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")"); rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")");
501 521 break; break;
 
... ... function rg_user_remove($db, $uid)
503 523 rg_sql_free_result($res); rg_sql_free_result($res);
504 524
505 525 // invalidate cache // invalidate cache
506 $rg_user_info_cache = array();
526 rg_cache_unset("user::" . $uid);
507 527
508 528 $ret = TRUE; $ret = TRUE;
509 529 } while (0); } while (0);
 
... ... function rg_user_remove($db, $uid)
515 535 /* /*
516 536 * Returns info about a user (by uid, user or e-mail) * Returns info about a user (by uid, user or e-mail)
517 537 */ */
518 $rg_user_info_cache = array();
519 538 function rg_user_info($db, $uid, $user, $email) function rg_user_info($db, $uid, $user, $email)
520 539 { {
521 global $rg_user_info_cache;
522
523 $key = $uid . "__" . $user . "__" . $email;
524 if (isset($rg_user_info_cache[$key]))
525 return $rg_user_info_cache[$key];
526
527 540 rg_prof_start("user_info"); rg_prof_start("user_info");
528 rg_log("user_info: uid/user/email=$uid/$user/$email...");
529 541
530 542 $ret = array(); $ret = array();
531 543 $ret['ok'] = 0; $ret['ok'] = 0;
532 544 $ret['exists'] = 0; $ret['exists'] = 0;
533 545 $ret['uid'] = 0; $ret['uid'] = 0;
534 546 $ret['is_admin'] = 0; $ret['is_admin'] = 0;
547 $ret['rights'] = "";
548
549 $set_cache = FALSE;
550 $set_cache_user = FALSE;
551 $set_cache_email = FALSE;
552 while (1) {
553 //rg_log("user_info: uid=$uid user=$user email=$email.");
554
555 if ($uid > 0) {
556 $c = rg_cache_get("user::" . $uid);
557 if ($c !== FALSE) {
558 $ret = unserialize($c);
559 if ($ret === FALSE)
560 rg_log("cannot unserialize ($c)");
561 break;
562 }
535 563
536 // in case we return error
537 $rg_user_info_cache[$key] = $ret;
564 $params = array($uid);
565 $sql = "SELECT * FROM users WHERE uid = $1";
566 $set_cache = TRUE;
567 } else if (!empty($user)) {
568 if (rg_user_ok($user) !== TRUE)
569 break;
538 570
539 if ($uid > 0) {
540 $add = " AND uid = " . sprintf("%u", $uid);
541 } else if (!empty($user)) {
542 if (rg_user_ok($user) !== TRUE)
543 return FALSE;
571 $c = rg_cache_get("username_to_uid::" . $user);
572 if ($c !== FALSE) {
573 $uid = $c;
574 continue;
575 }
544 576
545 $e_user = rg_sql_escape($db, $user);
546 $add = " AND username = '$e_user'";
547 } else if (!empty($email)) {
548 $e_email = rg_sql_escape($db, $email);
549 $add = " AND email = '$e_email'";
550 } else {
551 return FALSE;
552 }
577 $params = array($user);
578 $sql = "SELECT * FROM users WHERE username = $1";
579 $set_cache_user = TRUE;
580 } else if (!empty($email)) {
581 $c = rg_cache_get("email_to_uid::" . $email);
582 if ($c != FALSE) {
583 $uid = $c;
584 continue;
585 }
553 586
554 $sql = "SELECT * FROM users WHERE 1 = 1" . $add;
555 $res = rg_sql_query($db, $sql);
556 if ($res === FALSE) {
557 rg_user_set_error("cannot get info (" . rg_sql_error() . ")");
558 return $ret;
559 }
587 $params = array($email);
588 $sql = "SELECT * FROM users WHERE email = $1";
589 $set_cache_email = TRUE;
590 } else {
591 break;
592 }
560 593
561 $ret['ok'] = 1;
562 $rows = rg_sql_num_rows($res);
563 if ($rows > 0)
564 $row = rg_sql_fetch_array($res);
565 rg_sql_free_result($res);
566 if ($rows == 0) {
567 rg_user_set_error("user not found");
568 return $ret;
569 }
594 $res = rg_sql_query_params($db, $sql, $params);
595 if ($res === FALSE) {
596 rg_user_set_error("cannot get info (" . rg_sql_error() . ")");
597 break;
598 }
570 599
571 $row['ok'] = 1;
572 $row['exists'] = 1;
573 rg_log("\tUser found.");
600 $ret['ok'] = 1;
601 $rows = rg_sql_num_rows($res);
602 if ($rows > 0)
603 $row = rg_sql_fetch_array($res);
604 rg_sql_free_result($res);
605 if ($rows == 0) {
606 rg_log("user not found");
607 rg_user_set_error("user not found");
608 break;
609 }
610
611 $ret = array_merge($ret, $row);
612 $ret['exists'] = 1;
613 break;
614 };
615
616 if (($ret['ok'] == 1) && $set_cache)
617 rg_cache_set("user::" . $ret['uid'], serialize($ret));
618
619 if ($ret['exists'] == 1) {
620 if ($set_cache_user)
621 rg_cache_set("username_to_uid::" . $ret['username'], $ret['uid']);
574 622
575 $rg_user_info_cache[$key] = $row;
623 if ($set_cache_email)
624 rg_cache_set("email_to_uid::" . $ret['email'], $ret['uid']);
625 }
576 626
577 627 rg_prof_end("user_info"); rg_prof_end("user_info");
578 return $row;
628 return $ret;
579 629 } }
580 630
581 631 /* /*
 
... ... function rg_user_info($db, $uid, $user, $email)
583 633 */ */
584 634 function rg_user_login_by_sid($db, $sid, &$ui) function rg_user_login_by_sid($db, $sid, &$ui)
585 635 { {
636 rg_prof_start("user_login_by_sid");
586 637 rg_log("user_login_by_sid: sid=$sid..."); rg_log("user_login_by_sid: sid=$sid...");
587 638
588 639 // Make sure it is not passed by client // Make sure it is not passed by client
589 640 $ui = array(); $ui = array();
590 641 $ui['uid'] = 0; $ui['uid'] = 0;
591 642 $ui['is_admin'] = 0; $ui['is_admin'] = 0;
643 $ui['rights'] = "";
592 644 $ui['username'] = ""; $ui['username'] = "";
593 645
594 if (empty($sid)) {
595 rg_log("\tNo sid!");
596 return FALSE;
597 }
646 $ret = FALSE;
647 do {
648 if (empty($sid)) {
649 rg_log("\tNo sid!");
650 break;
651 }
598 652
599 $uid = rg_sess_valid($db, $sid);
600 if ($uid == 0)
601 return FALSE;
653 $sess = rg_sess_valid($db, $sid);
654 if ($sess == FALSE) {
655 rg_log("session is not valid");
656 break;
657 }
602 658
603 $ui = rg_user_info($db, $uid, "", "");
604 if ($ui['exists'] != 1) {
605 rg_log("\tUid $uid does not exists (" . rg_user_error() . ")!");
606 rg_user_set_error("invalid uid");
607 return FALSE;
608 }
659 $uid = $sess['uid'];
660 $ui = rg_user_info($db, $uid, "", "");
661 if ($ui['exists'] != 1) {
662 rg_log("\tUid $uid does not exists (" . rg_user_error() . ")!");
663 rg_user_set_error("invalid uid");
664 break;
665 }
609 666
610 rg_sess_update($db, $sid);
667 rg_sess_update($db, $sess);
611 668
612 rg_user_set_last_seen($db, $ui['uid']);
669 rg_user_set_last_seen($db, $ui['uid']);
613 670
614 return TRUE;
671 $ret = TRUE;
672 } while (0);
673
674 rg_prof_end("user_login_by_sid");
675 return $ret;
615 676 } }
616 677
617 678 /* /*
 
... ... function rg_user_pass_valid($db, $uid, $pass)
645 706 /* /*
646 707 * Auto login the user * Auto login the user
647 708 */ */
648 function rg_user_auto_login($db, $uid, &$ui)
709 function rg_user_auto_login($db, $uid, $lock_ip, &$ui)
649 710 { {
650 $ui = rg_user_info($db, $uid, "", "");
651 if ($ui['ok'] != 1)
652 return FALSE;
711 rg_prof_start("user_auto_login");
712 rg_log("user_auto_login: uid=$uid lock_ip=$lock_ip");
653 713
654 if ($ui['exists'] != 1)
655 return FALSE;
714 $ret = FALSE;
715 do {
716 $ui = rg_user_info($db, $uid, "", "");
717 if ($ui['ok'] != 1)
718 break;
656 719
657 $secure = FALSE;
658 if (isset($_SERVER['HTTPS']))
659 $secure = TRUE;
720 if ($ui['exists'] != 1) {
721 rg_log("user does not exists");
722 break;
723 }
660 724
661 $sid = rg_id(40);
662 rg_sess_add($db, $uid, $sid, $ui['session_time']);
663 setcookie("sid", $sid, 0, "/", $_SERVER['SERVER_NAME'],
664 $secure, TRUE /* httponly */);
725 $secure = FALSE;
726 if (isset($_SERVER['HTTPS']))
727 $secure = TRUE;
665 728
666 return TRUE;
729 $sid = rg_id(40);
730 rg_sess_add($db, $uid, $sid, $ui['session_time'], $lock_ip);
731 setcookie("sid", $sid, 0, "/", $_SERVER['SERVER_NAME'],
732 $secure, TRUE /* httponly */);
733
734 $ret = TRUE;
735 } while (0);
736
737 rg_prof_end("user_auto_login");
738 return $ret;
667 739 } }
668 740
669 741 /* /*
670 742 * Test if login is OK * Test if login is OK
671 743 */ */
672 function rg_user_login_by_user_pass($db, $user, $pass, &$ui)
744 function rg_user_login_by_user_pass($db, $user, $pass, $lock_ip, &$ui)
673 745 { {
674 rg_log("user_login_by_user_pass: user=$user, pass=$pass...");
746 rg_log("user_login_by_user_pass: user=$user, pass=$pass lock_ip=$lock_ip");
675 747
676 748 $ui = array(); $ui = array();
677 749 $ui['uid'] = 0; $ui['uid'] = 0;
678 750 $ui['is_admin'] = 0; $ui['is_admin'] = 0;
751 $ui['rights'] = "";
679 752
680 753 if (empty($user) || empty($pass)) { if (empty($user) || empty($pass)) {
681 754 rg_user_set_error("invalid user or pass"); rg_user_set_error("invalid user or pass");
755 rg_log("user or pass are empty");
682 756 return FALSE; return FALSE;
683 757 } }
684 758
685 759 $ui0 = rg_user_info($db, 0, $user, ""); $ui0 = rg_user_info($db, 0, $user, "");
686 if ($ui0['ok'] != 1) {
687 rg_user_set_error("internal error");
760 if ($ui0['ok'] != 1)
688 761 return FALSE; return FALSE;
689 }
690 762 if ($ui0['exists'] != 1) { if ($ui0['exists'] != 1) {
691 763 rg_user_set_error("invalid user or pass"); rg_user_set_error("invalid user or pass");
764 rg_log("user doesn't exists");
692 765 return FALSE; return FALSE;
693 766 } }
694 767
695 768 if ($ui0['suspended'] > 0) { if ($ui0['suspended'] > 0) {
696 769 rg_user_set_error("invalid user or pass"); rg_user_set_error("invalid user or pass");
770 rg_log("account is suspended");
697 771 return FALSE; return FALSE;
698 772 } }
699 773
700 774 if ($ui0['confirmed'] == 0) { if ($ui0['confirmed'] == 0) {
701 775 rg_user_set_error("invalid user or pass"); rg_user_set_error("invalid user or pass");
776 rg_log("account is not confirmed");
702 777 return FALSE; return FALSE;
703 778 } }
704 779
705 780 $sha1pass = rg_user_pass($ui0['salt'], $pass); $sha1pass = rg_user_pass($ui0['salt'], $pass);
706 781 if (strcmp($sha1pass, $ui0['pass']) != 0) { if (strcmp($sha1pass, $ui0['pass']) != 0) {
707 782 rg_user_set_error("invalid user or pass"); rg_user_set_error("invalid user or pass");
783 rg_log("pass mismatch");
708 784 return FALSE; return FALSE;
709 785 } }
710 786
711 787 $ui = $ui0; $ui = $ui0;
712 rg_user_auto_login($db, $ui['uid'], $ui);
788 rg_user_auto_login($db, $ui['uid'], $lock_ip, $ui);
713 789
714 790 rg_user_set_last_seen($db, $ui['uid']); rg_user_set_last_seen($db, $ui['uid']);
715 791
 
... ... function rg_user_suspend($db, $uid, $op)
724 800 { {
725 801 rg_log("user_suspend: uid=$uid, op=$op"); rg_log("user_suspend: uid=$uid, op=$op");
726 802
803 $login_ui = rg_get_login_ui();
804 if (!rg_rights_allow($login_ui['rights'], "S"))
805 return FALSE;
806
727 807 $now = time(); $now = time();
728 808
729 809 if ($op == 1) if ($op == 1)
 
... ... function rg_user_suspend($db, $uid, $op)
731 811 else else
732 812 $v = 0; $v = 0;
733 813
734 $sql = "UPDATE users SET suspended = $v WHERE uid = $uid";
735 $res = rg_sql_query($db, $sql);
814 $parmas = array($v, $uid);
815 $sql = "UPDATE users SET suspended = $1 WHERE uid = $2";
816 $res = rg_sql_query_params($db, $sql, $params);
736 817 if ($res === FALSE) { if ($res === FALSE) {
737 818 rg_user_set_error("cannot suspend (" . rg_sql_error() . ")"); rg_user_set_error("cannot suspend (" . rg_sql_error() . ")");
738 819 return FALSE; return FALSE;
739 820 } }
740 821 rg_sql_free_result($res); rg_sql_free_result($res);
741 822
823 // Invalidate cache.
824 rg_cache_unset("user::" . $uid);
825
742 826 return TRUE; return TRUE;
743 827 } }
744 828
 
... ... function rg_user_suspend($db, $uid, $op)
749 833 function rg_user_make_admin($db, $uid, $op) function rg_user_make_admin($db, $uid, $op)
750 834 { {
751 835 rg_log("user_make_admin: uid=$uid, op=$op"); rg_log("user_make_admin: uid=$uid, op=$op");
836 rg_prof_start("user_make_admin");
752 837
753 $sql = "UPDATE users SET is_admin = $op WHERE uid = $uid";
754 $res = rg_sql_query($db, $sql);
755 if ($res === FALSE) {
756 rg_user_set_error("cannot make admin (" . rg_sql_error() . ")");
757 return FALSE;
758 }
759 rg_sql_free_result($res);
838 $ret = FALSE;
839 do {
840 $login_ui = rg_get_login_ui();
841 if (!rg_rights_allow($login_ui['rights'], "A"))
842 return FALSE;
760 843
761 return TRUE;
844 $params = array($op, $uid);
845 $sql = "UPDATE users SET is_admin = $1 WHERE uid = $2";
846 $res = rg_sql_query_params($db, $sql, $params);
847 if ($res === FALSE) {
848 rg_user_set_error("cannot make admin (" . rg_sql_error() . ")");
849 break;
850 }
851 rg_sql_free_result($res);
852
853 // Invalidate cache.
854 rg_cache_unset("user::" . $uid);
855 $ret = TRUE;
856 } while (0);
857
858 rg_prof_end("user_make_admin");
859 return $ret;
762 860 } }
763 861
764 862 /* /*
 
... ... function rg_user_set_last_seen($db, $uid)
770 868
771 869 $now = time(); $now = time();
772 870
773 $sql = "UPDATE users SET last_seen = $now WHERE uid = $uid";
774 $res = rg_sql_query($db, $sql);
871 $params = array($now, $uid);
872 $sql = "UPDATE users SET last_seen = $1 WHERE uid = $2";
873 $res = rg_sql_query_params($db, $sql, $params);
775 874 if ($res === FALSE) { if ($res === FALSE) {
776 875 rg_user_set_error("cannot update last seen (" . rg_sql_error() . ")"); rg_user_set_error("cannot update last seen (" . rg_sql_error() . ")");
777 876 return FALSE; return FALSE;
778 877 } }
779 878 rg_sql_free_result($res); rg_sql_free_result($res);
780 879
880 // TODO: check if we need to invalidate cache
881
781 882 return TRUE; return TRUE;
782 883 } }
783 884
784 885 /* /*
785 886 * List users * List users
887 * TODO: switch to templates.
786 888 */ */
787 function rg_user_list($db, $url)
889 function rg_user_list($db)
788 890 { {
789 rg_log("user_list, url=$url...");
891 rg_log("user_list");
790 892
791 893 $ret = ""; $ret = "";
792 894
793 $uid = rg_var_uint("uid");
794
795 $suspend = rg_var_uint("suspend");
796 if ($suspend == 1) {
797 if (!rg_user_suspend($db, $uid, 1))
798 $ret .= "<font color=red>Cannot suspend!</font><br />";
799 }
800
801 $unsuspend = rg_var_uint("unsuspend");
802 if ($unsuspend == 1) {
803 if (!rg_user_suspend($db, $uid, 0))
804 $ret .= "<font color=red>Cannot unsuspend!</font><br />";
805 }
806
807 $make_admin = rg_var_uint("make_admin");
808 if ($make_admin == 1) {
809 if (!rg_user_make_admin($db, $uid, 1))
810 $ret .= "<font color=red>Cannot make admin!</font><br />";
811 }
812
813 $remove_admin = rg_var_uint("remove_admin");
814 if ($remove_admin == 1) {
815 if (!rg_user_make_admin($db, $uid, 0))
816 $ret .= "<font color=red>Cannot remove admin!</font><br />";
817 }
818
819 $remove = rg_var_uint("remove");
820 if ($remove > 0) {
821 if (!rg_user_remove($db, $uid))
822 $ret .= "<font color=red>Cannot remove!</font><br />";
823 }
824
825 895 $sql = "SELECT * FROM users ORDER BY username"; $sql = "SELECT * FROM users ORDER BY username";
826 896 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
827 897 if ($res === FALSE) { if ($res === FALSE) {
 
... ... function rg_user_list($db, $url)
836 906 $ret .= " <th>E-mail</th>\n"; $ret .= " <th>E-mail</th>\n";
837 907 $ret .= " <th>Admin?</th>\n"; $ret .= " <th>Admin?</th>\n";
838 908 $ret .= " <th>Creation date (UTC)</th>\n"; $ret .= " <th>Creation date (UTC)</th>\n";
839 $ret .= " <th>Quota</th>\n";
909 $ret .= " <th>Plan</th>\n";
840 910 $ret .= " <th>Suspended?</th>\n"; $ret .= " <th>Suspended?</th>\n";
841 911 $ret .= " <th>Confirmed?</th>\n"; $ret .= " <th>Confirmed?</th>\n";
842 912 $ret .= " <th>Session time</th>\n"; $ret .= " <th>Session time</th>\n";
 
... ... function rg_user_list($db, $url)
851 921 $ret .= " <td>" . $row['email'] . "</td>\n"; $ret .= " <td>" . $row['email'] . "</td>\n";
852 922 $ret .= " <td>" . ($row['is_admin'] == 1 ? "Yes" : "No") . "</td>\n"; $ret .= " <td>" . ($row['is_admin'] == 1 ? "Yes" : "No") . "</td>\n";
853 923 $ret .= " <td>" . gmdate("Y-m-d", $row['itime']) . "</td>\n"; $ret .= " <td>" . gmdate("Y-m-d", $row['itime']) . "</td>\n";
854 if ($row['disk_quota_mb'] > 0)
855 $_v = rg_1024($row['disk_quota_mb'] * 1024 * 1024);
856 else
857 $_v = "unlimited";
858 $ret .= " <td>" . $_v . "</td>\n";
924
925 $pi = rg_plan_info($db, $row['plan_id']);
926 $plan = "Unlimited";
927 if ($pi['exists'] == 1)
928 $plan = $pi['name'];
929 $ret .= " <td>" . $plan . "</td>\n";
859 930 $ret .= " <td>" . ($row['suspended'] == 0 ? "No" : "Yes") . "</th>\n"; $ret .= " <td>" . ($row['suspended'] == 0 ? "No" : "Yes") . "</th>\n";
860 931 $ret .= " <td>" . ($row['confirmed'] == 0 ? "No" : gmdate("Y-m-d", $row['confirmed'])) . "</th>\n"; $ret .= " <td>" . ($row['confirmed'] == 0 ? "No" : gmdate("Y-m-d", $row['confirmed'])) . "</th>\n";
861 932 $ret .= " <td>" . $row['session_time'] . "s</td>\n"; $ret .= " <td>" . $row['session_time'] . "s</td>\n";
 
... ... function rg_user_list($db, $url)
865 936 $ret .= " <td>" . $v . "</td>\n"; $ret .= " <td>" . $v . "</td>\n";
866 937
867 938 // operations // operations
868 $_url = $url . "&amp;uid=" . $row['uid'];
939 $url = "/op/admin/users";
940 $url2 = $row['username'];
869 941 $ret .= " <td>"; $ret .= " <td>";
870 942
871 943 // edit // edit
872 $ret .= "[<a href=\"$_url&amp;subsubop=3\">Edit</a>]";
944 $ret .= "[<a href=\"$url/edit/$url2\">Edit</a>]";
873 945
874 946 // suspend // suspend
875 $v = "suspend=1"; $t = "Suspend";
947 $v = "suspend"; $t = "Suspend";
876 948 if ($row['suspended'] > 0) { if ($row['suspended'] > 0) {
877 949 $t = "Unsuspend"; $t = "Unsuspend";
878 $v = "unsuspend=1";
950 $v = "unsuspend";
879 951 } }
880 $ret .= "[<a href=\"$_url&amp;subsubop=1&amp;$v\">$t</a>]";
952 $ret .= "[<a href=\"$url/$v/$url2\">$t</a>]";
881 953
882 954 // admin // admin
883 $v = "make_admin=1"; $t = "Make admin";
955 $v = "make_admin"; $t = "Make admin";
884 956 if ($row['is_admin'] == 1) { if ($row['is_admin'] == 1) {
885 957 $t = "Remove admin"; $t = "Remove admin";
886 $v = "remove_admin=1";
958 $v = "remove_admin";
887 959 } }
888 $ret .= "[<a href=\"$_url&amp;subsubop=1&amp;$v\">$t</a>]";
960 $ret .= "[<a href=\"$url/$v/$url2\">$t</a>]";
889 961
890 962 // remove // remove
891 963 if ($row['suspended'] > 0) if ($row['suspended'] > 0)
892 $ret .= "[<a href=\"$_url&amp;subsubop=1&amp;remove=1\">Remove!</a>]";
964 $ret .= "[<a href=\"$url/remove/$url2\">Remove!</a>]";
893 965
894 966 $ret .= " </td>"; $ret .= " </td>";
895 967 $ret .= "</tr>\n"; $ret .= "</tr>\n";
 
... ... function rg_user_forgot_pass_uid($db, $token)
912 984 rg_log("user_forgot_pass_uid: token=$token"); rg_log("user_forgot_pass_uid: token=$token");
913 985
914 986 $now = time(); $now = time();
915 $e_token = rg_sql_escape($db, $token);
916 987
988 $params = array($token, $now);
917 989 $sql = "SELECT uid FROM forgot_pass" $sql = "SELECT uid FROM forgot_pass"
918 . " WHERE token = '$e_token'"
919 . " AND expire > $now";
920 $res = rg_sql_query($db, $sql);
990 . " WHERE token = $1"
991 . " AND expire > $2";
992 $res = rg_sql_query_params($db, $sql, $params);
921 993 if ($res === FALSE) { if ($res === FALSE) {
922 994 rg_user_set_error("cannot lookup token (" . rg_sql_error() . ")"); rg_user_set_error("cannot lookup token (" . rg_sql_error() . ")");
923 995 return $ret; return $ret;
 
... ... function rg_user_forgot_pass_mail_prepare($db, $email)
964 1036 $uid = $r['uid']; $uid = $r['uid'];
965 1037
966 1038 // store token in database // store token in database
1039 $params = array($token, $uid, $expire);
967 1040 $sql = "INSERT INTO forgot_pass (token, uid, expire)" $sql = "INSERT INTO forgot_pass (token, uid, expire)"
968 . " VALUES ('$token', $uid, $expire)";
969 $res = rg_sql_query($db, $sql);
1041 . " VALUES ($1, $2, $3)";
1042 $res = rg_sql_query_params($db, $sql, $params);
970 1043 if ($res === FALSE) { if ($res === FALSE) {
971 1044 rg_user_set_error("cannot query (" . rg_sql_error() . ")"); rg_user_set_error("cannot query (" . rg_sql_error() . ")");
972 1045 return $ret; return $ret;
 
... ... function rg_user_forgot_pass_mail($db, $email)
1012 1085 "Hello!\n\n" "Hello!\n\n"
1013 1086 . "If you want to reset the password, follow:\n" . "If you want to reset the password, follow:\n"
1014 1087 . $base_url . $base_url
1015 . rg_re_url("/op/forgot_link") . "&forgot_token=" . $r['token']
1088 . rg_re_url("/op/forgot_link") . "/" . $r['token']
1016 1089 . "\n\nRocketGit team", . "\n\nRocketGit team",
1017 1090 $headers, $headers,
1018 1091 "-f $rg_admin_email")) { "-f $rg_admin_email")) {
 
... ... function rg_user_forgot_pass_destroy($db, $uid)
1033 1106 { {
1034 1107 rg_log("user_forgot_pass_destroy: uid=$uid"); rg_log("user_forgot_pass_destroy: uid=$uid");
1035 1108
1036 $sql = "DELETE FROM forgot_pass WHERE uid = $uid";
1037 $res = rg_sql_query($db, $sql);
1109 $params = array($uid);
1110 $sql = "DELETE FROM forgot_pass WHERE uid = $1";
1111 $res = rg_sql_query_params($db, $sql, $params);
1038 1112 if ($res === FALSE) { if ($res === FALSE) {
1039 1113 rg_user_set_error("cannot query (" . rg_sql_error() . ")"); rg_user_set_error("cannot query (" . rg_sql_error() . ")");
1040 1114 return FALSE; return FALSE;
 
... ... function rg_user_set_pass($db, $uid, $pass)
1048 1122 { {
1049 1123 rg_log("user_set_pass: uid=$uid pass=$pass"); rg_log("user_set_pass: uid=$uid pass=$pass");
1050 1124
1051 $e_salt = rg_id(40);
1052 $e_sha1pass = rg_user_pass($e_salt, $pass);
1125 $salt = rg_id(40);
1126 $pass = rg_user_pass($salt, $pass);
1053 1127
1128 $params = array($salt, $pass, $uid);
1054 1129 $sql = "UPDATE users SET" $sql = "UPDATE users SET"
1055 ." salt = '$e_salt'"
1056 . ", pass = '$e_sha1pass'"
1057 . " WHERE uid = " . $uid;
1058 $res = rg_sql_query($db, $sql);
1130 ." salt = $1"
1131 . ", pass = $2"
1132 . " WHERE uid = $3";
1133 $res = rg_sql_query_params($db, $sql, $params);
1059 1134 if ($res === FALSE) { if ($res === FALSE) {
1060 1135 rg_user_set_error("cannot update pass (" . rg_sql_error() . ")"); rg_user_set_error("cannot update pass (" . rg_sql_error() . ")");
1061 1136 return FALSE; return FALSE;
1062 1137 } }
1063 1138 rg_sql_free_result($res); rg_sql_free_result($res);
1064 1139
1140 // Invalidate cache.
1141 rg_cache_unset("user::" . $uid);
1142
1065 1143 return TRUE; return TRUE;
1066 1144 } }
1067 1145
1068 1146 /* /*
1069 * Confirm account creation (send mail)
1147 * Confirm account creation
1070 1148 */ */
1071 function rg_user_confirm_send($email, $token)
1149 function rg_user_confirm($db, $token)
1072 1150 { {
1073 global $rg_admin_name, $rg_admin_email;
1151 rg_prof_start("user_confirm");
1152 rg_log("user_confirm: token=$token");
1074 1153
1075 rg_log("user_confirm_send: email=$email, token=$token");
1154 $now = time();
1155 $token = preg_replace("/[^A-Za-z0-9]/", "", $token);
1076 1156
1077 $headers = "From: $rg_admin_name <$rg_admin_email>";
1157 $ret = FALSE;
1158 do {
1159 if (empty($token)) {
1160 rg_user_set_error("invalid token");
1161 break;
1162 }
1078 1163
1079 $proto = "http://";
1080 if (isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'], "on") == 0))
1081 $proto = "https://";
1164 $params = array($token);
1165 $sql = "SELECT uid FROM users WHERE confirm_token = $1";
1166 $res = rg_sql_query_params($db, $sql, $params);
1167 if ($res === FALSE) {
1168 rg_user_set_error("cannot search for token (" . rg_sql_error() . ")");
1169 break;
1170 }
1171 $rows = rg_sql_num_rows($res);
1172 if ($rows == 1)
1173 $row = rg_sql_fetch_array($res);
1174 rg_sql_free_result($res);
1175 if ($rows != 1) {
1176 rg_user_set_error("cannot find token");
1177 break;
1178 }
1179 $uid = $row['uid'];
1180
1181 // "< 2" because we mark with "1" if "no need to confirm"
1182 $params = array($now, $uid);
1183 $sql = "UPDATE users SET confirmed = $1"
1184 . " WHERE uid = $2"
1185 . " AND confirmed < 2";
1186 $res = rg_sql_query_params($db, $sql, $params);
1187 if ($res === FALSE) {
1188 rg_user_set_error("cannot update confirmed (" . rg_sql_error() . ")");
1189 break;
1190 }
1191 rg_sql_free_result($res);
1082 1192
1083 if (!mail($email,
1084 "Account creation confirmation",
1085 "Hello!\n\n"
1086 . "Please confirm your account creation following:\n"
1087 . $proto
1088 . @$_SERVER['HTTP_HOST']
1089 . rg_re_url("/op/confirm") . "&token=" . $token
1090 . "\n\nRocketGit team",
1091 $headers,
1092 "-f $rg_admin_email")) {
1093 rg_user_set_error("cannot send mail ($php_errormsg)!");
1094 return FALSE;
1095 }
1193 rg_cache_unset("user::" . $uid);
1096 1194
1097 return TRUE;
1195 $ret = $uid;
1196 } while (0);
1197
1198 rg_prof_end("user_confirm");
1199 return $ret;
1098 1200 } }
1099 1201
1100 1202 /* /*
1101 * Confirm account creation
1203 * Add a suggestion to database
1102 1204 */ */
1103 function rg_user_confirm($db, $token)
1205 function rg_user_suggestion($db, $uid, $email, $suggestion)
1104 1206 { {
1105 $now = time();
1106
1107 $sql = "SELECT uid FROM users WHERE confirm_token = '$token'";
1108 $res = rg_sql_query($db, $sql);
1207 $params = array($uid, $email, $suggestion);
1208 $sql = "INSERT INTO suggestions (uid, email, suggestion)"
1209 . " VALUES ($1, $2, $3)";
1210 $res = rg_sql_query_params($db, $sql, $params);
1109 1211 if ($res === FALSE) { if ($res === FALSE) {
1110 rg_user_set_error("cannot search for token (" . rg_sql_error() . ")");
1212 rg_user_set_error("cannot add suggestion (" . rg_sql_error() . ")");
1111 1213 return FALSE; return FALSE;
1112 1214 } }
1113 $rows = rg_sql_num_rows($res);
1114 if ($rows > 0)
1115 $row = rg_sql_fetch_array($res);
1116 1215 rg_sql_free_result($res); rg_sql_free_result($res);
1117 if ($rows == 0) {
1118 rg_user_set_error("cannot find token (" . rg_sql_error() . ")");
1216
1217 return TRUE;
1218 }
1219
1220 /*
1221 * Checks if a user is over limit.
1222 * Returns maximum allowed in @max.
1223 */
1224 function rg_user_over_limit($db, $ui, &$max)
1225 {
1226 $pi = rg_plan_info($db, $ui['plan_id']);
1227 if ($pi['exists'] != 1) {
1228 rg_internal_error("Invalid plan.");
1119 1229 return FALSE; return FALSE;
1120 1230 } }
1121 $uid = $row['uid'];
1122 1231
1123 $sql = "UPDATE users SET confirmed = $now"
1124 . " WHERE uid = $uid";
1125 $res = rg_sql_query($db, $sql);
1126 if ($res === FALSE) {
1127 rg_user_set_error("cannot update confirmed (" . rg_sql_error() . ")");
1232 $max = $pi['disk_mb'];
1233 if ($max == 0)
1128 1234 return FALSE; return FALSE;
1129 }
1130 rg_sql_free_result($res);
1131 1235
1132 return $uid;
1236 if ($ui['disk_used_mb'] >= $max)
1237 return TRUE;
1238
1239 return FALSE;
1133 1240 } }
1134 1241
1135 1242 /* /*
1136 * Add a suggestion to database
1243 * Returns the login structure of the logged-in user
1137 1244 */ */
1138 function rg_user_suggestion($db, $uid, $email, $suggestion)
1245 function rg_user_get_login_ui()
1139 1246 { {
1140 $e_email = rg_sql_escape($db, $email);
1141 $e_suggestion = rg_sql_escape($db, $suggestion);
1247 global $login_ui;
1142 1248
1143 $sql = "INSERT INTO suggestions (uid, email, suggestion)"
1144 . " VALUES ($uid, '$e_email', '$e_suggestion')";
1145 $res = rg_sql_query($db, $sql);
1146 if ($res === FALSE) {
1147 rg_user_set_error("cannot add suggestion (" . rg_sql_error() . ")");
1148 return FALSE;
1249 return $login_ui;
1250 }
1251
1252 /*
1253 * Returns the login structure of the target user (admin section)
1254 */
1255 function rg_user_get_target_ui()
1256 {
1257 global $target_ui;
1258
1259 return $target_ui;
1260 }
1261
1262 /*
1263 * Test access of a login_user to an uid
1264 * TODO: Admin will have access...
1265 */
1266 function rg_user_allow_access($login_ui, $uid)
1267 {
1268 /* uid 0 does not exists */
1269 if ($uid == 0)
1270 return TRUE;
1271
1272 if ($login_ui['uid'] == $uid)
1273 return TRUE;
1274
1275 if (rg_rights_allow($login_ui['rights'], "U"))
1276 return TRUE;
1277
1278 rg_security_violation_no_exit("uid " . $login_ui['uid']
1279 . " has no access to uid $uid!");
1280 return FALSE;
1281 }
1282
1283 /*
1284 * High level functions
1285 */
1286
1287 /*
1288 * High-level function for editing a user
1289 */
1290 function rg_user_edit_high_level($db, $sid, $more)
1291 {
1292 rg_log("user_edit_high_level");
1293
1294 $ret = "";
1295
1296 $login_ui = rg_user_get_login_ui();
1297 $target_ui = rg_user_get_target_ui();
1298 $doit = rg_var_uint("doit");
1299
1300 if (!rg_user_allow_access($login_ui, $target_ui['uid'])) {
1301 $ret .= rg_template("access_denied.html", $more);
1302 return $ret;
1149 1303 } }
1150 rg_sql_free_result($res);
1151 1304
1152 return TRUE;
1305 if (($target_ui['uid'] == 0) && ($more['rg_account_allow_creation'] != 1)) {
1306 $ret .= rg_template("user/create_na.html", $more);
1307 return $ret;
1308 }
1309
1310 if ($target_ui['uid'] > 0)
1311 $more['create_mode'] = 0;
1312 else
1313 $more['create_mode'] = 1;
1314
1315 if ($doit == 0) {
1316 if ($target_ui['uid'] > 0) {
1317 // TODO: check also access rights?
1318 $ui = $target_ui;
1319 } else {
1320 // Defaults
1321 $ui = array();
1322 $ui['uid'] = 0;
1323 $ui['username'] = "";
1324 $ui['realname'] = "";
1325 $ui['email'] = "";
1326 $ui['pass'] = "";
1327 $ui['pass2'] = "";
1328 $ui['is_admin'] = "0";
1329 $ui['rights'] = rg_rights_checkboxes("user", "C"); // TODO
1330 $ui['plan_id'] = 0;
1331 $ui['session_time'] = 600;
1332 }
1333 }
1334
1335 $errmsg = array();
1336 $load_form = TRUE;
1337 do {
1338 if ($doit != 1)
1339 break;
1340
1341 $ui = array();
1342 $ui['uid'] = $target_ui['uid'];
1343 $ui['username'] = rg_var_str("username");
1344 $ui['realname'] = rg_var_str("realname");
1345 $ui['email'] = rg_var_str("email");
1346 $ui['pass'] = rg_var_str("pass");
1347 $ui['pass2'] = rg_var_str("pass2");
1348 $ui['is_admin'] = rg_var_uint("is_admin");
1349 $ui['rights'] = "C"; // TODO
1350 $ui['plan_id'] = rg_var_uint("plan_id");
1351 $ui['session_time'] = rg_var_uint("session_time");
1352 $ui['confirm_token'] = rg_id(20);
1353
1354 $token = rg_var_str("token");
1355
1356 if (!rg_token_valid($db, $sid, $token)) {
1357 $errmsg[] = "invalid token; try again";
1358 break;
1359 }
1360
1361 if ($ui['uid'] == 0) {
1362 $_ui = rg_user_info($db, 0, $ui['username'], "");
1363 if ($_ui['ok'] != 1) {
1364 $errmsg[] = rg_user_error();
1365 break;
1366 }
1367 if ($_ui['exists'] == 1) {
1368 $errmsg[] = "user already exists";
1369 break;
1370 }
1371 }
1372
1373 // Security warning - a user can pass "pass" var to me avoiding
1374 // being asked for old pass
1375 if ($ui['uid'] > 0) {
1376 if (!empty($ui['pass']))
1377 rg_security_violation_no_exit("User tried to"
1378 . " change pass using 'edit info' page.");
1379 $ui['pass'] = "";
1380 }
1381
1382 $r = rg_user_edit($db, $ui);
1383 if ($r === FALSE) {
1384 $errmsg[] = rg_user_error();
1385 break;
1386 }
1387
1388 // TODO: should we just redirect to login page?
1389 // TODO: or to user page if there is no need to confirm the account?
1390 if ($ui['uid'] == 0)
1391 $ret = rg_template("user/create_ok.html", $more);
1392 else
1393 $ret = rg_template("user/edit_ok.html", $more);
1394 $load_form = FALSE;
1395 } while (0);
1396
1397 if ($load_form) {
1398 if (rg_rights_allow($login_ui['rights'], "U"))
1399 $more['admin_mode'] = 1;
1400 else
1401 $more['admin_mode'] = 0;
1402
1403 $more = array_merge($more, $ui);
1404 $more['HTML:select_plan'] = rg_plan_select($db, $ui['plan_id']);
1405 $more['HTML:checkbox_rights'] = rg_rights_checkboxes("user", $ui['rights']);
1406 $more['HTML:errmsg'] = rg_template_errmsg($errmsg);
1407 $more['rg_form_token'] = rg_token_get($db, $sid);
1408 $ret .= rg_template("user/add_edit.html", $more);
1409 }
1410
1411 return $ret;
1153 1412 } }
1154 1413
1155 1414 ?> ?>
File inc/user/confirm.php changed (mode: 100644) (index c21f2c7..9b91e35)
1 1 <?php <?php
2 2 rg_log("/inc/user/confirm"); rg_log("/inc/user/confirm");
3 3
4 $token = rg_var_re("token", "/[^A-Za-z0-9]/");
4 $token = empty($paras) ? "" : array_shift($paras);
5 5
6 6 $_confirm = ""; $_confirm = "";
7 7
8 8 $uid = rg_user_confirm($db, $token); $uid = rg_user_confirm($db, $token);
9 9 if ($uid !== FALSE) { if ($uid !== FALSE) {
10 10 // auto-login // auto-login
11 if (rg_user_auto_login($db, $uid, $login_ui)) {
11 $lock_ip = 0; // TODO: What should we do here? Present a form?
12 if (rg_user_auto_login($db, $uid, $lock_ip, $login_ui)) {
12 13 $url = rg_re_userpage($login_ui); $url = rg_re_userpage($login_ui);
13 14 rg_redirect($url); rg_redirect($url);
14 15 } }
15 16 } }
16 17
17 18 // error // error
18 $_confirm = rg_template("msg/internal.txt", array());
19 $_confirm = rg_template("user/bad_token.html", $more);
19 20
20 21 ?> ?>
File inc/user/create.php deleted (index 8e3357d..0000000)
1 <?php
2 rg_log("/inc/user/create");
3
4 $user_create_more = $more;
5 $_create = "";
6
7 if ($rg_account_allow_creation != 1) {
8 // TODO: move this in a template
9 $_create .= "This site does not allow account creation. Ask the Admin.";
10 return;
11 }
12
13 $uid = 0;
14 $errmsg = array();
15 $show_form = 1;
16
17 if ($doit == 1) {
18 $xuser = rg_var_str("xuser");
19 $realname = rg_var_str("realname");
20 $email = rg_var_str("email");
21 $xpass = rg_var_str("xpass");
22 $xpass2 = rg_var_str("xpass2");
23 $session_time = rg_var_uint("session_time");
24
25 do {
26 if (strcmp($xpass, $xpass2) != 0) {
27 $errmsg[] = "password are not the same";
28 break;
29 }
30
31 $_ui = rg_user_info($db, 0, $xuser, "");
32 if ($_ui['ok'] == 0) {
33 $errmsg[] = "internal error (" . rg_user_error() . ")";
34 break;
35 }
36
37 if ($_ui['exists'] == 1) {
38 $errmsg[] = "user already exists";
39 break;
40 }
41
42 $_u = array();
43 $_u['uid'] = $uid;
44 $_u['username'] = $xuser;
45 $_u['realname'] = $realname;
46 $_u['email'] = $email;
47 $_u['pass'] = $xpass;
48 $_u['is_admin'] = 0;
49 $_u['disk_quota_mb'] = 100;
50 $_u['rights'] = "C";
51 $_u['session_time'] = $session_time;
52 $_u['confirm_token'] = rg_id(20);
53 if (rg_user_edit($db, $_u) === FALSE) {
54 $errmsg[] = "Cannot add user (" . rg_user_error() . ").";
55 break;
56 }
57
58 $r = rg_user_confirm_send($email, $_u['confirm_token']);
59 if ($r === FALSE) {
60 $errmsg[] = "Cannot send e-mail (" . rg_user_error() . ")!";
61 break;
62 }
63
64 $show_form = 0;
65 $_create .= rg_template("user/email_conf.html", $user_create_more);
66 } while (0);
67 } else {
68 $xuser = "";
69 $realname = "";
70 $email = "";
71 $xpass = "";
72 $xpass2 = "";
73 $session_time = 3600;
74 }
75
76 if ($show_form == 1) {
77 $create_mode = 1;
78 $admin_mode = 0;
79 $pass_mode = 2;
80 include($INC . "/admin/users/user.form.php");
81 $_create .= $_form;
82 }
83
84 ?>
File inc/user/forgot.php changed (mode: 100644) (index 38f8c0f..3e1332c)
1 1 <?php <?php
2 2 rg_log("/inc/user/forgot"); rg_log("/inc/user/forgot");
3 3
4 $forgot_token = empty($paras) ? "" : array_shift($paras);
5 $forgot_token = preg_replace("/[^A-Za-z0-9]/", "", $forgot_token);
6
4 7 $forgot_more = $more; $forgot_more = $more;
5 $forgot_token = rg_var_re("forgot_token", "/[^A-Za-z0-9]/");
6 8 $pass1 = rg_var_str("pass1"); $pass1 = rg_var_str("pass1");
7 9 $pass2 = rg_var_str("pass2"); $pass2 = rg_var_str("pass2");
10 $lock_ip = rg_var_uint("lock_ip");
8 11
9 12 $_forgot = ""; $_forgot = "";
10 13
 
... ... if ($doit == 1) {
21 24 } }
22 25
23 26 if ($r['uid'] == 0) { if ($r['uid'] == 0) {
24 $_forgot .= "Invalid (or expired) reset pass URL!<br />\n";
27 $_forgot .= "Invalid (or expired) reset pass URL! Try again.<br />\n";
25 28 return; return;
26 29 } }
27 30
 
... ... if ($doit == 1) {
32 35
33 36 rg_user_forgot_pass_destroy($db, $r['uid']); rg_user_forgot_pass_destroy($db, $r['uid']);
34 37 // auto-login // auto-login
35 if (!rg_user_auto_login($db, $r['uid'], $login_ui)) {
38 if (!rg_user_auto_login($db, $r['uid'], $lock_ip, $login_ui)) {
36 39 $_forgot = rg_template("msg/internal.txt"); $_forgot = rg_template("msg/internal.txt");
37 40 return; return;
38 41 } }
File inc/user/home-page.php changed (mode: 100644) (index 8e89d93..d2bd67e)
... ... rg_log("/inc/user/home-page");
4 4 $_home = ""; $_home = "";
5 5
6 6 $page_ui = rg_user_info($db, 0, $user, ""); $page_ui = rg_user_info($db, 0, $user, "");
7 if ($page_ui === FALSE) {
8 $_home .= rg_warning("Invalid user!");
7 if ($page_ui['exists'] == 0) {
8 $_home .= rg_template("user/invalid.html", $more);
9 9 return; return;
10 10 } }
11 11
File inc/user/info/info.php deleted (index adf149b..0000000)
1 <?php
2 rg_log("/inc/user/info/info");
3
4 $errmsg = array();
5
6 $_info = "";
7
8 $_show_form = 1;
9 if ($doit == 1) {
10 if (!rg_token_valid($db, $sid, $token)) {
11 $_info .= "Invalid token. Try again.";
12 return;
13 }
14
15 $xuser = rg_var_str("xuser");
16 $realname = rg_var_str("realname");
17 $email = rg_var_str("email");
18 $is_admin = $login_ui['is_admin']; // TODO: doesn't seems too elegant
19 $disk_quota_mb = $login_ui['disk_quota_mb'];
20 $rights = $login_ui['rights'];
21 $session_time = rg_var_uint("session_time");
22
23 do {
24 $_u = array();
25 $_u['uid'] = $login_ui['uid'];
26 $_u['username'] = $xuser;
27 $_u['realname'] = $realname;
28 $_u['email'] = $email;
29 $_u['pass'] = "";
30 $_u['is_admin'] = $is_admin;
31 $_u['disk_quota_mb'] = $disk_quota_mb;
32 $_u['rights'] = $rights;
33 $_u['session_time'] = $session_time;
34 if (!rg_user_edit($db, $_u)) {
35 $errmsg[] = "Cannot change info (" . rg_user_error() . ").";
36 break;
37 }
38
39 $_info .= rg_ok("Information was updated!");
40 $_show_form = 0;
41 } while (0);
42 } else {
43 $xuser = $login_ui['username'];
44 $realname = $login_ui['realname'];
45 $email = $login_ui['email'];
46 $is_admin = $login_ui['is_admin'];
47 $disk_quota_mb = $login_ui['disk_quota_mb'];
48 $rights = $login_ui['rights'];
49 $session_time = $login_ui['session_time'];
50 }
51
52 if ($_show_form == 1) {
53 $create_mode = 0;
54 $admin_mode = 0;
55 $pass_mode = 0;
56 include($INC . "/admin/users/user.form.php");
57 $_info .= $_form;
58 }
59
60 ?>
File inc/user/keys/keys.php changed (mode: 100644) (index 6cebcc1..ab8a437)
... ... if (rg_var_uint("add") == 1) {
38 38 break; break;
39 39 } }
40 40
41 if (rg_keys_remove_multi($db, $login_ui, $key_delete_ids) !== TRUE) {
41 if (rg_keys_remove($db, $login_ui, $key_delete_ids) !== TRUE) {
42 42 $del_errmsg[] = rg_keys_error(); $del_errmsg[] = rg_keys_error();
43 43 break; break;
44 44 } }
File inc/user/pass/pass.php changed (mode: 100644) (index 1370214..fb012be)
... ... $pass1 = rg_var_str("pass1");
12 12 $pass2 = rg_var_str("pass2"); $pass2 = rg_var_str("pass2");
13 13
14 14 $show_form = 1; $show_form = 1;
15 if ($doit == 1) {
16 do {
17 if (!rg_token_valid($db, $sid, $token)) {
18 $errmsg[] = "invalid token; try again";
19 break;
20 }
21
22 if (strcmp($pass1, $pass2) != 0) {
23 $errmsg[] = "passwords does not match";
24 break;
25 }
26
27 if (!rg_user_pass_valid($db, $login_ui['uid'], $old_pass)) {
28 $errmsg[] = "old password is invalid";
29 break;
30 }
31
32 if (!rg_user_set_pass($db, $login_ui['uid'], $pass1)) {
33 $errmsg[] = rg_user_error();
34 break;
35 }
36
37 $_pass .= rg_ok("Password was changed with success!");
38 $show_form = 0;
39 } while (0);
40 }
15 do {
16 if ($doit != 1)
17 break;
18
19 if (!rg_token_valid($db, $sid, $token)) {
20 $errmsg[] = "invalid token; try again";
21 break;
22 }
23
24 if (strcmp($pass1, $pass2) != 0) {
25 $errmsg[] = "passwords does not match";
26 break;
27 }
28
29 if (!rg_user_pass_valid($db, $login_ui['uid'], $old_pass)) {
30 $errmsg[] = "old password is invalid";
31 break;
32 }
33
34 if (!rg_user_set_pass($db, $login_ui['uid'], $pass1)) {
35 $errmsg[] = rg_user_error();
36 break;
37 }
38
39 $_pass .= rg_ok("Password was changed with success!");
40 $show_form = 0;
41 } while (0);
41 42
42 43 if ($show_form == 1) { if ($show_form == 1) {
43 44 $user_pass_more['HTML:errmsg'] = rg_template_errmsg($errmsg); $user_pass_more['HTML:errmsg'] = rg_template_errmsg($errmsg);
File inc/user/repo-page.php changed (mode: 100644) (index 5fdecc5..3ed4258)
... ... if (rg_user_ok($user) !== TRUE) {
9 9 $_repo_page .= rg_warning("Invalid user!"); $_repo_page .= rg_warning("Invalid user!");
10 10 return; return;
11 11 } }
12
13 12 $page_ui = rg_user_info($db, 0, $user, ""); $page_ui = rg_user_info($db, 0, $user, "");
14 if ($page_ui === FALSE) {
15 $_repo_page .= rg_warning("Invalid user!");
13 if ($page_ui['ok'] != 1) {
14 $_repo_page .= rg_warning("Internal error!");
15 return;
16 }
17 if ($page_ui['exists'] != 1) {
18 $_repo_page .= rg_template("user/invalid.html", $repo_more);
16 19 return; return;
17 20 } }
18 21
19 22 if (rg_repo_ok($repo) !== TRUE) { if (rg_repo_ok($repo) !== TRUE) {
20 $_repo_page .= rg_warning("Invalid repo!");
23 $_repo_page .= rg_template("repo/invalid.html", $repo_more);
21 24 return; return;
22 25 } }
23
24 26 $ri = rg_repo_info($db, 0, $page_ui['uid'], $repo); $ri = rg_repo_info($db, 0, $page_ui['uid'], $repo);
25 27 if ($ri['ok'] != 1) { if ($ri['ok'] != 1) {
26 28 $_repo_page .= rg_warning("Internal error!"); $_repo_page .= rg_warning("Internal error!");
27 29 return; return;
28 30 } }
29 31 if ($ri['exists'] != 1) { if ($ri['exists'] != 1) {
30 $_repo_page .= rg_warning("Non existing repo!");
32 $_repo_page .= rg_template("repo/invalid.html", $repo_more);
31 33 return; return;
32 34 } }
33 35
 
... ... if ($ri['git_dir_done'] == 0) {
36 38 // TODO: Should we really wait for this?! // TODO: Should we really wait for this?!
37 39 // We may just consider that the repo is empty. Hm. // We may just consider that the repo is empty. Hm.
38 40 $ev_id = "repo_create-" . $login_ui['uid'] . "-" . $ri['repo_id'] . "-git"; $ev_id = "repo_create-" . $login_ui['uid'] . "-" . $ri['repo_id'] . "-git";
39 $timeout = 10; // seconds
41 $timeout = 10 * 1000; // seconds
40 42 $r = rg_event_signal_daemon($ev_id, $timeout); $r = rg_event_signal_daemon($ev_id, $timeout);
41 43 if ($r === FALSE) { if ($r === FALSE) {
42 44 // Seems we did not get the notification // Seems we did not get the notification
File inc/user/repo/admin/delete/delete.php changed (mode: 100644) (index c3c5010..482b26f)
... ... $_delete = "";
9 9 $errmsg = array(); $errmsg = array();
10 10
11 11 $_show_form = 1; $_show_form = 1;
12 if ($doit == 1) {
12 do {
13 if ($doit != 1)
14 break;
15
13 16 if ($are_you_sure == 0) { if ($are_you_sure == 0) {
14 17 $_delete .= rg_template("user/repo/delete/no.html", $repo_delete_more); $_delete .= rg_template("user/repo/delete/no.html", $repo_delete_more);
15 18 $_show_form = 0; $_show_form = 0;
16 } else {
17 do {
18 if (!rg_token_valid($db, $sid, $token)) {
19 $del_errmsg[] = "invalid token; try again";
20 break;
21 }
22
23 $r = rg_repo_delete($db, $ri['repo_id'], $login_ui);
24 if ($r === FALSE) {
25 $errmsg[] = rg_repo_error();
26 break;
27 }
28
29 $_delete .= rg_template("user/repo/delete/done.html", $repo_delete_more);
30 $_show_form = 0;
31 } while (0);
19 break;
32 20 } }
33 }
21
22 if (!rg_token_valid($db, $sid, $token)) {
23 $del_errmsg[] = "invalid token; try again";
24 break;
25 }
26
27 $r = rg_repo_delete($db, $ri['repo_id'], $login_ui);
28 if ($r === FALSE) {
29 $errmsg[] = rg_repo_error();
30 break;
31 }
32
33 $_delete .= rg_template("user/repo/delete/done.html", $repo_delete_more);
34 $_show_form = 0;
35 } while (0);
34 36
35 37 if ($_show_form == 1) { if ($_show_form == 1) {
36 38 $repo_delete_more['HTML:errmsg'] = rg_template_errmsg($errmsg); $repo_delete_more['HTML:errmsg'] = rg_template_errmsg($errmsg);
File inc/user/repo/admin/rights/rights.php changed (mode: 100644) (index 9b2d729..5a0786b)
... ... $delete = rg_var_uint("delete");
10 10 $edit_uid = rg_var_uint("edit_uid"); $edit_uid = rg_var_uint("edit_uid");
11 11 $grant = rg_var_uint("grant"); $grant = rg_var_uint("grant");
12 12 $rights_delete_ids = rg_var_str("rights_delete_ids"); $rights_delete_ids = rg_var_str("rights_delete_ids");
13 $ref = rg_var_str("ref");
14 $path = rg_var_str("path");
13 15
14 16 // we need it in forms // we need it in forms
15 17 $repo_id = $ri['repo_id']; $repo_id = $ri['repo_id'];
 
... ... $repo_rights_more['rights'] = $rights;
22 24
23 25 $load_defaults = 1; $load_defaults = 1;
24 26
25 while ($delete == 1) {
27 do {
28 if ($delete != 1)
29 break;
30
26 31 $load_defaults = 0; $load_defaults = 0;
27 32
28 33 if (!rg_token_valid($db, $sid, $token)) { if (!rg_token_valid($db, $sid, $token)) {
 
... ... while ($delete == 1) {
36 41 } }
37 42
38 43 foreach ($rights_delete_ids as $remove_uid => $junk) { foreach ($rights_delete_ids as $remove_uid => $junk) {
39 $e = rg_repo_rights_set($db, $ri, $remove_uid, "");
44 $e = rg_repo_rights_set($db, $ri, $remove_uid, "", "");
40 45 if ($e !== TRUE) { if ($e !== TRUE) {
41 46 $del_errmsg[] = rg_repo_error(); $del_errmsg[] = rg_repo_error();
42 47 break; break;
43 48 } }
44 49 } }
50 } while (0);
45 51
46 break;
47 }
52 do {
53 if ($edit_uid == 0)
54 break;
48 55
49 while ($edit_uid > 0) {
50 56 $load_defaults = 0; $load_defaults = 0;
51 57
52 58 $r = rg_repo_rights_get($db, $ri, $edit_uid, 0); $r = rg_repo_rights_get($db, $ri, $edit_uid, 0);
 
... ... while ($edit_uid > 0) {
65 71
66 72 $repo_rights_more['target_user'] = $target_ui['username']; $repo_rights_more['target_user'] = $target_ui['username'];
67 73 $repo_rights_more['rights'] = $r['rights']; $repo_rights_more['rights'] = $r['rights'];
68 break;
69 }
74 } while (0);
70 75
71 76 // Adding // Adding
72 while ($grant == 1) {
77 do {
78 if ($grant != 1)
79 break;
80
73 81 $load_defaults = 0; $load_defaults = 0;
74 82
75 83 if (!rg_token_valid($db, $sid, $token)) { if (!rg_token_valid($db, $sid, $token)) {
 
... ... while ($grant == 1) {
85 93 break; break;
86 94 } }
87 95
88 $e = rg_repo_rights_set($db, $ri, $_ui['uid'], $rights);
96 $misc = array();
97 $misc['ref'] = $ref;
98 $misc['path'] = $path;
99 $e = rg_repo_rights_set($db, $ri, $_ui['uid'], $rights, $misc);
89 100 if ($e === FALSE) { if ($e === FALSE) {
90 101 $errmsg[] = rg_repo_error(); $errmsg[] = rg_repo_error();
91 102 break; break;
 
... ... while ($grant == 1) {
94 105 // no need to pre-fill user beause was just added // no need to pre-fill user beause was just added
95 106 $repo_rights_more['target_user'] = ""; $repo_rights_more['target_user'] = "";
96 107 $repo_rights_more['rights'] = ""; $repo_rights_more['rights'] = "";
97 break;
98 }
108 } while (0);
99 109
100 110 if ($load_defaults == 1) { if ($load_defaults == 1) {
111 $ref = "";
112 $path = "";
101 113 $rights = $rg_repo_rights_default; $rights = $rg_repo_rights_default;
102 114 } }
103 115
File inc/user/repo/bug/show/add_note.php changed (mode: 100644) (index 1c96fbc..f61e6c7)
... ... $add_note_more = $repo_bug_show_more;
7 7 $note = ""; $note = "";
8 8
9 9 $note_errmsg = array(); $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 }
10
11 do {
12 if ($note_add_doit != 1)
13 break;
14
15 $note = rg_var_str("note");
16
17 if (!rg_token_valid($db, $sid, $token)) {
18 $note_errmsg[] = "Invalid token. Try again.";
19 break;
20 }
21
22 if (empty($note)) {
23 $note_errmsg[] = "Cannot be empty";
24 break;
25 }
26
27 // add note
28 $_d = array();
29 $_d['note'] = $note;
30 $ret = rg_bug_note_add($db, $ri['repo_id'], $bug_id, $login_ui['uid'], $_d);
31 if ($ret === FALSE) {
32 $note_errmsg[] = "Cannot add note (" . rg_bug_error() . ")";
33 break;
34 }
35
36 // allow another note to be added
37 $note = "";
38 } while (0);
37 39
38 40 // add note form // add note form
39 41 $add_note_more['HTML:note_errmsg'] = rg_template_errmsg($note_errmsg); $add_note_more['HTML:note_errmsg'] = rg_template_errmsg($note_errmsg);
File inc/user/repo/bug/show/edit.php changed (mode: 100644) (index e939dfc..7b5c5f8)
... ... $_bug_edit = "";
9 9 $bug_errmsg = array(); $bug_errmsg = array();
10 10
11 11 $_x = $ibug; $_x = $ibug;
12 while ($doit == 1) {
12 do {
13 if ($doit != 1)
14 break;
15
13 16 $_x = rg_bug_vars(); $_x = rg_bug_vars();
14 17
15 18 if (!rg_token_valid($db, $sid, $token)) { if (!rg_token_valid($db, $sid, $token)) {
 
... ... while ($doit == 1) {
27 30 // TODO: Should we redirect, so user can press reload to refresh the bug? // TODO: Should we redirect, so user can press reload to refresh the bug?
28 31 //$url = rg_re_bugpage($page_ui, $ri['name'], $bug_id); //$url = rg_re_bugpage($page_ui, $ri['name'], $bug_id);
29 32 //rg_redirect($url); //rg_redirect($url);
30 }
33 } while (0);
31 34
32 35 // add note form // add note form
33 36 $repo_bug_edit_more = array_merge($repo_bug_edit_more, $_x); $repo_bug_edit_more = array_merge($repo_bug_edit_more, $_x);
File inc/user/repo/bug/show/show.php changed (mode: 100644) (index 7d9d68f..1d41eee)
... ... if (rg_var_uint("edit") == 1) {
33 33
34 34 // close/re-open // close/re-open
35 35 $close_reopen_error = ""; $close_reopen_error = "";
36 while (rg_var_uint("close_reopen") == 1) {
36 do {
37 if (rg_var_uint("close_reopen") != 1)
38 break;
39
37 40 if (!rg_token_valid($db, $sid, $token)) { if (!rg_token_valid($db, $sid, $token)) {
38 41 $close_reopen_error = "Invalid token. Try again."; $close_reopen_error = "Invalid token. Try again.";
39 42 break; break;
 
... ... while (rg_var_uint("close_reopen") == 1) {
48 51 } }
49 52
50 53 // TODO: do something with the error code // TODO: do something with the error code
51 break;
52 }
54 } while (0);
53 55 if ($ibug['state'] == 1) if ($ibug['state'] == 1)
54 56 $t = "repo/bug/b_close.html"; $t = "repo/bug/b_close.html";
55 57 else else
File inc/user/settings.php changed (mode: 100644) (index 3e7da32..7140034)
... ... if ($login_ui['uid'] == 0) {
8 8 return; return;
9 9 } }
10 10
11 $target_ui = $login_ui;
12
11 13 $errmsg = array(); $errmsg = array();
12 14
13 15 $_subop = empty($paras) ? "edit_info" : array_shift($paras); $_subop = empty($paras) ? "edit_info" : array_shift($paras);
 
... ... rg_menu_add($rg_menu, $_m, $_subop);
31 33
32 34 switch ($_subop) { switch ($_subop) {
33 35 case 'edit_info': case 'edit_info':
34 include($INC . "/user/info/info.php");
35 $_settings .= $_info;
36 $more['ask_for_pass'] = 0;
37 $_settings .= rg_user_edit_high_level($db, $sid, $more);
36 38 break; break;
37 39
38 40 case 'change_pass': case 'change_pass':
File inc/util.inc.php changed (mode: 100644) (index 474f101..dbf987f)
... ... require_once($INC . "/prof.inc.php");
3 3 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
4 4
5 5 set_error_handler("rg_error_handler"); set_error_handler("rg_error_handler");
6 register_shutdown_function("rg_shutdown_error");
6 register_shutdown_function("rg_error_shutdown");
7 7
8 8 $rg_util_error = ""; $rg_util_error = "";
9 9
 
... ... function rg_re_url($area)
129 129 if (isset($_REQUEST['rwe'])) if (isset($_REQUEST['rwe']))
130 130 return $area; return $area;
131 131
132 return "/?vv=" . $area;
133 }
134
135 /*
136 * This is used for forms
137 */
138 function rg_re_post($op)
139 {
140 if (isset($_REQUEST['rwe']))
141 return $op;
132 $add = "";
133 if (isset($_SERVER['PHP_SELF']))
134 $add = $_SERVER['PHP_SELF'];
142 135
143 return "/?vv=$op";
136 return $add . "/?vv=" . $area;
144 137 } }
145 138
146 139 function rg_re_userpage($ui) function rg_re_userpage($ui)
 
... ... function rg_re_userpage($ui)
156 149
157 150 $s = $prefix . "/" . $ui['username']; $s = $prefix . "/" . $ui['username'];
158 151
159 if (isset($_REQUEST['rwe']))
160 return $s;
161
162 return $_SERVER['PHP_SELF'] . "?vv=$s";
152 return rg_re_url($s);
163 153 } }
164 154
165 155 function rg_re_repopage($ui, $repo_name) function rg_re_repopage($ui, $repo_name)
 
... ... function rg_re_repopage($ui, $repo_name)
171 161
172 162 $s = rg_re_userpage($ui) . "/" . $repo_name; $s = rg_re_userpage($ui) . "/" . $repo_name;
173 163
174 if (isset($_REQUEST['rwe']))
175 return $s;
176
177 return $_SERVER['PHP_SELF'] . "?vv=$s";
164 return rg_re_url($s);
178 165 } }
179 166
180 167 function rg_re_bugpage($ui, $repo_name, $bug_id) function rg_re_bugpage($ui, $repo_name, $bug_id)
181 168 { {
182 $s = rg_re_repopage($ui, $repo_name) . "/bug/" . $bug_id;
183
184 if (isset($_REQUEST['rwe']))
185 return $s;
186
187 return $_SERVER['PHP_SELF'] . "?vv=$s";
169 return rg_re_repopage($ui, $repo_name) . "/bug/" . $bug_id;
188 170 } }
189 171
190 172 function rg_base_url() function rg_base_url()
191 173 { {
174 if (!isset($_SERVER['REMOTE_ADDR']))
175 return "http://SERVER/";
176
192 177 $port = ""; $port = "";
193 178 if (isset($_SERVER['HTTPS'])) { if (isset($_SERVER['HTTPS'])) {
194 179 $proto = "https"; $proto = "https";
 
... ... function rg_chars_allow($name, $allowed_regexp)
296 281 */ */
297 282 function rg_rmdir($dir) function rg_rmdir($dir)
298 283 { {
299 rg_log("rmdir: $dir");
300
301 284 if (!is_dir($dir)) { if (!is_dir($dir)) {
302 285 rg_util_set_error("WARN: asked to remove a non-existing dir ($dir)"); rg_util_set_error("WARN: asked to remove a non-existing dir ($dir)");
303 286 return TRUE; return TRUE;
 
... ... function rg_rmdir($dir)
341 324 */ */
342 325 function rg_menu_add(&$menu, $sub, $op) function rg_menu_add(&$menu, $sub, $op)
343 326 { {
344 //rg_log_ml("DEBUG: rg_menu_add (op=$op): " . print_r($sub, TRUE));
345
346 327 if (isset($sub[$op])) if (isset($sub[$op]))
347 328 $sub[$op]['active'] = 1; $sub[$op]['active'] = 1;
348 329
 
... ... function rg_menu_add(&$menu, $sub, $op)
352 333 } }
353 334
354 335 // search for last active menu // search for last active menu
355 foreach ($menu as $_op => $_info) {
336 foreach ($menu as $_op => &$_info) {
356 337 if (!isset($_info['active'])) if (!isset($_info['active']))
357 338 continue; continue;
358 339
 
... ... function rg_menu_add(&$menu, $sub, $op)
363 344 } }
364 345
365 346 // we are on parent of the correct menu // we are on parent of the correct menu
366 rg_menu_add($menu[$_op], $sub, $op);
347 rg_menu_add($_info['sub'], $sub, $op);
367 348 break; break;
368 349 } }
369 350 } }
 
... ... function rg_menu_add(&$menu, $sub, $op)
373 354 */ */
374 355 function rg_menu($a, $url, $ui) function rg_menu($a, $url, $ui)
375 356 { {
376 rg_log_ml("DEBUG: rg_menu: url=$url a=" . print_r($a, TRUE));
377
378 $ret = array();
379 $submenu = array();
380
381 $menu = "<div class=\"menu\">\n";
382 $menu .= "\t<ul>\n";
357 $menu = array();
358 $submenu = "";
383 359 foreach ($a as $_id => $_info) { foreach ($a as $_id => $_info) {
360 $entry = array();
361
384 362 // we ignore fake menus like 'home' // we ignore fake menus like 'home'
385 363 if (!isset($_info['text'])) if (!isset($_info['text']))
386 364 continue; continue;
 
... ... function rg_menu($a, $url, $ui)
394 372 if (!isset($_info['uid0']) && ($ui['uid'] == 0)) if (!isset($_info['uid0']) && ($ui['uid'] == 0))
395 373 continue; continue;
396 374
397 $_text = $_info['text'];
375 $entry['text'] = $_info['text'];
398 376 $prefix = empty($url) ? "" : $url . "/"; $prefix = empty($url) ? "" : $url . "/";
399 $_url = $prefix . rg_re_url($_info['op']);
400 //$menu .= "<!-- op=" . $_info['op'] . " url=$_url." . " -->\n";
377 $menu_url = $prefix . rg_re_url($_info['op']);
378 $entry['url'] = $menu_url;
401 379
402 //rg_log("\tDEBUG: compare with [" . $_info['op'] . "]");
403 $add = "";
380 $entry['selected'] = 0;
404 381 if (isset($_info['active'])) if (isset($_info['active']))
405 $add = " class=\"selected\"";;
406 $menu .= "\t\t<li><a href=\"" . $_url . "\"" . $add . ">"
407 . $_text . "</a></li>\n";
382 $entry['selected'] = 1;
383
384 $menu[] = $entry;
408 385
409 386 if (!isset($_info['sub']) || (count($_info['sub']) == 0)) if (!isset($_info['sub']) || (count($_info['sub']) == 0))
410 387 continue; continue;
411 388
412 389 // submenu // submenu
413 $submenu = rg_menu($_info['sub'], $_url, $ui);
390 $submenu = rg_menu($_info['sub'], $menu_url, $ui);
414 391 } }
415 $menu .= "\t</ul>\n";
416 $menu .= "\t</div>\n";
417 $ret[] = $menu;
418 392
419 if (!empty($submenu)) {
420 foreach ($submenu as $_index => $_menu)
421 $ret[] = $_menu;
422 }
393 // Build menu
394 $ret = rg_template_table("menu", $menu, array());
395 $ret .= $submenu;
423 396
424 397 return $ret; return $ret;
425 398 } }
 
... ... function rg_menu($a, $url, $ui)
430 403 */ */
431 404 function rg_image_callback($matches) function rg_image_callback($matches)
432 405 { {
433 global $rg_scripts;
406 global $rg_theme_dir;
434 407 global $rg_theme; global $rg_theme;
435 408
436 409 $n = $matches[1]; $n = $matches[1];
437 410 $url = "/themes/" . $rg_theme . "/" . $n; $url = "/themes/" . $rg_theme . "/" . $n;
438 $xfile = $rg_scripts . "/root" . $url;
411 $xfile = $rg_theme_dir . "/" . $rg_theme . "/" . $n;
439 412 if (!is_file($xfile)) if (!is_file($xfile))
440 413 $url = "/themes/default/" . $n; $url = "/themes/default/" . $n;
441 414
 
... ... function rg_image_callback($matches)
443 416 } }
444 417
445 418 /* /*
446 * Prepare an image taking in consideration the them. It will use rg_img as
447 * callback.
419 * Prepares the images to point to a correct image.
448 420 */ */
449 421 function rg_prepare_image($line) function rg_prepare_image($line)
450 422 { {
 
... ... function rg_prepare_replace(&$data, &$what, &$values)
457 429 if (!is_array($data)) if (!is_array($data))
458 430 rg_internal_error("invalid type passed"); rg_internal_error("invalid type passed");
459 431 foreach ($data as $k => $v) { foreach ($data as $k => $v) {
460 if (is_array($v)) {
461 rg_log_ml("value of key [$k] is array!"
432 if (is_array($v))
433 rg_fatal("value of key [$k] is array!"
462 434 . " data: " . print_r($data, TRUE)); . " data: " . print_r($data, TRUE));
463 exit(1);
464 }
435
465 436 if (strncmp($k, "HTML:", 5) == 0) { if (strncmp($k, "HTML:", 5) == 0) {
466 437 $k = substr($k, 5); $k = substr($k, 5);
467 438 } else { } else {
 
... ... function rg_replace_conditionals_block($block, &$data, &$stack)
555 526 return FALSE; return FALSE;
556 527 } }
557 528 //rg_log("DEBUG: matches2: " . rg_array2string($matches2)); //rg_log("DEBUG: matches2: " . rg_array2string($matches2));
529 if (count($matches2) < 3) {
530 rg_internal_error("Cannot match condition.");
531 return FALSE;
532 }
558 533 $left = rg_replace_lookup($data, trim($matches2[1])); $left = rg_replace_lookup($data, trim($matches2[1]));
559 534 $op = trim($matches2[2]); $op = trim($matches2[2]);
560 535 $right = rg_replace_lookup($data, trim($matches2[3])); $right = rg_replace_lookup($data, trim($matches2[3]));
 
... ... function rg_file_get_contents($f)
648 623 */ */
649 624 function rg_template_table($dir, &$data, $more) function rg_template_table($dir, &$data, $more)
650 625 { {
626 global $rg_theme_dir;
651 627 global $rg_theme; global $rg_theme;
652 global $rg_scripts;
653 628
654 $xdir = $rg_scripts . "/root/themes/" . $rg_theme . "/" . $dir;
629 $xdir = $rg_theme_dir . "/" . $rg_theme . "/" . $dir;
655 630 if (!is_dir($xdir)) { if (!is_dir($xdir)) {
656 631 rg_log("$xdir not found."); rg_log("$xdir not found.");
657 $xdir = $rg_scripts . "/root/themes/default/" . $dir;
632 $xdir = $rg_theme_dir . "/default/" . $dir;
658 633 rg_log("Using [$xdir]"); rg_log("Using [$xdir]");
659 634 } }
660 635
 
... ... function rg_template_table($dir, &$data, $more)
695 670 $body .= $between; $body .= $between;
696 671 } }
697 672
698 $r = rg_replace_conditionals($line, $more);
673 $more2 = array_merge($more, $info);
674 $r = rg_replace_conditionals($line, $more2);
699 675 $body .= preg_replace($what, $values, $r); $body .= preg_replace($what, $values, $r);
700 676 } }
701 677
 
... ... function rg_template_table($dir, &$data, $more)
704 680
705 681 function rg_template($file, &$data) function rg_template($file, &$data)
706 682 { {
707 global $rg_scripts;
683 global $rg_theme_dir;
708 684 global $rg_theme; global $rg_theme;
709 685
710 686 rg_log("Loading template from $file..."); rg_log("Loading template from $file...");
711 687
712 $xfile = $rg_scripts . "/root/themes/" . $rg_theme . "/" . $file;
688 $xfile = $rg_theme_dir . "/" . $rg_theme . "/" . $file;
713 689 if (!is_file($xfile)) if (!is_file($xfile))
714 $xfile = $rg_scripts . "/root/themes/default/" . $file;
690 $xfile = $rg_theme_dir . "/default/" . $file;
715 691
716 692 $body = rg_file_get_contents($xfile); $body = rg_file_get_contents($xfile);
717 693 if (empty($body)) { if (empty($body)) {
 
... ... function rg_exec($cmd)
890 866 */ */
891 867 function rg_redirect($url) function rg_redirect($url)
892 868 { {
869 rg_log("Redirecting to [$url]");
893 870 header("Location: $url"); header("Location: $url");
894 871 exit(0); exit(0);
895 872 } }
 
... ... function rg_array2string($a)
944 921 } }
945 922
946 923 /* /*
947 * Load files from a folder
924 * Load files from a folder using a pattern for match
948 925 */ */
949 function rg_dir_load($dir)
926 function rg_dir_load_pattern($dir, $pattern)
950 927 { {
951 $ret = array();
928 $ret = FALSE;
952 929 if (!file_exists($dir)) { if (!file_exists($dir)) {
953 rg_log("$dir does not exists!");
930 rg_util_set_error("$dir does not exists");
954 931 return $ret; return $ret;
955 932 } }
956 933
957 934 $d = @scandir($dir); $d = @scandir($dir);
958 935 if ($d === FALSE) { if ($d === FALSE) {
959 rg_log("Cannot scan dir $dir ($php_errormsg).");
936 rg_util_set_error("cannot scan dir $dir ($php_errormsg)");
960 937 return $ret; return $ret;
961 938 } }
962 939
940 $ret = array();
963 941 foreach ($d as $file) { foreach ($d as $file) {
964 942 if ((strcmp($file, ".") == 0) || (strcmp($file, "..") == 0)) if ((strcmp($file, ".") == 0) || (strcmp($file, "..") == 0))
965 943 continue; continue;
966 944
945 if (preg_match("/" . $pattern . "/", $file) !== 1)
946 continue;
947
967 948 $ret[] = $file; $ret[] = $file;
968 949 } }
969 950
970 951 return $ret; return $ret;
971 952 } }
972 953
954 /*
955 * Load all files from a folder
956 */
957 function rg_dir_load($dir)
958 {
959 return rg_dir_load_pattern($dir, ".*");
960 }
961
973 962 /* /*
974 963 * Recursive dir load (used for references) * Recursive dir load (used for references)
975 964 */ */
 
... ... function rg_copy_tree($src, $dst, $mask)
1039 1028 */ */
1040 1029 function rg_error_handler($no, $str, $file, $line) function rg_error_handler($no, $str, $file, $line)
1041 1030 { {
1042 global $rg_admin_email;
1043
1044 1031 if ($no == 0) if ($no == 0)
1045 1032 return; return;
1046 1033
1047 $str = str_replace("\n", "\\n", $str);
1048
1049 1034 $msg = "PHP ERROR: $file:$line: $str (errno=$no)"; $msg = "PHP ERROR: $file:$line: $str (errno=$no)";
1050 rg_log($msg);
1051
1052 mail("rg_error@embedromix.ro", "PHP ERROR",
1053 $msg
1054 . "\n" . rg_log_buffer(),
1055 "", "-f $rg_admin_email");
1035 $key = md5($msg);
1036 rg_error_core($msg);
1056 1037
1057 1038 if ($no == E_ERROR) if ($no == E_ERROR)
1058 1039 die(); die();
1059 1040
1041 $rg_error_seen[$key] = 1;
1042
1060 1043 return FALSE; return FALSE;
1061 1044 } }
1062 1045
1063 1046 /* /*
1064 * shutdown function to call fatal errors
1047 * shutdown function to log fatal errors
1065 1048 */ */
1066 function rg_shutdown_error()
1049 function rg_error_shutdown()
1067 1050 { {
1068 1051 $a = error_get_last(); $a = error_get_last();
1069 1052 if ($a === NULL) if ($a === NULL)
 
... ... function rg_mail($template, $more)
1140 1123
1141 1124 /* /*
1142 1125 * Merges an array (a) into another (src), using a namespace * Merges an array (a) into another (src), using a namespace
1126 * Protects modifiers (HTML: etc.).
1143 1127 */ */
1144 1128 function rg_array_merge($src, $namespace, $a) function rg_array_merge($src, $namespace, $a)
1145 1129 { {
 
... ... function rg_array_merge($src, $namespace, $a)
1148 1132 if (empty($a)) if (empty($a))
1149 1133 return $ret; return $ret;
1150 1134
1151 foreach ($a as $k => $v)
1152 $ret[$namespace . "." . $k] = $v;
1135 foreach ($a as $k => $v) {
1136 $t = explode(":", $k, 2);
1137 if (count($t) == 1)
1138 $ret[$namespace . "." . $k] = $v;
1139 else
1140 $ret[$t[0] . ":" . $namespace . "." . $t[1]] = $v;
1141 }
1153 1142
1154 1143 return $ret; return $ret;
1155 1144 } }
 
... ... function rg_implode($prefix, $a, $postfix)
1172 1161 return implode($postfix, $ret); return implode($postfix, $ret);
1173 1162 } }
1174 1163
1164 /*
1165 * Here we will cache the connections
1166 */
1167 $rg_socket_cache = array();
1168
1169 /*
1170 * Receives buffers and test if @wait string is present.
1171 * @timeout - in miliseconds
1172 */
1173 function rg_socket_recv_wait($socket, $wait, $timeout)
1174 {
1175 $ret = FALSE;
1176
1177 if ($timeout === NULL) {
1178 $tv_sec = NULL;
1179 $tv_usec = NULL;
1180 } else {
1181 $tv_sec = $timeout / 1000;
1182 $tv_usec = ($timeout % 1000) * 1000;
1183 }
1184
1185 $ret_buf = "";
1186 do {
1187 $reads = array($socket); $writes = array(); $ex = array();
1188 $r = socket_select($reads, $writes, $ex, $tv_sec, $tv_usec);
1189 if ($r === FALSE) {
1190 rg_log("Cannot select(" . socket_strerror(socket_last_error()) . ")!");
1191 break;
1192 }
1193
1194 if ($r === 0) { // timeout
1195 rg_log("Timeout!");
1196 break;
1197 }
1198
1199 if (!in_array($socket, $reads)) {
1200 rg_log("Select returned > 0 and my socket is not in reads");
1201 break;
1202 }
1203
1204 $r = socket_recv($socket, $buf, 32 * 4096, 0);
1205 if ($r === FALSE) {
1206 rg_log("Cannot receive(" . socket_strerror(socket_last_error()) . ")!");
1207 break;
1208 }
1209 rg_log("Received [$buf]");
1210 $ret_buf .= $buf;
1211
1212 $pos = strpos($buf, $wait);
1213 if ($pos !== FALSE) {
1214 $ret = $ret_buf;
1215 break;
1216 }
1217 } while (0);
1218
1219 return $ret;
1220 }
1221
1222 /*
1223 * Sends a full buffer
1224 * TODO: Take timeout in consideration.
1225 */
1226 function rg_socket_send($socket, $buf)
1227 {
1228 $ret = FALSE;
1229 $len = strlen($buf);
1230 $off = 0;
1231 while (1) {
1232 $r = socket_send($socket, substr($buf, $off), $len - $off, 0);
1233 if ($r === FALSE) {
1234 rg_log("Could not send (" . socket_strerror(socket_last_error()) . ")!");
1235 break;
1236 }
1237 rg_log("Sent $r bytes (" . substr($buf, $off, $r) . ").");
1238
1239 $len -= $r; $off += $r;
1240 if ($len == 0) {
1241 $ret = TRUE;
1242 break;
1243 }
1244 }
1245
1246 return $ret;
1247 }
1248
1249 /*
1250 * Connects to a socket, send @buf and returns the answer.
1251 * If timeout is 0, we do not wait for an answer. If is NULL, we wait forever.
1252 * Else, wait the number of miliseconds.
1253 */
1254 function rg_socket($path, $buf, $timeout)
1255 {
1256 global $rg_socket_cache;
1257
1258 rg_prof_start("socket");
1259
1260 $ret = FALSE;
1261 do {
1262 if (isset($rg_socket_cache[$path])) {
1263 $socket = $rg_socket_cache[$path];
1264 } else {
1265 $socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
1266 if ($socket === FALSE) {
1267 rg_log("Could not create socket (" . socket_strerror(socket_last_error()) . ")!");
1268 break;
1269 }
1270
1271 // try 3 times
1272 $tries = 3;
1273 while ($tries > 0) {
1274 $r = socket_connect($socket, $path);
1275 if ($r === FALSE) {
1276 $tries--;
1277 usleep(200000);
1278 continue;
1279 }
1280
1281 break;
1282 }
1283 if ($r === FALSE) {
1284 rg_log("Could not connect the socket (" . socket_strerror(socket_last_error()) . ")!");
1285 break;
1286 }
1287
1288 $rg_socket_cache[$path] = $socket;
1289 }
1290
1291 $r = rg_socket_send($socket, $buf);
1292 if ($r !== TRUE)
1293 break;
1294
1295 if ($timeout == 0) {
1296 rg_log("We do not have to wait. Exit.");
1297 $ret = "";
1298 break;
1299 }
1300
1301 $ret = rg_socket_recv_wait($socket, "\n", $timeout);
1302 } while (0);
1303
1304 rg_prof_end("socket");
1305 return $ret;
1306 }
1307
1175 1308 ?> ?>
File inc/watch.inc.php changed (mode: 100644) (index 355d1c8..aafb8fb)
... ... function rg_watch_load($db, $type, $login_uid, $obj_id1, $obj_id2)
38 38 $ret = FALSE; $ret = FALSE;
39 39 do { do {
40 40 if (strcmp($type, "bug") == 0) { if (strcmp($type, "bug") == 0) {
41 $params = array($login_uid, $obj_id1, $obj_id2);
41 42 $sql = "SELECT 1 FROM watch_bug" $sql = "SELECT 1 FROM watch_bug"
42 . " WHERE uid = $login_uid"
43 . " AND repo_id = $obj_id1"
44 . " AND bug_id = $obj_id2";
43 . " WHERE uid = $1"
44 . " AND repo_id = $2"
45 . " AND bug_id = $3";
45 46 } else if (strcmp($type, "repo") == 0) { } else if (strcmp($type, "repo") == 0) {
47 $params = array($login_uid, $obj_id1);
46 48 $sql = "SELECT 1 FROM watch_repo" $sql = "SELECT 1 FROM watch_repo"
47 . " WHERE uid = $login_uid"
48 . " AND repo_id = $obj_id1";
49 . " WHERE uid = $1"
50 . " AND repo_id = $2";
49 51 } else { } else {
50 52 rg_internal_error("Invalid watch type!"); rg_internal_error("Invalid watch type!");
51 53 break; break;
52 54 } }
53 $res = rg_sql_query($db, $sql);
55 $res = rg_sql_query_params($db, $sql, $params);
54 56 if ($res === FALSE) if ($res === FALSE)
55 57 break; break;
56 58
 
... ... function rg_watch_add($db, $type, $login_uid, $obj_id1, $obj_id2)
92 94 } }
93 95
94 96 if (strcmp($type, "bug") == 0) { if (strcmp($type, "bug") == 0) {
97 $params = array($login_uid, $obj_id1, $obj_id2);
95 98 $sql = "INSERT INTO watch_bug (uid, repo_id, bug_id)" $sql = "INSERT INTO watch_bug (uid, repo_id, bug_id)"
96 . " VALUES ($login_uid, $obj_id1, $obj_id2)";
99 . " VALUES ($1, $2, $3)";
97 100 } else if (strcmp($type, "repo") == 0) { } else if (strcmp($type, "repo") == 0) {
101 $parmas = array($login_uid, $obj_id1);
98 102 $sql = "INSERT INTO watch_repo (uid, repo_id)" $sql = "INSERT INTO watch_repo (uid, repo_id)"
99 . " VALUES ($login_uid, $obj_id1)";
103 . " VALUES ($1, $2)";
100 104 } else { } else {
101 105 rg_internal_error("Invalid watch type!"); rg_internal_error("Invalid watch type!");
102 106 break; break;
103 107 } }
104 $res = rg_sql_query($db, $sql);
108 $res = rg_sql_query_params($db, $sql, $params);
105 109 if ($res === FALSE) if ($res === FALSE)
106 110 break; break;
107 111 rg_sql_free_result($res); rg_sql_free_result($res);
 
... ... function rg_watch_load_by_obj_id($db, $type, $obj_id1, $obj_id2)
161 165 $ret = FALSE; $ret = FALSE;
162 166 do { do {
163 167 if (strcmp($type, "bug") == 0) { if (strcmp($type, "bug") == 0) {
168 $params = array($obj_id1, $obj_id2);
164 169 $sql = "SELECT uid FROM watch_bug" $sql = "SELECT uid FROM watch_bug"
165 . " WHERE repo_id = $obj_id1"
166 . " AND bug_id = $obj_id2";
170 . " WHERE repo_id = $1"
171 . " AND bug_id = $2";
167 172 } else if (strcmp($type, "repo") == 0) { } else if (strcmp($type, "repo") == 0) {
173 $params = array($obj_id1);
168 174 $sql = "SELECT uid FROM watch_repo" $sql = "SELECT uid FROM watch_repo"
169 . " WHERE repo_id = $obj_id1";
175 . " WHERE repo_id = $1";
170 176 } else { } else {
171 177 rg_internal_error("Invalid watch type!"); rg_internal_error("Invalid watch type!");
172 178 break; break;
173 179 } }
174 $res = rg_sql_query($db, $sql);
180 $res = rg_sql_query_params($db, $sql, $params);
175 181 if ($res === FALSE) if ($res === FALSE)
176 182 break; break;
177 183
File rocketgit.spec.in changed (mode: 100644) (index c750c1e..222c88e)
... ... rm -rf ${RPM_BUILD_ROOT}
82 82 @ETC@/logrotate.d/rocketgit @ETC@/logrotate.d/rocketgit
83 83 %config(noreplace) @ETC@/xinetd.d/rocketgit %config(noreplace) @ETC@/xinetd.d/rocketgit
84 84 %config(noreplace) @ETC@/httpd/conf.d/rocketgit.conf %config(noreplace) @ETC@/httpd/conf.d/rocketgit.conf
85 %attr(0700,rocketgit,rocketgit) %dir @VAR_LOG@/@PRJ@
86 %attr(0700,apache,apache) %dir @VAR_LOG@/@PRJ@-web
85 %attr(0755,rocketgit,rocketgit) %dir @VAR_LOG@/@PRJ@
86 %attr(0755,apache,apache) %dir @VAR_LOG@/@PRJ@-web
87 87 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@ %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@
88 %attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/locks
88 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/locks
89 89 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/repos %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/repos
90 %attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/q_merge_requests
90 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/q_merge_requests
91 91 %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/sockets %attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/sockets
92 92 @USR_SHARE@/@PRJ@/* @USR_SHARE@/@PRJ@/*
93 93 @USR_SHARE@/selinux/*/@PRJ@.pp @USR_SHARE@/selinux/*/@PRJ@.pp
File root/index.php changed (mode: 100644) (index c857640..70fa3af)
... ... include_once($INC . "/prof.inc.php");
17 17 include_once($INC . "/mr.inc.php"); include_once($INC . "/mr.inc.php");
18 18 include_once($INC . "/bug.inc.php"); include_once($INC . "/bug.inc.php");
19 19 include_once($INC . "/fixes.inc.php"); include_once($INC . "/fixes.inc.php");
20 include_once($INC . "/plan.inc.php");
21 include_once($INC . "/ver.php");
20 22
21 23 rg_prof_start("MAIN"); rg_prof_start("MAIN");
22 24
23 25 rg_log_set_file($rg_web_log_dir . "/main.log"); rg_log_set_file($rg_web_log_dir . "/main.log");
24 26
27 // Last time fixes for configurations options that were added after
28 if (!isset($rg_theme_dir))
29 $rg_theme_dir = $rg_scripts . "/root/themes";
30
31 // Store confirguration into 'more'
32 if (!isset($rg_account_email_confirm))
33 $rg_account_email_confirm = 1;
34 $more['rg_account_email_confirm'] = $rg_account_email_confirm;
35 if (!isset($rg_account_allow_creation))
36 $rg_account_allow_creation = 0;
37 $more['rg_account_allow_creation'] = $rg_account_allow_creation;
38
25 39 // Init variables // Init variables
26 40 $THEME_URL = "/themes/" . $rg_theme; $THEME_URL = "/themes/" . $rg_theme;
27 41 $sparas = ""; $sparas = "";
28 42 $login_ui = array(); $login_ui = array();
43 $target_ui = array("ok" => 1, "exists" => 0, "uid" => 0);
29 44
30 45 // We have variable 'vv' passed from webserver - build 'op' and rest of paras // We have variable 'vv' passed from webserver - build 'op' and rest of paras
31 46 $sparas = rg_var_str("vv"); $sparas = rg_var_str("vv");
 
... ... $user = ""; $repo = ""; $organization = 0;
49 64 rg_log("IP: " . @$_SERVER['REMOTE_ADDR']); rg_log("IP: " . @$_SERVER['REMOTE_ADDR']);
50 65 rg_log("_REQUEST: " . rg_array2string($_REQUEST)); rg_log("_REQUEST: " . rg_array2string($_REQUEST));
51 66 rg_log("_COOKIE: " . rg_array2string($_COOKIE)); rg_log("_COOKIE: " . rg_array2string($_COOKIE));
52 rg_log("Start! sid=$sid");
67 rg_log("Start! ver=$rocketgit_version");
53 68
54 69
55 70 // database connection // database connection
56 71 $db = rg_sql_open($rg_sql); $db = rg_sql_open($rg_sql);
57 if ($db === FALSE) {
58 // TODO: Retry?
59 die("Cannot open database!");
60 }
61 72
62 while (1) {
73 $good = 0;
74 $tries = 10;
75 while ($tries > 0) {
63 76 $r = rg_sql_struct_update_needed($db); $r = rg_sql_struct_update_needed($db);
64 77 if ($r === FALSE) { if ($r === FALSE) {
78 rg_log("sql_struct_update_needed returned FALSE! Exit.");
79 break;
80 }
81
82 if ($r === 0) {
65 83 $r = rg_fixes_needed($db); $r = rg_fixes_needed($db);
66 if ($r === FALSE)
84 if ($r === FALSE) {
85 $good = 1;
67 86 break; break;
87 }
68 88 } }
69 89
70 90 rg_log("Schema/fixes is not up-to-date! Sleep 1 second..."); rg_log("Schema/fixes is not up-to-date! Sleep 1 second...");
71 sleep(5);
91 $tries--;
92 sleep(1);
93 }
94 if ($good == 0) {
95 // TODO: we must let if go to dispatcher instead of redirecting = another connection
96 $url = rg_re_url("fatal");
97 rg_fatal_web("Internal error", $url);
72 98 } }
73 99
74 100 rg_user_login_by_sid($db, $sid, $login_ui); rg_user_login_by_sid($db, $sid, $login_ui);
 
... ... rg_log("Dispatching to [$_op]");
107 133 include($INC . "/dispatch/dispatch.php"); include($INC . "/dispatch/dispatch.php");
108 134
109 135
110 $_m = rg_menu($rg_menu, "", $login_ui);
111 $more['HTML:rg_menu'] = implode("", $_m);
136 $more['HTML:rg_menu'] = rg_menu($rg_menu, "", $login_ui);
112 137
113 138 if ($login_ui['uid'] > 0) { if ($login_ui['uid'] > 0) {
114 139 $more['rg_username'] = $login_ui['username']; $more['rg_username'] = $login_ui['username'];
 
... ... echo rg_template("index.html", $more);
139 164
140 165 rg_log("DONE!"); rg_log("DONE!");
141 166 rg_prof_log("rg_log"); rg_prof_log("rg_log");
167
142 168 ?> ?>
File root/themes/default/access_denied.html copied from file root/themes/default/repo/history/nodata.html (similarity 55%) (mode: 100644) (index 6b49479..e5e4ea1)
1 1 <div class="warning"> <div class="warning">
2 No history found.
2 Access is not allowed!
3 3 </div> </div>
File root/themes/default/admin/plans/add_edit.html changed (mode: 100644) (index c70b229..b41f39b)
1 1 <div class="formarea"> <div class="formarea">
2 2
3 <div class="formarea_title">Add a new ssh key</div><br />
3 <div class="formarea_title">@@if(@@id@@ == 0){{Add a new plan}}{{Edit plan}}</div><br />
4 4
5 @@add_errmsg@@
5 @@errmsg@@
6 6
7 7 <form method="post" action="@@url@@"> <form method="post" action="@@url@@">
8 <input type="hidden" name="add" value="1" />
8 <input type="hidden" name="id" value="@@id@@" />
9 <input type="hidden" name="doit" value="1" />
9 10 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
10 11
11 <label for="key" class="form_item_title">Key string (starts with ssh-...)</label><br />
12 <textarea name="key" value="@@key@@" rows="4" cols="50"></textarea>
12 <label for="position" class="form_item_title">Position in the list</label><br />
13 <input type="text" name="position" value="@@position@@" />
13 14 <br /> <br />
14 15 <br /> <br />
15 16
16 <input type="submit" name="button" value="Add" />
17 <label for="name" class="form_item_title">Name</label><br />
18 <input type="text" name="name" value="@@name@@" />
19 <br />
20 <br />
21
22 <label for="description" class="form_item_title">Description</label><br />
23 <textarea name="description" value="@@description@@" rows="4" cols="50"></textarea>
24 <br />
25 <br />
26
27 <label for="disk_mb" class="form_item_title">Maximum disk space (0 = unlimited)</label><br />
28 <input type="text" name="disk_mb" value="@@disk_mb@@" />
29 <br />
30 <br />
31
32 <label for="users" class="form_item_title">Maximum number of co-workers (0 = unlimited)</label><br />
33 <input type="text" name="users" value="@@users@@" />
34 <br />
35 <br />
36
37 <label for="speed" class="form_item_title">Maximum speed (kbit/s, 0 = unlimited)</label><br />
38 <input type="text" name="speed" value="@@speed@@" />
39 <br />
40 <br />
41
42 <label for="bw" class="form_item_title">Maximum bandwidth (MiB/month, 0 = unlimited)</label><br />
43 <input type="text" name="bw" value="@@bw@@" />
44 <br />
45 <br />
46
47 <input type="submit" name="button" value="@@if(@@id@@ == 0){{Add}}{{Edit}}" />
17 48
18 49 </form> </form>
19 50 </div> </div>
File root/themes/default/admin/plans/list/header.html changed (mode: 100644) (index 626440b..6567679)
13 13 <th>Name</th> <th>Name</th>
14 14 <th>Description</th> <th>Description</th>
15 15 <th>Users</th> <th>Users</th>
16 <th>Bandwidth (kbit/s)</th>
16 <th>Speed (kbit/s)</th>
17 <th>Bandwidth (MiB/month)</th>
17 18 <th>Disk (MiB)</th> <th>Disk (MiB)</th>
18 19 </tr> </tr>
19 20
File root/themes/default/admin/plans/list/line.html changed (mode: 100644) (index 90499d2..fc6609c)
1 1 <!-- @@DUMP-DISABLED@@ --> <!-- @@DUMP-DISABLED@@ -->
2 2 <tr> <tr>
3 <td><input type="checkbox" name="plan_delete_ids[@@id@@]" /></td>
3 <td><input type="checkbox" name="delete_list[@@id@@]" /></td>
4 4 <td>@@position@@</td> <td>@@position@@</td>
5 5 <td>@@name@@</td> <td>@@name@@</td>
6 6 <td>@@description@@</td> <td>@@description@@</td>
7 <td>@@users@@</td>
8 <td>@@bw@@</td>
9 <td>@@disk_mb@@</td>
7 <td>@@if(@@users@@ == 0){{Unlimited}}{{@@users@@}}</td>
8 <td>@@if(@@speed@@ == 0){{Unlimited}}{{@@speed@@}}</td>
9 <td>@@if(@@bw@@ == 0){{Unlimited}}{{@@bw@@}}</td>
10 <td>@@if(@@disk_mb@@ == 0){{Unlimited}}{{@@disk_mb@@}}</td>
10 11 </tr> </tr>
11 12
File root/themes/default/admin/plans/list/nodata.html changed (mode: 100644) (index 2a4c0b5..760abd1)
1 1 <div class="warning"> <div class="warning">
2 No plans yet.
2 No plans defined yet.
3 3 </div> </div>
File root/themes/default/admin/plans/list_err.html changed (mode: 100644) (index 7fbd42a..5e8958f)
1 could not delete the plans selected (@@errmsg@@)
1 could not list plans (@@errmsg@@)
File root/themes/default/admin/users/bad_admin.html added (mode: 100644) (index 0000000..f231222)
1 <div class="warning">
2 Cannot upgrade account to admin level.
3 </div>
File root/themes/default/admin/users/bad_remove.html added (mode: 100644) (index 0000000..b89abcb)
1 <div class="warning">
2 Cannot remove account.
3 </div>
File root/themes/default/admin/users/bad_suspend.html added (mode: 100644) (index 0000000..f4930a2)
1 <div class="warning">
2 Cannot suspend account.
3 </div>
File root/themes/default/admin/users/bad_unadmin.html added (mode: 100644) (index 0000000..6f67b9d)
1 <div class="warning">
2 Cannot downgrade account from admin level.
3 </div>
File root/themes/default/admin/users/bad_unsuspend.html added (mode: 100644) (index 0000000..d3d1965)
1 <div class="warning">
2 Cannot un-suspend account.
3 </div>
File root/themes/default/hints/ssh/key.html changed (mode: 100644) (index dd08f27..9212c74)
... ... How to create a SSH key for RocketGit:<br />
3 3 ssh-keygen -C "Key for RocketGit" -f ~/.ssh/rocketgit1<br /> ssh-keygen -C "Key for RocketGit" -f ~/.ssh/rocketgit1<br />
4 4 cat ~/.ssh/rocketgit1.pub<br /> cat ~/.ssh/rocketgit1.pub<br />
5 5 </code> </code>
6 Now, copy in clipboard starting with "ssh-...", including the comment.<br />
6 Now, copy in clipboard starting with "ssh-...", including the comment
7 and paste it in the form above.<br />
7 8 <br /> <br />
8 9
9 10 To force the use of this key when you connect to the server,<br /> To force the use of this key when you connect to the server,<br />
 
... ... Host @@rg_ssh_host@@<br />
16 17 </code> </code>
17 18 <br /> <br />
18 19
19 To see the fingerprint of your key (for comparation):<br />
20 To see the fingerprint of your local key (for comparation):<br />
20 21 <code> <code>
21 22 ssh-keygen -f ~/.ssh/rocketgit1 -l</br /> ssh-keygen -f ~/.ssh/rocketgit1 -l</br />
22 23 </code> </code>
File root/themes/default/mail/user/key/del.body.txt changed (mode: 100644) (index 0bd1a33..3901edf)
1 1 Hello! Hello!
2 2
3 A SSH key was removed from your account.
3 Some SSH keys were removed from your account.
4 4
5 5 IP: @@IP@@ IP: @@IP@@
6 6
File root/themes/default/mail/user/key/del.subj.txt changed (mode: 100644) (index 1a4c997..433f836)
1 A SSH key was removed
1 SSH keys were removed
File root/themes/default/mail/user/repo/del.body.txt changed (mode: 100644) (index b782131..1d7797d)
1 1 Hello! Hello!
2 2
3 Repository '@@ri.name@@' was delete.
3 Repository '@@ri.name@@' was deleted.
4 4
5 5 IP: @@IP@@ IP: @@IP@@
6 6
File root/themes/default/mail/user/welcome.body.txt changed (mode: 100644) (index eb3918f..e9788ea)
... ... Welcome to RocketGit!
4 4
5 5 We will gladly host your projects. We will gladly host your projects.
6 6 Enjoy your stay! Enjoy your stay!
7 @@if(@@rg_account_email_confirm@@ == 1)
8 {{
9 You must confirm your e-mail address before you can use your account,
10 by clicking on the link below:}}
11 {{You may want to confirm your e-mail address by clicking on the link below:}}
12 @@url@@/op/confirm/@@ui.confirm_token@@
7 13
8 14 Thank you! Thank you!
9 15
File root/themes/default/main.css changed (mode: 100644) (index b32c882..108e6b2)
... ... form input[type="submit"] {
197 197 color: red; color: red;
198 198 } }
199 199
200 .form_item_title {
201 }
200 .form_item_title {}
202 201
203 202 .rg_keys_list { .rg_keys_list {
204 203 margin-top: 20px; margin-top: 20px;
205 204 } }
206 205
206 .rg_plans_list {}
207
207 208 .blob_title { .blob_title {
208 209 font-size: 10pt; font-size: 10pt;
209 210 color: red; color: red;
File root/themes/default/menu/line.html changed (mode: 100644) (index 0887b12..2b29c2a)
1 <li><a href="@@url@@"@@selected@@>@@text@@</a></li>
1 <li><a href="@@url@@"@@if(@@selected@@ == 1){{ class="selected"}}{{}}>@@text@@</a></li>
File root/themes/default/msg/internal.txt changed (mode: 100644) (index 2a4f4fb..911a3b8)
1 An internal error occured. Please try again later.
1 An internal error occured. Please try again later.
File root/themes/default/repo/bug/bug_add_edit.html changed (mode: 100644) (index 9f3e560..d046148)
1 1 <div class="formarea"> <div class="formarea">
2 2
3 <div class="formarea_title">@@if(@@bug_id == 0){{Add bug}}{{Edit 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
File root/themes/default/repo/invalid.html copied from file root/themes/default/repo/history/nodata.html (similarity 59%) (mode: 100644) (index 6b49479..61fcdc1)
1 1 <div class="warning"> <div class="warning">
2 No history found.
2 Invalid repository.
3 3 </div> </div>
File root/themes/default/repo/list/header.html changed (mode: 100644) (index 79e48b3..f2ac164)
6 6 <th>Clone of</th> <th>Clone of</th>
7 7 <th>Creation date (UTC)</th> <th>Creation date (UTC)</th>
8 8 <th>Default rights</th> <th>Default rights</th>
9 <th>Disk used/max</th>
10 <th>Max commit size</th>
11 <th>Max users</th>
9 <th>Disk used</th>
12 10 </tr> </tr>
13 11
File root/themes/default/repo/list/line.html changed (mode: 100644) (index ca22cee..5e680a9)
5 5 <td>@@creation@@</td> <td>@@creation@@</td>
6 6 <td>@@rights@@</td> <td>@@rights@@</td>
7 7 <td>@@disk_used@@</td> <td>@@disk_used@@</td>
8 <td>@@max_commit_size@@</td>
9 <td>@@max_users@@</td>
10 8 </tr> </tr>
File root/themes/default/user/add_edit.html added (mode: 100644) (index 0000000..20ed0bb)
1 <div class="formarea">
2
3 <div class="formarea_title">@@if(@@create_mode@@ == 1){{Create a new account}}{{Change account}}</div><br />
4
5 @@errmsg@@
6
7 <form method="post" action="@@url@@">
8 <input type="hidden" name="uid" value="@@uid@@" />
9 <input type="hidden" name="doit" value="1" />
10 <input type="hidden" name="token" value="@@rg_form_token@@" />
11
12 <label for="username" class="form_item_title">User name</label><br />
13 <input type="text" name="username" value="@@username@@" />
14 <br />
15 <br />
16
17 <label for="realname" class="form_item_title">Name (not public)</label><br />
18 <input type="text" name="realname" value="@@realname@@" />
19 <br />
20 <br />
21
22 <label for="email" class="form_item_title">E-mail</label><br />
23 <input type="text" name="email" value="@@email@@" />
24 <br />
25 <br />
26
27 @@if(@@ask_for_pass@@ == 1){{
28 <label for="pass" class="form_item_title">Password</label><br />
29 <input type="password" name="pass" value="@@pass@@" />
30 <br />
31 <br />
32
33 <label for="pass2" class="form_item_title">Password (confirmation)</label><br />
34 <input type="password" name="pass2" value="@@pass2@@" />
35 <br />
36 <br />
37 }}
38 {{}}
39
40 @@if(@@admin_mode@@ == 1){{
41 <label for="is_admin" class="form_item_title">Admin?</label><br />
42 <select name="is_admin">
43 <option value="0"@@if(@@is_admin@@ == 0){{ selected="selected"}}{{}}>No</option>
44 <option value="1"@@if(@@is_admin@@ == 1){{ selected="selected"}}{{}}>Yes</option>
45 </select>
46 <br />
47 <br />
48
49 <label for="rights" class="form_item_title">Rights</label><br />
50 @@checkbox_rights@@
51 <br />
52 <br />
53 }}
54 {{}}
55
56 <label for="plan" class="form_item_title">Plan</label><br />
57 @@select_plan@@
58 <br />
59 <br />
60
61 <label for="session_time" class="form_item_title">Preferred session time (in seconds)</label><br />
62 <input type="text" name="session_time" value="@@session_time@@" />
63 <br />
64 <br />
65
66 <input type="submit" value="@@if(@@create_mode@@ == 1){{Create}}{{Edit}}" />
67 </form>
68 </div>
File root/themes/default/user/bad_token.html copied from file root/themes/default/admin/plans/list/nodata.html (similarity 65%) (mode: 100644) (index 2a4c0b5..2bc6b10)
1 1 <div class="warning"> <div class="warning">
2 No plans yet.
2 Invalid token.
3 3 </div> </div>
File root/themes/default/user/create_na.html added (mode: 100644) (index 0000000..4875389)
1 <div class="warning">
2 This site does not allow account creation. Talk with Admin.
3 </div>
File root/themes/default/user/create_ok.html added (mode: 100644) (index 0000000..ac2350f)
1 <div class="ok">
2 Your account was created.
3 @@if(@@rg_account_email_confirm@@ == 1){{
4 <br />You must confirm the account before you can login.
5 <br />Check you e-mail for instructions.
6 }}
7 {{}}
8 </div>
File root/themes/default/user/edit_ok.html added (mode: 100644) (index 0000000..76ab87e)
1 <div class="ok">
2 Information was updated with success.
3 </div>
File root/themes/default/user/forgot.html changed (mode: 100644) (index 9810fc2..44c2cee)
18 18 <br /> <br />
19 19 <br /> <br />
20 20
21 <label for="lock_ip" class="form_item_title">Lock login from current IP</label><br />
22 <input type="radio" name="lock_ip" value="1" checked="checked"/> Yes (more secure)<br />
23 <input type="radio" name="lock_ip" value="0" /> No (works everywhere)<br />
24 <br />
25
21 26 <input type="submit" name="button" value="Change password" /> <input type="submit" name="button" value="Change password" />
22 27
23 28 </form> </form>
File root/themes/default/user/invalid.html copied from file root/themes/default/repo/tree/nodata.html (similarity 67%) (mode: 100644) (index d5ef081..8d1424e)
1 1 <div class="warning"> <div class="warning">
2 Empty tree.
2 Invalid user.
3 3 </div> </div>
File root/themes/default/user/keys/list/header.html changed (mode: 100644) (index 3b78fc1..ac7e523)
12 12 <th>Upload date (UTC)</th> <th>Upload date (UTC)</th>
13 13 <th>Fingerprint</th> <th>Fingerprint</th>
14 14 <th>Comment</th> <th>Comment</th>
15 <th>First use (UTC)</th>
15 16 <th>Last use (UTC)</th> <th>Last use (UTC)</th>
16 17 <th>Last IP</th> <th>Last IP</th>
18 <th>Count</th>
17 19 </tr> </tr>
18 20
File root/themes/default/user/keys/list/line.html changed (mode: 100644) (index 9af8056..7011df5)
4 4 <td>@@itime@@</td> <td>@@itime@@</td>
5 5 <td>@@fingerprint@@</td> <td>@@fingerprint@@</td>
6 6 <td>@@comment@@</td> <td>@@comment@@</td>
7 <td>@@first_use@@</td>
7 8 <td>@@last_use@@</td> <td>@@last_use@@</td>
8 9 <td>@@last_ip@@</td> <td>@@last_ip@@</td>
10 <td>@@count@@</td>
9 11 </tr> </tr>
10 12
File root/themes/default/user/login.html changed (mode: 100644) (index dac1e84..ef80a59)
8 8 <input type="hidden" name="doit" value="1" /> <input type="hidden" name="doit" value="1" />
9 9
10 10 <label for="username" class="form_item_title">Username</label><br /> <label for="username" class="form_item_title">Username</label><br />
11 <input type="text" name="user" value="@@user@@" />
12 <br />
11 <input type="text" name="user" value="@@user@@" /><br />
13 12 <br /> <br />
14 13
15 14 <label for="password" class="form_item_title">Password</label><br /> <label for="password" class="form_item_title">Password</label><br />
16 <input type="password" name="pass" value="@@pass@@" />
15 <input type="password" name="pass" value="@@pass@@" /><br />
17 16 <br /> <br />
17
18 <label for="lock_ip" class="form_item_title">Lock login from current IP</label><br />
19 <input type="radio" name="lock_ip" value="1" checked="checked"/> Yes (more secure)<br />
20 <input type="radio" name="lock_ip" value="0" /> No (works everywhere)<br />
18 21 <br /> <br />
19 22
20 23 <input type="submit" name="button" value="Login" /> <input type="submit" name="button" value="Login" />
 
23 26
24 27 <a href="@@forgot_send@@">Forgot your password?</a> <a href="@@forgot_send@@">Forgot your password?</a>
25 28
26 @@if(@@allow_creation@@ == 1){{
29 @@if(@@rg_account_allow_creation@@ == 1){{
27 30 <br /> <br />
28 31 <a href="@@create_account@@">Create a new account</a> <a href="@@create_account@@">Create a new account</a>
29 32 }} }}
File root/themes/default/user/repo/rights/form.html changed (mode: 100644) (index ff0cf6f..d119635)
13 13 <br /> <br />
14 14 <br /> <br />
15 15
16 <table>
17 <tr>
18 <th>For repo</th>
19 <th>For refs</th>
20 </tr>
21
22 <tr>
23 <td>
24 <label class="form_item_title" for="rights">Rights</label><br />
25 @@rights_checkboxes@@
26 </td>
27
28 <td>
29 <label class="form_item_title" for="ref">Reference</label><br />
30 <input type="text" name="ref" value="@@ref@@" />
31 <br />
32 <br />
33
34 <label class="form_item_title" for="path">Path</label><br />
35 <input type="text" name="path" value="@@path@@" />
36 <br />
37 <br />
38
16 39 <label class="form_item_title" for="rights">Rights</label><br /> <label class="form_item_title" for="rights">Rights</label><br />
17 40 @@rights_checkboxes@@ @@rights_checkboxes@@
18 41 <br /> <br />
42 </td>
43 </tr>
44 </table>
19 45
20 46 <input type="submit" name="button" value="Grant" /> <input type="submit" name="button" value="Grant" />
21 47
File samples/config.php changed (mode: 100644) (index fc06ed2..8da6a03)
... ... $rg_admin_email = "admin@site.tld";
42 42 // Else, only the admin can create accounts. // Else, only the admin can create accounts.
43 43 $rg_account_allow_creation = 1; $rg_account_allow_creation = 1;
44 44
45 // Set to 0 if you do not want mandatory e-mail confirmation before usage.
46 $rg_account_email_confirm = 0;
47
45 48 // Maximum number of keys per user // Maximum number of keys per user
46 49 $rg_max_ssh_keys = 10; $rg_max_ssh_keys = 10;
47 50
 
... ... $rg_lock_dir = $rg_state_dir . "/locks";
58 61 // Repositories dir // Repositories dir
59 62 $rg_repos = $rg_state_dir . "/repos"; $rg_repos = $rg_state_dir . "/repos";
60 63
64 // Directory for themes
65 $rg_theme_dir = $rg_scripts . "/root/themes";
66
61 67 // Default theme // Default theme
62 68 $rg_theme = "default"; $rg_theme = "default";
63 69
File samples/cron changed (mode: 100644) (index 72f6e23..aac1836)
1 1 * * * * * rocketgit /usr/share/rocketgit/scripts/cron.sh * * * * * rocketgit /usr/share/rocketgit/scripts/cron.sh
2 2 * * * * * rocketgit /usr/share/rocketgit/scripts/q.sh * * * * * rocketgit /usr/share/rocketgit/scripts/q.sh
3 3 * * * * * rocketgit /usr/share/rocketgit/scripts/events.sh * * * * * rocketgit /usr/share/rocketgit/scripts/events.sh
4 * * * * * rocketgit /usr/share/rocketgit/scripts/cache.sh
File samples/rg.conf changed (mode: 100644) (index 7e032cc..4bc4045)
17 17 #RewriteLog /var/log/httpd/rg-Rewrite.log #RewriteLog /var/log/httpd/rg-Rewrite.log
18 18 #RewriteLogLevel 3 #RewriteLogLevel 3
19 19
20 # index.php is special
21 RewriteCond %{REQUEST_URI} ^/index\.php
22 RewriteRule .* /index.php?rwe=1 [L,QSA]
23
20 24 # Allow .ico, 'themes' folder and any txt file (think robots.txt) # Allow .ico, 'themes' folder and any txt file (think robots.txt)
21 25 # Also, avoid scripts that are looking for exploits # Also, avoid scripts that are looking for exploits
22 26 RewriteCond %{REQUEST_URI} ^/(favicon\.ico|themes|.*\.txt|.*\.php) RewriteCond %{REQUEST_URI} ^/(favicon\.ico|themes|.*\.txt|.*\.php)
23 27 RewriteRule .* - [L] RewriteRule .* - [L]
24 28
25 # index.php is special
26 RewriteCond %{REQUEST_URI} ^/index\.php
27 RewriteRule .* /index.php?rwe=1 [L,QSA]
28
29 29 # all rest # all rest
30 30 RewriteRule (.*) /index.php?rwe=1&vv=$1 [L,QSA] RewriteRule (.*) /index.php?rwe=1&vv=$1 [L,QSA]
31 31
File scripts/cache.php changed (mode: 100644) (index 9ee3448..c8279d6)
4 4 // It will receive signals using a UNIX socket. // It will receive signals using a UNIX socket.
5 5 error_reporting(E_ALL); error_reporting(E_ALL);
6 6 ini_set("track_errors", "On"); ini_set("track_errors", "On");
7 set_time_limit(0);
7 8
8 9 // Increment this if we need to restart this daemon (protocol changes etc.) // Increment this if we need to restart this daemon (protocol changes etc.)
9 $rg_cache_version = 1;
10 $rg_cache_version = 35;
10 11
11 12 $now = time(); $now = time();
12 13 $_s = microtime(TRUE); $_s = microtime(TRUE);
 
... ... require_once($INC . "/init.inc.php");
18 19 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
19 20 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
20 21 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
21 require_once($INC . "/events.inc.php");
22 require_once($INC . "/cache.inc.php");
22 23 require_once($INC . "/repo.inc.php"); require_once($INC . "/repo.inc.php");
23 24 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
24 25 require_once($INC . "/mr.inc.php"); require_once($INC . "/mr.inc.php");
 
... ... require_once($INC . "/keys.inc.php");
26 27 require_once($INC . "/user.inc.php"); require_once($INC . "/user.inc.php");
27 28 require_once($INC . "/bug.inc.php"); require_once($INC . "/bug.inc.php");
28 29 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
30 require_once($INC . "/ver.php");
31
32 function rg_destroy($k, &$conn_table)
33 {
34 if (isset($conn_table['r'][$k]))
35 unset($conn_table['r'][$k]);
36 if (isset($conn_table['w'][$k]))
37 unset($conn_table['w'][$k]);
38 // TODO: seems socket is already closed
39 if (is_resource($conn_table['conns'][$k]['socket']))
40 socket_close($conn_table['conns'][$k]['socket']);
41 unset($conn_table['conns'][$k]);
42 }
43
44 function rg_handle_command($k, &$conn_table, $cmd)
45 {
46 rg_log("rg_handle_command: k=$k, cmd=$cmd");
47
48 $s = &$conn_table['conns'][$k];
49
50 $a = explode(" ", $cmd, 2);
51 $buf = "WHAT?!\n";
52 do {
53 if (!isset($a[0]))
54 break;
55
56 $cmd = trim($a[0]);
57
58 /* here, no parameters */
59
60 /* From, here, at least 1 para */
61 if (!isset($a[1]))
62 break;
63 $para1 = trim($a[1]);
64
65 if (strcmp($cmd, "SET") == 0) {
66 $ns_var_value = explode("=", $para1, 2);
67 if (!isset($ns_var_value[1]))
68 break;
69 $ns_var = trim($ns_var_value[0]);
70 $value = trim($ns_var_value[1]);
71 rg_cache_server_set("normal::" . $ns_var, $value);
72 $buf = "OK\n";
73 break;
74 }
75
76 if (strcmp($cmd, "INC") == 0) {
77 $v = rg_cache_server_inc("normal::" . $para1);
78 $buf = "OK v=$v\n";
79 break;
80 }
81
82 if (strcmp($cmd, "GET") == 0) {
83 $ret = rg_cache_server_get("normal::" . $para1);
84 if ($ret === FALSE)
85 $buf = "NOT_FOUND\n";
86 else
87 $buf = "OK " . $ret . "\n";
88 break;
89 }
90
91 if (strcmp($cmd, "UNSET") == 0) {
92 $ret = rg_cache_server_unset("normal::" . $para1);
93 if ($ret === FALSE)
94 $buf = "NOT_FOUND\n";
95 else
96 $buf = "OK\n";
97 break;
98 }
99
100 if (strcmp($cmd, "ADUMP") == 0) {
101 $ret = rg_cache_server_adump("normal::" . $para1);
102 if ($ret === FALSE)
103 $buf = "NOT_FOUND\n";
104 else
105 $buf = "OK " . $ret . "\n";
106 break;
107 }
108
109 if (strcmp($cmd, "APUSH") == 0) {
110 $ns_var_value = explode("=", $para1, 2);
111 if (!isset($ns_var_value[1]))
112 break;
113 $ns_var = trim($ns_var_value[0]);
114 $value = trim($ns_var_value[1]);
115 rg_cache_server_apush("normal::" . $ns_var, $value);
116 $buf = "OK\n";
117 break;
118 }
119
120 if (strcmp($cmd, "APOP") == 0) {
121 $ret = rg_cache_server_apop("normal::" . $para1);
122 if ($ret === FALSE)
123 $buf = "NOT_FOUND\n";
124 else
125 $buf = "OK " . $ret . "\n";
126 break;
127 }
128
129 if (strcmp($cmd, "ASHIFT") == 0) {
130 $ret = rg_cache_server_ashift("normal::" . $para1);
131 if ($ret === FALSE)
132 $buf = "NOT_FOUND\n";
133 else
134 $buf = "OK " . $ret . "\n";
135 break;
136 }
137 } while (0);
138
139 $s['send'] .= $buf;
140 $conn_table['w'][$k] = $s['socket'];
141 }
142
143 function rg_handle_recv($k, &$conn_table)
144 {
145 $s = &$conn_table['conns'][$k];
146
147 $ret = @socket_recv($s['socket'], $buf, 32 * 4096, 0);
148 if ($ret === FALSE) {
149 rg_log("Error in recv (" . socket_strerror(socket_last_error()) . ")");
150 rg_destroy($k, $conn_table);
151 return;
152 }
153 if ($ret === 0) {
154 //rg_log("Remote closed the connection.");
155 rg_destroy($k, $conn_table);
156 return;
157 }
158
159 rg_log("Received data on key $k [$buf]...");
160
161 $s['recv'] .= $buf;
162 $s['close_at'] = time() + 300;
163
164 while (1) {
165 $pos = strpos($s['recv'], "\n");
166 if ($pos === FALSE)
167 return;
168
169 $cmd = substr($s['recv'], 0, $pos);
170 $s['recv'] = substr($s['recv'], $pos + 1);
171
172 rg_handle_command($k, $conn_table, $cmd);
173 };
174 }
175
176 function rg_handle_send($k, &$conn_table)
177 {
178 $s = &$conn_table['conns'][$k];
179
180 rg_log("Sending on key $k [" . $s['send'] . "]...");
181 $ret = @socket_send($s['socket'], $s['send'], strlen($s['send']), 0);
182 if ($ret === FALSE) {
183 rg_log("Cannot send (" . socket_strerror(socket_last_error()) . ")");
184 rg_destroy($k, $conn_table);
185 return;
186 }
187
188 $s['send'] = substr($s['send'], $ret);
189 if (empty($s['send']))
190 unset($conn_table['w'][$k]);
191 }
192
193 function rg_handle_new($client, &$conn_table)
194 {
195 socket_set_nonblock($client);
196
197 $key = intval($client);
198 $conn_table['conns'][$key] = array(
199 "socket" => $client,
200 "recv" => "",
201 "send" => "",
202 "close_at" => time() + 300
203 );
204 $conn_table['r'][$key] = $client;
205 rg_log("Added client with key $key.");
206 }
207
208 function rg_handle_idle(&$conn_table)
209 {
210 $now = time();
211
212 foreach ($conn_table['conns'] as $key => $info) {
213 if (strcmp($key, "master") == 0)
214 continue;
215
216 if ($info['close_at'] < $now) {
217 rg_log("Destroy $key because was too much time idle.");
218 rg_destroy($key, $conn_table);
219 }
220 }
221 }
222
29 223
30 224 rg_prof_start("MAIN"); rg_prof_start("MAIN");
31 225
32 226 rg_log_set_file($rg_log_dir . "/cache.log"); rg_log_set_file($rg_log_dir . "/cache.log");
33 227 rg_log_set_sid("000000"); // to spread the logs rg_log_set_sid("000000"); // to spread the logs
34 228
35 rg_log("Start...");
36
37 // TODO: really needed db connection?
38 $db = rg_sql_open($rg_sql);
39 if ($db === FALSE) {
40 rg_internal_error("Cannot connect to database!");
41 exit(1);
42 }
229 rg_log("Start (ver=$rocketgit_version)...");
43 230
44 231 // Remove the socket, else we will get error // Remove the socket, else we will get error
45 232 if (file_exists($rg_cache_socket)) if (file_exists($rg_cache_socket))
46 233 unlink($rg_cache_socket); unlink($rg_cache_socket);
47 234
48 $socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
49 if ($socket === FALSE) {
235 $master = socket_create(AF_UNIX, SOCK_STREAM, 0);
236 if ($master === FALSE) {
50 237 rg_internal_error("Cannot create events socket!"); rg_internal_error("Cannot create events socket!");
51 238 exit(1); exit(1);
52 239 } }
53 240
54 $r = socket_bind($socket, $rg_cache_socket);
241 $r = socket_bind($master, $rg_cache_socket);
55 242 if ($r === FALSE) { if ($r === FALSE) {
56 243 rg_internal_error("Cannot bind socket!"); rg_internal_error("Cannot bind socket!");
57 244 exit(1); exit(1);
58 245 } }
59 246
60 $r = socket_listen($socket, 128);
247 $r = socket_listen($master, 128);
61 248 if ($r === FALSE) { if ($r === FALSE) {
62 249 rg_internal_error("Cannot set queue length on socket!"); rg_internal_error("Cannot set queue length on socket!");
63 250 exit(1); exit(1);
64 251 } }
65 252
253 socket_set_nonblock($master);
254
66 255 // Allow apache (at least) to connect to socket // Allow apache (at least) to connect to socket
67 256 // TODO: this is a security hole. Take care. Hm. How?! // TODO: this is a security hole. Take care. Hm. How?!
68 257 $r = chmod($rg_cache_socket, 0666); $r = chmod($rg_cache_socket, 0666);
 
... ... if ($r === FALSE) {
71 260 exit(1); exit(1);
72 261 } }
73 262
74 $notify_list = array();
75 $r = array(); $w = array();
76 $r['master'] = $socket;
263 $conn_table = array("r" => array(), "w" => array(), "conns" => array());
264 $conn_table['r']['master'] = $master;
77 265 do { do {
78 266 $new_ver = file_get_contents(__FILE__); $new_ver = file_get_contents(__FILE__);
79 267 $new_ver = preg_match("/rg_cache_version = (.*);/", $new_ver, $matches); $new_ver = preg_match("/rg_cache_version = (.*);/", $new_ver, $matches);
 
... ... do {
85 273
86 274 rg_log_buffer_clear(); rg_log_buffer_clear();
87 275
88 $r2 = $r; $w2 = $w; $ex = array();
276 $r2 = $conn_table['r']; $w2 = $conn_table['w']; $ex = array();
89 277 $r = socket_select($r2, $w2, $ex, 5); $r = socket_select($r2, $w2, $ex, 5);
90 278 if ($r === FALSE) if ($r === FALSE)
91 279 rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!"); rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!");
92 280
93 rg_log("select returned $r.");
281 //rg_log_ml("conn_table: " . print_r($conn_table, TRUE));
94 282
95 print_r($r); exit(0);
96 foreach ($r as $k) {
97 }
283 foreach ($r2 as $key => $socket) {
284 if (strcmp($key, "master") == 0) {
285 $client = socket_accept($socket);
286 if ($client === FALSE) {
287 rg_log("Connection seems broken!");
288 continue;
289 }
98 290
99 $client = socket_accept($socket);
100 if ($client === FALSE) {
101 rg_log("Connection seems broken!");
102 continue;
103 }
104
105 // TODO: this will be used with select
106 //socket_set_nonblock($client);
107
108 $close = 1;
109 $r = socket_recv($client, $buf, 1024, 0);
110 if ($r === 0) { // remote close the connection
111 rg_log("Remote closed the connection.");
112 } else if ($r === FALSE) {
113 $errno = socket_last_error($client);
114 rg_log("Error in receive (" . socket_strerror($errno) . ").");
115 } else {
116 rg_log("Received $r byte(s): [$buf].");
117 if (strncmp($buf, "NOTIFY ", 7) == 0) {
118 $ev_id = trim(substr($buf, 7));
119 $notify_list[$ev_id][] = array("fd" => $client, "itime" => time());
120 $close = 0;
121
122 // It is possible that we already executed the task
123 rg_event_notify($notify_list, $ev_id, "");
124 } else if (strncmp($buf, "SET ", 4) == 0) {
125 $_t = explode("=", substr($buf, 4), 2);
126 $ns_var = trim($_t[0]);
127 $value = trim($_t[1]);
128 $_t = explode("::", $ns_var, 2);
129 $ns = trim($_t[0]);
130 $var = trim($_t[1]);
131 rg_event_set($ns, $var, $value);
132 rg_event_notify($notify_list, $ns . "::" . $var, $value);
133 } else if (strncmp($buf, "GET ", 4) == 0) {
134 $_t = explode("::", substr($buf, 4), 2);
135 $ns = trim($_t[0]);
136 $var = trim($_t[1]);
137 $out = rg_event_get($ns, $var);
138 if ($out === FALSE)
139 $out = "NOT_FOUND";
140 $r = socket_send($client, $out, strlen($out), 0);
141 } else if (strncmp($buf, "UNSET ", 6) == 0) {
142 $_t = explode("::", substr($buf, 6), 2);
143 $ns = trim($_t[0]);
144 $var = trim($_t[1]);
145 rg_event_unset($ns, $var);
146 $r = socket_send($client, $out, strlen($out), 0);
147 rg_event_notify($notify_list, $ns . "::" . $var, ""); // TODO: need to signal FALSE
291 rg_handle_new($client, $conn_table);
292 continue;
148 293 } }
294
295 rg_handle_recv($key, $conn_table);
149 296 } }
150 297
151 if ($close == 1)
152 socket_close($client);
298 foreach ($w2 as $key => $sock)
299 rg_handle_send($key, $conn_table);
153 300
154 // clean up notify_list
155 rg_event_notify_clean($notify_list);
301 rg_handle_idle($conn_table);
156 302 } while (1); } while (1);
157 303
158 socket_close($socket);
304 socket_close($master);
159 305
160 306 rg_log("Exiting..."); rg_log("Exiting...");
161 307
File scripts/cache.sh changed (mode: 100755) (index e97acdd..ab95c68)
2 2
3 3 # This is a wrapper for cache.php, to not wait a lot after it exits # This is a wrapper for cache.php, to not wait a lot after it exits
4 4
5 . /usr/share/rocketgit/scripts/common.sh
6
7 check_context
8
5 9 exec 100<>/var/lib/rocketgit/locks/cache.sh.lock exec 100<>/var/lib/rocketgit/locks/cache.sh.lock
6 10
7 11 flock --exclusive --nonblock 100 flock --exclusive --nonblock 100
 
... ... if [ "${?}" != "0" ]; then
9 13 exit 0 exit 0
10 14 fi fi
11 15
16 # Be sure we are running under correct context
17 if [ -r /proc/self/attr/current ]; then
18 grep -q rocketgit_t /proc/self/attr/current
19 if [ "${?}" != "0" ]; then
20 exit 0
21 fi
22 fi
23
12 24 while [ 1 ]; do while [ 1 ]; do
13 25 php /usr/share/rocketgit/scripts/cache.php php /usr/share/rocketgit/scripts/cache.php
14 26
File scripts/cachec.php changed (mode: 100644) (index 5539aba..d02edd1)
... ... require_once($INC . "/init.inc.php");
14 14 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
15 15 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
16 16 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
17 require_once($INC . "/events.inc.php");
17 require_once($INC . "/cache.inc.php");
18 18 require_once($INC . "/repo.inc.php"); require_once($INC . "/repo.inc.php");
19 19 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
20 20 require_once($INC . "/mr.inc.php"); require_once($INC . "/mr.inc.php");
File scripts/common.sh added (mode: 100644) (index 0000000..e873dfa)
1 #!/bin/bash
2
3 # Be sure we are running under correct context
4 function check_context()
5 {
6 if [ -r /proc/self/attr/current ]; then
7 grep -q rocketgit_t /proc/self/attr/current
8 if [ "${?}" != "0" ]; then
9 exit 0
10 fi
11 fi
12 }
13
File scripts/cron.php changed (mode: 100644) (index d7e089c..c927072)
... ... require_once($INC . "/struct.inc.php");
15 15 require_once($INC . "/repo.inc.php"); require_once($INC . "/repo.inc.php");
16 16 require_once($INC . "/keys.inc.php"); require_once($INC . "/keys.inc.php");
17 17 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
18 require_once($INC . "/ver.php");
18 19
19 20 rg_log_set_file($rg_log_dir . "/cron.log"); rg_log_set_file($rg_log_dir . "/cron.log");
20 21 rg_log_set_sid("000000"); // to spread the logs rg_log_set_sid("000000"); // to spread the logs
 
... ... rg_log_set_sid("000000"); // to spread the logs
22 23 // locking // locking
23 24 rg_lock_or_exit("cron.lock"); rg_lock_or_exit("cron.lock");
24 25
25 rg_log("Start...");
26 rg_log("Start (ver=$rocketgit_version)...");
26 27
27 28 $db = rg_sql_open($rg_sql); $db = rg_sql_open($rg_sql);
28 29 if ($db === FALSE) { if ($db === FALSE) {
 
... ... $r = rg_fixes_update($db);
39 40 if ($r !== TRUE) if ($r !== TRUE)
40 41 exit(1); exit(1);
41 42
42 if (gmdate("H") == 4) {
43 if ((gmdate("H") == 0) && (gmdate("i") == 3)) {
43 44 do { do {
44 45 rg_log("Compute repository sizes if dirty..."); rg_log("Compute repository sizes if dirty...");
45 46 // delete 'dirty' files // delete 'dirty' files
46 $sql = "SELECT uid, repo_id FROM repos";
47 $sql = "SELECT uid, repo_id, master FROM repos";
47 48 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
48 49 if ($res === FALSE) { if ($res === FALSE) {
49 50 // TODO: rg_internal_error? it must notify me in case of problems // TODO: rg_internal_error? it must notify me in case of problems
 
... ... if (gmdate("H") == 4) {
54 55 while (($row = rg_sql_fetch_array($res))) { while (($row = rg_sql_fetch_array($res))) {
55 56 rg_log("Processing repo " . $row['repo_id'] . "..."); rg_log("Processing repo " . $row['repo_id'] . "...");
56 57 $repo_path = rg_repo_path_by_id($row['uid'], $row['repo_id']); $repo_path = rg_repo_path_by_id($row['uid'], $row['repo_id']);
57 $disk_used_mb = rg_repo_disk_mb($repo_path);
58 $sql = "UPDATE repos SET disk_used_mb = $disk_used_mb"
59 . " WHERE repo_id = " . $row['repo_id'];
60 $res2 = rg_sql_query($db, $sql);
61 if ($res2 === FALSE) {
62 rg_log("Cannot run query!");
63 break;
64 }
65 58
66 if (file_exists($repo_path . "/rocketgit/dirty"))
67 @unlink($repo_path . "/rocketgit/dirty");
68 rg_sql_free_result($res2);
59 $all_files = $row['master'] == 0 ? TRUE : FALSE;
60 $disk_used = rg_repo_size($repo_path, $all_files);
61 if ($disk_used === FALSE) {
62 rg_log("Could not open dir!");
63 } else {
64 $disk_used_mb = intval($disk_used / 1024 / 1024);
65 $sql = "UPDATE repos SET disk_used_mb = $disk_used_mb"
66 . " WHERE repo_id = " . $row['repo_id'];
67 $res2 = rg_sql_query($db, $sql);
68 if ($res2 === FALSE) {
69 rg_log("Cannot run query!");
70 break;
71 }
72
73 rg_sql_free_result($res2);
74 }
69 75 } }
70 76 rg_sql_free_result($res); rg_sql_free_result($res);
71 77 } while (0); } while (0);
 
... ... if (gmdate("H") == 4) {
92 98 } while (0); } while (0);
93 99 } }
94 100
95 // TODO
96 //rg_log("Sending notifications...");
97
98 101 if (gmdate("H") == 3) { if (gmdate("H") == 3) {
99 102 rg_log("Clean old forget_pass entries..."); rg_log("Clean old forget_pass entries...");
100 103 $sql = "DELETE FROM forgot_pass WHERE expire < $now"; $sql = "DELETE FROM forgot_pass WHERE expire < $now";
 
... ... if (gmdate("H") == 1) {
116 119 rg_sql_free_result($res); rg_sql_free_result($res);
117 120 } }
118 121
122 rg_log_cron();
119 123
120 124 if (gmdate("H") == 4) if (gmdate("H") == 4)
121 125 rg_sql_struct_slaves_update($db); rg_sql_struct_slaves_update($db);
122 126
123 127
124 rg_keys_regen($db);
125
126 // Arhive deleted repositories
127 if (gmdate("H") == 23) {
128 //TODO: rg_log("Delete repositories...");
129 }
130
131 128 rg_log("Done!"); rg_log("Done!");
132 129 ?> ?>
File scripts/cron.sh changed (mode: 100755) (index d321beb..5f8c29b)
1 1 #!/bin/bash #!/bin/bash
2 2
3 # This is a wrapper just to correctly transition to rocketgit_t domain
3 . /usr/share/rocketgit/scripts/common.sh
4
5 check_context
4 6
5 7 exec php /usr/share/rocketgit/scripts/cron.php exec php /usr/share/rocketgit/scripts/cron.php
File scripts/events.php changed (mode: 100644) (index 550012b..bcd0706)
5 5 // TODO: This will obsolete q.php // TODO: This will obsolete q.php
6 6 error_reporting(E_ALL); error_reporting(E_ALL);
7 7 ini_set("track_errors", "On"); ini_set("track_errors", "On");
8 set_time_limit(0);
8 9
9 10 $now = time(); $now = time();
10 11 $_s = microtime(TRUE); $_s = microtime(TRUE);
 
... ... require_once($INC . "/keys.inc.php");
24 25 require_once($INC . "/user.inc.php"); require_once($INC . "/user.inc.php");
25 26 require_once($INC . "/bug.inc.php"); require_once($INC . "/bug.inc.php");
26 27 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
28 require_once($INC . "/plan.inc.php");
29 require_once($INC . "/ver.php");
27 30
28 31 rg_prof_start("MAIN"); rg_prof_start("MAIN");
29 32
30 33 rg_log_set_file($rg_log_dir . "/events.log"); rg_log_set_file($rg_log_dir . "/events.log");
31 34 rg_log_set_sid("000000"); // to spread the logs rg_log_set_sid("000000"); // to spread the logs
32 35
33 rg_log("Start...");
36 rg_log("Start (ver=$rocketgit_version)...");
34 37
35 38 $db = rg_sql_open($rg_sql); $db = rg_sql_open($rg_sql);
36 39 if ($db === FALSE) { if ($db === FALSE) {
 
... ... if ($r === FALSE) {
76 79 exit(1); exit(1);
77 80 } }
78 81
79 $r = socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 0, "usec" => 0));
82 /* This will force accept "accept" to return too early
83 $r = socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 5, "usec" => 0));
80 84 if ($r === FALSE) { if ($r === FALSE) {
81 85 rg_internal_error("Cannot set SO_RCVTIMEO!"); rg_internal_error("Cannot set SO_RCVTIMEO!");
82 86 exit(1); exit(1);
83 87 } }
88 */
84 89
85 90 $original_mtime = filemtime(__FILE__); $original_mtime = filemtime(__FILE__);
86 91 $notify_list = array(); $notify_list = array();
 
... ... do {
95 100 break; break;
96 101 } }
97 102
98 // check machine load - if too big we will delay
99 $load = rg_load();
100 if ($load > 10) {
101 rg_log("\tLoad too big! Sleeping 10s.");
102 sleep(10);
103 continue;
104 }
103 rg_log_buffer_clear();
105 104
106 105 do { do {
106 // check machine load - if too big we will delay
107 $load = rg_load();
108 if ($load > 10) {
109 rg_log("\tLoad too big! Skip queue processing.");
110 break;
111 }
112
107 113 $r = rg_event_process_queue($db, $notify_list); $r = rg_event_process_queue($db, $notify_list);
108 114 if ($r === FALSE) if ($r === FALSE)
109 115 break; break;
 
... ... do {
113 119
114 120 // Wait for signal // Wait for signal
115 121 rg_log("Waiting for signal..."); rg_log("Waiting for signal...");
122 // TODO: use socket_select because, else, we are blocking!
116 123 $client = socket_accept($socket); $client = socket_accept($socket);
117 124 if ($client === FALSE) { if ($client === FALSE) {
118 125 rg_log("Connection seems broken!"); rg_log("Connection seems broken!");
 
... ... do {
137 144 $close = 0; $close = 0;
138 145
139 146 // It is possible that we already executed the task // It is possible that we already executed the task
140 rg_event_notify($notify_list, $ev_id);
147 rg_event_notify($notify_list, $ev_id, "");
141 148 } }
142 149 } }
143 150
File scripts/events.sh changed (mode: 100755) (index baf408c..33b5174)
2 2
3 3 # This is a wrapper for events.php, to not wait a lot after it exits # This is a wrapper for events.php, to not wait a lot after it exits
4 4
5 . /usr/share/rocketgit/scripts/common.sh
6
7 check_context
8
5 9 exec 100<>/var/lib/rocketgit/locks/events.sh.lock exec 100<>/var/lib/rocketgit/locks/events.sh.lock
6 10
7 11 flock --exclusive --nonblock 100 flock --exclusive --nonblock 100
File scripts/q.php changed (mode: 100644) (index 082cc5b..dfcdbd8)
... ... require_once($INC . "/repo.inc.php");
18 18 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
19 19 require_once($INC . "/mr.inc.php"); require_once($INC . "/mr.inc.php");
20 20 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
21 require_once($INC . "/plan.inc.php");
22 require_once($INC . "/ver.php");
21 23
22 24 rg_prof_start("MAIN"); rg_prof_start("MAIN");
23 25
 
... ... rg_log_set_sid("000000"); // to spread the logs
27 29 // locking // locking
28 30 rg_lock_or_exit("q.lock"); rg_lock_or_exit("q.lock");
29 31
30 rg_log("Start...");
32 rg_log("Start (ver=$rocketgit_version)...");
31 33
32 34 $db = rg_sql_open($rg_sql); $db = rg_sql_open($rg_sql);
33 35 if ($db === FALSE) { if ($db === FALSE) {
 
... ... $original_mtime = filemtime(__FILE__);
50 52 while (TRUE) { while (TRUE) {
51 53 clearstatcache(); clearstatcache();
52 54 $mtime = filemtime(__FILE__); $mtime = filemtime(__FILE__);
53 rg_log("mtime=$mtime, original_mtime=$original_mtime");
55 //rg_log("mtime=$mtime, original_mtime=$original_mtime");
54 56 if ($mtime != $original_mtime) { if ($mtime != $original_mtime) {
55 57 rg_log("File changed. Exiting..."); rg_log("File changed. Exiting...");
56 58 break; break;
File scripts/q.sh changed (mode: 100755) (index 66b2766..34a8317)
2 2
3 3 # This is a wrapper just to correctly transition to rocketgit_t # This is a wrapper just to correctly transition to rocketgit_t
4 4
5 . /usr/share/rocketgit/scripts/common.sh
6
7 check_context
8
5 9 exec 100<>/var/lib/rocketgit/locks/q.sh.lock exec 100<>/var/lib/rocketgit/locks/q.sh.lock
6 10
7 11 flock --exclusive --nonblock 100 flock --exclusive --nonblock 100
File scripts/remote.php changed (mode: 100644) (index 981e57a..8ff6a4d)
... ... require_once($INC . "/prof.inc.php");
16 16 require_once($INC . "/ssh.inc.php"); require_once($INC . "/ssh.inc.php");
17 17 require_once($INC . "/keys.inc.php"); require_once($INC . "/keys.inc.php");
18 18 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
19 require_once($INC . "/plan.inc.php");
20 require_once($INC . "/ver.php");
19 21
20 22 rg_prof_start("remote.php"); rg_prof_start("remote.php");
21 23
 
... ... function fatal($str)
45 47
46 48 umask(0022); umask(0022);
47 49
48 rg_log("Start...");
50 rg_log("Start ($rocketgit_version)...");
49 51 rg_log("_SERVER: " . rg_array2string($_SERVER)); rg_log("_SERVER: " . rg_array2string($_SERVER));
50 52 // DEBUG SELinux // DEBUG SELinux
51 53 $label = @file_get_contents("/proc/self/attr/current"); $label = @file_get_contents("/proc/self/attr/current");
 
... ... if (strcmp($_t[0], "user") == 0) {
159 161 rg_log("host=[$host] cmd=[$cmd] prefix=[$prefix] user=[$user] repo=[$repo]."); rg_log("host=[$host] cmd=[$cmd] prefix=[$prefix] user=[$user] repo=[$repo].");
160 162
161 163 // validity/security checks // validity/security checks
162 // Load info about the user
164 // Load info about the owner
163 165 if (rg_user_ok($user) !== TRUE) if (rg_user_ok($user) !== TRUE)
164 166 fatal("User [$user] is invalid (" . rg_user_error() . ")!"); fatal("User [$user] is invalid (" . rg_user_error() . ")!");
165 167 $owner_ui = rg_user_info($db, 0, $user, ""); $owner_ui = rg_user_info($db, 0, $user, "");
 
... ... if ($owner_ui['ok'] != 1)
168 170 if ($owner_ui['exists'] != 1) if ($owner_ui['exists'] != 1)
169 171 fatal("User does not exists."); fatal("User does not exists.");
170 172
173 // Load info about the connecting user
174 /* Seems is not used now
175 $conn_ui = rg_user_info($db, $conn_uid, "", "");
176 if ($conn_ui['exists'] != 0)
177 fatal("User does not exists.");
178 */
179
171 180 // Loading info about the repository // Loading info about the repository
172 181 if (rg_repo_ok($repo) !== TRUE) if (rg_repo_ok($repo) !== TRUE)
173 182 fatal("Repo is invalid (" . rg_repo_error() . ")"); fatal("Repo is invalid (" . rg_repo_error() . ")");
 
... ... if (rg_rights_allow($rights, $needed_rights) === FALSE)
201 210 // TODO: put process in a cgroup? // TODO: put process in a cgroup?
202 211
203 212
204 if (($push == 1) && rg_repo_over_limit($ri))
205 fatal("Cannot push: repo is over limit"
206 . " (" . $ri['disk_used_mb']. "MiB >= "
207 . $ri['disk_quota_mb'] . "MiB)");
213 if (($push == 1) && rg_user_over_limit($db, $owner_ui, $max))
214 fatal("Cannot push: user is over limit"
215 . " (" . $owner_ui['disk_used_mb']. "MiB >= " . $max . "MiB)");
208 216
209 217 // Put in environment all we need // Put in environment all we need
210 218 putenv("ROCKETGIT_UID=" . $conn_uid); putenv("ROCKETGIT_UID=" . $conn_uid);
File scripts/wake.php changed (mode: 100644) (index 04e15e6..42f815d)
... ... require_once($INC . "/fixes.inc.php");
25 25 rg_log_set_file($rg_log_dir . "/wake.log"); rg_log_set_file($rg_log_dir . "/wake.log");
26 26 rg_log_set_sid("000000"); // to spread the logs rg_log_set_sid("000000"); // to spread the logs
27 27
28 rg_event_signal_daemon("", 0);
28 rg_event_signal_daemon("", NULL);
29 29
30 30 ?> ?>
File selinux/rocketgit.te changed (mode: 100644) (index 52dccae..48bb18d)
1 policy_module(rocketgit,1.0.69)
1 policy_module(rocketgit,1.0.71)
2 2
3 3 ######################################## ########################################
4 4 # #
 
... ... apache_content_template(rocketgit)
20 20 # Allow crons to search in /var/lib - not clear why # Allow crons to search in /var/lib - not clear why
21 21 files_search_var_lib(rocketgit_t) files_search_var_lib(rocketgit_t)
22 22
23 # Allow rocketgit_t to manage .ssh/authorized_keys
24 ssh_manage_home_files(rocketgit_t)
25
23 26 type rocketgit_exec_t; type rocketgit_exec_t;
24 27 domain_entry_file(rocketgit_t, rocketgit_exec_t) domain_entry_file(rocketgit_t, rocketgit_exec_t)
25 28
 
... ... type rocketgit_usr_t;
64 67 files_type(rocketgit_usr_t) files_type(rocketgit_usr_t)
65 68 read_files_pattern(rocketgit_t, rocketgit_usr_t, rocketgit_usr_t) read_files_pattern(rocketgit_t, rocketgit_usr_t, rocketgit_usr_t)
66 69 exec_files_pattern(rocketgit_t, rocketgit_usr_t, rocketgit_usr_t) exec_files_pattern(rocketgit_t, rocketgit_usr_t, rocketgit_usr_t)
70 list_dirs_pattern(rocketgit_t, rocketgit_usr_t, rocketgit_usr_t)
67 71 read_files_pattern(httpd_t, rocketgit_usr_t, rocketgit_usr_t) read_files_pattern(httpd_t, rocketgit_usr_t, rocketgit_usr_t)
68 72
69 73
 
... ... type rocketgit_log_t;
72 76 files_type(rocketgit_log_t) files_type(rocketgit_log_t)
73 77 manage_files_pattern(rocketgit_t, rocketgit_log_t, rocketgit_log_t) manage_files_pattern(rocketgit_t, rocketgit_log_t, rocketgit_log_t)
74 78 logging_log_filetrans(rocketgit_t, rocketgit_log_t, file) logging_log_filetrans(rocketgit_t, rocketgit_log_t, file)
79 # allow rocketgit_t access to /var/log/rocketgit-web. Why?
80 allow rocketgit_t httpd_log_t:dir { read open };
75 81
76 82
77 83 # content (repos) # content (repos)
File tests/.gitignore changed (mode: 100644) (index f229ab9..4ad44a7)
... ... mr_queue
4 4 *.log *.log
5 5 tree1.copy tree1.copy
6 6 repos repos
7 afile.txt
8 err-*
File tests/Makefile changed (mode: 100644) (index 552bef5..9017f43)
1 tests := util db keys user repo rights state git prof bug log \
2 hook_update hook_update_anon bug event
1 tests := util log state cache prof db event rights keys user repo git bug \
2 hook_update hook_update_anon hook_update_anon_nm
3 3 .PHONY: $(tests) .PHONY: $(tests)
4 4
5 5 all: $(tests) all: $(tests)
 
... ... log:
40 40 event: event:
41 41 php event.php php event.php
42 42
43 cache:
44 php cache.php
45
43 46 hook_update: hook_update:
44 47 ./hook_update.sh ./hook_update.sh
45 48
46 49 hook_update_anon: hook_update_anon:
47 50 ./hook_update_anon.sh ./hook_update_anon.sh
48 51
52 hook_update_anon_nm:
53 ./hook_update_anon_nm.sh
54
49 55 .PHONY: clean .PHONY: clean
50 56 clean: clean:
51 57 @rm -f *.log *.strace *.out @rm -f *.log *.strace *.out
File tests/bug.php changed (mode: 100644) (index b59d51a..394babe)
... ... require_once($INC . "/bug.inc.php");
8 8 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
9 9 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
10 10 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
11 require_once("common.php");
11 12
12 13 rg_log_set_file("bug.log"); rg_log_set_file("bug.log");
13 14
14 $rg_sql_debug = 1;
15
16 // Defaults
17 $rg_admin_email = "rg@embedromix.ro";
18
19 15 $db = rg_sql_open("dbname=trg"); $db = rg_sql_open("dbname=trg");
20 16 if ($db === FALSE) { if ($db === FALSE) {
21 17 rg_log("Cannot create a database (" . rg_sql_error() . ")!"); rg_log("Cannot create a database (" . rg_sql_error() . ")!");
 
... ... if ($r !== TRUE) {
47 43 } }
48 44
49 45 // defaults // defaults
50 $repo_id = 100;
51 46 $uid = 1; $uid = 1;
47 $ui = array("uid" => $uid, "username" => "userX", "organization" => 0, "email" => "test@embedromix.ro");
48 $repo_name = "A";
49
50 rg_log("Creating a repo");
51 $repo_id = rg_repo_create($db, 0, $ui, $repo_name, 0, "desc", "F", 0);
52 if ($repo_id === FALSE) {
53 rg_log("Cannot insert a repo (" . rg_repo_error() . ")!");
54 exit(1);
55 }
52 56
53 57 $data = array("bug_id" => 0, $data = array("bug_id" => 0,
54 58 "title" => "Bug title", "title" => "Bug title",
 
... ... $data = array("bug_id" => 0,
56 60 "labels" => "label1,label2,label3", "labels" => "label1,label2,label3",
57 61 "state" => 1, "state" => 1,
58 62 "assigned_uid" => 6); "assigned_uid" => 6);
59 $ri = array("repo_id" => $repo_id);
60 $ui = array("uid" => $uid);
63 $ri = array("repo_id" => $repo_id, "name" => "repoX");
61 64 $r = rg_bug_edit($db, $ri, $ui, $data); $r = rg_bug_edit($db, $ri, $ui, $data);
62 65 if ($r === FALSE) { if ($r === FALSE) {
63 66 rg_log("Cannot insert a bug (" . rg_bug_error() . ")!"); rg_log("Cannot insert a bug (" . rg_bug_error() . ")!");
 
... ... if ($r === FALSE) {
65 68 } }
66 69 $bug_id = $r; $bug_id = $r;
67 70
68 $uid = 10;
71 // add user
72 $_u['uid'] = 0;
73 $_u['realname'] = "userA real name";
74 $_u['username'] = "userA";
75 $_u['email'] = "rg@localhost";
76 $_u['pass'] = "pass1";
77 $_u['pass2'] = "pass1";
78 $_u['is_admin'] = 1;
79 $_u['rights'] = "C";
80 $_u['session_time'] = 3600;
81 $_u['confirm_token'] = "";
82 $_u['plan_id'] = 1000;
83 $uid = rg_user_edit($db, $_u);
84 if ($uid === FALSE) {
85 echo "Cannot add user (" . rg_user_error() . ")!\n";
86 exit(1);
87 }
88
69 89 $data = array("note" => "This is just a note."); $data = array("note" => "This is just a note.");
70 90 $r = rg_bug_note_add($db, $repo_id, $bug_id, $uid, $data); $r = rg_bug_note_add($db, $repo_id, $bug_id, $uid, $data);
71 91 if ($r === FALSE) { if ($r === FALSE) {
File tests/cache.php changed (mode: 100644) (index 5f1047c..437109b)
... ... $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
8 8 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
9 require_once($INC . "/cache.inc.php");
10 require_once("common.php");
9 11
10 rg_log_set_file("log.log");
12 rg_log_set_file("cache.log");
11 13
12 // Defaults
13 $rg_scripts = ".";
14 $rg_theme = "util";
15 $rg_admin_email = "rg@embedromix.ro";
14 rg_cache_server_set("a::b::c", "1");
16 15
17 $n = "șacal\n\t";
18 rg_log($n);
16 $e = "1";
17 $r = rg_cache_server_get("a::b::c");
18 if ($r !== $e) {
19 print_r($rg_cache);
20 echo "[$r] != [$e]!\n";
21 exit(1);
22 }
19 23
20 rg_log_ml("Multiline test\nline2\nline3");
24 $e = FALSE;
25 $r = rg_cache_server_get("x::y::z");
26 if ($r !== $e) {
27 print_r($rg_cache);
28 echo "r must be FALSE!\n";
29 exit(1);
30 }
31
32 rg_cache_server_unset("x::y::z");
33 $e = FALSE;
34 $r = rg_cache_server_get("x::y::z");
35 if ($r !== $e) {
36 print_r($rg_cache);
37 echo "r must be FALSE ($r)!\n";
38 exit(1);
39 }
40
41 ////////////////////////////////// Arrays
42
43 rg_cache_server_apush("v", "1");
44 rg_cache_server_apush("v", "2");
45 rg_cache_server_apush("v", "aa");
46 $e = "1,2,aa";
47 $r = rg_cache_server_adump("v");
48 if ($r !== $e) {
49 print_r($rg_cache);
50 echo "[$r] != [$e]!\n";
51 exit(1);
52 }
53
54 $e = "aa";
55 $r = rg_cache_server_apop("v");
56 if ($r !== $e) {
57 print_r($rg_cache);
58 echo "[$r] != [$e]!\n";
59 exit(1);
60 }
61
62 $e = "1";
63 $r = rg_cache_server_ashift("v");
64 if ($r !== $e) {
65 print_r($rg_cache);
66 echo "[$r] != [$e]!\n";
67 exit(1);
68 }
69
70 $e = FALSE;
71 $r = rg_cache_server_ashift("v");
72 $r = rg_cache_server_ashift("v");
73 if ($r !== $e) {
74 print_r($rg_cache);
75 echo "r is not FALSE ($r)!\n";
76 exit(1);
77 }
21 78
22 79 ?> ?>
File tests/common.php added (mode: 100644) (index 0000000..b223af9)
1 <?php
2
3 // Defaults
4 $rg_base = dirname(__FILE__);
5 $rg_sql_debug = 1;
6 $rg_session_time = 3600;
7 $rg_keys_file = "afile.txt";
8 $rg_scripts = dirname(dirname(__FILE__));
9 $rg_repo_allow = '/^[\pL\pN\pP]*$/uU';
10 $rg_repo_min_len = 1;
11 $rg_repo_max_len = 100;
12 $rg_user_allow = '/^[\pL\pN\pP]*$/uU';
13 $rg_user_min_len = 1;
14 $rg_user_max_len = 20;
15 $rg_ssh_paras = "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty";
16 $rg_admin_name = "RocketGit Admin (test)";
17 $rg_admin_email = "admin@site.tld";
18 $rg_account_allow_creation = 1;
19 $rg_account_email_confirm = 0;
20 $rg_max_ssh_keys = 10;
21 $rg_log_dir = dirname(__FILE__);
22 $rg_web_log_dir = dirname(__FILE__);
23 $rg_state_dir = dirname(__FILE__);
24 $rg_lock_dir = dirname(__FILE__);
25 $rg_repos = "base";
26 $rg_theme_dir = "themes";
27 $rg_theme = "util";
28 $rg_lang = "en";
29 $rg_cache_enable = FALSE;
30 $rg_event_socket = "";
31
32 ?>
File tests/email.php changed (mode: 100644) (index e29020b..73c9764)
... ... ini_set("track_errors", "On");
5 5 $INC = "../inc"; $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
8 require_once("common.php");
8 9
9 10 $rg_scripts = "../"; $rg_scripts = "../";
10 11 $rg_theme = "default"; $rg_theme = "default";
11 12
12 13 rg_log_set_file("email.log"); rg_log_set_file("email.log");
13 14
14 // Defaults
15 $rg_admin_email = "admin@embedromix.ro";
16 $rg_admin_name = "Cătă";
17
18 15 $more = array( $more = array(
19 16 "to" => "xxx@embedromix.ro" "to" => "xxx@embedromix.ro"
20 17 ); );
File tests/event.php changed (mode: 100644) (index 40813d0..5d12c2a)
... ... require_once($INC . "/events.inc.php");
11 11 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
12 12 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
13 13 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
14 require_once("common.php");
14 15
15 16 rg_log_set_file("event.log"); rg_log_set_file("event.log");
16 17
17 18 $rg_sql_debug = 1; $rg_sql_debug = 1;
18 19
19 // Defaults
20 $rg_admin_email = "rg@embedromix.ro";
21
22 20 $db = rg_sql_open("dbname=trg"); $db = rg_sql_open("dbname=trg");
23 21 if ($db === FALSE) { if ($db === FALSE) {
24 22 rg_log("Cannot create a database (" . rg_sql_error() . ")!"); rg_log("Cannot create a database (" . rg_sql_error() . ")!");
File tests/git.php changed (mode: 100644) (index 36b9aba..6785ae9)
... ... ini_set("track_errors", "On");
5 5 $INC = "../inc"; $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/git.inc.php"); require_once($INC . "/git.inc.php");
8 require_once("common.php");
8 9
9 10 rg_log_set_file("git.log"); rg_log_set_file("git.log");
10 11
11 // Defaults
12 $rg_scripts = "/usr/share/rocketgit";
13 $rg_admin_email = "rg@embedromix.ro";
14
15 12 echo "[*] Checking if git-init works...\n"; echo "[*] Checking if git-init works...\n";
16 13 $r = rg_git_init("git.tmp"); $r = rg_git_init("git.tmp");
17 14 if ($r !== TRUE) { if ($r !== TRUE) {
File tests/git2.php changed (mode: 100644) (index 10b12e6..f76e72e)
... ... ini_set("track_errors", "On");
5 5 $INC = "../inc"; $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/git.inc.php"); require_once($INC . "/git.inc.php");
8 require_once("common.php");
8 9
9 10 rg_log_set_file("git2.log"); rg_log_set_file("git2.log");
10 11
11 // Defaults
12 $rg_scripts = "/usr/share/rocketgit";
13 $rg_admin_email = "rg@embedromix.ro";
14
15 12 system("./git2.sh"); system("./git2.sh");
16 13
17 14 // test rg_git_refs // test rg_git_refs
File tests/hook_update.sh changed (mode: 100755) (index 52b30ce..f9d0eaa)
1 1 #!/bin/bash #!/bin/bash
2 2
3 export ROCKETGIT_CONF_FILE="`pwd`/common.php"
4
3 5 rm -rf hook_update_*.git rm -rf hook_update_*.git
4 6 mkdir hook_update_dest.git mkdir hook_update_dest.git
5 7 ( (
 
... ... if [ "${?}" != "0" ]; then
162 164 exit 1 exit 1
163 165 fi fi
164 166
165 echo "=== Testing annotated tag change without rights..."
166 echo "aaa" >> a; git commit -a -m "xx"
167 git tag -d tag2
168 git tag -a tag2 -m "xxx2"
169 git push origin --tags
170 if [ "${?}" != "1" ]; then
171 echo "Should not work!"
172 exit 1
173 fi
174 echo "=== Testing annotated tag change with rights..."
175 export ROCKETGIT_REPO_RIGHTS="${ROCKETGIT_REPO_RIGHTS}N"
176 git push origin --tags
177 if [ "${?}" != "0" ]; then
178 echo "Should work!"
179 exit 1
180 fi
181
182 167 echo "=== Testing annotated tag delete without rights (${ROCKETGIT_REPO_RIGHTS})..." echo "=== Testing annotated tag delete without rights (${ROCKETGIT_REPO_RIGHTS})..."
183 168 git tag -d tag2 git tag -d tag2
184 169 git push origin :refs/tags/tag2 git push origin :refs/tags/tag2
File tests/hook_update_anon.sh changed (mode: 100755) (index 6699ffe..9b3885e)
2 2
3 3 # Test anonymous push # Test anonymous push
4 4
5 export ROCKETGIT_CONF_FILE="`pwd`/common.php"
6
5 7 C=`pwd` C=`pwd`
6 8
7 9 rm -rf hook_update_anon_*.git rm -rf hook_update_anon_*.git
File tests/hook_update_anon_nm.sh changed (mode: 100755) (index bc64810..8949310)
3 3 # Test anonymous push with a custom branch # Test anonymous push with a custom branch
4 4 # nm = non-master # nm = non-master
5 5
6 export ROCKETGIT_CONF_FILE="`pwd`/common.php"
7
6 8 C=`pwd` C=`pwd`
7 9 P="hook_update_anon_nm" P="hook_update_anon_nm"
8 10
File tests/keys.php changed (mode: 100644) (index 6737510..10c3ffa)
... ... require_once($INC . "/keys.inc.php");
9 9 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
10 10 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
11 11 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
12 require_once("common.php");
12 13
13 14 rg_log_set_file("keys.log"); rg_log_set_file("keys.log");
14 15
 
... ... if ($key_id2 === FALSE) {
74 75
75 76 // test key file generation // test key file generation
76 77 $rg_scripts = "/a"; $rg_scripts = "/a";
77 $rg_keys_file = "afile.txt";
78 78 $rg_ssh_paras = "ssh1,ssh2,ssh3"; $rg_ssh_paras = "ssh1,ssh2,ssh3";
79 79 $r = rg_keys_regen($db); $r = rg_keys_regen($db);
80 80 if ($r === FALSE) { if ($r === FALSE) {
 
... ... if ($c === FALSE) {
86 86 echo "Cannot regenerate file (afile.txt not found)!\n"; echo "Cannot regenerate file (afile.txt not found)!\n";
87 87 exit(1); exit(1);
88 88 } }
89 $e = "command=\"/usr/bin/php "
90 . $rg_scripts . "/scripts/remote.php 1 $key_id1\","
89 $e = "command=\""
90 . $rg_scripts . "/scripts/remote.sh 1 $key_id1\","
91 91 . $rg_ssh_paras . " aaa 'bbb' first_key\n" . $rg_ssh_paras . " aaa 'bbb' first_key\n"
92 . "command=\"/usr/bin/php "
93 . $rg_scripts . "/scripts/remote.php 2 $key_id2\","
92 . "command=\""
93 . $rg_scripts . "/scripts/remote.sh 2 $key_id2\","
94 94 . $rg_ssh_paras . " aaa 'bbb' second_key\n"; . $rg_ssh_paras . " aaa 'bbb' second_key\n";
95 95 if (strcmp($c, $e) != 0) { if (strcmp($c, $e) != 0) {
96 96 echo "Generated file does not seems OK!\n"; echo "Generated file does not seems OK!\n";
 
... ... if (strcmp($c, $e) != 0) {
104 104
105 105 // delete a key // delete a key
106 106 $rg_ui['uid'] = 1; $rg_ui['uid'] = 1;
107 $flags = array();
108 $r = rg_keys_remove($db, $rg_ui, $key_id1, $flags);
107 $list = array($key_id1 => "junk");
108 $r = rg_keys_remove($db, $rg_ui, $list);
109 109 if ($r === FALSE) { if ($r === FALSE) {
110 110 echo "Cannot remove key (" . rg_keys_error() . ")!\n"; echo "Cannot remove key (" . rg_keys_error() . ")!\n";
111 111 exit(1); exit(1);
File tests/log.php changed (mode: 100644) (index 5f1047c..bf2d431)
... ... $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
8 8 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
9 require_once("common.php");
9 10
10 11 rg_log_set_file("log.log"); rg_log_set_file("log.log");
11 12
12 // Defaults
13 $rg_scripts = ".";
14 $rg_theme = "util";
15 $rg_admin_email = "rg@embedromix.ro";
16
17 13 $n = "șacal\n\t"; $n = "șacal\n\t";
18 14 rg_log($n); rg_log($n);
19 15
File tests/prof.php changed (mode: 100644) (index 0843f82..9ffd729)
... ... require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
8 8 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
9 9 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
10 require_once("common.php");
10 11
11 12 rg_log_set_file("prof.log"); rg_log_set_file("prof.log");
12 13
13 // Defaults
14 $rg_admin_email = "rg@embedromix.ro";
15
16 14 rg_prof_start("label1"); rg_prof_start("label1");
17 15 sleep(.1); sleep(.1);
18 16 rg_prof_set(array("xxx" => 1)); rg_prof_set(array("xxx" => 1));
File tests/repo.php changed (mode: 100644) (index 0620aae..76813c1)
2 2 error_reporting(E_ALL | E_STRICT); error_reporting(E_ALL | E_STRICT);
3 3 ini_set("track_errors", "On"); ini_set("track_errors", "On");
4 4
5 $rg_cache_socket = "rg_cache_socket";
6
5 7 $INC = "../inc"; $INC = "../inc";
6 8 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 9 require_once($INC . "/repo.inc.php"); require_once($INC . "/repo.inc.php");
8 10 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
9 11 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
10 12 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
11
12 rg_log_set_file("repo.log");
13 require_once("common.php");
13 14
14 15 $rg_sql_debug = 1; $rg_sql_debug = 1;
15 16
16 // defaults
17 $rg_admin_email = "rg@embedromix.ro";
18 $rg_scripts = dirname(dirname(__FILE__));
19 $rg_repo_max_len = 100;
20 $rg_repos = "base";
21
17 rg_log_set_file("repo.log");
22 18
23 19 rg_log("rg_repo_path 1"); rg_log("rg_repo_path 1");
24 20 $e = $rg_repos . "/by_id/11/22/33/44/11223344/repos/by_id/55.git"; $e = $rg_repos . "/by_id/11/22/33/44/11223344/repos/by_id/55.git";
 
... ... $e = array();
156 152 $e = rg_array_merge($e, "ri", $ri); $e = rg_array_merge($e, "ri", $ri);
157 153 $e['ui.uid'] = $rg_ui['uid']; $e['ui.uid'] = $rg_ui['uid'];
158 154 $r = rg_repo_event_storage_create($db, $e); $r = rg_repo_event_storage_create($db, $e);
159 if ($r !== TRUE) {
155 if ($r === FALSE) {
160 156 echo "Cannot create storage dir (" . rg_repo_error() . ")!\n"; echo "Cannot create storage dir (" . rg_repo_error() . ")!\n";
161 157 exit(1); exit(1);
162 158 } }
163 159
164 160 rg_log("test giving rights"); rg_log("test giving rights");
165 161 $tuid = 10; $tuid = 10;
166 $v = rg_repo_rights_set($db, $ri, $tuid, "P");
162 $v = rg_repo_rights_set($db, $ri, $tuid, "P", array());
167 163 if ($v === FALSE) { if ($v === FALSE) {
168 164 rg_log("Cannot give rights (1)!"); rg_log("Cannot give rights (1)!");
169 165 exit(1); exit(1);
 
... ... if (strcmp($c, $e) != 0) {
180 176
181 177 rg_log("non-owner gets correct rights: F gets from default rights."); rg_log("non-owner gets correct rights: F gets from default rights.");
182 178 $xuid = 12; $xuid = 12;
183 $r = rg_repo_rights_set($db, $ri, $xuid, "P");
179 $r = rg_repo_rights_set($db, $ri, $xuid, "P", array());
184 180 if ($r !== TRUE) { if ($r !== TRUE) {
185 181 rg_log("Cannot set rights (" . rg_repo_error() . ")!"); rg_log("Cannot set rights (" . rg_repo_error() . ")!");
186 182 exit(1); exit(1);
 
... ... if (strcmp($c, $e) != 0) {
194 190 } }
195 191
196 192 rg_log("owner can set separate rights for him"); rg_log("owner can set separate rights for him");
197 $v = rg_repo_rights_set($db, $ri, $uid, "A");
193 $v = rg_repo_rights_set($db, $ri, $uid, "A", array());
198 194 if ($v === FALSE) { if ($v === FALSE) {
199 195 rg_log("Owner cannot set separate rights for him!"); rg_log("Owner cannot set separate rights for him!");
200 196 exit(1); exit(1);
 
... ... if ($r === FALSE) {
208 204 } }
209 205 // TODO: we should test if expected fields are returned! // TODO: we should test if expected fields are returned!
210 206
211 rg_log("disk1");
212 $ri['disk_quota_mb'] = 10;
213 $ri['disk_used_mb'] = 20;
214 $r = rg_repo_over_limit($ri);
215 if ($r !== TRUE) {
216 rg_log("Over limit is wrong (1)!");
217 exit(1);
218 }
219
220 rg_log("disk2");
221 $ri['disk_quota_mb'] = 20;
222 $ri['disk_used_mb'] = 10;
223 $r = rg_repo_over_limit($ri);
224 if ($r !== FALSE) {
225 rg_log("Over limit is wrong (2)!");
226 exit(1);
227 }
228
229 207
230 208 // test stats // test stats
231 209 $rg_state_dir = "repos"; $rg_state_dir = "repos";
 
... ... if ($r === FALSE) {
283 261 exit(1); exit(1);
284 262 } }
285 263
264 // disk size
265 $size = rg_repo_size("size", TRUE);
266 $e = 13;
267 if ($size != $e) {
268 echo "Dir 'size' has an unexpected size ($e != $r)!\n";
269 exit(1);
270 }
271
286 272 rg_sql_close($db); rg_sql_close($db);
287 273
288 274 echo "repo: OK!\n"; echo "repo: OK!\n";
File tests/rights.php changed (mode: 100644) (index bb48d34..cf8f65e)
... ... ini_set("track_errors", "On");
5 5 $INC = "../inc"; $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/rights.inc.php"); require_once($INC . "/rights.inc.php");
8 require_once("common.php");
8 9
9 10 rg_log_set_file("rights.log"); rg_log_set_file("rights.log");
10 11
File tests/size/dir/b added (mode: 100644) (index 0000000..73c4297)
1 dsfdfvdffd
File tests/sql.php changed (mode: 100644) (index b393c12..0d127ba)
... ... $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
8 8 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
9 require_once("common.php");
9 10
10 11 rg_log_set_file("sql.log"); rg_log_set_file("sql.log");
11 12
12 // Defaults
13 $rg_admin_email = "rg@embedromix.ro";
14
15 13 echo "db: open connection...\n"; echo "db: open connection...\n";
16 14 $db = rg_sql_open("dbname=trg"); $db = rg_sql_open("dbname=trg");
17 15 if ($db === FALSE) { if ($db === FALSE) {
File tests/state.php changed (mode: 100644) (index a27948e..d11e1a2)
... ... require_once($INC . "/log.inc.php");
8 8 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
9 9 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
10 10 require_once($INC . "/state.inc.php"); require_once($INC . "/state.inc.php");
11 require_once("common.php");
11 12
12 13 rg_log_set_file("state.log"); rg_log_set_file("state.log");
13 14
14 // Defaults
15 $rg_admin_email = "rg@embedromix.ro";
16 15 $rg_sql_debug = 1; $rg_sql_debug = 1;
17 $rg_lock_dir = ".";
18 16
19 17 $db = rg_sql_open("dbname=trg"); $db = rg_sql_open("dbname=trg");
20 18 if ($db === FALSE) { if ($db === FALSE) {
File tests/themes/util/t1/nodata.html renamed from tests/root/themes/util/t1/nodata.html (similarity 100%)
File tests/themes/util/t2/footer.html renamed from tests/root/themes/util/t2/footer.html (similarity 100%)
File tests/themes/util/t2/header.html renamed from tests/root/themes/util/t2/header.html (similarity 100%)
File tests/themes/util/t2/line.html renamed from tests/root/themes/util/t2/line.html (similarity 100%)
File tests/themes/util/t3/c1 renamed from tests/root/themes/util/t3/c1 (similarity 100%)
File tests/themes/util/t3/c2 renamed from tests/root/themes/util/t3/c2 (similarity 100%)
File tests/themes/util/t3/c3 renamed from tests/root/themes/util/t3/c3 (similarity 100%)
File tests/themes/util/t3/c4 renamed from tests/root/themes/util/t3/c4 (similarity 100%)
File tests/themes/util/t3/c5 renamed from tests/root/themes/util/t3/c5 (similarity 100%)
File tests/themes/util/t3/c6 renamed from tests/root/themes/util/t3/c6 (similarity 100%)
File tests/themes/util/t3/c7 renamed from tests/root/themes/util/t3/c7 (similarity 100%)
File tests/themes/util/t3/c8 renamed from tests/root/themes/util/t3/c8 (similarity 100%)
File tests/user.php changed (mode: 100644) (index 106b95f..bc030ce)
... ... require_once($INC . "/user.inc.php");
8 8 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
9 9 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
10 10 require_once($INC . "/fixes.inc.php"); require_once($INC . "/fixes.inc.php");
11 require_once("common.php");
11 12
12 13 $rg_sql_debug = 1; $rg_sql_debug = 1;
13 14
 
... ... $_u['realname'] = "userA real name";
65 66 $_u['username'] = "userA"; $_u['username'] = "userA";
66 67 $_u['email'] = "rg@localhost"; $_u['email'] = "rg@localhost";
67 68 $_u['pass'] = "pass1"; $_u['pass'] = "pass1";
69 $_u['pass2'] = "pass1";
68 70 $_u['is_admin'] = 1; $_u['is_admin'] = 1;
69 $_u['disk_quota_mb'] = 100;
70 71 $_u['rights'] = "C"; $_u['rights'] = "C";
71 72 $_u['session_time'] = 3600; $_u['session_time'] = 3600;
72 73 $_u['confirm_token'] = ""; $_u['confirm_token'] = "";
74 $_u['plan_id'] = 1000;
73 75 $uid = rg_user_edit($db, $_u); $uid = rg_user_edit($db, $_u);
74 76 if ($uid === FALSE) { if ($uid === FALSE) {
75 77 echo "Cannot add user (" . rg_user_error() . ")!\n"; echo "Cannot add user (" . rg_user_error() . ")!\n";
 
... ... if ($uid === FALSE) {
77 79 } }
78 80
79 81 // Simulate event: link_by_name // Simulate event: link_by_name
80 $ev = array("uid" => $uid, "username" => $_u['username']);
82 $ev = array("ui.uid" => $uid, "ui.username" => $_u['username']);
81 83 $r = rg_user_link_by_name($db, $ev); $r = rg_user_link_by_name($db, $ev);
82 84 if ($r === FALSE) { if ($r === FALSE) {
83 85 echo "Cannot link by name (" . rg_user_error() . ")!\n"; echo "Cannot link by name (" . rg_user_error() . ")!\n";
 
... ... if ($_ui['exists'] != 1) {
113 115 exit(1); exit(1);
114 116 } }
115 117 if (strcmp($pass, $_ui['pass']) != 0) { if (strcmp($pass, $_ui['pass']) != 0) {
116 echo "Password was changed!\n";
118 echo "Password was changed! Bad!\n";
117 119 exit(1); exit(1);
118 120 } }
119 121
120 122 // edit user - no empty pass // edit user - no empty pass
121 123 $_u['pass'] = "pass2"; $_u['pass'] = "pass2";
124 $_u['pass2'] = "pass2";
122 125 $r = rg_user_edit($db, $_u); $r = rg_user_edit($db, $_u);
123 126 if ($r === FALSE) { if ($r === FALSE) {
124 127 echo "Cannot edit user with not empty pass (" . rg_user_error() . ")!\n"; echo "Cannot edit user with not empty pass (" . rg_user_error() . ")!\n";
 
... ... $_u['realname'] = "user5 real name";
189 192 $_u['username'] = "user5"; $_u['username'] = "user5";
190 193 $_u['email'] = "rg@localhost"; $_u['email'] = "rg@localhost";
191 194 $_u['pass'] = "pass1"; $_u['pass'] = "pass1";
195 $_u['pass2'] = "pass1";
192 196 $_u['is_admin'] = 1; $_u['is_admin'] = 1;
193 $_u['disk_quota_mb'] = 100;
194 197 $_u['rights'] = "C"; $_u['rights'] = "C";
195 198 $_u['session_time'] = 3600; $_u['session_time'] = 3600;
196 199 $_u['confirm_token'] = ""; $_u['confirm_token'] = "";
200 $_u['plan_id'] = 1000;
197 201 $uid5 = rg_user_edit($db, $_u); $uid5 = rg_user_edit($db, $_u);
198 202 if ($uid5 === FALSE) { if ($uid5 === FALSE) {
199 203 echo "Cannot add user5 (" . rg_user_error() . ")!\n"; echo "Cannot add user5 (" . rg_user_error() . ")!\n";
File tests/util.php changed (mode: 100644) (index 81979dd..4a24f5a)
... ... $INC = "../inc";
6 6 require_once($INC . "/init.inc.php"); require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
8 8 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
9 require_once("common.php");
9 10
10 11 rg_log_set_file("util.log"); rg_log_set_file("util.log");
11 12
12 // Defaults
13 $rg_scripts = ".";
14 $rg_theme = "util";
15 $rg_admin_email = "rg@embedromix.ro";
16
17 13 $id = rg_id(16); $id = rg_id(16);
18 14 if (strlen($id) != 16) { if (strlen($id) != 16) {
19 15 echo "Cannot generate an id!\n"; echo "Cannot generate an id!\n";
 
... ... if (!file_exists("tree1.copy/a/f2")) {
243 239 exit(1); exit(1);
244 240 } }
245 241
242 $x = rg_dir_load("/non_existing_dir");
243 if ($x !== FALSE) {
244 echo "rg_dir_load(non_existing) is not working right!\n";
245 exit(1);
246 }
247
248 $x = rg_dir_load_pattern("util/dir_pattern", "err-.*");
249 $x2 = implode("", $x);
250 $e = "err-asasasas";
251 if (strcmp($x2, $e) != 0) {
252 echo "rg_dir_load_pattern() is not working right ($r != $e)!\n";
253 exit(1);
254 }
255
256 $src = array();
257 $a = array("u" => "uval", "HTML:A" => "Aval");
258 $x = rg_array_merge($src, "X", $a);
259 if (strcmp($x['HTML:X.A'], "Aval") != 0) {
260 echo "array_merge is not working correctly (1)!\n";
261 print_r($x);
262 exit(1);
263 }
264 if (strcmp($x['X.u'], "uval") != 0) {
265 echo "array_merge is not working correctly (2)!\n";
266 print_r($x);
267 exit(1);
268 }
269
270
271
246 272 echo "util: OK!\n"; echo "util: OK!\n";
247 273 ?> ?>
File tests/util/dir_pattern/err-asasasas copied from file inc/admin/plans/plans.php (similarity 100%)
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://rocketgit.com/user/catalinux/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/rocketgit

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/rocketgit

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