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

Fixes infrastructure; bug fixing
Author: Catalin(ux) M. BOIE
Author date (UTC): 2012-12-01 21:01
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2012-12-01 21:01
Parent(s): 561943c9bfd37fcf2b3c53724af2c8145d76d664
Signing key:
Tree: 487ae179006a1da48b04f62e24636849edfcccc3
File Lines added Lines deleted
TODO 19 2
admin/init.php 7 0
inc/events.inc.php 1 1
inc/fixes.inc.php 301 0
inc/git.inc.php 202 171
inc/keys.inc.php 4 0
inc/mr.inc.php 0 4
inc/repo.inc.php 376 103
inc/struct.inc.php 37 7
inc/user.inc.php 354 97
inc/user/create.php 1 1
inc/user/repo-page.php 4 4
inc/user/repo/admin/edit/edit.php 1 1
inc/util.inc.php 33 9
root/index.php 7 3
root/themes/default/mail/user/repo/new.body.txt 1 1
scripts/cron.php 36 31
scripts/events.php 5 0
scripts/q.php 9 46
scripts/remote.php 28 17
tests/.gitignore 6 0
tests/Makefile 1 1
tests/bug.php 19 0
tests/event.php 23 14
tests/git.php 2 0
tests/hook_update_anon.sh 2 0
tests/hook_update_anon_nm.sh 2 0
tests/keys.php 26 7
tests/repo.php 89 24
tests/user.php 79 14
File TODO changed (mode: 100644) (index 246d7d6..5c44107)
1 1 == BEFORE FIRST RELEASE! == == BEFORE FIRST RELEASE! ==
2 [ ] http://joeyh.name/blog/entry/git_push_over_XMPP/ (ialbescu)
2 [ ] repo.php tests does not say "ok".
3 [ ] Functions from util.inc.php set rg_util_error(). Use it.
4 [ ] Rempove all "exit(?)" calls.
5 [ ] Locking is done in global dirs for tests. Use a local folder!
6 [ ] We must provide a way to propagate errors from events!
7 [ ] repo.inc should not depend on user.inc!
8 [ ] rg_repo_info will have almost the same paras as rg_user_info!
9 [ ] Check if there are unused paramters after name2base(_path).
10 [ ] Remove any trace of $rr.
11 [ ] After the switch from username to uid, should we pass uid into forms?
12 [ ] How to deal with browser accessing an old name (after rename)?
13 [ ] $rr is a mess! Switch to repo_id and use cache.
14 [ ] repo_invalidate_cache does an implode that can reorder. Use repo_id as key?
15 No. But use some combinations of paras.
16 [ ] Why we use "FOR UPDATE" on 'events' table?! events.php is the only user.
17 [ ] We need to parallelize the event processing.
3 18 [ ] Checking mtime of event.php is not enough. Maybe checking version. [ ] Checking mtime of event.php is not enough. Maybe checking version.
4 19 Think of includes that may change. Think of includes that may change.
5 20 [ ] Create a unique index on users(username,organization)? [ ] Create a unique index on users(username,organization)?
 
10 25 [ ] Optimize keyring invalidation. [ ] Optimize keyring invalidation.
11 26 [ ] Put "create user" on login page! [ ] Put "create user" on login page!
12 27 [ ] We should make stuff more robust. For example: CREATE REPO + HISTORY_INSERT. [ ] We should make stuff more robust. For example: CREATE REPO + HISTORY_INSERT.
13 [ ] What happens if we unlock an unlocked resource.
28 [ ] What happens if we unlock an unlocked resource?
14 29 [ ] Renaming a repo! [ ] Renaming a repo!
15 30 If we move to numbers, and the names are links, we may have problems If we move to numbers, and the names are links, we may have problems
16 31 when we create a repo with the same name. when we create a repo with the same name.
 
58 73
59 74
60 75 == Medium == == Medium ==
76 [ ] http://joeyh.name/blog/entry/git_push_over_XMPP/ (ialbescu)
77 [ ] Graphics with database/table/index sizes.
61 78 [ ] Add history also for user. [ ] Add history also for user.
62 79 [ ] 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/
63 80 [ ] Put in history how many visitors received. [ ] Put in history how many visitors received.
File admin/init.php changed (mode: 100644) (index c9a0e0f..45832cb)
... ... require_once($INC . "/sql.inc.php");
13 13 require_once($INC . "/struct.inc.php"); require_once($INC . "/struct.inc.php");
14 14 require_once($INC . "/state.inc.php"); require_once($INC . "/state.inc.php");
15 15 require_once($INC . "/rights.inc.php"); require_once($INC . "/rights.inc.php");
16 require_once($INC . "/fixes.inc.php");
16 17
17 18 rg_log_set_file("init.log"); rg_log_set_file("init.log");
18 19
 
... ... if ($r !== TRUE) {
28 29 exit(1); exit(1);
29 30 } }
30 31
32 $r = rg_fixes_update($db);
33 if ($r !== TRUE) {
34 echo "Cannot apply fixes. Check the logs!\n";
35 exit(1);
36 }
37
31 38 // creating admin user // creating admin user
32 39 $_u = array(); $_u = array();
33 40 $_u['uid'] = 0; $_u['uid'] = 0;
File inc/events.inc.php changed (mode: 100644) (index bc8f557..f329079)
... ... function rg_event_add($db, $event)
99 99 . " VALUES ($now, $prio, '$e_data')"; . " VALUES ($now, $prio, '$e_data')";
100 100 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
101 101 if ($res === FALSE) { if ($res === FALSE) {
102 rg_event_set_error("Coulnd not add event (" . rg_sql_error() . ")");
102 rg_event_set_error("Could not add event (" . rg_sql_error() . ")");
103 103 break; break;
104 104 } }
105 105 rg_sql_free_result($res); rg_sql_free_result($res);
File inc/fixes.inc.php added (mode: 100644) (index 0000000..773bb03)
1 <?php
2 //
3 // This is a set of fixes that must be applied when the software is upgraded.
4 //
5 include_once($INC . "/sql.inc.php");
6 include_once($INC . "/state.inc.php");
7 include_once($INC . "/util.inc.php");
8
9 $rg_fixes = array();
10 $rg_fixes[1] = array("rg_fixes_repo_index_by_id");
11 $rg_fixes[1] = array("rg_fixes_user_index_by_id");
12
13 // This must be the last line
14 $rg_fixes_ver = count($rg_fixes);
15
16 /*
17 * Fix one repo
18 */
19 function rg_fixes_repo_index_by_id_one($uid, $repo_id, $repo_name)
20 {
21 rg_log("Fix repo path: uid=$uid repo_id=$repo_id repo_name=$repo_name");
22
23 $ret = FALSE;
24 do {
25 $repos_path = rg_repo_path_by_id($uid);
26 rg_log("repos_path=$repos_path");
27
28 // we expect to have a folder <user>/repos/by_id
29 if (!is_dir($repos_path . "/by_id")) {
30 $r = mkdir($repos_path . "by_id", 0755);
31 if ($r !== TRUE) {
32 rg_log("Cannot create by_id folder!");
33 break;
34 }
35 }
36
37 // we expect to have a folder <user>/repos/by_name
38 if (!is_dir($repos_path . "/by_name")) {
39 $r = mkdir($repos_path . "/by_name", 0755);
40 if ($r !== TRUE) {
41 rg_log("Cannot create by_name folder!");
42 break;
43 }
44 }
45
46 // We already moved it?
47 $old_path = $repos_path . "/" . $repo_name . ".git";
48 $new_path = $repos_path . "/by_id/" . $repo_id . ".git";
49 if (!is_dir($new_path)) {
50 $r = rename($old_path, $new_path);
51 if ($r !== TRUE) {
52 rg_log("Cannot rename $old_path -> $new_path!");
53 break;
54 }
55 }
56
57 // Now, make links from by_name
58 $name = $repos_path . "/by_name/" . $repo_name . ".git";
59 if (!is_link($name)) {
60 $master = "../by_id/" . $repo_id . ".git";
61 $r = symlink($master, $name);
62 if ($r !== TRUE) {
63 rg_log("Cannot symlink $new_path to $name!");
64 break;
65 }
66 }
67
68 $ret = TRUE;
69 } while (0);
70
71 return $ret;
72 }
73
74 /*
75 * Reindex repos by id so we can rename repos easier.
76 * And is more normal to index them by the unique id.
77 */
78 function rg_fixes_repo_index_by_id($db)
79 {
80 rg_prof_start("fixes_repo_index_by_id");
81
82 $ret = FALSE;
83 do {
84 $sql = "SELECT uid, repo_id, name FROM repos"
85 . " WHERE git_dir_done > 0";
86 $res = rg_sql_query($db, $sql);
87 if ($res === FALSE)
88 break;
89
90 $all_repos_moved = TRUE;
91 while (($row = rg_sql_fetch_array($res))) {
92 $r = rg_fixes_repo_index_by_id_one($row['uid'],
93 $row['repo_id'], $row['name']);
94 if ($r !== TRUE) {
95 $all_repos_moved = FALSE;
96 break;
97 }
98 }
99 rg_sql_free_result($res);
100
101 if ($all_repos_moved !== TRUE)
102 break;
103
104 $ret = TRUE;
105 } while (0);
106
107 rg_prof_end("fixes_repo_index_by_id");
108 return $ret;
109 }
110
111 /*
112 * Index user by id and make links for names
113 */
114 function rg_fixes_user_index_by_id_one($uid, $username)
115 {
116 global $rg_repos;
117
118 rg_log("Fix user path: uid=$uid username=$username");
119
120 $ret = FALSE;
121 do {
122 $user_path_uid = rg_user_path_by_id($uid);
123 $user_path_name = rg_user_path_by_name($username);
124 rg_log("\tuser_path=[$user_path_uid][$user_path_name]");
125
126 // parend dir exits? if not, create it
127 $p = dirname($user_path_uid);
128 if (!is_dir($p) && (mkdir($p, 0755, TRUE) === FALSE)) {
129 rg_log("cannot create parent dir [$p]");
130 break;
131 }
132
133 // We already moved it?
134 if (!is_dir($user_path_uid)) {
135 $x = $username . "_";
136 $old_path = $rg_repos . "/users/" . $x[0] . "/" . $x[1]
137 . "/" . $username;
138 $r = rename($old_path, $user_path_uid);
139 if ($r !== TRUE) {
140 rg_log("Cannot rename $old_path -> $user_path_uid!");
141 break;
142 }
143 }
144
145 // Now, make links from name to id
146 if (!is_link($user_path_name)) {
147 $master = rg_user_path_by_id_rel($uid);
148 $r = symlink($master, $user_path_name);
149 if ($r !== TRUE) {
150 rg_log("Cannot symlink $new_path to $name!");
151 break;
152 }
153 }
154
155 $ret = TRUE;
156 } while (0);
157
158 return $ret;
159 }
160
161 /*
162 * Reindex users by id so we can rename users easier.
163 * And is more normal to index them by the unique id.
164 */
165 function rg_fixes_user_index_by_id($db)
166 {
167 global $rg_repos;
168
169 rg_prof_start("fixes_user_index_by_id");
170
171 $ret = FALSE;
172 do {
173 $sql = "SELECT uid, username FROM users";
174 $res = rg_sql_query($db, $sql);
175 if ($res === FALSE)
176 break;
177
178 $all_users_moved = TRUE;
179 while (($row = rg_sql_fetch_array($res))) {
180 $r = rg_fixes_user_index_by_id_one($row['uid'],
181 $row['username']);
182 if ($r !== TRUE) {
183 $all_users_moved = FALSE;
184 break;
185 }
186 }
187 rg_sql_free_result($res);
188
189 if ($all_users_moved !== TRUE)
190 break;
191
192 // Remove old structure dirs
193 $r = rg_rmdir($rg_repos . "/users");
194 if ($r === FALSE) {
195 rg_log("Cannot remove old structure dirs"
196 . " (" . rg_util_error() . ").");
197 break;
198 }
199
200 $ret = TRUE;
201 } while (0);
202
203 rg_prof_end("fixes_user_index_by_id");
204 return $ret;
205 }
206
207
208 /*
209 * Apply fixes
210 */
211 function rg_fixes_run($db, $old_ver)
212 {
213 global $rg_fixes;
214 global $rg_fixes_ver;
215
216 rg_log("rg_fixes_run: old_ver=$old_ver...");
217
218 for ($i = $old_ver + 1; $i <= $rg_fixes_ver; $i++) {
219 foreach ($rg_fixes[$i] as $function) {
220 rg_log("Calling function $function...");
221 $r = $function($db);
222 if ($r !== TRUE) {
223 rg_log("Function $function returned error!");
224 return FALSE;
225 }
226 }
227 }
228
229 return TRUE;
230 }
231
232 /*
233 * Tests if fixes are needed. Return old version
234 */
235 function rg_fixes_needed($db)
236 {
237 global $rg_fixes_ver;
238
239 rg_log("fixes_needed:");
240
241 $old = rg_state_get($db, "fixes_version");
242 if ($old === FALSE) {
243 //TODO: error rg_log("\tDEBUG: schema is up to date!");
244 return FALSE;
245 }
246
247 if (empty($old))
248 $old = 0;
249
250 rg_log("\tDEBUG: old=$old new=$rg_fixes_ver");
251 if ($old == $rg_fixes_ver) {
252 rg_log("\tDEBUG: fixes are up to date!");
253 return FALSE;
254 }
255
256 return $old;
257 }
258
259 /*
260 * Apply fixes if needed
261 * Returns FALSE in case of error
262 * This must not be run by web user because of the owner of the locking file.
263 */
264 function rg_fixes_update($db)
265 {
266 global $rg_fixes_ver;
267
268 rg_log("fixes_update:");
269
270 $old = rg_fixes_needed($db);
271 if ($old === FALSE)
272 return TRUE;
273
274 // If we cannot lock, return error
275 if (rg_lock("fixes.lock") === FALSE)
276 return FALSE;
277
278 $ret = FALSE;
279 $rollback = 0;
280 do {
281 $r = rg_fixes_run($db, $old);
282 if ($r !== TRUE) {
283 rg_internal_error("Cannot apply fixes.");
284 break;
285 }
286
287 $r = rg_state_set($db, "fixes_version", $rg_fixes_ver);
288 if ($r !== TRUE) {
289 rg_log("Cannot set state ver (" . rg_state_error() . ")");
290 break;
291 }
292
293 $ret = TRUE;
294 } while (0);
295
296 rg_unlock("fixes.lock");
297
298 return $ret;
299 }
300
301 ?>
File inc/git.inc.php changed (mode: 100644) (index 5cdbaab..0c99b89)
... ... function rg_git_info($msg)
43 43 echo "==========\n"; echo "==========\n";
44 44 } }
45 45
46 /*
47 * Installs rg hooks instead of original ones, by making a link
48 */
46 49 function rg_git_install_hooks($dst) function rg_git_install_hooks($dst)
47 50 { {
48 51 global $rg_scripts; global $rg_scripts;
49 52
50 53 rg_prof_start("git_install_hooks"); rg_prof_start("git_install_hooks");
51
52 54 rg_log("git_install_hooks: dst=$dst"); rg_log("git_install_hooks: dst=$dst");
53 55
54 if (file_exists($dst . "/hooks")) {
55 if (is_link($dst . "/hooks")) {
56 $_dir = @readlink($dst . "/hooks");
57 if ($_dir !== FALSE) {
58 if (strcmp($_dir, $rg_scripts . "/hooks") == 0)
59 return TRUE;
60 rg_log("\tWARN: readlink returned=[$_dir]");
56 $ret = FALSE;
57 do {
58 if (file_exists($dst . "/hooks")) {
59 if (is_link($dst . "/hooks")) {
60 $_dir = readlink($dst . "/hooks");
61 if ($_dir === FALSE) {
62 rg_git_set_error("cannot read hooks link");
63 break;
64 }
65
66 if (strcmp($_dir, $rg_scripts . "/hooks") == 0) {
67 $ret = TRUE;
68 break;
69 }
61 70 } }
71
62 72 } }
63 73
64 rg_log("\tNot a link to scripts one, make it...");
74 rg_log("\tRemoving wrong hooks dir...");
65 75 if (!rg_rmdir($dst . "/hooks")) { if (!rg_rmdir($dst . "/hooks")) {
66 76 rg_git_set_error("cannot remove hooks dir" rg_git_set_error("cannot remove hooks dir"
67 77 . " (" . rg_util_error() . ")"); . " (" . rg_util_error() . ")");
68 return FALSE;
78 break;
69 79 } }
70 }
71 80
72 if (!@symlink($rg_scripts . "/hooks", $dst . "/hooks")) {
73 rg_git_set_error("cannot make symlink [$rg_scripts/hooks]"
74 . "->[$dst/] ($php_errormsg).");
75 return FALSE;
76 }
81 rg_log("\tLink hooks dir...");
82 if (symlink($rg_scripts . "/hooks", $dst . "/hooks") === FALSE) {
83 rg_git_set_error("cannot make symlink [$rg_scripts/hooks]"
84 . "->[$dst/] ($php_errormsg).");
85 break;
86 }
77 87
78 rg_prof_end("git_install_hooks");
88 $ret = TRUE;
89 } while (0);
79 90
80 return TRUE;
91 rg_prof_end("git_install_hooks");
92 return $ret;
81 93 } }
82 94
95 /*
96 * Init a dir to host a git repository
97 */
83 98 function rg_git_init($dst) function rg_git_init($dst)
84 99 { {
85 100 rg_prof_start("git_init"); rg_prof_start("git_init");
86
87 101 rg_log("git_init: dst=$dst"); rg_log("git_init: dst=$dst");
88 102
89 $dir = dirname($dst);
90 if (!file_exists($dir)) {
91 $r = @mkdir($dir, 0755, TRUE);
92 if ($r === FALSE) {
93 rg_git_set_error("cannot create dir [$dir] ($php_errormsg)");
94 return FALSE;
103 $ret = FALSE;
104 do {
105 $dir = dirname($dst);
106 if (!file_exists($dir)) {
107 $r = @mkdir($dir, 0755, TRUE);
108 if ($r === FALSE) {
109 rg_git_set_error("cannot create dir [$dir] ($php_errormsg)");
110 break;
111 }
95 112 } }
96 }
97 113
98 if (!file_exists($dst . "/rocketgit")) {
99 $cmd = "git init --bare " . escapeshellarg($dst);
100 $a = rg_exec($cmd);
101 if ($a['ok'] != 1) {
102 rg_git_set_error("error on init " . $a['errmsg'] . ")");
103 return FALSE;
104 }
114 // TODO: What if the git init does not finish?!
115 // Should we create it in a tmp dir and rename?
116 // Does git has any protection?
117 if (!is_dir($dst . "/rocketgit")) {
118 $cmd = "git init --bare " . escapeshellarg($dst);
119 $a = rg_exec($cmd);
120 if ($a['ok'] != 1) {
121 rg_git_set_error("error on init " . $a['errmsg'] . ")");
122 break;
123 }
105 124
106 if (!@mkdir($dst . "/rocketgit")) {
107 rg_git_set_error("cannot create '$dst/rocketgit' dir ($php_errormsg)");
108 return FALSE;
125 if (!@mkdir($dst . "/rocketgit")) {
126 rg_git_set_error("cannot create '$dst/rocketgit' dir ($php_errormsg)");
127 break;
128 }
109 129 } }
110 }
111 130
112 if (rg_git_install_hooks($dst) !== TRUE)
113 return FALSE;
131 if (rg_git_install_hooks($dst) !== TRUE)
132 break;
114 133
115 rg_prof_end("git_init");
134 $ret = TRUE;
135 } while (0);
116 136
117 return TRUE;
137 rg_prof_end("git_init");
138 return $ret;
118 139 } }
119 140
120 141 function rg_git_clone($src, $dst) function rg_git_clone($src, $dst)
121 142 { {
122 143 rg_prof_start("git_clone"); rg_prof_start("git_clone");
123
124 144 rg_log("git_clone: src=$src, dst=$dst"); rg_log("git_clone: src=$src, dst=$dst");
125 145
126 $dir = dirname($dst);
127 if (!file_exists($dir)) {
128 $r = @mkdir($dir, 0755, TRUE);
129 if ($r === FALSE) {
130 rg_git_set_error("cannot create dir [$dir] ($php_errormsg)");
131 return FALSE;
146 $ret = FALSE;
147 do {
148 $dir = dirname($dst);
149 if (!file_exists($dir)) {
150 $r = @mkdir($dir, 0755, TRUE);
151 if ($r === FALSE) {
152 rg_git_set_error("cannot create dir [$dir] ($php_errormsg)");
153 break;
154 }
132 155 } }
133 }
134 156
135 if (!file_exists($dst . "/rocketgit")) {
136 $cmd = "git clone --bare " . escapeshellarg($src)
137 . " " . escapeshellarg($dst);
138 $a = rg_exec($cmd);
139 if ($a['ok'] != 1) {
140 rg_git_set_error("error on clone (" . $a['errmsg'] . ")");
141 return FALSE;
142 }
157 if (!file_exists($dst . "/rocketgit")) {
158 $cmd = "git clone --bare " . escapeshellarg($src)
159 . " " . escapeshellarg($dst);
160 $a = rg_exec($cmd);
161 if ($a['ok'] != 1) {
162 rg_git_set_error("error on clone (" . $a['errmsg'] . ")");
163 break;
164 }
143 165
144 if (!@mkdir($dst . "/rocketgit", 0700)) {
145 rg_git_set_error("cannot create '$dst/rocketgit' dir ($php_errormsg)");
146 return FALSE;
166 if (!@mkdir($dst . "/rocketgit", 0700)) {
167 rg_git_set_error("cannot create '$dst/rocketgit' dir ($php_errormsg)");
168 break;
169 }
147 170 } }
148 }
149 171
150 if (rg_git_install_hooks($dst) !== TRUE)
151 return FALSE;
172 if (rg_git_install_hooks($dst) !== TRUE)
173 break;
152 174
153 rg_prof_end("git_clone");
175 $ret = TRUE;
176 } while (0);
154 177
155 return TRUE;
178 rg_prof_end("git_clone");
179 return $ret;
156 180 } }
157 181
158 182 /* /*
 
... ... function rg_git_type($obj)
163 187 global $rg_git_zero; global $rg_git_zero;
164 188
165 189 rg_prof_start("git_type"); rg_prof_start("git_type");
166
167 190 rg_log("git_type: obj=$obj"); rg_log("git_type: obj=$obj");
168 191
169 if (strcmp($obj, $rg_git_zero) == 0)
170 return "zero";
192 $ret = FALSE;
193 do {
194 if (strcmp($obj, $rg_git_zero) == 0) {
195 $ret = "zero";
196 break;
197 }
198
199 $cmd = "git cat-file -t '" . $obj . "'";
200 $a = rg_exec($cmd);
201 if ($a['ok'] != 1) {
202 rg_git_set_error("error on cat-file (" . $a['errmsg'] . ")");
203 break;
204 }
171 205
172 $cmd = "git cat-file -t '" . $obj . "'";
173 $a = rg_exec($cmd);
174 if ($a['ok'] != 1) {
175 rg_git_set_error("error on cat-file (" . $a['errmsg'] . ")");
176 $ret = FALSE;
177 } else {
178 206 $ret = trim($a['data']); $ret = trim($a['data']);
179 }
207 } while (0);
180 208
181 209 rg_prof_end("git_type"); rg_prof_end("git_type");
182
183 210 return $ret; return $ret;
184 211 } }
185 212
 
... ... function rg_git_type($obj)
189 216 function rg_git_content($obj) function rg_git_content($obj)
190 217 { {
191 218 rg_prof_start("git_content"); rg_prof_start("git_content");
192
193 219 rg_log("git_content: obj=$obj"); rg_log("git_content: obj=$obj");
194 220
195 $cmd = "git cat-file -p '" . $obj . "'";
196 $a = rg_exec($cmd);
197 if ($a['ok'] != 1) {
198 rg_git_set_error("error on cat-file (" . $a['errmsg'] . ")");
199 $ret = FALSE;
200 } else {
221 $ret = FALSE;
222 do {
223 $cmd = "git cat-file -p '" . $obj . "'";
224 $a = rg_exec($cmd);
225 if ($a['ok'] != 1) {
226 rg_git_set_error("error on cat-file (" . $a['errmsg'] . ")");
227 break;
228 }
229
201 230 $ret = $a['data']; $ret = $a['data'];
202 }
231 } while (0);
203 232
204 233 rg_prof_end("git_content"); rg_prof_end("git_content");
205
206 234 return $ret; return $ret;
207 235 } }
208 236
 
... ... function rg_git_reference($refname)
230 258 function rg_git_rev_ok($rev) function rg_git_rev_ok($rev)
231 259 { {
232 260 rg_prof_start("git_rev_ok"); rg_prof_start("git_rev_ok");
233
234 261 rg_log("git_rev_ok: rev=$rev"); rg_log("git_rev_ok: rev=$rev");
235 262
236 $cmd = "git rev-parse --verify '" . $rev . "'";
237 $a = rg_exec($cmd);
238 if ($a['ok'] != 1) {
239 rg_git_set_error("error on rev-parse (" . $a['errmsg'] . ")");
240 $ret = FALSE;
241 } else {
263 $ret = FALSE;
264 do {
265 $cmd = "git rev-parse --verify '" . $rev . "'";
266 $a = rg_exec($cmd);
267 if ($a['ok'] != 1) {
268 rg_git_set_error("error on rev-parse (" . $a['errmsg'] . ")");
269 break;
270 }
271
242 272 $ret = TRUE; $ret = TRUE;
243 }
273 } while (0);
244 274
245 275 rg_prof_end("git_rev_ok"); rg_prof_end("git_rev_ok");
246
247 276 return $ret; return $ret;
248 277 } }
249 278
 
... ... function rg_git_whitespace_ok($old, $new)
257 286 global $rg_git_empty; global $rg_git_empty;
258 287
259 288 rg_prof_start("git_whitespace_ok"); rg_prof_start("git_whitespace_ok");
260
261 289 rg_log("git_whitespace_ok: old=$old new=$new"); rg_log("git_whitespace_ok: old=$old new=$new");
262 290
263 if (strcmp($old, $rg_git_zero) == 0)
264 $old = $rg_git_empty;
291 $ret = FALSE;
292 do {
293 if (strcmp($old, $rg_git_zero) == 0)
294 $old = $rg_git_empty;
265 295
266 $cmd = "git diff --check"
267 . " " . escapeshellarg($old)
268 . " " . escapeshellarg($new);
269 $a = rg_exec($cmd);
270 rg_log("\ta:" . rg_array2string($a));
271 if ($a['ok'] != 1) {
272 rg_git_set_error("error on diff (" . $a['errmsg'] . ")");
273 $ret = $a['data'];
274 } else {
275 $ret = TRUE;
276 }
296 $cmd = "git diff --check"
297 . " " . escapeshellarg($old)
298 . " " . escapeshellarg($new);
299 $a = rg_exec($cmd);
300 rg_log("\ta:" . rg_array2string($a));
301 if ($a['ok'] != 1) {
302 rg_git_set_error("error on diff (" . $a['errmsg'] . ")");
303 $ret = $a['data']; // TODO: should we return FALSE?!
304 } else {
305 $ret = TRUE;
306 }
307 } while (0);
277 308
278 309 rg_prof_end("git_whitespace_ok"); rg_prof_end("git_whitespace_ok");
279
280 310 return $ret; return $ret;
281 311 } }
282 312
 
... ... function rg_git_whitespace_ok($old, $new)
284 314 function rg_git_merge_base($old, $new) function rg_git_merge_base($old, $new)
285 315 { {
286 316 rg_prof_start("git_merge_base"); rg_prof_start("git_merge_base");
287
288 317 rg_log("git_merge_base: old=$old new=$new"); rg_log("git_merge_base: old=$old new=$new");
289 318
290 $cmd = "git merge-base " . $old . " " . $new;
291 $a = rg_exec($cmd);
292 if ($a['ok'] != 1) {
293 rg_git_set_error("error on merge-base (" . $a['errmsg'] . ")");
294 $ret = FALSE;
295 } else {
319 $ret = FALSE;
320 do {
321 $cmd = "git merge-base " . $old . " " . $new;
322 $a = rg_exec($cmd);
323 if ($a['ok'] != 1) {
324 rg_git_set_error("error on merge-base (" . $a['errmsg'] . ")");
325 break;
326 }
327
296 328 $ret = trim($a['data']); $ret = trim($a['data']);
297 }
329 } while (0);
298 330
299 331 rg_prof_end("git_merge_base"); rg_prof_end("git_merge_base");
300
301 332 return $ret; return $ret;
302 333 } }
303 334
 
... ... function rg_git_merge_base($old, $new)
309 340 function rg_git_update_ref($ref, $old, $new, $reason) function rg_git_update_ref($ref, $old, $new, $reason)
310 341 { {
311 342 rg_prof_start("git_update_ref"); rg_prof_start("git_update_ref");
312
313 343 rg_log("git_update_ref: ref=$ref old=$old new=$new reason=$reason"); rg_log("git_update_ref: ref=$ref old=$old new=$new reason=$reason");
314 344
315 345 $ret = FALSE; $ret = FALSE;
346 do {
347 $cmd = "git update-ref";
348 if (!empty($reason))
349 $cmd .= " -m " . escapeshellarg($reason);
316 350
317 $cmd = "git update-ref";
318 if (!empty($reason))
319 $cmd .= " -m " . escapeshellarg($reason);
351 if (empty($new))
352 $cmd .= " -d " . escapeshellarg($ref);
353 else
354 $cmd .= " " . escapeshellarg($ref) . " " . escapeshellarg($new);
320 355
321 if (empty($new))
322 $cmd .= " -d " . escapeshellarg($ref);
323 else
324 $cmd .= " " . escapeshellarg($ref) . " " . escapeshellarg($new);
356 if (!empty($old))
357 $cmd .= " " . escapeshellarg($old);
325 358
326 if (!empty($old))
327 $cmd .= " " . escapeshellarg($old);
359 $a = rg_exec($cmd);
360 if ($a['ok'] != 1) {
361 rg_git_set_error("error on update-ref (" . $a['errmsg'] . ")");
362 break;
363 }
328 364
329 $a = rg_exec($cmd);
330 if ($a['ok'] == 1) {
331 365 $ret = TRUE; $ret = TRUE;
332 } else {
333 rg_git_set_error("error on update-ref (" . $a['errmsg'] . ")");
334 }
366 } while (0);
335 367
336 368 rg_prof_end("git_update_ref"); rg_prof_end("git_update_ref");
337
338 369 return $ret; return $ret;
339 370 } }
340 371
 
... ... function rg_git_update_ref($ref, $old, $new, $reason)
344 375 function rg_git_ls_tree($tree, $path) function rg_git_ls_tree($tree, $path)
345 376 { {
346 377 rg_prof_start("git_ls_tree"); rg_prof_start("git_ls_tree");
347
348 378 rg_log("rg_git_ls_tree: tree=$tree path=$path"); rg_log("rg_git_ls_tree: tree=$tree path=$path");
349 379
350 $ret = array();
351
352 $op = " ";
353 if (empty($tree)) {
354 $op = " --full-tree";
355 $tree = " HEAD";
356 }
357
358 $cmd = "git ls-tree --long" . $op . $tree;
359 if (!empty($path))
360 $cmd .= " " . escapeshellarg($path);
361 rg_log("DEBUG: cmd=$cmd");
362 $a = rg_exec($cmd);
363 if ($a['ok'] != 1) {
364 rg_git_set_error("error on ls-tree (" . $a['errmsg'] . ")");
365 return FALSE;
366 }
380 $ret = FALSE;
381 do {
382 $op = " ";
383 if (empty($tree)) {
384 $op = " --full-tree";
385 $tree = " HEAD";
386 }
367 387
368 if (empty($a['data'])) {
369 rg_git_set_error("error on ls-tree: empty answer");
370 return FALSE;
371 }
388 $cmd = "git ls-tree --long" . $op . $tree;
389 if (!empty($path))
390 $cmd .= " " . escapeshellarg($path);
391 rg_log("DEBUG: cmd=$cmd");
392 $a = rg_exec($cmd);
393 if ($a['ok'] != 1) {
394 rg_git_set_error("error on ls-tree (" . $a['errmsg'] . ")");
395 break;
396 }
372 397
373 $output = explode("\n", trim($a['data']));
374 foreach ($output as $line) {
375 $_y = array();
376 $_t = explode("\t", $line);
377 $_y['file'] = trim($_t[1]);
378 $_i = preg_replace("/([0-9]*) ([a-z]*) ([a-z0-9]*) ( *)([0-9]*)/",
379 '${1} ${2} ${3} ${5}', $_t[0]);
380 $_t = explode(" ", $_i);
381 $_y['mode'] = $_t[0];
382 $_y['type'] = $_t[1];
383 $_y['ref'] = $_t[2];
384 $_y['size'] = $_t[3];
385 $ret[] = $_y;
386 }
398 if (empty($a['data'])) {
399 rg_git_set_error("error on ls-tree: empty answer");
400 break;
401 }
387 402
388 rg_prof_end("git_ls_tree");
403 $output = explode("\n", trim($a['data']));
404 $ret = array();
405 foreach ($output as $line) {
406 $_y = array();
407 $_t = explode("\t", $line);
408 $_y['file'] = trim($_t[1]);
409 $_i = preg_replace("/([0-9]*) ([a-z]*) ([a-z0-9]*) ( *)([0-9]*)/",
410 '${1} ${2} ${3} ${5}', $_t[0]);
411 $_t = explode(" ", $_i);
412 $_y['mode'] = $_t[0];
413 $_y['type'] = $_t[1];
414 $_y['ref'] = $_t[2];
415 $_y['size'] = $_t[3];
416 $ret[] = $_y;
417 }
418 } while (0);
389 419
390 420 // We are forced to use print_r instead of array2string because // We are forced to use print_r instead of array2string because
391 421 // it may be a multilevel array. // it may be a multilevel array.
392 422 rg_log_ml("DEBUG: ls-tree: " . print_r($ret, TRUE)); rg_log_ml("DEBUG: ls-tree: " . print_r($ret, TRUE));
393 423
424 rg_prof_end("git_ls_tree");
394 425 return $ret; return $ret;
395 426 } }
396 427
File inc/keys.inc.php changed (mode: 100644) (index d994d30..cb411aa)
... ... function rg_keys_regen($db)
363 363 $ret = FALSE; $ret = FALSE;
364 364 do { do {
365 365 $dirty = rg_state_get($db, "authorized_keys"); $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 }
366 370 if ($dirty == 0) { if ($dirty == 0) {
367 371 // Skip generation because is not dirty // Skip generation because is not dirty
368 372 $ret = TRUE; $ret = TRUE;
File inc/mr.inc.php changed (mode: 100644) (index bdb91bf..a459c51)
... ... function rg_mr_error()
30 30 */ */
31 31 function rg_mr_queue_add($repo_id, $namespace, $old_rev, $new_rev, $refname, $ip) function rg_mr_queue_add($repo_id, $namespace, $old_rev, $new_rev, $refname, $ip)
32 32 { {
33 global $php_errormsg;
34 33 global $rg_mr_queue; global $rg_mr_queue;
35 34
36 35 rg_log("rg_mr_create: repo_id=$repo_id namespace=$namespace" rg_log("rg_mr_create: repo_id=$repo_id namespace=$namespace"
 
... ... function rg_mr_create($db, $repo_id, $namespace, $old_rev, $new_rev, $refname,
91 90 */ */
92 91 function rg_mr_queue_load_file($file) function rg_mr_queue_load_file($file)
93 92 { {
94 global $php_errormsg;
95
96 93 $ret = array(); $ret = array();
97 94 $ret['ok'] = 0; $ret['ok'] = 0;
98 95
 
... ... function rg_mr_queue_load_file($file)
117 114 */ */
118 115 function rg_mr_queue_process($db) function rg_mr_queue_process($db)
119 116 { {
120 global $php_errormsg;
121 117 global $rg_mr_queue; global $rg_mr_queue;
122 118
123 119 rg_log("mr_queue_process..."); rg_log("mr_queue_process...");
File inc/repo.inc.php changed (mode: 100644) (index 4d397ad..29b5eca)
... ... function rg_repo_ok($repo)
232 232 } }
233 233
234 234 if (strlen($repo) < $rg_repo_min_len) { if (strlen($repo) < $rg_repo_min_len) {
235 rg_repo_set_error("Repository name is too short"
236 . " (minimum $rg_repo_min_len).");
235 rg_repo_set_error("repository name is too short"
236 . " (minimum $rg_repo_min_len)");
237 237 return FALSE; return FALSE;
238 238 } }
239 239
240 240 if (strlen($repo) > $rg_repo_max_len) { if (strlen($repo) > $rg_repo_max_len) {
241 rg_repo_set_error("Repository name is too long"
242 . " (maximum $rg_repo_max_len).");
241 rg_repo_set_error("repository name is too long"
242 . " (maximum $rg_repo_max_len)");
243 243 return FALSE; return FALSE;
244 244 } }
245 245
246 246 return TRUE; return TRUE;
247 247 } }
248 248
249 /*
250 * Returns the relative path to a repository based on id
251 */
252 function rg_repo_path_by_id_rel($uid, $repo_id)
253 {
254 return "../by_id/" . $repo_id . ".git";
255 }
256
257 /*
258 * Returns the path to a repository based on id
259 */
260 function rg_repo_path_by_id($uid, $repo_id)
261 {
262 return rg_user_path_by_id($uid) . "/repos/by_id/" . $repo_id . ".git";
263 }
264
249 265 /* /*
250 266 * Returns the path to a repository based on name * Returns the path to a repository based on name
251 267 */ */
252 function rg_repo_name2base($rr)
268 function rg_repo_path_by_name($uid, $repo_name)
253 269 { {
254 return rg_user_name2path($rr) . "/repos/";
270 return rg_user_path_by_id($uid) . "/repos/by_name/" . $repo_name . ".git";
255 271 } }
256 272
257 273 $rg_repo_info_cache = array(); $rg_repo_info_cache = array();
 
... ... function rg_repo_invalidate_cache($rr)
266 282
267 283 /* /*
268 284 * Return info about a repo * Return info about a repo
269 * @param rr contains data about user and repo
270 285 */ */
271 function rg_repo_info($db, $rr)
286 function rg_repo_info($db, $uid, $repo_id, $repo_name)
272 287 { {
273 288 global $rg_repo_info_cache; global $rg_repo_info_cache;
274 289
275 290 rg_prof_start("repo_info"); rg_prof_start("repo_info");
291 rg_log("repo_info: uid=$uid repo_id=$repo_id repo_name=$repo_name");
276 292
277 $key = implode("__", $rr);
278 if (isset($rg_repo_info_cache[$key]))
279 return $rg_repo_info_cache[$key];
280
281 rg_log("repo_info: rr: " . rg_array2string($rr));
282
283 $uid = isset($rr['uid']) ? $rr['uid'] : 0;
284 $repo_id = isset($rr['repo_id']) ? $rr['repo_id'] : 0;
285 $user = isset($rr['user']) ? $rr['user'] : "";
286 $repo = isset($rr['repo']) ? $rr['repo'] : "";
293 $key1 = $uid . "-" . $repo_id;
294 if (isset($rg_repo_info_cache[$key1]))
295 return $rg_repo_info_cache[$key1];
296 $key2 = $uid . "-" . $repo_name;
297 if (isset($rg_repo_info_cache[$key2]))
298 return $rg_repo_info_cache[$key2];
287 299
288 300 $ret['ok'] = 0; $ret['ok'] = 0;
289 301 $ret['exists'] = 0; $ret['exists'] = 0;
290 302
291 $rg_repo_info_cache[$key] = $ret;
292
293 if (($uid == 0) && (!empty($user))) {
294 $ui = rg_user_info($db, 0, $user, "");
295 if ($ui['ok'] != 1) {
296 rg_repo_set_error("invalid repo path (user)");
297 return $ret;
298 }
299
300 $uid = $ui['uid'];
301 }
303 $rg_repo_info_cache[$key1] = $ret;
304 $rg_repo_info_cache[$key2] = $ret;
302 305
303 306 if ($repo_id > 0) { if ($repo_id > 0) {
304 $add = " repo_id = $repo_id";
305 } else if (($uid > 0) && !empty($repo)) {
306 $e_repo = rg_sql_escape($db, $repo);
307 $add = " uid = " . $uid . " AND name = '$e_repo'";
307 $add = " AND repo_id = $repo_id";
308 } else if (!empty($repo_name)) {
309 $e_repo = rg_sql_escape($db, $repo_name);
310 $add = " AND name = '$e_repo'";
308 311 } else { } else {
309 312 rg_repo_set_error("no repo_id or user/repo specified!"); rg_repo_set_error("no repo_id or user/repo specified!");
310 313 return $ret; return $ret;
311 314 } }
312 315
313 $sql = "SELECT * FROM repos WHERE " . $add;
316 $sql = "SELECT * FROM repos WHERE uid = $uid" . $add;
314 317 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
315 318 if ($res === FALSE) { if ($res === FALSE) {
316 319 rg_repo_set_error("cannot query (" . rg_sql_error() . ")"); rg_repo_set_error("cannot query (" . rg_sql_error() . ")");
317 320 return $ret; return $ret;
318 321 } }
319 322 $ret['ok'] = 1; $ret['ok'] = 1;
320 $row = rg_sql_fetch_array($res);
323 $rows = rg_sql_num_rows($res);
324 if ($rows > 0)
325 $row = rg_sql_fetch_array($res);
321 326 rg_sql_free_result($res); rg_sql_free_result($res);
322 if (!isset($row['repo_id'])) {
323 rg_log("\tRepo not found!");
324 return $ret;
327 if (($rows == 0) && ($repo_id == 0)) {
328 // Repo not found, maybe it was renamed
329 $_repo_id = rg_repo_lookup_by_old_name($db, $uid, $repo_name);
330 if (($_repo_id === FALSE) || ($_repo_id == 0)) {
331 rg_log("\tRepo not found!");
332 return $ret;
333 }
334
335 return rg_repo_info($db, $uid, $_repo_id, "");
325 336 } }
326 337
327 338 // small fixes // small fixes
 
... ... function rg_repo_info($db, $rr)
330 341 $row['exists'] = 1; $row['exists'] = 1;
331 342 $row['ok'] = 1; $row['ok'] = 1;
332 343
333 $rg_repo_info_cache[$key] = $row;
344 $rg_repo_info_cache[$key1] = $row;
345 $rg_repo_info_cache[$key2] = $row;
334 346
335 347 rg_prof_end("repo_info"); rg_prof_end("repo_info");
336
337 348 return $row; return $row;
338 349 } }
339 350
 
... ... function rg_repo_create($db, $master, $rg_ui, $name, $max_commit_size,
408 419 break; break;
409 420
410 421 // First, test if it already exists // First, test if it already exists
411 $rr = array("user" => $rg_ui['username'], "repo" => $name);
412 $ri = rg_repo_info($db, $rr);
422 $ri = rg_repo_info($db, $rg_ui['uid'], 0, $name);
413 423 if ($ri['ok'] != 1) if ($ri['ok'] != 1)
414 424 break; break;
415 425 if ($ri['exists'] == 1) { if ($ri['exists'] == 1) {
 
... ... function rg_repo_create($db, $master, $rg_ui, $name, $max_commit_size,
458 468 $ret = $row['repo_id']; $ret = $row['repo_id'];
459 469 } while (0); } while (0);
460 470
461 // git repo creation will be delayed for serialization reasons
462 // and for permission reasons (we are 'apache' user here)
471 // git repo creation will be delayed for speed reasons
472 // and for permission reasons (we are 'web' user here).
463 473
464 474 rg_prof_end("repo_create"); rg_prof_end("repo_create");
465 475 return $ret; return $ret;
 
... ... function rg_repo_delete($db, $repo_id, $rg_ui)
473 483 rg_prof_start("repo_delete"); rg_prof_start("repo_delete");
474 484 rg_log("repo_delete: rg_uid=" . $rg_ui['uid'] . ", repo_id=$repo_id"); rg_log("repo_delete: rg_uid=" . $rg_ui['uid'] . ", repo_id=$repo_id");
475 485
476 // TODO: Check rights
486 $ret = FALSE;
487 do {
488 // TODO: Check rights
477 489
478 // Only mark it as such, deletion will happen in background
479 $sql = "UPDATE repos SET deleted = 1 WHERE repo_id = $repo_id";
480 $res = rg_sql_query($db, $sql);
481 if ($res === FALSE) {
482 rg_repo_set_error("Cannot delete (" . rg_sql_error() . ")");
483 return FALSE;
484 }
485 rg_sql_free_result($res);
490 // Only mark it as such, deletion will happen in background
491 $sql = "UPDATE repos SET deleted = 1 WHERE repo_id = $repo_id";
492 $res = rg_sql_query($db, $sql);
493 if ($res === FALSE) {
494 rg_repo_set_error("Cannot delete (" . rg_sql_error() . ")");
495 break;
496 }
497 rg_sql_free_result($res);
498
499 $event = array("category" => 3001, "prio" => 50,
500 "name" => $name,
501 "description" => $description,
502 "email" => $rg_ui['email'],
503 "IP" => rg_var_str("REMOTE_ADDR"),
504 "repo_id" => $repo_id);
505 $r = rg_event_add($db, $event);
506 if ($r !== TRUE) {
507 rg_repo_set_error("cannot add event"
508 . " (" . rg_event_error() . ")");
509 break;
510 }
511
512 $ret = TRUE;
513 } while (0);
486 514
487 515 rg_prof_end("repo_delete"); rg_prof_end("repo_delete");
488 return TRUE;
516 return $ret;
517 }
518
519 /*
520 * Lookup in db the old names, so we can redirect the user to the new name
521 */
522 function rg_repo_lookup_by_old_name($db, $uid, $old_name)
523 {
524 rg_prof_start("rg_repo_lookup_by_old_name");
525 rg_log("repo_lookup_by_old_name: uid=$uid old_name=$old_name");
526
527 $ret = FALSE;
528 do {
529 $e_old_name = rg_sql_escape($db, $old_name);
530 $sql = "SELECT repo_id FROM repos_renames"
531 . " WHERE uid = " . $uid
532 . " AND old_name = '$e_old_name'";
533 $res = rg_sql_query($db, $sql);
534 if ($res === FALSE) {
535 rg_repo_set_error("cannot lookup old name ("
536 . rg_sql_error() . ")");
537 break;
538 }
539 $rows = rg_sql_num_rows($res);
540 if ($rows > 0)
541 $row = rg_sql_fetch_array($res);
542 rg_sql_free_result($res);
543 if ($rows == 0)
544 $ret = 0;
545 else
546 $ret = $row['repo_id'];
547 } while (0);
548
549 rg_prof_end("rg_repo_lookup_by_old_name");
550 return $ret;
551 }
552
553 /*
554 * Add a rename to the database
555 */
556 function rg_repo_insert_rename($db, $uid, $repo_id, $old_name)
557 {
558 rg_prof_start("repo_insert_rename");
559 rg_log("repo_insert_rename: uid=$uid repo_id=$repo_id old_name=$old_name");
560
561 $ret = FALSE;
562 do {
563 $e_old_name = rg_sql_escape($db, $old_name);
564
565 // Check if already exists in the database
566 $r = rg_repo_lookup_by_old_name($db, $uid, $old_name);
567 if ($r === FALSE)
568 break;
569 if ($r > 0) {
570 $sql = "UPDATE repos_renames"
571 . " SET repo_id = $repo_id"
572 . " WHERE uid = " . $uid
573 . " AND old_name = '$e_old_name'";
574 } else {
575 $now = time();
576 $sql = "INSERT INTO repos_renames (uid, old_name"
577 . ", repo_id, itime)"
578 . " VALUES (" . $uid
579 . ", '$e_old_name'"
580 . ", " . $repo_id
581 . ", $now"
582 . ")";
583 }
584 $res = rg_sql_query($db, $sql);
585 if ($res === FALSE) {
586 rg_repo_set_error("cannot link with old_name in db"
587 . " (" . rg_sql_error() . ")");
588 break;
589 }
590
591 $ret = TRUE;
592 } while (0);
593
594 rg_prof_end("repo_insert_rename");
595 return $ret;
596 }
597
598 /*
599 * Rename a repo
600 * We keep the old name around, so the clients do not break.
601 * TODO: When we create a new repo, we should remove any links!
602 */
603 function rg_repo_rename($db, $uid, $repo_id, $old_name, $new_name)
604 {
605 rg_prof_start("repo_rename");
606 rg_log("repo_rename: uid=$uid repo_id=$repo_id"
607 . " from=[" . $old_name . "]"
608 . " to=[" . $new_name . "]");
609
610 $id_path = rg_repo_path_by_id($uid, $repo_id);
611 $id_path_rel = rg_repo_path_by_id_rel($uid, $repo_id);
612 $new_path = rg_repo_path_by_name($uid, $new_name);
613
614 $ret = FALSE;
615 do {
616 $do_link = TRUE;
617
618 // Check if we already did the rename
619 if (file_exists($new_path)) {
620 if (!is_link($new_path)) {
621 rg_internal_error("$new_path is not a link!");
622 break;
623 }
624
625 $v = readlink($new_path);
626 if ($v === FALSE) {
627 rg_internal_error("Cannot read link $new_path!");
628 break;
629 }
630 rg_log("new_path points to [$v]");
631
632 if (strcmp($id_path_rel, $v) == 0) {
633 // Link already done
634 $do_link = FALSE;
635 } else {
636 // Seems that new_path points to other place
637 $r = rename($new_path, $new_path . ".BOGUS." . time());
638 if ($r !== TRUE) {
639 rg_internal_error("Cannot rename bogus!");
640 break;
641 }
642 }
643 }
644
645 if ($do_link === TRUE) {
646 // Now, the new name is free, do the link
647 $r = symlink($id_path_rel, $new_path);
648 if ($r !== TRUE) {
649 rg_internal_error("Cannot symlink $id_path -> $new_path!");
650 break;
651 }
652 }
653
654 // TOOD: transaction?
655 $r = rg_repo_insert_rename($db, $uid, $repo_id, $old_name);
656 if ($r !== TRUE)
657 break;
658
659 $event = array("category" => 3002, "prio" => 50,
660 "rename_uid" => $uid,
661 "rename_from" => $old_name,
662 "rename_to" => $new_name,
663 "IP" => rg_var_str("REMOTE_ADDR"),
664 "repo_id" => $repo_id);
665 $r = rg_event_add($db, $event);
666 if ($r !== TRUE) {
667 rg_repo_set_error("cannot add event"
668 . " (" . rg_event_error() . ")");
669 break;
670 }
671
672 $ret = TRUE;
673 } while (0);
674
675 rg_prof_end("repo_rename");
676 return $ret;
489 677 } }
490 678
491 679 /* /*
492 680 * Update a repository * Update a repository
681 * @login_ui - info of the user logged in
493 682 * TODO: check rights - also for create? * TODO: check rights - also for create?
494 683 */ */
495 function rg_repo_update($db, $user, &$new)
684 function rg_repo_update($db, $login_ui, &$new)
496 685 { {
497 686 rg_prof_start("repo_update"); rg_prof_start("repo_update");
498 rg_log("repo_update: user=" . $user
687 rg_log("repo_update: uid=" . $login_ui['uid']
499 688 . " new=" . rg_array2string($new)); . " new=" . rg_array2string($new));
500 689
501 if (rg_repo_ok($new['name']) !== TRUE)
502 return FALSE;
690 $ret = FALSE;
691 do {
692 if (rg_repo_ok($new['name']) !== TRUE)
693 break;
503 694
504 // First, test if it already exists
505 $rr = array("user" => $user, "repo" => $new['name']);
506 $ri = rg_repo_info($db, $rr);
507 if ($ri['ok'] != 1)
508 return FALSE;
509 if (($ri['exists'] == 1) && ($ri['repo_id'] != $new['repo_id'])) {
510 rg_repo_set_error("Name already taken.");
511 return FALSE;
512 }
695 // TODO: Something is strange here, why we need to lookup the repo?!
696 // First, test if it already exists
697 $ri = rg_repo_info($db, $login_ui['uid'], $new['repo_id'], $new['name']);
698 if ($ri['ok'] != 1)
699 break;
700 if (($ri['exists'] == 1) && ($ri['repo_id'] != $new['repo_id'])) {
701 rg_repo_set_error("Name already taken.");
702 break;
703 }
513 704
514 // Second, test if repo_id is valid
515 $rr = array("repo_id" => $new['repo_id']);
516 $ri = rg_repo_info($db, $rr);
517 if ($ri['ok'] != 1)
518 return FALSE;
519 if ($ri['exists'] == 0) {
520 rg_repo_set_error("Repo " . $new['repo_id'] . " does not exists.");
521 return FALSE;
522 }
705 // Second, test if repo_id is valid
706 $ri = rg_repo_info($db, $login_ui['uid'], $new['repo_id'], "");
707 if ($ri['ok'] != 1)
708 break;
709 if ($ri['exists'] == 0) {
710 rg_repo_set_error("Repo " . $new['repo_id'] . " does not exists.");
711 break;
712 }
523 713
524 $e_name = rg_sql_escape($db, $new['name']);
525 $e_description = rg_sql_escape($db, $new['description']);
714 // Check if the user renamed the repo
715 if (strcmp($new['name'], $ri['name']) != 0) {
716 $r = rg_repo_rename($db, $rg_ui['uid'], $new['repo_id'],
717 $ri['name'], $new['name']);
718 if ($r === FALSE)
719 break;
720 }
526 721
527 $sql = "UPDATE repos SET name = '$e_name'"
528 . ", max_commit_size = " . $new['max_commit_size']
529 . ", description = '$e_description'"
530 . ", default_rights = '" . $new['default_rights'] . "'"
531 . ", max_users = " . $new['max_users']
532 . " WHERE repo_id = " . $new['repo_id'];
533 $res = rg_sql_query($db, $sql);
534 if ($res === FALSE) {
535 rg_repo_set_error("Cannot update (" . rg_sql_error() . ")");
536 return FALSE;
537 }
538 rg_sql_free_result($res);
722 $e_name = rg_sql_escape($db, $new['name']);
723 $e_description = rg_sql_escape($db, $new['description']);
724
725 $sql = "UPDATE repos SET name = '$e_name'"
726 . ", max_commit_size = " . $new['max_commit_size']
727 . ", description = '$e_description'"
728 . ", default_rights = '" . $new['default_rights'] . "'"
729 . ", max_users = " . $new['max_users']
730 . " WHERE repo_id = " . $new['repo_id'];
731 $res = rg_sql_query($db, $sql);
732 if ($res === FALSE) {
733 rg_repo_set_error("Cannot update (" . rg_sql_error() . ")");
734 break;
735 }
736 rg_sql_free_result($res);
737
738 $ret = TRUE;
739 } while (0);
539 740
540 741 rg_prof_end("repo_update"); rg_prof_end("repo_update");
541 return TRUE;
742 return $ret;
542 743 } }
543 744
544 745 /* /*
 
... ... function rg_repo_disk_mb($path)
669 870 function rg_repo_git_done($db, $repo_id) function rg_repo_git_done($db, $repo_id)
670 871 { {
671 872 rg_prof_start("repo_git_done"); rg_prof_start("repo_git_done");
672
673 873 rg_log("repo_git_done: repo_id=$repo_id..."); rg_log("repo_git_done: repo_id=$repo_id...");
674 874
675 $sql = "UPDATE repos SET git_dir_done = 1"
676 . " WHERE repo_id = $repo_id";
677 $res = rg_sql_query($db, $sql);
678 if ($res === FALSE) {
679 rg_repo_set_error("Cannot query (" . rg_sql_error() . ")");
680 return FALSE;
681 }
682 rg_sql_free_result($res);
875 $ret = FALSE;
876 do {
877 $sql = "UPDATE repos SET git_dir_done = 1"
878 . " WHERE repo_id = $repo_id";
879 $res = rg_sql_query($db, $sql);
880 if ($res === FALSE) {
881 rg_repo_set_error("Cannot query (" . rg_sql_error() . ")");
882 break;
883 }
884 rg_sql_free_result($res);
683 885
684 rg_prof_end("repo_git_done");
886 $ret = TRUE;
887 } while (0);
685 888
686 return TRUE;
889 rg_prof_end("repo_git_done");
890 return $ret;
687 891 } }
688 892
689 893 /* /*
 
... ... function rg_repo_over_limit($ri)
791 995 */ */
792 996 function rg_repo_stats_push2file($a) function rg_repo_stats_push2file($a)
793 997 { {
794 global $php_errormsg;
795 998 global $rg_state_dir; global $rg_state_dir;
796 999
797 1000 $q = $rg_state_dir . "/qstats"; $q = $rg_state_dir . "/qstats";
 
... ... function rg_repo_stats_push2file($a)
814 1017 return $file; return $file;
815 1018 } }
816 1019
1020 /*
1021 * Creates git folder
1022 */
1023 function rg_repo_storage_create($db, $ri)
1024 {
1025 rg_prof_start("repo_storage_create");
1026 rg_log("repo_storage_create: ri=" . rg_array2string($ri));
1027
1028 $ret = FALSE;
1029 do {
1030 $by_id_path = rg_repo_path_by_id($ri['uid'], $ri['repo_id']);
1031 if (!is_dir($by_id_path)) {
1032 if (mkdir($by_id_path, 0755, TRUE) === FALSE) {
1033 rg_repo_set_error("could not create folder $dst");
1034 break;
1035 }
1036 }
1037
1038 if ($ri['master'] == 0) {
1039 $r = rg_git_init($by_id_path);
1040 if ($r === FALSE) {
1041 rg_repo_set_error("cannot init master"
1042 . " (" . rg_git_error() . ")");
1043 break;
1044 }
1045 } else {
1046 $mi = rg_repo_info($db, $ri['master'], "");
1047 if ($mi['exists'] != 1) {
1048 rg_repo_set_error("cannot find master (" . rg_repo_error() . ")");
1049 break;
1050 }
1051
1052 $master_by_id_path = rg_repo_path_by_id($mi['uid'], $mi['repo_id']);
1053 $r = rg_git_clone($master_by_id_path, $by_id_path);
1054 if ($r === FALSE) {
1055 rg_repo_set_error("could not create repo (" . rg_git_error() . ")");
1056 break;
1057 }
1058
1059 }
1060
1061 // Link by name
1062 $link = rg_repo_path_by_name($ri['uid'], $ri['name']);
1063 $link_parent = dirname($link);
1064 if (!is_dir($link_parent)) {
1065 $r = mkdir($link_parent, 0755, TRUE);
1066 if ($r === FALSE) {
1067 rg_repo_set_error("cannot create links' parent");
1068 break;
1069 }
1070 }
1071
1072 $master = rg_repo_path_by_id_rel($ri['uid'], $ri['repo_id']);
1073 $r = symlink($master, $link);
1074 if ($r === FALSE) {
1075 rg_repo_set_error("cannot symlink($master, $link)");
1076 break;
1077 }
1078
1079 $r = rg_repo_git_done($db, $ri['repo_id']);
1080 if ($r !== TRUE)
1081 break;
1082
1083 $ret = TRUE;
1084 } while (0);
1085
1086 rg_prof_end("repo_storage_create");
1087 return $ret;
1088 }
1089
817 1090 ?> ?>
File inc/struct.inc.php changed (mode: 100644) (index 51d8064..ece4516)
... ... $rg_sql_struct[9]['tables'] = array();
194 194 $rg_sql_struct[9]['other'] = array( $rg_sql_struct[9]['other'] = array(
195 195 "allow duplicate ssh keys" => "ALTER TABLE keys" "allow duplicate ssh keys" => "ALTER TABLE keys"
196 196 . " DROP CONSTRAINT IF EXISTS keys_pkey", . " DROP CONSTRAINT IF EXISTS keys_pkey",
197 "allow duplicate ssh keys2" => "ALTER TABLE keys"
198 . " DROP CONSTRAINT IF EXISTS keys_key_key",
197 199 "index on key_id" => "CREATE INDEX keys_i_key_id" "index on key_id" => "CREATE INDEX keys_i_key_id"
198 200 . " ON keys(key_id)", . " ON keys(key_id)",
199 201 "allow duplicate repos names" => "ALTER TABLE repos" "allow duplicate repos names" => "ALTER TABLE repos"
200 202 . " DROP CONSTRAINT IF EXISTS repos_pkey", . " DROP CONSTRAINT IF EXISTS repos_pkey",
203 "allow duplicate repos names2" => "ALTER TABLE repos"
204 . " DROP CONSTRAINT IF EXISTS repos_name_key",
201 205 "index on repos names" => "CREATE INDEX repos_i_name" "index on repos names" => "CREATE INDEX repos_i_name"
202 206 . " ON repos(name)" . " ON repos(name)"
203 207 ); );
 
... ... $rg_sql_struct_slaves['repo_history'] = "repo_history";
215 219
216 220 $rg_sql_struct[11] = array(); $rg_sql_struct[11] = array();
217 221 $rg_sql_struct[11]['tables'] = array( $rg_sql_struct[11]['tables'] = array(
218 "repo_history" => "CREATE TABLE events ("
222 "events" => "CREATE TABLE events ("
219 223 . "id BIGSERIAL PRIMARY KEY" . "id BIGSERIAL PRIMARY KEY"
220 224 . ", itime INT NOT NULL" . ", itime INT NOT NULL"
221 . ", type INT NOT NULL"
225 . ", prio SMALLINT NOT NULL"
222 226 . ", data TEXT NOT NULL)" . ", data TEXT NOT NULL)"
223 227 ); );
224 228 $rg_sql_struct[11]['other'] = array(); $rg_sql_struct[11]['other'] = array();
225 229
226 230 $rg_sql_struct[12] = array(); $rg_sql_struct[12] = array();
227 $rg_sql_struct[12]['tables'] = array(
228 "index on uid" => "CREATE INDEX repos_i_uid ON repos(uid)",
229 "index on repo_id" => "CREATE INDEX repos_i_repo_id ON repos(repo_id)"
231 $rg_sql_struct[12]['tables'] = array();
232 $rg_sql_struct[12]['other'] = array(
233 "index repos-uid" => "CREATE INDEX repos_i_uid ON repos(uid)",
234 "index on repos-repo_id" => "CREATE INDEX repos_i_repo_id ON repos(repo_id)"
235 );
236
237 $rg_sql_struct[13] = array();
238 $rg_sql_struct[13]['tables'] = array(
239 "repos_renames" => "CREATE TABLE repos_renames ("
240 . "uid INT NOT NULL"
241 . ", old_name TEXT NOT NULL"
242 . ", itime INT NOT NULL"
243 . ", repo_id INT NOT NULL)"
244 );
245 $rg_sql_struct[13]['other'] = array(
246 "repos_renames_index_ui_old_name" => "CREATE INDEX repos_renames_i_uid_old_name"
247 . " ON repos_renames(uid, old_name)"
248 );
249
250
251 $rg_sql_struct[14] = array();
252 $rg_sql_struct[14]['tables'] = array(
253 "users_renames" => "CREATE TABLE users_renames ("
254 . "uid INT NOT NULL"
255 . ", old_name TEXT NOT NULL"
256 . ", itime INT NOT NULL)"
257 );
258 $rg_sql_struct[14]['other'] = array(
259 "users_renames_index_old_name" => "CREATE INDEX users_renames_i_old_name"
260 . " ON repos_renames(old_name)"
230 261 ); );
231 $rg_sql_struct[12]['other'] = array();
232 262
233 263
234 264 // This must be the last line // This must be the last line
 
... ... function rg_sql_struct_run($db, $flags, $old_schema_ver)
263 293 if ((strcmp($type, "tables") == 0) if ((strcmp($type, "tables") == 0)
264 294 && ($drop_tables === TRUE)) { && ($drop_tables === TRUE)) {
265 295 rg_log("Dropping table [$id]..."); rg_log("Dropping table [$id]...");
266 $sql2 = "DROP TABLE IF EXISTS $id";
296 $sql2 = "DROP TABLE IF EXISTS $id CASCADE";
267 297 $res = rg_sql_query($db, $sql2); $res = rg_sql_query($db, $sql2);
268 298 if ($res === FALSE) { if ($res === FALSE) {
269 299 rg_log("WARN: Cannot run sql ($sql2) (" . rg_sql_error() . ")!"); rg_log("WARN: Cannot run sql ($sql2) (" . rg_sql_error() . ")!");
File inc/user.inc.php changed (mode: 100644) (index 9248762..e1982ea)
... ... function rg_user_error()
32 32 */ */
33 33 $rg_user_functions = array( $rg_user_functions = array(
34 34 2000 => "rg_user_event_new", 2000 => "rg_user_event_new",
35 2002 => "rg_user_event_notify_user"
35 2002 => "rg_user_event_notify_user",
36 2005 => "rg_user_event_rename",
37 2006 => "rg_user_link_by_name"
36 38 ); );
37 39 rg_event_register_functions($rg_user_functions); rg_event_register_functions($rg_user_functions);
38 40
 
... ... function rg_user_event_new($db, $event)
44 46 $ret = array(); $ret = array();
45 47
46 48 $event['op'] = "new"; $event['op'] = "new";
49 // create link by name
50 $ret[] = array_merge($event, array("category" => 2006, "prio" => 200));
47 51 // notify user // notify user
48 52 $ret[] = array_merge($event, array("category" => 2002, "prio" => 100)); $ret[] = array_merge($event, array("category" => 2002, "prio" => 100));
49 53
 
... ... function rg_user_event_notify_user($db, $event)
57 61 { {
58 62 rg_log("user_event_notify_user: event=" . rg_array2string($event)); rg_log("user_event_notify_user: event=" . rg_array2string($event));
59 63
64 if (strcmp($event['op'], "rename") == 0) {
65 $r = rg_mail("mail/user/rename", $event);
66 if ($r === FALSE)
67 return FALSE;
68 }
69
60 70 $r = rg_mail("mail/user/welcome", $event); $r = rg_mail("mail/user/welcome", $event);
61 71 if ($r === FALSE) if ($r === FALSE)
62 72 return FALSE; return FALSE;
 
... ... function rg_user_event_notify_user($db, $event)
65 75 } }
66 76
67 77 /* /*
68 * Returns the path to user home based on name
78 * Event for renaming an user
79 */
80 function rg_user_event_rename($db, $event)
81 {
82 $ret = array();
83
84 $event['op'] = "rename";
85 // notify user
86 $ret[] = array_merge($event, array("category" => 2002, "prio" => 100));
87 // TODO: notify watchers
88
89 return $ret;
90 }
91
92 /*
93 * Event for creating a link by name to the uid
69 94 */ */
70 function rg_user_name2path($rr)
95 function rg_user_link_by_name($db, $event)
96 {
97 rg_log("user_link_by_name: event=" . rg_array2string($event));
98
99 $by_id = rg_user_path_by_id($event['uid']);
100 if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) {
101 rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)");
102 return FALSE;
103 }
104
105 $by_name = rg_user_path_by_name($event['username']);
106 $by_name_parent = dirname($by_name);
107 if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) {
108 rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)");
109 return FALSE;
110 }
111
112 $by_id_rel = rg_user_path_by_id_rel($event['uid']);
113 if (symlink($by_id_rel, $by_name) === FALSE) {
114 rg_user_set_error("cannot symlink $by_id_rel <- $by_name");
115 return FALSE;
116 }
117
118 return array();
119 }
120
121 /*
122 * Returns the relative path to user home based on uid
123 */
124 function rg_user_path_by_id_rel($uid)
125 {
126 $xuid = sprintf("%08X", $uid);
127 $uid_path = array();
128 for ($i = 0; $i < 8; $i += 2)
129 $uid_path[] = $xuid[$i] . $xuid[$i + 1];
130 $uid_path = implode("/", $uid_path);
131
132 return "../../../../by_id/" . $uid_path . "/" . $xuid;
133 }
134
135 /*
136 * Returns the path to user home based on uid
137 */
138 function rg_user_path_by_id($uid)
71 139 { {
72 140 global $rg_repos; global $rg_repos;
73 141
74 $len = strlen($rr['user']);
75 $v = $rr['user'];
76 if ($len == 1)
77 $v .= "_";
142 $xuid = sprintf("%08X", $uid);
143 $uid_path = array();
144 for ($i = 0; $i < 8; $i += 2)
145 $uid_path[] = $xuid[$i] . $xuid[$i + 1];
146 $uid_path = implode("/", $uid_path);
78 147
79 if (empty($rr['prefix']))
80 $type = "org";
81 else
82 $type = "user";
148 return $rg_repos . "/by_id/" . $uid_path . "/" . $xuid;
149 }
150
151 /*
152 * Returns the path to user home based on name
153 */
154 function rg_user_path_by_name($name)
155 {
156 global $rg_repos;
83 157
84 return $rg_repos . "/" . $type . "s/"
85 . $v[0] . "/" . $v[1] . "/" . $rr['user'];
158 $x = $name . "__";
159
160 return $rg_repos . "/by_name/"
161 . $x[0] . "/" . $x[1] . "/" . $x[2] . "/" . $name;
86 162 } }
87 163
88 164 /* /*
 
... ... function rg_user_ok($user)
146 222 } }
147 223
148 224 /* /*
149 * Add a user
150 * If uid > 0 - edit, else, add
225 * Lookup in db the old names, so we can redirect the user to the new name
151 226 */ */
152 function rg_user_edit($db, $d)
227 function rg_user_lookup_by_old_name($db, $old_name)
153 228 { {
154 global $rg_user_info_cache; // TODO: what we do with this?
229 rg_prof_start("rg_user_lookup_by_old_name");
230 rg_log("user_lookup_by_old_name: old_name=$old_name");
231
232 $ret = FALSE;
233 do {
234 $e_old_name = rg_sql_escape($db, $old_name);
235 $sql = "SELECT uid FROM users_renames"
236 . " WHERE old_name = '$e_old_name'";
237 $res = rg_sql_query($db, $sql);
238 if ($res === FALSE) {
239 rg_user_set_error("cannot lookup old name ("
240 . rg_sql_error() . ")");
241 break;
242 }
243 $rows = rg_sql_num_rows($res);
244 if ($rows > 0)
245 $row = rg_sql_fetch_array($res);
246 rg_sql_free_result($res);
247 if ($rows == 0)
248 $ret = 0;
249 else
250 $ret = $row['uid'];
251 } while (0);
155 252
156 rg_log("user_edit: data: " . rg_array2string($d));
253 rg_prof_end("rg_user_lookup_by_old_name");
254 return $ret;
255 }
256
257 /*
258 * Add a rename to the database
259 */
260 function rg_user_insert_rename($db, $uid, $old_name)
261 {
262 rg_prof_start("user_insert_rename");
263 rg_log("user_insert_rename: uid=$uid old_name=$old_name");
264
265 $ret = FALSE;
266 do {
267 $e_old_name = rg_sql_escape($db, $old_name);
268
269 // Check if already exists in the database
270 $r = rg_user_lookup_by_old_name($db, $old_name);
271 if ($r === FALSE)
272 break;
273 if ($r > 0) {
274 $sql = "UPDATE users_renames"
275 . " SET uid = $uid"
276 . " WHERE old_name = '$e_old_name'";
277 } else {
278 $now = time();
279 $sql = "INSERT INTO users_renames (uid, old_name"
280 . ", itime)"
281 . " VALUES (" . $uid
282 . ", '$e_old_name'"
283 . ", $now"
284 . ")";
285 }
286 $res = rg_sql_query($db, $sql);
287 if ($res === FALSE) {
288 rg_user_set_error("cannot link with old_name in db"
289 . " (" . rg_sql_error() . ")");
290 break;
291 }
157 292
158 // DEBUG
159 if (!isset($d['username']))
160 rg_internal_error("username not passed");
293 $ret = TRUE;
294 } while (0);
161 295
162 if (rg_user_ok($d['username']) !== TRUE)
163 return FALSE;
296 rg_prof_end("user_insert_rename");
297 return $ret;
298 }
164 299
165 $now = time();
166 $e_username = rg_sql_escape($db, $d['username']);
167 $e_realname = rg_sql_escape($db, $d['realname']);
168 $e_salt = rg_id(40);
169 $e_pass = rg_user_pass($e_salt, $d['pass']);
170 $e_email = rg_sql_escape($db, $d['email']);
171 $e_rights = rg_sql_escape($db, $d['rights']);
172 $e_is_admin = $d['is_admin'];
173 $e_disk_quota_mb = $d['disk_quota_mb'];
174 $e_session_time = $d['session_time'];
175 $e_confirm_token = isset($d['confirm_token']) ? $d['confirm_token'] : "";
176
177 if (empty($d['confirm_token'])) {
178 // no need to confirm account
179 $e_confirmed = $now;
180 } else {
181 $e_confirmed = 0;
182 }
300 /*
301 * Rename a user
302 * We keep the old name around, so the clients do not break.
303 */
304 function rg_user_rename($db, $ui, $new_name)
305 {
306 rg_prof_start("user_rename");
307 rg_log("user_rename: from=[" . $ui['username'] . "]"
308 . " to=[" . $new_name . "]...");
309
310 $user_path = rg_user_path_by_id($ui['uid']);
311 $old_path = rg_user_path_by_id_rel($ui['uid']);
312 $new_path = rg_user_path_by_name($new_name);
313 rg_log("old_path=$old_path new_path=$new_path");
314
315 $ret = FALSE;
316 do {
317 $do_link = TRUE;
318
319 // Check if we already did the rename
320 if (file_exists($new_path)) {
321 if (!is_link($new_path)) {
322 rg_internal_error("$new_path is not a link!");
323 break;
324 }
325
326 $v = readlink($new_path);
327 if ($v === FALSE) {
328 rg_internal_error("Cannot read link $new_path!");
329 break;
330 }
331 rg_log("new_path points to [$v]");
332
333 if (strcmp($old_path, $v) == 0) {
334 // Link already done
335 $do_link = FALSE;
336 } else {
337 // Seems that new_path points to other place
338 $r = rename($new_path, $new_path . ".BOGUS." . time());
339 if ($r !== TRUE) {
340 rg_internal_error("Cannot rename bogus!");
341 break;
342 }
343 }
344 }
183 345
184 if ($d['uid'] == 0) { // add
185 if (rg_user_pass_ok($d['pass']) !== TRUE)
186 return FALSE;
346 if ($do_link === TRUE) {
347 // Now, the new name is free, do the link
348 $r = symlink($old_path, $new_path);
349 if ($r !== TRUE) {
350 rg_internal_error("Cannot symlink $old_path -> $new_path!");
351 break;
352 }
353 }
354
355 // TOOD: transaction?
356 $r = rg_user_insert_rename($db, $ui['uid'], $new_name);
357 if ($r !== TRUE)
358 break;
359
360 // TODO: Check if all parameters are used.
361 $event = array("category" => 2005, "prio" => 50,
362 "rename_from" => $ui['username'],
363 "rename_to" => $new_name,
364 "IP" => rg_var_str("REMOTE_ADDR"),
365 "uid" => $ui['uid']);
366 $r = rg_event_add($db, $event);
367 if ($r !== TRUE) {
368 rg_repo_set_error("cannot add event"
369 . " (" . rg_event_error() . ")");
370 break;
371 }
187 372
188 $sql = "INSERT INTO users (username, realname, salt, pass"
189 . ", email, itime"
190 . ", is_admin, disk_quota_mb, rights, session_time"
191 . ", confirmed, confirm_token)"
192 . " VALUES ('$e_username', '$e_realname', '$e_salt', '$e_pass'"
193 . ", '$e_email', $now, $e_is_admin, $e_disk_quota_mb"
194 . ", '$e_rights', $e_session_time"
195 . ", $e_confirmed, '$e_confirm_token')";
196 } else { // edit
197 $salt_pass_add = "";
198 if (!empty($d['pass']))
199 $salt_pass_add = ", pass = '$e_pass', salt = '$e_salt'";
200
201 $sql = "UPDATE users"
202 . " SET username = '$e_username'"
203 . ", realname = '$e_realname'"
204 . $salt_pass_add
205 . ", email = '$e_email'"
206 . ", is_admin = $e_is_admin"
207 . ", disk_quota_mb = $e_disk_quota_mb"
208 . ", rights = '$e_rights'"
209 . ", session_time = $e_session_time"
210 . " WHERE uid = " . $d['uid'];
211 }
373 $ret = TRUE;
374 } while (0);
212 375
213 $res = rg_sql_query($db, $sql);
214 if ($res === FALSE) {
215 rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")");
216 return FALSE;
217 }
218 rg_sql_free_result($res);
376 rg_prof_end("user_rename");
377 return $ret;
378 }
219 379
220 // invalidate cache
221 $rg_user_info_cache = array();
380 /*
381 * Add/edit a user
382 * If uid > 0 - edit, else, add
383 */
384 function rg_user_edit($db, $d)
385 {
386 global $rg_user_info_cache; // TODO: what we do with this?
222 387
223 if ($d['uid'] == 0) { // add
224 $event = array("category" => 2000, "prio" => 50,
225 "email" => $d['email']
226 );
227 $r = rg_event_add($db, $event);
228 if ($r === FALSE) {
229 rg_user_set_error("Canot add event!");
230 return FALSE;
388 rg_prof_start("user_edit");
389 rg_log("user_edit: data: " . rg_array2string($d));
390
391 $ret = FALSE;
392 do {
393 // DEBUG
394 if (!isset($d['username'])) {
395 rg_internal_error("username not passed");
396 break;
231 397 } }
232 }
233 398
234 return TRUE;
399 if (rg_user_ok($d['username']) !== TRUE)
400 break;
401
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'])) {
415 // no need to confirm account
416 $e_confirmed = $now;
417 } else {
418 $e_confirmed = 0;
419 }
420
421 if ($d['uid'] == 0) { // add
422 if (rg_user_pass_ok($d['pass']) !== TRUE)
423 break;
424
425 $sql = "INSERT INTO users (username, realname, salt, pass"
426 . ", 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')"
433 . " RETURNING uid";
434 } else { // edit
435 $salt_pass_add = "";
436 if (!empty($d['pass']))
437 $salt_pass_add = ", pass = '$e_pass', salt = '$e_salt'";
438
439 $sql = "UPDATE users"
440 . " SET username = '$e_username'"
441 . ", realname = '$e_realname'"
442 . $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']
449 . " RETURNING uid";
450 }
451
452 $res = rg_sql_query($db, $sql);
453 if ($res === FALSE) {
454 rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")");
455 break;
456 }
457 $row = rg_sql_fetch_array($res);
458 rg_sql_free_result($res);
459
460 // invalidate cache
461 $rg_user_info_cache = array();
462
463 if ($d['uid'] == 0) { // add
464 $event = array("category" => 2000, "prio" => 50,
465 "uid" => $d['uid'],
466 "username" => $d['username'],
467 "email" => $d['email']
468 );
469 $r = rg_event_add($db, $event);
470 if ($r === FALSE) {
471 rg_user_set_error("Canot add event!");
472 break;
473 }
474 }
475
476 $ret = $row['uid'];
477 } while (0);
478
479 rg_prof_end("user_edit");
480 return $ret;
235 481 } }
236 482
237 483 /* /*
 
... ... function rg_user_remove($db, $uid)
241 487 { {
242 488 global $rg_user_info_cache; global $rg_user_info_cache;
243 489
244 $uid = sprintf("%u", $uid);
490 rg_prof_start("user_remove");
491 rg_log("user_remove: uid=$uid");
245 492
246 $sql = "DELETE FROM users WHERE uid = $uid";
247 $res = rg_sql_query($db, $sql);
248 if ($res === FALSE) {
249 rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")");
250 return FALSE;
251 }
252 rg_sql_free_result($res);
493 $ret = FALSE;
494 do {
495 $uid = sprintf("%u", $uid);
253 496
254 // invalidate cache
255 $rg_user_info_cache = array();
497 $sql = "DELETE FROM users WHERE uid = $uid";
498 $res = rg_sql_query($db, $sql);
499 if ($res === FALSE) {
500 rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")");
501 break;
502 }
503 rg_sql_free_result($res);
256 504
257 return TRUE;
505 // invalidate cache
506 $rg_user_info_cache = array();
507
508 $ret = TRUE;
509 } while (0);
510
511 rg_prof_end("user_remove");
512 return $ret;
258 513 } }
259 514
260 515 /* /*
 
... ... function rg_user_info($db, $uid, $user, $email)
269 524 if (isset($rg_user_info_cache[$key])) if (isset($rg_user_info_cache[$key]))
270 525 return $rg_user_info_cache[$key]; return $rg_user_info_cache[$key];
271 526
527 rg_prof_start("user_info");
272 528 rg_log("user_info: uid/user/email=$uid/$user/$email..."); rg_log("user_info: uid/user/email=$uid/$user/$email...");
273 529
274 530 $ret = array(); $ret = array();
 
... ... function rg_user_info($db, $uid, $user, $email)
318 574
319 575 $rg_user_info_cache[$key] = $row; $rg_user_info_cache[$key] = $row;
320 576
577 rg_prof_end("user_info");
321 578 return $row; return $row;
322 579 } }
323 580
File inc/user/create.php changed (mode: 100644) (index 02a730e..8e3357d)
... ... if ($doit == 1) {
50 50 $_u['rights'] = "C"; $_u['rights'] = "C";
51 51 $_u['session_time'] = $session_time; $_u['session_time'] = $session_time;
52 52 $_u['confirm_token'] = rg_id(20); $_u['confirm_token'] = rg_id(20);
53 if (!rg_user_edit($db, $_u)) {
53 if (rg_user_edit($db, $_u) === FALSE) {
54 54 $errmsg[] = "Cannot add user (" . rg_user_error() . ")."; $errmsg[] = "Cannot add user (" . rg_user_error() . ").";
55 55 break; break;
56 56 } }
File inc/user/repo-page.php changed (mode: 100644) (index ddb649e..af6d253)
... ... $repo_more['max_commit_size'] = $ri['max_commit_size'] == 0 ? "unlimited" : rg_1
63 63 $repo_more['max_users'] = $ri['max_users'] == 0 ? "unlimited" : rg_1000($ri['max_users']); $repo_more['max_users'] = $ri['max_users'] == 0 ? "unlimited" : rg_1000($ri['max_users']);
64 64 $repo_more['hints'] = ""; $repo_more['hints'] = "";
65 65
66 $repo_dir = rg_repo_name2base($rr) . $rr['repo'] . ".git";
67 rg_log("repo_dir=$repo_dir");
68 putenv("GIT_DIR=$repo_dir");
66 $repo_path = rg_repo_path_by_id($ri['uid'], $ri['name']);
67 rg_log("repo_path=$repo_path");
68 putenv("GIT_DIR=$repo_path");
69 69
70 70 $repo_more['repo_body'] = ""; $repo_more['repo_body'] = "";
71 71 $repo_more['repo_right'] = ""; $repo_more['repo_right'] = "";
 
... ... if (strcmp($subop, "history") == 0) {
101 101 $ref = $type_ref['ref_path']; $ref = $type_ref['ref_path'];
102 102 $repo_more = array_merge($repo_more, $type_ref); $repo_more = array_merge($repo_more, $type_ref);
103 103
104 $bt = rg_git_branches_and_tags($repo_dir, $repo_more['url_repo'],
104 $bt = rg_git_branches_and_tags($repo_path, $repo_more['url_repo'],
105 105 $type_ref['ref_url']); $type_ref['ref_url']);
106 106 //rg_log("DEBUG: repo_more: " . rg_array2string($repo_more)); //rg_log("DEBUG: repo_more: " . rg_array2string($repo_more));
107 107 $repo_more = array_merge($repo_more, $bt); $repo_more = array_merge($repo_more, $bt);
File inc/user/repo/admin/edit/edit.php changed (mode: 100644) (index 078bd33..4396929)
... ... if ($doit == 1) {
37 37 $ri['description'] = $description; // TODO: filter $ri['description'] = $description; // TODO: filter
38 38 $ri['default_rights'] = $rights; // TODO: filter $ri['default_rights'] = $rights; // TODO: filter
39 39 $ri['max_users'] = $max_users; $ri['max_users'] = $max_users;
40 $_r = rg_repo_update($db, $_ui['username'], $ri);
40 $_r = rg_repo_update($db, $_ui, $ri);
41 41 if ($_r === FALSE) { if ($_r === FALSE) {
42 42 $errmsg[] = rg_repo_error(); $errmsg[] = rg_repo_error();
43 43 break; break;
File inc/util.inc.php changed (mode: 100644) (index 30d9412..675c187)
... ... function rg_chars_allow($name, $allowed_regexp)
268 268 */ */
269 269 function rg_rmdir($dir) function rg_rmdir($dir)
270 270 { {
271 rg_log("rmdir: $dir");
272
273 if (!is_dir($dir)) {
274 rg_util_set_error("asked to remove a non-existing dir ($dir)");
275 return FALSE;
276 }
277
271 278 $scan = glob($dir . "/*"); $scan = glob($dir . "/*");
272 279 if ($scan === FALSE) { if ($scan === FALSE) {
273 280 rg_util_set_error("invalid pattern [$dir/*]"); rg_util_set_error("invalid pattern [$dir/*]");
 
... ... function rg_rmdir($dir)
275 282 } }
276 283
277 284 if (count($scan) > 0) { if (count($scan) > 0) {
285 $all_good = TRUE;
278 286 foreach ($scan as $junk => $path) { foreach ($scan as $junk => $path) {
279 if (!@unlink($path)) {
287 if (is_dir($path)) {
288 $r = rg_rmdir($path);
289 if ($r !== TRUE)
290 return FALSE;
291
292 continue;
293 }
294
295 if (!unlink($path)) {
280 296 rg_util_set_error("cannot remove [$path] ($php_errormsg)"); rg_util_set_error("cannot remove [$path] ($php_errormsg)");
281 297 return FALSE; return FALSE;
282 298 } }
283 299 } }
284 300 } }
285 301
286 if (!@rmdir($dir)) {
302 if (!rmdir($dir)) {
287 303 rg_util_set_error("cannot remove main dir ($php_errormsg)"); rg_util_set_error("cannot remove main dir ($php_errormsg)");
288 304 return FALSE; return FALSE;
289 305 } }
 
... ... function rg_exec($cmd)
686 702 $ret = array(); $ret = array();
687 703 $ret['ok'] = 0; $ret['ok'] = 0;
688 704 $ret['errmsg'] = ""; $ret['errmsg'] = "";
705 $ret['code'] = 65000; // fake code
689 706 do { do {
690 707 $desc = array( $desc = array(
691 708 0 => array("pipe", "r"), 0 => array("pipe", "r"),
 
... ... function rg_exec($cmd)
714 731 // . ", revents: " . rg_array2string($revents)); // . ", revents: " . rg_array2string($revents));
715 732
716 733 foreach ($revents as $fd) { foreach ($revents as $fd) {
734 if (!empty($ret['errmsg']))
735 break;
736
717 737 //rg_log("Event on fd $fd!"); //rg_log("Event on fd $fd!");
718 738 if (feof($fd)) { if (feof($fd)) {
719 739 //rg_log("eof on fd $fd!"); //rg_log("eof on fd $fd!");
 
... ... function rg_exec($cmd)
736 756 else if ($fd === $pipes[1]) else if ($fd === $pipes[1])
737 757 $ret['data'] .= $_d; $ret['data'] .= $_d;
738 758 } }
759
760 if (!empty($ret['errmsg']))
761 break;
739 762 } }
740 763 $stderr = trim($stderr); $stderr = trim($stderr);
741 764 $ret['data'] = trim($ret['data']); $ret['data'] = trim($ret['data']);
 
... ... function rg_exec($cmd)
744 767 fclose($pipes[$i]); fclose($pipes[$i]);
745 768
746 769 $err = proc_close($a); $err = proc_close($a);
747 if (empty($errmsg) && ($err == 0))
748 $ret['ok'] = 1;
749 else
770 if ($err != 0) {
771 $ret['code'] = $err;
750 772 $ret['errmsg'] = "code " . $err . ": " . $stderr; $ret['errmsg'] = "code " . $err . ": " . $stderr;
773 }
774
775 if (empty($ret['errmsg'])) {
776 $ret['code'] = 0;
777 $ret['ok'] = 1;
778 }
751 779 } while (0); } while (0);
752 780
753 781 rg_prof_end("exec($cmd)"); rg_prof_end("exec($cmd)");
 
... ... function rg_array2string($a)
805 833 */ */
806 834 function rg_dir_load($dir) function rg_dir_load($dir)
807 835 { {
808 global $php_errormsg;
809
810 836 $ret = array(); $ret = array();
811 837 if (!file_exists($dir)) { if (!file_exists($dir)) {
812 838 rg_log("$dir does not exists!"); rg_log("$dir does not exists!");
 
... ... function rg_dir_load_deep($dir)
858 884 */ */
859 885 function rg_copy_tree($src, $dst, $mask) function rg_copy_tree($src, $dst, $mask)
860 886 { {
861 global $php_errormsg;
862
863 887 if (!is_dir($dst)) { if (!is_dir($dst)) {
864 888 $r = @mkdir($dst, $mask); $r = @mkdir($dst, $mask);
865 889 if ($r !== TRUE) { if ($r !== TRUE) {
File root/index.php changed (mode: 100644) (index 9a4ac39..3acb327)
... ... include_once($INC . "/token.inc.php");
16 16 include_once($INC . "/prof.inc.php"); 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 include_once($INC . "/fixes.inc.php");
19 20
20 21 rg_prof_start("MAIN"); rg_prof_start("MAIN");
21 22
 
... ... if ($db === FALSE) {
95 96
96 97 while (1) { while (1) {
97 98 $r = rg_sql_struct_update_needed($db); $r = rg_sql_struct_update_needed($db);
98 if ($r === FALSE)
99 break;
99 if ($r === FALSE) {
100 $r = rg_fixes_needed($db);
101 if ($r === FALSE)
102 break;
103 }
100 104
101 rg_log("Schema is not up-to-date! Sleep 1 second...");
105 rg_log("Schema/fixes is not up-to-date! Sleep 1 second...");
102 106 sleep(1); sleep(1);
103 107 } }
104 108
File root/themes/default/mail/user/repo/new.body.txt changed (mode: 100644) (index 1dd9740..60dae36)
1 1 Hello! Hello!
2 2
3 Repo '@@name@@' was created.
3 Repository '@@name@@' was created.
4 4
5 5 Anonymous rights: Anonymous rights:
6 6 @@rights@@ @@rights@@
File scripts/cron.php changed (mode: 100644) (index 0acf8f8..14bf6af)
... ... require_once($INC . "/sql.inc.php");
14 14 require_once($INC . "/struct.inc.php"); 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 require_once($INC . "/fixes.inc.php");
17 18
18 19 rg_log_set_file($rg_log_dir . "/cron.log"); rg_log_set_file($rg_log_dir . "/cron.log");
19 20
 
... ... $r = rg_sql_struct_update($db, 0);
33 34 if ($r !== TRUE) if ($r !== TRUE)
34 35 exit(1); exit(1);
35 36
37 $r = rg_fixes_update($db);
38 if ($r !== TRUE)
39 exit(1);
40
36 41 if (date("H") == 4) { if (date("H") == 4) {
37 rg_log("Compute repository sizes if dirty...");
38 // delete 'dirty' files
39 $sql = "SELECT a.*, b.username, b.organization"
40 . " FROM repos a, users b"
41 . " WHERE a.uid = b.uid";
42 $res = rg_sql_query($db, $sql);
43 if ($res === FALSE) {
44 // TODO: rg_internal_error? it must notify me in case of problems
45 rg_log("Cannot run query (" . rg_sql_error() . ")!");
46 } else {
42 do {
43 rg_log("Compute repository sizes if dirty...");
44 // delete 'dirty' files
45 $sql = "SELECT uid, repo_id FROM repos";
46 $res = rg_sql_query($db, $sql);
47 if ($res === FALSE) {
48 // TODO: rg_internal_error? it must notify me in case of problems
49 rg_log("Cannot run query (" . rg_sql_error() . ")!");
50 break;
51 }
52
47 53 while (($row = rg_sql_fetch_array($res))) { while (($row = rg_sql_fetch_array($res))) {
48 $prefix = ($row['organization'] == 1) ? "" : "/user";
49
50 rg_log("Processing $prefix/" . $row['username']
51 . "/" . $row['name'] . "...");
52 $_rr = array("prefix" => $prefix,
53 "user" => $row['username'],
54 "repo" => $row['name']);
55 $repo_path = rg_repo_name2base($_rr) . $row['name'] . ".git";
54 rg_log("Processing repo " . $row['repo_id'] . "...");
55 $repo_path = rg_repo_path_by_id($row['uid'], $row['repo_id']);
56 56 $disk_used_mb = rg_repo_disk_mb($repo_path); $disk_used_mb = rg_repo_disk_mb($repo_path);
57 57 $sql = "UPDATE repos SET disk_used_mb = $disk_used_mb" $sql = "UPDATE repos SET disk_used_mb = $disk_used_mb"
58 58 . " WHERE repo_id = " . $row['repo_id']; . " WHERE repo_id = " . $row['repo_id'];
59 59 $res2 = rg_sql_query($db, $sql); $res2 = rg_sql_query($db, $sql);
60 60 if ($res2 === FALSE) { if ($res2 === FALSE) {
61 61 rg_log("Cannot run query!"); rg_log("Cannot run query!");
62 } else {
63 if (file_exists($repo_path . "/rocketgit/dirty"))
64 @unlink($repo_path . "/rocketgit/dirty");
65 rg_sql_free_result($res2);
62 break;
66 63 } }
64
65 if (file_exists($repo_path . "/rocketgit/dirty"))
66 @unlink($repo_path . "/rocketgit/dirty");
67 rg_sql_free_result($res2);
67 68 } }
68 69 rg_sql_free_result($res); rg_sql_free_result($res);
69 }
70 } while (0);
71
72 do {
73 rg_log("Compute repository sizes per user...");
74 $sql = "SELECT SUM(disk_used_mb) AS disk_used_mb, uid"
75 . " FROM repos"
76 . " GROUP BY uid";
77 $res = rg_sql_query($db, $sql);
78 if ($res === FALSE) {
79 rg_log("Cannot run query (" . rg_sql_error() . ")!");
80 break;
81 }
70 82
71 rg_log("Compute repository sizes per user...");
72 $sql = "SELECT SUM(disk_used_mb) AS disk_used_mb, uid FROM repos"
73 . " GROUP BY uid";
74 $res = rg_sql_query($db, $sql);
75 if ($res === FALSE) {
76 rg_log("Cannot run query (" . rg_sql_error() . ")!");
77 } else {
78 83 while (($row = rg_sql_fetch_array($res))) { while (($row = rg_sql_fetch_array($res))) {
79 84 $sql = "UPDATE users" $sql = "UPDATE users"
80 85 . " SET disk_used_mb = " . $row['disk_used_mb'] . " SET disk_used_mb = " . $row['disk_used_mb']
 
... ... if (date("H") == 4) {
83 88 rg_sql_free_result($res2); rg_sql_free_result($res2);
84 89 } }
85 90 rg_sql_free_result($res); rg_sql_free_result($res);
86 }
91 } while (0);
87 92 } }
88 93
89 94 // TODO // TODO
File scripts/events.php changed (mode: 100644) (index 5553891..f4fac72)
... ... require_once($INC . "/prof.inc.php");
22 22 require_once($INC . "/mr.inc.php"); require_once($INC . "/mr.inc.php");
23 23 require_once($INC . "/keys.inc.php"); require_once($INC . "/keys.inc.php");
24 24 require_once($INC . "/user.inc.php"); require_once($INC . "/user.inc.php");
25 require_once($INC . "/fixes.inc.php");
25 26
26 27 rg_prof_start("MAIN"); rg_prof_start("MAIN");
27 28
 
... ... $r = rg_sql_struct_update($db, 0);
43 44 if ($r !== TRUE) if ($r !== TRUE)
44 45 exit(1); exit(1);
45 46
47 $r = rg_fixes_update($db);
48 if ($r !== TRUE)
49 exit(1);
50
46 51 // Remove the socket, else we will get error // Remove the socket, else we will get error
47 52 if (file_exists($rg_event_socket)) if (file_exists($rg_event_socket))
48 53 unlink($rg_event_socket); unlink($rg_event_socket);
File scripts/q.php changed (mode: 100644) (index b5c3993..c213f44)
... ... require_once($INC . "/struct.inc.php");
17 17 require_once($INC . "/repo.inc.php"); 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 require_once($INC . "/fixes.inc.php");
20 21
21 22 rg_prof_start("MAIN"); rg_prof_start("MAIN");
22 23
 
... ... $r = rg_sql_struct_update($db, 0);
38 39 if ($r !== TRUE) if ($r !== TRUE)
39 40 exit(1); exit(1);
40 41
42 $r = rg_fixes_update($db);
43 if ($r !== TRUE)
44 exit(1);
45
41 46 $original_mtime = filemtime(__FILE__); $original_mtime = filemtime(__FILE__);
42 47
43 48 // Check our mtime so we can upgrade the software and this script will restart. // Check our mtime so we can upgrade the software and this script will restart.
 
... ... while (TRUE) {
73 78 rg_log("\tCannot query (" . rg_sql_error() . ")!"); rg_log("\tCannot query (" . rg_sql_error() . ")!");
74 79 exit(1); exit(1);
75 80 } }
76 while (($row = rg_sql_fetch_array($res))) {
77 $rr = array(
78 "prefix" => ($row['organization'] == 1) ? "" : "/user",
79 "user" => $row['username'],
80 "repo" => $row['name']);
81
82 rg_log("\tProcessing rr: " . rg_array2string($rr));
83
84 $dst = rg_repo_name2base($rr) . $row['name'] . ".git";
85 if ($row['master'] == 0) {
86 $r = rg_git_init($dst);
87 if ($r === FALSE) {
88 rg_log("\tCannot init master (" . rg_git_error() . ")!");
89 continue;
90 }
91
92 rg_repo_git_done($db, $row['repo_id']);
93 } else {
94 $rr = array("repo_id" => $row['master']);
95 $mi = rg_repo_info($db, $rr);
96 if ($mi['exists'] != 1) {
97 rg_log("\tCannot find master (" . rg_repo_error() . ")!");
98 continue;
99 }
100
101 $ui = rg_user_info($db, $mi['uid'], "", "");
102 if ($ui['ok'] != 1) {
103 rg_log("\tCannot lookup uid "
104 . $mi['uid'] . " (" . rg_user_error() . ")!");
105 continue;
106 }
107
108 $rr = array(
109 "prefix" => ($mi['organization'] == 1) ? "" : "/user",
110 "user" => $ui['username'],
111 "repo" => $mi['name']);
112 $src = rg_repo_name2base($rr) . $mi['name'] . ".git";
113 $r = rg_git_clone($src, $dst);
114 if ($r === FALSE) {
115 rg_log("\tCould not create repo (" . rg_git_error() . ")!");
116 continue;
117 }
118
119 rg_repo_git_done($db, $row['repo_id']);
120 }
121 }
81
82 while (($row = rg_sql_fetch_array($res)))
83 rg_repo_storage_create($db, $row);
84
122 85 rg_sql_free_result($res); rg_sql_free_result($res);
123 86
124 87 sleep(1); sleep(1);
File scripts/remote.php changed (mode: 100644) (index cb73cce..acebfa6)
... ... require_once($INC . "/repo.inc.php");
15 15 require_once($INC . "/prof.inc.php"); 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 require_once($INC . "/fixes.inc.php");
18 19
19 20 rg_prof_start("remote.php"); rg_prof_start("remote.php");
20 21
 
... ... $r = rg_sql_struct_update($db, 0);
55 56 if ($r !== TRUE) if ($r !== TRUE)
56 57 fatal("We are in a short maintenance. Try again later."); fatal("We are in a short maintenance. Try again later.");
57 58
59 $r = rg_fixes_update($db);
60 if ($r !== TRUE)
61 fatal("We are in a short maintenance. Try again later.");
62
58 63 if (isset($_SERVER['SSH_CONNECTION'])) { if (isset($_SERVER['SSH_CONNECTION'])) {
59 64 rg_log("SSH connection: " . $_SERVER['SSH_CONNECTION']); rg_log("SSH connection: " . $_SERVER['SSH_CONNECTION']);
60 65
 
... ... if (isset($_SERVER['SSH_CONNECTION'])) {
62 67 $host = ""; $host = "";
63 68
64 69 // first parameter must be uid of the user // first parameter must be uid of the user
65 $uid = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 0;
66 if ($uid == 0)
70 $conn_uid = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 0;
71 if ($conn_uid == 0)
67 72 fatal("uid not provided!"); fatal("uid not provided!");
68 rg_log("\tuid is $uid.");
73 rg_log("\tuid is $conn_uid.");
69 74
70 75 // second parameter must be the ssh key id // second parameter must be the ssh key id
71 76 $key_id = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : 0; $key_id = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : 0;
 
... ... if (isset($_SERVER['SSH_CONNECTION'])) {
77 82 $cmd_repo = ""; $cmd_repo = "";
78 83 else else
79 84 $cmd_repo = trim($_SERVER['SSH_ORIGINAL_COMMAND']); $cmd_repo = trim($_SERVER['SSH_ORIGINAL_COMMAND']);
80 rg_ssh_dispatch($db, $uid, $cmd_repo);
85 rg_ssh_dispatch($db, $conn_uid, $cmd_repo);
81 86
82 87 $ssh_client = getenv("SSH_CLIENT"); $ssh_client = getenv("SSH_CLIENT");
83 88 $_t = explode(" ", $ssh_client); $_t = explode(" ", $ssh_client);
 
... ... if (isset($_SERVER['SSH_CONNECTION'])) {
91 96 rg_log("git-daemon connection..."); rg_log("git-daemon connection...");
92 97
93 98 // we have no client info // we have no client info
94 $uid = 0;
99 $conn_uid = 0;
95 100 $key_id = 0; $key_id = 0;
96 101
97 102 $f = @fopen("php://stdin", "r"); $f = @fopen("php://stdin", "r");
 
... ... if (strcmp($_t[0], "user") == 0) {
151 156 rg_log("host=[$host] cmd=[$cmd] prefix=[$prefix] user=[$user] repo=[$repo]."); rg_log("host=[$host] cmd=[$cmd] prefix=[$prefix] user=[$user] repo=[$repo].");
152 157
153 158 // validity/security checks // validity/security checks
159 // Load info about the user
154 160 if (rg_user_ok($user) !== TRUE) if (rg_user_ok($user) !== TRUE)
155 161 fatal("User [$user] is invalid (" . rg_user_error() . ")!"); fatal("User [$user] is invalid (" . rg_user_error() . ")!");
156
157 if (rg_repo_ok($repo) !== TRUE)
158 fatal("Repo [$repo] is invalid (" . rg_repo_error() . ")");
162 $owner_ui = rg_user_info($db, 0, $user, "");
163 if ($owner_ui['ok'] != 1)
164 fatal("Internal problems. Try again later, please.");
165 if ($owner_ui['exists'] != 1)
166 fatal("User does not exists.");
159 167
160 168 // Loading info about the repository // Loading info about the repository
161 $rr = array("prefix" => $prefix, "user" => $user, "repo" => $repo);
162 $ri = rg_repo_info($db, $rr);
169 if (rg_repo_ok($repo) !== TRUE)
170 fatal("Repo is invalid (" . rg_repo_error() . ")");
171 $ri = rg_repo_info($db, $owner_ui['uid'], 0, $repo);
163 172 if ($ri['ok'] != 1) if ($ri['ok'] != 1)
164 fatal("Temporary error!");
173 fatal("Internal problems. Try again later, please.");
165 174 if ($ri['exists'] != 1) if ($ri['exists'] != 1)
166 fatal("Repo does not exists!");
175 fatal("Repo does not exists.");
167 176 if ($ri['deleted'] == 1) if ($ri['deleted'] == 1)
168 177 fatal("Repo was deleted!"); fatal("Repo was deleted!");
169 178
179 $repo_path = rg_repo_path_by_id($owner_ui['uid'], $ri['repo_id']);
180 rg_log("repo_path=$repo_path.");
181
182 // TODO: signal user that the repo moved and provide a hint how to move
183
170 184 // We must not use here the rg_repo_allow function because we need // We must not use here the rg_repo_allow function because we need
171 185 // $rights variable below. // $rights variable below.
172 $ret = rg_repo_rights_get($db, $ri, $uid, 0);
186 $ret = rg_repo_rights_get($db, $ri, $conn_uid, 0);
173 187 if ($ret['ok'] !== 1) if ($ret['ok'] !== 1)
174 188 fatal("Internal error (rights_get)"); fatal("Internal error (rights_get)");
175 189 $rights = $ret['rights']; $rights = $ret['rights'];
 
... ... if (rg_rights_allow($rights, $needed_rights) === FALSE)
183 197 // TODO: limit io // TODO: limit io
184 198 // TODO: put process in a cgroup? // TODO: put process in a cgroup?
185 199
186 $repo_base = rg_repo_name2base($rr);
187 $repo_path = $repo_base . $repo . ".git";
188 rg_log("repo_path=$repo_path.");
189 200
190 201 if (($push == 1) && rg_repo_over_limit($ri)) if (($push == 1) && rg_repo_over_limit($ri))
191 202 fatal("Cannot push: repo is over limit" fatal("Cannot push: repo is over limit"
 
... ... if (($push == 1) && rg_repo_over_limit($ri))
193 204 . $ri['disk_quota_mb'] . "MiB)"); . $ri['disk_quota_mb'] . "MiB)");
194 205
195 206 // Put in environment all we need // Put in environment all we need
196 putenv("ROCKETGIT_UID=" . $uid);
207 putenv("ROCKETGIT_UID=" . $conn_uid);
197 208 putenv("ROCKETGIT_KEY_ID=" . $key_id); putenv("ROCKETGIT_KEY_ID=" . $key_id);
198 209 putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']); putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']);
199 210 putenv("ROCKETGIT_REPO_RIGHTS=" . $rights); putenv("ROCKETGIT_REPO_RIGHTS=" . $rights);
File tests/.gitignore added (mode: 100644) (index 0000000..f229ab9)
1 base
2 ubase
3 mr_queue
4 *.log
5 tree1.copy
6 repos
File tests/Makefile changed (mode: 100644) (index 8d402f4..63c50dc)
1 tests := util db keys repo rights state user git prof bug log \
1 tests := util db keys user repo rights state git prof bug log \
2 2 hook_update hook_update_anon bug event hook_update hook_update_anon bug event
3 3 .PHONY: $(tests) .PHONY: $(tests)
4 4
File tests/bug.php changed (mode: 100644) (index d92ca6d..b0b7b48)
... ... require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/bug.inc.php"); 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 require_once($INC . "/fixes.inc.php");
10 11
11 12 rg_log_set_file("bug.log"); rg_log_set_file("bug.log");
12 13
 
... ... if ($db === FALSE) {
18 19 exit(1); exit(1);
19 20 } }
20 21
22 $r = rg_state_set($db, "schema_version", "0");
23 if ($r !== TRUE) {
24 echo "Cannot reset schema (" . rg_state_error() . ")!\n";
25 exit(1);
26 }
27
21 28 $r = rg_sql_struct_update($db, RG_DROP_TABLES|RG_IGNORE_ERRORS); $r = rg_sql_struct_update($db, RG_DROP_TABLES|RG_IGNORE_ERRORS);
22 29 if ($r !== TRUE) { if ($r !== TRUE) {
23 30 rg_log("Cannot create struct (" . rg_sql_error() . ")!"); rg_log("Cannot create struct (" . rg_sql_error() . ")!");
24 31 exit(1); exit(1);
25 32 } }
26 33
34 $r = rg_fixes_update($db);
35 if ($r !== TRUE) {
36 rg_log("Cannot apply fixes!");
37 exit(1);
38 }
39
40 $r = rg_sql_struct_slaves_update($db);
41 if ($r !== TRUE) {
42 rg_log("Cannot create slaves!");
43 exit(1);
44 }
45
27 46 // defaults // defaults
28 47 $repo_id = 100; $repo_id = 100;
29 48 $uid = 1; $uid = 1;
File tests/event.php changed (mode: 100644) (index d55cd6a..471bdfd)
... ... require_once($INC . "/init.inc.php");
10 10 require_once($INC . "/events.inc.php"); 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 require_once($INC . "/fixes.inc.php");
13 14
14 15 rg_log_set_file("event.log"); rg_log_set_file("event.log");
15 16
 
... ... if ($db === FALSE) {
21 22 exit(1); exit(1);
22 23 } }
23 24
25 $r = rg_state_set($db, "schema_version", "0");
26 if ($r !== TRUE) {
27 echo "Cannot reset schema (" . rg_state_error() . ")!\n";
28 exit(1);
29 }
30
24 31 $r = rg_sql_struct_update($db, RG_DROP_TABLES|RG_IGNORE_ERRORS); $r = rg_sql_struct_update($db, RG_DROP_TABLES|RG_IGNORE_ERRORS);
25 32 if ($r !== TRUE) { if ($r !== TRUE) {
26 33 rg_log("Cannot create struct (" . rg_sql_error() . ")!"); rg_log("Cannot create struct (" . rg_sql_error() . ")!");
27 34 exit(1); exit(1);
28 35 } }
29 36
30 $sql = "TRUNCATE TABLE events";
31 $res = rg_sql_query($db, $sql);
32 if ($res === FALSE) {
33 echo "Cannot truncate table!\n";
37 $r = rg_fixes_update($db);
38 if ($r !== TRUE) {
39 rg_log("Cannot aply fixes!");
40 exit(1);
41 }
42
43 $r = rg_sql_struct_slaves_update($db);
44 if ($r !== TRUE) {
45 rg_log("Cannot create slaves!");
34 46 exit(1); exit(1);
35 47 } }
36 rg_sql_free_result($res);
37 48
38 49 /* /*
39 50 * This function will generate an array of sub-events * This function will generate an array of sub-events
 
... ... function notif_new_repo($db, $ev)
45 56 $ret = array(); $ret = array();
46 57
47 58 // Send mail to the owner // Send mail to the owner
48 $ret[] = array_merge($ev, "category" => 1);
59 $ret[] = array_merge($ev, array("category" => 1, "prio" => 1));
49 60
50 61 // Send mail to admin // Send mail to admin
51 $ret[] = array_merge($ev, "category" => 2);
62 $ret[] = array_merge($ev, array("category" => 2, "prio" => 1));
52 63
53 64 // Other junk // Other junk
54 $ret[] = array_merge($ev, "category" => 3);
65 $ret[] = array_merge($ev, array("category" => 3, "prio" => 1));
55 66
56 67 return $ret; return $ret;
57 68 } }
 
... ... if ($r !== TRUE) {
67 78
68 79 // defaults // defaults
69 80 $event = array( $event = array(
70 "type" => 0,
71 "data" => array(
72 "category" => 1,
73 "repo_id" => 200
74 )
81 "prio" => 1,
82 "category" => 1,
83 "repo_id" => 200
75 84 ); );
76 85
77 86 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
 
... ... if ($r !== TRUE) {
81 90 } }
82 91
83 92 $r = rg_event_process_queue($db); $r = rg_event_process_queue($db);
84 if ($r !== TRUE) {
93 if ($r === FALSE) {
85 94 echo "Cannot process queue (" . rg_event_error() . ")!\n"; echo "Cannot process queue (" . rg_event_error() . ")!\n";
86 95 exit(1); exit(1);
87 96 } }
File tests/git.php changed (mode: 100644) (index 22cf8aa..ccf0775)
... ... if ($r !== TRUE) {
17 17 exit(1); exit(1);
18 18 } }
19 19
20 /*
20 21 echo "[*] Populate repo...\n"; echo "[*] Populate repo...\n";
21 22 file_put_contents("git.tmp/a", "aaa"); file_put_contents("git.tmp/a", "aaa");
22 23 system("cd git.tmp; git commit -a -m \"aa\"; git checkout -n b1"); system("cd git.tmp; git commit -a -m \"aa\"; git checkout -n b1");
23 24 // This is a bare repo! Could not work! // This is a bare repo! Could not work!
25 */
24 26
25 27 echo "[*] Testing rg_git_refs...\n"; echo "[*] Testing rg_git_refs...\n";
26 28 $refs = rg_git_refs("git.tmp"); $refs = rg_git_refs("git.tmp");
File tests/hook_update_anon.sh changed (mode: 100755) (index f2a299c..6699ffe)
... ... git clone hook_update_anon_dest.git hook_update_anon_src.git
16 16
17 17 cd hook_update_anon_src.git cd hook_update_anon_src.git
18 18
19 mkdir -p "${C}/mr_queue"
20
19 21 export ROCKETGIT_REPO_ID=2000000000 export ROCKETGIT_REPO_ID=2000000000
20 22 export ROCKETGIT_IP="IP" export ROCKETGIT_IP="IP"
21 23 export GIT_NAMESPACE="abcdefgh" # we have to set it manually export GIT_NAMESPACE="abcdefgh" # we have to set it manually
File tests/hook_update_anon_nm.sh changed (mode: 100755) (index 35296c0..bc64810)
... ... git clone ${P}_dest.git ${P}_src.git
18 18
19 19 cd ${P}_src.git cd ${P}_src.git
20 20
21 mkdir -p "${C}/mr_queue"
22
21 23 export ROCKETGIT_REPO_ID=2000000001 export ROCKETGIT_REPO_ID=2000000001
22 24 export ROCKETGIT_IP="IP" export ROCKETGIT_IP="IP"
23 25 export GIT_NAMESPACE="abcdefgh" # we have to set it manually export GIT_NAMESPACE="abcdefgh" # we have to set it manually
File tests/keys.php changed (mode: 100644) (index 8964324..10a1832)
... ... require_once($INC . "/util.inc.php");
8 8 require_once($INC . "/keys.inc.php"); 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 require_once($INC . "/fixes.inc.php");
11 12
12 13 rg_log_set_file("keys.log"); rg_log_set_file("keys.log");
13 14
 
... ... if ($db === FALSE) {
19 20 exit(1); exit(1);
20 21 } }
21 22
23 $r = rg_state_set($db, "schema_version", "0");
24 if ($r !== TRUE) {
25 echo "Cannot reset schema (" . rg_state_error() . ")!\n";
26 exit(1);
27 }
28
22 29 $r = rg_sql_struct_update($db, RG_DROP_TABLES); $r = rg_sql_struct_update($db, RG_DROP_TABLES);
23 30 if ($r !== TRUE) { if ($r !== TRUE) {
24 31 echo "Cannot create structure (" . rg_sql_error() . ")!\n"; echo "Cannot create structure (" . rg_sql_error() . ")!\n";
25 32 exit(1); exit(1);
26 33 } }
27 34
35 $r = rg_fixes_update($db);
36 if ($r !== TRUE) {
37 echo "Cannot apply fixes!\n";
38 exit(1);
39 }
40
41 $r = rg_sql_struct_slaves_update($db);
42 if ($r !== TRUE) {
43 rg_log("Cannot create slaves!");
44 exit(1);
45 }
46
28 47 // clean all old keys // clean all old keys
29 48 $sql = "DELETE FROM keys"; $sql = "DELETE FROM keys";
30 49 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
31 50 rg_sql_free_result($res); rg_sql_free_result($res);
32 51
52 $rg_ui = array("uid" => 1, "is_admin" => 0, "email" => "test@embedromix.ro");
53
33 54 // insert a key 1 // insert a key 1
34 $rg_ui = array("uid" => 1, "is_admin" => 0);
35 55 $key = "aaa 'bbb' first_key"; $key = "aaa 'bbb' first_key";
36 56 $key_id1 = rg_keys_add($db, $rg_ui, $key); $key_id1 = rg_keys_add($db, $rg_ui, $key);
37 57 if ($key_id1 === FALSE) { if ($key_id1 === FALSE) {
 
... ... if ($key_id1 === FALSE) {
40 60 } }
41 61
42 62 // insert a key 2 // insert a key 2
43 $rg_ui = array("uid" => 2, "is_admin" => 0);
63 $rg_ui['uid'] = 2;
44 64 $key = "aaa 'bbb' second_key"; $key = "aaa 'bbb' second_key";
45 65 $key_id2 = rg_keys_add($db, $rg_ui, $key); $key_id2 = rg_keys_add($db, $rg_ui, $key);
46 66 if ($key_id2 === FALSE) { if ($key_id2 === FALSE) {
 
... ... if ($r === FALSE) {
60 80 } }
61 81 $c = @file_get_contents("afile.txt"); $c = @file_get_contents("afile.txt");
62 82 if ($c === FALSE) { if ($c === FALSE) {
63 echo "Cannot regenerate file: " . rg_keys_error() . "!\n";
83 echo "Cannot regenerate file (afile.txt not found)!\n";
64 84 exit(1); exit(1);
65 85 } }
66 86 $e = "command=\"/usr/bin/php " $e = "command=\"/usr/bin/php "
 
... ... if (strcmp($c, $e) != 0) {
80 100
81 101
82 102 // delete a key // delete a key
83 $rg_ui = array("uid" => 1, "is_admin" => 0);
103 $rg_ui['uid'] = 1;
84 104 $flags = array(); $flags = array();
85 105 $r = rg_keys_remove($db, $rg_ui, $key_id1, $flags); $r = rg_keys_remove($db, $rg_ui, $key_id1, $flags);
86 106 if ($r === FALSE) { if ($r === FALSE) {
 
... ... if ($r === FALSE) {
92 112 // test rg_max_ssh_keys // test rg_max_ssh_keys
93 113 $rg_max_ssh_keys = 1; $rg_max_ssh_keys = 1;
94 114 // insert a key - should succeed // insert a key - should succeed
95 $rg_ui = array("uid" => 10, "is_admin" => 0);
115 $rg_ui['uid'] = 10;
96 116 $key = "aaa 'bbb' first_key"; $key = "aaa 'bbb' first_key";
97 117 $key_id1 = rg_keys_add($db, $rg_ui, $key); $key_id1 = rg_keys_add($db, $rg_ui, $key);
98 118 if ($key_id1 === FALSE) { if ($key_id1 === FALSE) {
99 119 echo "Cannot add key 1 (" . rg_keys_error() . ")!\n"; echo "Cannot add key 1 (" . rg_keys_error() . ")!\n";
100 120 exit(1); exit(1);
101 121 } }
102 // insert a key - must fail
103 $rg_ui = array("uid" => 10, "is_admin" => 0);
122 // insert a key - must fail because overlimit
104 123 $key = "aaa 'bbb' second_key"; $key = "aaa 'bbb' second_key";
105 124 $key_id2 = rg_keys_add($db, $rg_ui, $key); $key_id2 = rg_keys_add($db, $rg_ui, $key);
106 125 if ($key_id2 !== FALSE) { if ($key_id2 !== FALSE) {
File tests/repo.php changed (mode: 100644) (index c5880f9..4663b0c)
... ... require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/repo.inc.php"); require_once($INC . "/repo.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 require_once($INC . "/fixes.inc.php");
10 11
11 12 rg_log_set_file("repo.log"); rg_log_set_file("repo.log");
12 13
13 14 $rg_sql_debug = 1; $rg_sql_debug = 1;
14 15
15 16 // defaults // defaults
17 $rg_scripts = dirname(dirname(__FILE__));
16 18 $rg_repo_max_len = 100; $rg_repo_max_len = 100;
17 $rg_repos = "/base";
19 $rg_repos = "base";
18 20
19 21
20 rg_log("name2base1");
21 $rr = array("prefix" => "/user", "user" => "user1", "repo" => "junk");
22 $e = "/base/users/u/s/user1/repos/";
23 $c = rg_repo_name2base($rr);
22 rg_log("rg_repo_path 1");
23 $e = $rg_repos . "/by_id/11/22/33/44/11223344/repos/by_id/55.git";
24 $c = rg_repo_path_by_id(0x11223344, 55);
24 25 if (strcmp($c, $e) != 0) { if (strcmp($c, $e) != 0) {
25 rg_log("name2base1 is not working correctly: c=$c e=$e.");
26 rg_log("rg_repo_path 1 is not working correctly: c=$c e=$e.");
26 27 exit(1); exit(1);
27 28 } }
28 29
29 rg_log("name2base2");
30 $rr = array("prefix" => "", "user" => "u", "repo" => "junk");
31 $e = "/base/orgs/u/_/u/repos/";
32 $c = rg_repo_name2base($rr);
30 rg_log("rg_repo_path 2");
31 $e = $rg_repos . "/by_id/00/00/00/02/00000002/repos/by_id/55.git";
32 $c = rg_repo_path_by_id(2, 55);
33 33 if (strcmp($c, $e) != 0) { if (strcmp($c, $e) != 0) {
34 rg_log("name2base2 is not working correctly: c=$c e=$e.");
34 rg_log("rg_repo_path 2 is not working correctly: c=$c e=$e.");
35 35 exit(1); exit(1);
36 36 } }
37 37
 
... ... if ($db === FALSE) {
87 87 exit(1); exit(1);
88 88 } }
89 89
90 $r = rg_state_set($db, "schema_version", "0");
91 if ($r !== TRUE) {
92 echo "Cannot reset schema (" . rg_state_error() . ")!\n";
93 exit(1);
94 }
95
90 96 $r = rg_sql_struct_update($db, RG_DROP_TABLES|RG_IGNORE_ERRORS); $r = rg_sql_struct_update($db, RG_DROP_TABLES|RG_IGNORE_ERRORS);
91 97 if ($r !== TRUE) { if ($r !== TRUE) {
92 98 rg_log("Cannot create struct (" . rg_sql_error() . ")!"); rg_log("Cannot create struct (" . rg_sql_error() . ")!");
93 99 exit(1); exit(1);
94 100 } }
95 101
102 $r = rg_fixes_update($db);
103 if ($r !== TRUE) {
104 rg_log("Cannot apply fixes!");
105 exit(1);
106 }
107
108 $r = rg_sql_struct_slaves_update($db);
109 if ($r !== TRUE) {
110 rg_log("Cannot create slaves!");
111 exit(1);
112 }
113
96 114 $uid = time(); $uid = time();
97 115 rg_log("Inserting a fake user"); rg_log("Inserting a fake user");
98 116 $sql = "INSERT INTO users (uid, username, realname, salt, pass, email, itime, suspended" $sql = "INSERT INTO users (uid, username, realname, salt, pass, email, itime, suspended"
 
... ... if ($res === FALSE) {
104 122 rg_log("Cannot insert a user (" . rg_sql_error() . ")!"); rg_log("Cannot insert a user (" . rg_sql_error() . ")!");
105 123 exit(1); exit(1);
106 124 } }
125 $rg_ui = rg_user_info($db, $uid, "", "");
126 if ($rg_ui['exists'] != 1) {
127 echo "Cannot load user info!\n";
128 exit(1);
129 }
107 130
108 $repo_id = time();
109 $repo_name = "repo-" . $repo_id;
110 rg_log("Inserting a fake repo");
111 $sql = "INSERT INTO repos (repo_id, name, uid, itime"
112 . ", disk_quota_mb, max_commit_size"
113 . ", master, description, git_dir_done, default_rights)"
114 . " VALUES ($repo_id, '$repo_name', $uid, 0, 0, 0, 0, 'bla bla desc', 1, 'F')";
115 $res = rg_sql_query($db, $sql);
116 if ($res === FALSE) {
117 rg_log("Cannot insert a repo (" . rg_sql_error() . ")!");
131 rg_log("Creating a repo");
132 $repo_name = "A";
133 $repo_id = rg_repo_create($db, 0, $rg_ui, $repo_name, 0, "desc", "F", 0);
134 if ($repo_id === FALSE) {
135 rg_log("Cannot insert a repo (" . rg_repo_error() . ")!");
118 136 exit(1); exit(1);
119 137 } }
120 138
121 rg_log("test giving rights");
122 $rr = array("repo_id" => $repo_id);
123 $ri = rg_repo_info($db, $rr);
139 $ri = rg_repo_info($db, $rg_ui['uid'], $repo_id, "");
124 140 if ($ri['exists'] != 1) { if ($ri['exists'] != 1) {
125 141 rg_log("ri: " . print_r($ri, TRUE)); rg_log("ri: " . print_r($ri, TRUE));
126 142 rg_log("Cannot lookup repo_id $repo_id!"); rg_log("Cannot lookup repo_id $repo_id!");
127 143 exit(1); exit(1);
128 144 } }
145
146 rg_log("Clean repos folder...");
147 $r = rg_exec("rm -rf base/*");
148 if ($r['ok'] != 1) {
149 echo "Failed to clean base folder.\n";
150 exit(1);
151 }
152
153 rg_log("Creating git folder.");
154 $r = rg_repo_storage_create($db, $ri);
155 if ($r !== TRUE) {
156 echo "Cannot create storage dir (" . rg_repo_error() . ")!\n";
157 exit(1);
158 }
159
160 rg_log("test giving rights");
129 161 $tuid = 10; $tuid = 10;
130 162 $v = rg_repo_rights_set($db, $ri, $tuid, "P"); $v = rg_repo_rights_set($db, $ri, $tuid, "P");
131 163 if ($v === FALSE) { if ($v === FALSE) {
 
... ... if ($r['repo_id'] != 3000) {
216 248 exit(1); exit(1);
217 249 } }
218 250
251 // Testing the rename of the repos
252 // Create history table
253 $sql = "CREATE TABLE repo_history_" . date("Y-m") . " INHERITS (repo_history)";
254 $res = rg_sql_query($db, $sql);
255 if ($res === FALSE) {
256 echo "Cannot create repo_history table (" . rg_sql_error() . ")!\n";
257 exit(1);
258 }
259
260 $rg_repos = "repos";
261 $r = mkdir($rg_repos . "/users/u/s/user-$uid/repos/by_id/$repo_id.git", 0755, TRUE);
262 if ($r !== TRUE) {
263 echo "Cannot create fake dir!\n";
264 exit(1);
265 }
266 $r = mkdir($rg_repos . "/users/u/s/user-$uid/repos/by_name", 0755, TRUE);
267 if ($r !== TRUE) {
268 echo "Cannot create fake dir 2!\n";
269 exit(1);
270 }
271 $rg_repo_max_len = 100;
272 $r = rg_repo_rename($db, $rg_ui['uid'], $repo_id, $repo_name, $repo_name . "-b");
273 if ($r !== TRUE) {
274 echo "Cannot rename repository (" . rg_repo_error() . ")!\n";
275 exit(1);
276 }
277 // Do a second rename
278 $r = rg_repo_rename($db, $rg_ui['uid'], $repo_id, $repo_name, $repo_name . "-c");
279 if ($r !== TRUE) {
280 echo "Cannot rename repository (" . rg_repo_error() . ")!\n";
281 exit(1);
282 }
283
219 284 rg_sql_close($db); rg_sql_close($db);
220 285
221 286 echo "repo: OK!\n"; echo "repo: OK!\n";
File tests/user.php changed (mode: 100644) (index 20b84b8..e6d935a)
... ... require_once($INC . "/init.inc.php");
7 7 require_once($INC . "/user.inc.php"); 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 require_once($INC . "/fixes.inc.php");
10 11
11 12 $rg_sql_debug = 1; $rg_sql_debug = 1;
12 13
13 14 rg_log_set_file("user.log"); rg_log_set_file("user.log");
14 15
16 $rg_repos = "ubase";
15 17 $rg_user_max_len = 20; $rg_user_max_len = 20;
16 18 $rg_session_time = 3600; $rg_session_time = 3600;
17 19 $rg_user_allow = '/^[A-Za-z0-9_.-]*$/'; $rg_user_allow = '/^[A-Za-z0-9_.-]*$/';
 
... ... if ($db === FALSE) {
26 28 exit(1); exit(1);
27 29 } }
28 30
31 $r = rg_state_set($db, "schema_version", "0");
32 if ($r !== TRUE) {
33 echo "Cannot reset schema (" . rg_state_error() . ")!\n";
34 exit(1);
35 }
36
29 37 $r = rg_sql_struct_update($db, RG_DROP_TABLES); $r = rg_sql_struct_update($db, RG_DROP_TABLES);
30 38 if ($r !== TRUE) { if ($r !== TRUE) {
31 39 echo "Cannot create structure (" . rg_sql_error() . ")!\n"; echo "Cannot create structure (" . rg_sql_error() . ")!\n";
32 40 exit(1); exit(1);
33 41 } }
34 42
35 // Clean userA
36 $sql = "DELETE FROM users WHERE username = 'userA'";
37 $res = rg_sql_query($db, $sql);
38 rg_sql_free_result($res);
43 $r = rg_fixes_update($db);
44 if ($r !== TRUE) {
45 echo "Cannot apply fixes!\n";
46 exit(1);
47 }
48
49 $r = rg_sql_struct_slaves_update($db);
50 if ($r !== TRUE) {
51 rg_log("Cannot create slaves!");
52 exit(1);
53 }
54
55 $r = rg_exec("rm -rf ubase");
56 if ($r['ok'] != 1) {
57 echo "Cannot remove ubase dir (" . $r['errmsg'] . ")!\n";
58 exit(1);
59 }
39 60
40 61 // add user // add user
41 62 $_u['uid'] = 0; $_u['uid'] = 0;
 
... ... $_u['disk_quota_mb'] = 100;
48 69 $_u['rights'] = "C"; $_u['rights'] = "C";
49 70 $_u['session_time'] = 3600; $_u['session_time'] = 3600;
50 71 $_u['confirm_token'] = ""; $_u['confirm_token'] = "";
51 $r = rg_user_edit($db, $_u);
52 if ($r !== TRUE) {
72 $uid = rg_user_edit($db, $_u);
73 if ($uid === FALSE) {
53 74 echo "Cannot add user (" . rg_user_error() . ")!\n"; echo "Cannot add user (" . rg_user_error() . ")!\n";
54 75 exit(1); exit(1);
55 76 } }
56 $uid = rg_sql_last_id($db);
77
78 // Simulate event: link_by_name
79 $ev = array("uid" => $uid, "username" => $_u['username']);
80 $r = rg_user_link_by_name($db, $ev);
81 if ($r === FALSE) {
82 echo "Cannot link by name (" . rg_user_error() . ")!\n";
83 exit(1);
84 }
57 85
58 86 $v = rg_user_forgot_pass_mail_prepare($db, "rg@localhost"); $v = rg_user_forgot_pass_mail_prepare($db, "rg@localhost");
59 87 if (empty($v['token'])) { if (empty($v['token'])) {
 
... ... $pass = $_ui['pass'];
73 101 $_u['uid'] = $uid; $_u['uid'] = $uid;
74 102 $_u['pass'] = ""; $_u['pass'] = "";
75 103 $r = rg_user_edit($db, $_u); $r = rg_user_edit($db, $_u);
76 if ($r !== TRUE) {
104 if ($r === FALSE) {
77 105 echo "Cannot edit user with empty pass (" . rg_user_error() . ")!\n"; echo "Cannot edit user with empty pass (" . rg_user_error() . ")!\n";
78 106 exit(1); exit(1);
79 107 } }
 
... ... if (strcmp($pass, $_ui['pass']) != 0) {
91 119 // edit user - no empty pass // edit user - no empty pass
92 120 $_u['pass'] = "pass2"; $_u['pass'] = "pass2";
93 121 $r = rg_user_edit($db, $_u); $r = rg_user_edit($db, $_u);
94 if ($r !== TRUE) {
122 if ($r === FALSE) {
95 123 echo "Cannot edit user with not empty pass (" . rg_user_error() . ")!\n"; echo "Cannot edit user with not empty pass (" . rg_user_error() . ")!\n";
96 124 exit(1); exit(1);
97 125 } }
 
... ... if ($r['uid'] != $uid) {
136 164 exit(1); exit(1);
137 165 } }
138 166
139 // test name2path
140 $rg_repos = "/base"; $user = "b"; $e = "/base/users/b/_/b";
141 $rr = array("prefix" => "/" . $user, "user" => $user);
142 $r = rg_user_name2path($rr);
167 // test rg_user_path
168 $x = sprintf("%08X", $uid);
169 $e = "ubase/by_id/" . substr($x, 0, 2) . "/" . substr($x, 2, 2)
170 . "/" . substr($x, 4, 2) . "/" . substr($x, 6, 2) . "/" . $x;
171 $r = rg_user_path_by_id($uid);
143 172 if (strcmp($r, $e) != 0) { if (strcmp($r, $e) != 0) {
144 echo "name2path: e=[$e] != r=[$r]!\n";
173 echo "path_by_id: e=[$e] != r=[$r]!\n";
174 exit(1);
175 }
176
177 // test renames
178 $r = rg_user_rename($db, $_ui, "userA2");
179 if ($r === FALSE) {
180 echo "Cannot rename user (" . rg_user_error() . ")!\n";
181 exit(1);
182 }
183
184 rg_log("Testing fixes...");
185 // add user5
186 $_u['uid'] = 0;
187 $_u['realname'] = "user5 real name";
188 $_u['username'] = "user5";
189 $_u['email'] = "rg@localhost";
190 $_u['pass'] = "pass1";
191 $_u['is_admin'] = 1;
192 $_u['disk_quota_mb'] = 100;
193 $_u['rights'] = "C";
194 $_u['session_time'] = 3600;
195 $_u['confirm_token'] = "";
196 $uid5 = rg_user_edit($db, $_u);
197 if ($uid5 === FALSE) {
198 echo "Cannot add user5 (" . rg_user_error() . ")!\n";
199 exit(1);
200 }
201
202 $r = system("mkdir -p ubase/users/u/s/user5");
203 if ($r === FALSE) {
204 echo "Cannot make fixes simulation dir ($php_errormsg)!\n";
205 exit(1);
206 }
207 $r = rg_fixes_user_index_by_id($db);
208 if ($r === FALSE) {
209 echo "cannot re-index by id!\n";
145 210 exit(1); exit(1);
146 211 } }
147 212
Hints

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

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

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

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