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 ea67645051e11f3ef9ba3a115ccecb8e1f8cfee0

Small changes all over the place: CSS, keys etc.
Author: Catalin(ux) M. BOIE
Author date (UTC): 2012-10-24 21:48
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2012-10-24 21:48
Parent(s): f82d44b18897564d35c0a133303c3a47e419d38b
Signing key:
Tree: 470bcc9454a0e3e385a170d137a895ef42b948bf
File Lines added Lines deleted
TODO 11 1
duilder.conf 2 1
hooks/pre-commit 1 1
hooks/pre-receive 1 1
hooks/update 1 1
inc/.gitignore 1 0
inc/git.inc.php 1 1
inc/init.inc.php 3 0
inc/keys.inc.php 276 165
inc/ssh.inc.php 12 6
inc/struct.inc.php 10 0
inc/user.inc.php 1 1
inc/user/keys/keys.php 37 11
inc/user/pass/pass.form.php 0 34
inc/user/pass/pass.php 15 8
inc/util.inc.php 22 6
inc/ver.php.in 5 0
rocketgit.spec.in 2 2
root/themes/default/hints/ssh/key.html 1 0
root/themes/default/index.html 31 18
root/themes/default/main.css 60 16
root/themes/default/ok.html 3 0
root/themes/default/repo/bug/search/remove.html 1 1
root/themes/default/repo/bug/search/search.html 1 1
root/themes/default/repo/list/header.html 1 0
root/themes/default/user/keys/add.html 1 1
root/themes/default/user/keys/list/footer.html 3 0
root/themes/default/user/keys/list/header.html 10 1
root/themes/default/user/keys/list/line.html 3 1
root/themes/default/user/pass.html 29 0
root/themes/default/warning.html 1 1
scripts/remote.php 28 5
tests/keys.php 8 3
File TODO changed (mode: 100644) (index adc2088..6d54040)
4 4 [ ] Should we expire the reset password token? Why? [ ] Should we expire the reset password token? Why?
5 5 Somebody can request another one! Somebody can request another one!
6 6 [ ] All internal error should show a special page? [ ] All internal error should show a special page?
7 [ ] Deleting a SSH key should be done with token.
7 [ ] Deleting a SSH key should be done with token:
8 First, invalidate it, second delete it. Maybe show an undelete page?
9 Or, allow delete and move it to deleted list and allow undelete and
10 then delete? Hm.
8 11 [ ] All operations must be verified with tokens. [ ] All operations must be verified with tokens.
9 12 [ ] If the confirmation code is truncated, an internal error is generated [ ] If the confirmation code is truncated, an internal error is generated
10 13 instead of a user error! instead of a user error!
 
13 16 even if is not confirmed (option in config). even if is not confirmed (option in config).
14 17 [ ] Fix the headers (+dkim) to avoid spam. [ ] Fix the headers (+dkim) to avoid spam.
15 18 [ ] logrotate is not working. [ ] logrotate is not working.
19 [ ] Build a function to store data in a processing queue:
20 dirs like YYYY/MM/DD/HH/MM/job
21 [ ] Use some named pipes to signal q.php/cron.php to do some stuff.
16 22 [ ] [ ]
17 23
18 24
19 25 == Medium == == Medium ==
26 [ ] Replace all *.form.php with templates.
27 [ ] Also log errmsg[] array!
28 [ ] Do we need subop=1 into login.html?
29 [ ] Add possibility to donload the "CV" of a user.
20 30 [ ] Happy birthday for projects/users/etc. [ ] Happy birthday for projects/users/etc.
21 31 [ ] Check if if we remove rocketgit, the repos stay! [ ] Check if if we remove rocketgit, the repos stay!
22 32 [ ] Bug rights: add note, anonymous add note, add label, add global search. [ ] Bug rights: add note, anonymous add note, add label, add global search.
File duilder.conf changed (mode: 100644) (index 0a25613..6b1afcd)
1 1 PRJ="rocketgit" PRJ="rocketgit"
2 VER="0.13"
2 VER="0.14"
3 3 REV="1" REV="1"
4 4 EXCLUDE=".exclude" EXCLUDE=".exclude"
5 5 EXPORT_PATH="/data/www/umbrella/kernel/us/rocketgit" EXPORT_PATH="/data/www/umbrella/kernel/us/rocketgit"
 
... ... SRPM_DEST="../dinorepo/fedora/SRPMS"
10 10 BUILD_TGZ="1" BUILD_TGZ="1"
11 11 BUILD_DEB="1" BUILD_DEB="1"
12 12 RELEASE_SCRIPT="/usr/local/bin/duilder_release" RELEASE_SCRIPT="/usr/local/bin/duilder_release"
13 CONFIG_H="inc/ver.php"
File hooks/pre-commit changed (mode: 100755) (index a8711da..ccef4c4)
... ... else
38 38 $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000);
39 39 rg_log("Took " . $diff . "ms."); rg_log("Took " . $diff . "ms.");
40 40
41 @file_put_contents($repo_path . "/rg/hook-pre-commit",
41 @file_put_contents($repo_path . "/rocketgit/hook-pre-commit",
42 42 "repo: " . $repo . " ($repo_path)" "repo: " . $repo . " ($repo_path)"
43 43 . "\nat: " . sprintf("%u", $_start) . "\nat: " . sprintf("%u", $_start)
44 44 . "\nuid: " . $uid . "\nuid: " . $uid
File hooks/pre-receive changed (mode: 100755) (index a7956c0..785f8b8)
... ... fclose($f);
58 58 $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000);
59 59 rg_log("Took " . $diff . "ms."); rg_log("Took " . $diff . "ms.");
60 60
61 @file_put_contents($repo_path . "/rg/hook-pre-receive",
61 @file_put_contents($repo_path . "/rocketgit/hook-pre-receive",
62 62 "repo: " . $repo . " ($repo_path)" "repo: " . $repo . " ($repo_path)"
63 63 . "\nat: " . sprintf("%u", $_start) . "\nat: " . sprintf("%u", $_start)
64 64 . "\nuid: " . $uid . "\nuid: " . $uid
File hooks/update changed (mode: 100755) (index 515c3d6..7765def)
... ... if (strncmp($a['refname'], "refs/tags/", 10) == 0) {
69 69 rg_git_fatal("Unknown refname type provided [" . $a['refname'] . "]"); rg_git_fatal("Unknown refname type provided [" . $a['refname'] . "]");
70 70 } }
71 71
72 @file_put_contents($a['repo_path'] . "/rg/hook-update",
72 @file_put_contents($a['repo_path'] . "/rocketgit/hook-update",
73 73 "repo: " . $a['repo_path'] "repo: " . $a['repo_path']
74 74 . "\nat: " . sprintf("%u", $_start) . "\nat: " . sprintf("%u", $_start)
75 75 . "\nuid: " . $a['uid'] . "\nuid: " . $a['uid']
File inc/.gitignore added (mode: 100644) (index 0000000..e4b9c6c)
1 ver.php
File inc/git.inc.php changed (mode: 100644) (index 47613f0..e224b27)
... ... function rg_git_branches_and_tags($repo_dir, $base_url, $current_ref)
996 996 foreach ($list as $name) { foreach ($list as $name) {
997 997 $name = htmlspecialchars($name); $name = htmlspecialchars($name);
998 998 $ename = preg_replace('/\//', ',', $name); $ename = preg_replace('/\//', ',', $name);
999 rg_log("DEBUG: compare with [" . $o . "/" . $ename . "]");
999 //rg_log("DEBUG: compare with [" . $o . "/" . $ename . "]");
1000 1000 if (strcmp($current, $o . "/" . $ename) == 0) { if (strcmp($current, $o . "/" . $ename) == 0) {
1001 1001 $add_s = "<b>"; $add_s = "<b>";
1002 1002 $add_e = "</b>"; $add_e = "</b>";
File inc/init.inc.php changed (mode: 100644) (index b31a15d..e610a03)
1 1 <?php <?php
2 2 // This is the first file that is included by all scripts. // This is the first file that is included by all scripts.
3 3
4 require_once($INC . "/ver.php");
5
4 6 $more = array(); $more = array();
5 7
6 8 // For escapeshellarg to work with UTF-8, we are forced to set a locale // For escapeshellarg to work with UTF-8, we are forced to set a locale
 
... ... if (empty($rg_ssh_host)) {
14 16 $more['rg_ssh_host'] = $rg_ssh_host; $more['rg_ssh_host'] = $rg_ssh_host;
15 17 $more['rg_ssh_port'] = $rg_ssh_port; $more['rg_ssh_port'] = $rg_ssh_port;
16 18
19 $more['rg_version'] = $rocketgit_version;
17 20 ?> ?>
File inc/keys.inc.php changed (mode: 100644) (index d7746af..4ceaf37)
... ... function rg_keys_error()
23 23 */ */
24 24 function rg_keys_info($key) function rg_keys_info($key)
25 25 { {
26 $t = explode(" ", $key, 3);
26 rg_prof_start("keys_info");
27 27
28 28 $ret = array(); $ret = array();
29 29 $ret['ok'] = 0; $ret['ok'] = 0;
30 do {
31 if (strpos($key, "PRIVATE KEY") !== FALSE) {
32 rg_keys_set_error("private instead of pulic key");
33 break;
34 }
30 35
31 if (!isset($t[1])) {
32 rg_keys_set_error("malformed ssh key (missing fields)");
33 return $ret;
34 }
36 $t = explode(" ", $key, 3);
37 if (!isset($t[1])) {
38 rg_keys_set_error("malformed ssh key (missing fields)");
39 break;
40 }
35 41
36 $ret['type'] = $t[0];
37 $ret['key'] = isset($t[1]) ? $t[1] : "";
38 $ret['comment'] = isset($t[2]) ? $t[2] : "";
42 $ret['type'] = $t[0];
43 $ret['key'] = isset($t[1]) ? $t[1] : "";
44 $ret['comment'] = isset($t[2]) ? $t[2] : "";
39 45
40 $d = base64_decode($ret['key']);
41 if ($d === FALSE) {
42 rg_keys_set_error("malformed input (base64 failed)");
43 return $ret;
44 }
45 $digest = md5($d);
46 $d = base64_decode($ret['key']);
47 if ($d === FALSE) {
48 rg_keys_set_error("malformed input (base64 failed)");
49 break;
50 }
51 $digest = md5($d);
52
53 $a = array();
54 for ($i = 0; $i < 16; $i++)
55 $a[] = substr($digest, $i * 2, 2);
46 56
47 $a = array();
48 for ($i = 0; $i < 16; $i++)
49 $a[] = substr($digest, $i * 2, 2);
57 $ret['fingerprint'] = implode(":", $a);
50 58
51 $ret['fingerprint'] = implode(":", $a);
59 $ret['ok'] = 1;
60 } while (0);
52 61
53 $ret['ok'] = 1;
62 rg_prof_end("keys_info");
54 63 return $ret; return $ret;
55 64 } }
56 65
57 66 /* /*
58 * Remove a key from database
67 * Mark state as dirty
59 68 */ */
60 function rg_keys_remove($db, $rg_ui, $key_id)
69 function rg_keys_mark_dirty($db)
61 70 { {
62 rg_prof_start("keys_remove");
63
64 // TODO: move this to caller?
65 $e_key_id = sprintf("%u", $key_id);
66
67 $sql = "DELETE FROM keys"
68 . " WHERE uid = " . $rg_ui['uid']
69 . " AND key_id = $e_key_id";
70 $res = rg_sql_query($db, $sql);
71 if ($res === FALSE) {
72 rg_keys_set_error("cannot delete key $key_id (" . rg_sql_error() . ")");
73 return FALSE;
74 }
75 rg_sql_free_result($res);
71 rg_prof_start("keys_mark_dirty");
76 72
77 // mark dirty
73 $ret = TRUE;
78 74 if (rg_state_set($db, "authorized_keys", 1) === FALSE) { if (rg_state_set($db, "authorized_keys", 1) === FALSE) {
79 75 rg_keys_set_error("cannot make state dirty (" . rg_state_error() . ")!"); rg_keys_set_error("cannot make state dirty (" . rg_state_error() . ")!");
80 return FALSE;
76 $ret = FALSE;
81 77 } }
82 78
79 rg_prof_end("keys_mark_dirty");
80 return $ret;
81 }
82
83 /*
84 * Remove a key from database
85 */
86 function rg_keys_remove($db, $rg_ui, $key_id, $flags)
87 {
88 rg_prof_start("keys_remove");
89 rg_log("keys_remove: key_id=$key_id flags=" . rg_array2string($flags));
90
91 $ret = FALSE;
92 do {
93 // Do not move this to caller.
94 // TODO: Do rg_var_array that will enforce index to be numeric?
95 $e_key_id = sprintf("%u", $key_id);
96
97 $sql = "DELETE FROM keys"
98 . " WHERE uid = " . $rg_ui['uid']
99 . " AND key_id = $e_key_id";
100 $res = rg_sql_query($db, $sql);
101 if ($res === FALSE) {
102 rg_keys_set_error("cannot delete key $key_id (" . rg_sql_error() . ")");
103 break;
104 }
105 rg_sql_free_result($res);
106
107 if (!isset($flags['no_dirty'])) {
108 if (rg_keys_mark_dirty($db) !== TRUE)
109 break;
110 }
111
112 $ret = TRUE;
113 } while (0);
114
83 115 rg_prof_end("keys_remove"); rg_prof_end("keys_remove");
116 return $ret;
117 }
118
119 /*
120 * Remove multiple keys from database
121 */
122 function rg_keys_remove_multi($db, $rg_ui, $list)
123 {
124 rg_prof_start("keys_remove_multi");
125 rg_log("keys_remove_multi: list=" . rg_array2string($list));
126
127 $ret = FALSE;
128 do {
129 if (empty($list)) {
130 rg_keys_set_error("no keys provided");
131 break;
132 }
133
134 $flags = array("no_dirty" => 1);
135 foreach ($list as $key_id => $junk) {
136 $r = rg_keys_remove($db, $rg_ui, $key_id, $flags);
137 if ($r !== TRUE)
138 break;
139 }
84 140
85 return TRUE;
141 if (rg_keys_mark_dirty($db) != TRUE)
142 break;
143
144 $ret = TRUE;
145 } while (0);
146
147 rg_prof_end("keys_remove_multi");
148 return $ret;
86 149 } }
87 150
88 151 /* /*
 
... ... function rg_keys_count($db, $uid)
92 155 { {
93 156 rg_prof_start("keys_count"); rg_prof_start("keys_count");
94 157
95 $sql = "SELECT COUNT(*) AS count FROM keys WHERE uid = $uid";
96 $res = rg_sql_query($db, $sql);
97 if ($res === FALSE) {
98 rg_keys_set_error("cannot query (" . rg_sql_error() . ")");
99 return FALSE;
100 }
101 $row = rg_sql_fetch_array($res);
102 rg_sql_free_result($res);
158 $ret = FALSE;
159 do {
160 $sql = "SELECT COUNT(*) AS count FROM keys WHERE uid = $uid";
161 $res = rg_sql_query($db, $sql);
162 if ($res === FALSE) {
163 rg_keys_set_error("cannot query (" . rg_sql_error() . ")");
164 break;
165 }
166 $row = rg_sql_fetch_array($res);
167 rg_sql_free_result($res);
103 168
104 rg_prof_end("keys_count");
169 $ret = $row['count'];
170 } while (0);
105 171
106 return $row['count'];
172 rg_prof_end("keys_count");
173 return $ret;
107 174 } }
108 175
109 176 /* /*
 
... ... function rg_keys_add($db, $rg_ui, $key)
115 182 global $rg_max_ssh_keys; global $rg_max_ssh_keys;
116 183
117 184 rg_prof_start("keys_add"); rg_prof_start("keys_add");
185 rg_log("keys_add: $key=$key");
186
187 $ret = FALSE;
188 do {
189 $itime = time();
190 $e_key = rg_sql_escape($db, $key);
191
192 $ki = rg_keys_info($key);
193 if ($ki['ok'] != 1)
194 break;
195
196 // check if we are over the maximum
197 // the config after update may not have this defined.
198 if ($rg_max_ssh_keys == 0)
199 $rg_max_ssh_keys = 10;
200 $no_of_keys = rg_keys_count($db, $rg_ui['uid']);
201 if ($no_of_keys === FALSE)
202 break;
203
204 if ($no_of_keys >= $rg_max_ssh_keys) {
205 rg_keys_set_error("too many keys; please delete some");
206 break;
207 }
118 208
119 $itime = time();
120 $e_key = rg_sql_escape($db, $key);
209 $sql = "INSERT INTO keys (itime, uid, key)"
210 . " VALUES ($itime, " . $rg_ui['uid'] . ", '$e_key')"
211 . " RETURNING key_id";
212 $res = rg_sql_query($db, $sql);
213 if ($res === FALSE) {
214 rg_keys_set_error("cannot insert key (" . rg_sql_error() . ")");
215 break;
216 }
217 $row = rg_sql_fetch_array($res);
218 $id = $row['key_id'];
219 rg_sql_free_result($res);
121 220
122 $ki = rg_keys_info($key);
123 if ($ki['ok'] != 1)
124 return FALSE;
221 // set dirty
222 if (rg_keys_mark_dirty($db) != TRUE)
223 break;
125 224
126 // check if we are over the maximum
127 // the config after update may not have this defined.
128 if ($rg_max_ssh_keys == 0)
129 $rg_max_ssh_keys = 10;
130 $no_of_keys = rg_keys_count($db, $rg_ui['uid']);
131 if ($no_of_keys === FALSE)
132 return FALSE;
225 $ret = $id;
226 } while (0);
133 227
134 if ($no_of_keys >= $rg_max_ssh_keys) {
135 rg_keys_set_error("too many keys; please delete some");
136 return FALSE;
137 }
228 rg_prof_end("keys_add");
229 return $ret;
230 }
138 231
139 $sql = "INSERT INTO keys (itime, uid, key)"
140 . " VALUES ($itime, " . $rg_ui['uid'] . ", '$e_key')"
141 . " RETURNING key_id";
142 $res = rg_sql_query($db, $sql);
143 if ($res === FALSE) {
144 rg_keys_set_error("cannot insert key (" . rg_sql_error() . ")");
145 return FALSE;
146 }
147 $row = rg_sql_fetch_array($res);
148 $id = $row['key_id'];
149 rg_sql_free_result($res);
232 /*
233 * Update last_use and last_ip
234 */
235 function rg_keys_update_use($db, $key_id, $ip)
236 {
237 rg_prof_start("keys_update_use");
238 rg_log("keys_update_use: key_id=$key_id, $ip=$ip");
150 239
151 // set dirty
152 if (rg_state_set($db, "authorized_keys", 1) === FALSE) {
153 rg_keys_set_error("cannot make state dirty: " . rg_state_error());
154 return FALSE;
155 }
240 $ret = FALSE;
241 do {
242 $now = time();
156 243
157 rg_prof_end("keys_add");
244 $e_ip = rg_sql_escape($db, $ip);
245
246 $sql = "UPDATE keys SET last_use = $now, last_ip = '$e_ip'"
247 . " WHERE key_id = $key_id";
248 $res = rg_sql_query($db, $sql);
249 if ($res === FALSE) {
250 rg_keys_set_error("cannot update key (" . rg_sql_error() . ")");
251 break;
252 }
253 rg_sql_free_result($res);
254 } while (0);
158 255
159 return $id;
256 rg_prof_end("keys_update_use");
257 return $ret;
160 258 } }
161 259
162 260 /* /*
 
... ... function rg_keys_regen($db)
170 268
171 269 rg_prof_start("keys_regen"); rg_prof_start("keys_regen");
172 270
173 $dirty = rg_state_get($db, "authorized_keys");
174 if ($dirty == 0) {
175 // Skip generation because is not dirty
176 return TRUE;
177 }
271 $ret = FALSE;
272 do {
273 $dirty = rg_state_get($db, "authorized_keys");
274 if ($dirty == 0) {
275 // Skip generation because is not dirty
276 $ret = TRUE;
277 break;
278 }
178 279
179 // create .ssh folder if does not exists
180 $dir = dirname($rg_keys_file);
181 if (!file_exists($dir)) {
182 if (!@mkdir($dir, 0700, TRUE)) {
183 rg_keys_set_error("cannot create dir $dir ($php_errormsg)");
184 return FALSE;
280 // create .ssh folder if does not exists
281 $dir = dirname($rg_keys_file);
282 if (!file_exists($dir)) {
283 if (!@mkdir($dir, 0700, TRUE)) {
284 rg_keys_set_error("cannot create dir $dir ($php_errormsg)");
285 break;
286 }
185 287 } }
186 }
187 288
188 $tmp = $rg_keys_file . ".tmp";
189 $f = @fopen($tmp, "w");
190 if ($f === FALSE) {
191 rg_keys_set_error("cannot open file $tmp ($php_errormsg)");
192 return FALSE;
193 }
289 $tmp = $rg_keys_file . ".tmp";
290 $f = @fopen($tmp, "w");
291 if ($f === FALSE) {
292 rg_keys_set_error("cannot open file $tmp ($php_errormsg)");
293 break;
294 }
194 295
195 if (chmod($tmp, 0600) === FALSE) {
196 rg_keys_set_error("cannot chmod tmp file ($php_errmsg)");
197 fclose($f);
198 return FALSE;
199 }
296 if (chmod($tmp, 0600) === FALSE) {
297 rg_keys_set_error("cannot chmod tmp file ($php_errmsg)");
298 fclose($f);
299 break;
300 }
200 301
201 // mark file as clean
202 rg_state_set($db, "authorized_keys", 0);
302 // mark file as clean
303 rg_state_set($db, "authorized_keys", 0);
203 304
204 $sql = "SELECT uid, key FROM keys";
205 $res = rg_sql_query($db, $sql);
206 if ($res === FALSE) {
207 rg_keys_set_error("cannot query (" . rg_sql_error() . ")");
208 return FALSE;
209 }
210 while (($row = rg_sql_fetch_array($res))) {
211 rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']);
212 $buf = "command=\"/usr/bin/php " . $rg_scripts . "/scripts/remote.php"
213 . " " . $row['uid'] . "\""
214 . "," . $rg_ssh_paras
215 . " " . $row['key'] . "\n";
216 if (@fwrite($f, $buf) === FALSE) {
217 rg_keys_set_error("cannot write. Disk space problems? ($php_errormsg)");
218 fclose($f);
219 unlink($tmp);
220 rg_sql_free_result($res);
221 return FALSE;
305 $sql = "SELECT key_id, uid, key FROM keys";
306 $res = rg_sql_query($db, $sql);
307 if ($res === FALSE) {
308 rg_keys_set_error("cannot query (" . rg_sql_error() . ")");
309 break;
222 310 } }
223 }
224 rg_sql_free_result($res);
311 while (($row = rg_sql_fetch_array($res))) {
312 rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']);
313 $buf = "command=\"/usr/bin/php " . $rg_scripts . "/scripts/remote.php"
314 . " " . $row['uid']
315 . " " . $row['key_id'] . "\""
316 . "," . $rg_ssh_paras
317 . " " . $row['key'] . "\n";
318 if (@fwrite($f, $buf) === FALSE) {
319 rg_keys_set_error("cannot write. Disk space problems? ($php_errormsg)");
320 fclose($f);
321 unlink($tmp);
322 rg_sql_free_result($res);
323 break;
324 }
325 }
326 rg_sql_free_result($res);
225 327
226 fclose($f);
328 fclose($f);
227 329
228 if (@rename($tmp, $rg_keys_file) === FALSE) {
229 rg_keys_set_error("cannot rename $tmp to $rg_keys_file ($php_errormsg)");
230 unlink($tmp);
231 return FALSE;
232 }
330 if (@rename($tmp, $rg_keys_file) === FALSE) {
331 rg_keys_set_error("cannot rename $tmp to $rg_keys_file ($php_errormsg)");
332 unlink($tmp);
333 break;
334 }
233 335
234 rg_prof_end("keys_regen");
336 $ret = TRUE;
337 } while (0);
235 338
236 return TRUE;
339 rg_prof_end("keys_regen");
340 return $ret;
237 341 } }
238 342
239 343 /* /*
240 344 * List keys * List keys
241 345 */ */
242 function rg_keys_list($db, $rg_ui, $url)
346 function rg_keys_list($db, $rg_ui)
243 347 { {
244 348 rg_prof_start("keys_list"); rg_prof_start("keys_list");
245
246 rg_log("keys_list: rg_uid=" . $rg_ui['uid'] . ", url=$url...");
247
248 $sql = "SELECT * FROM keys WHERE uid = " . $rg_ui['uid'];
249 $res = rg_sql_query($db, $sql);
250 if ($res === FALSE) {
251 rg_keys_set_error("Cannot query (" . rg_sql_error() . ")");
252 return FALSE;
253 }
254
255 $data = array();
256 while (($row = rg_sql_fetch_array($res))) {
257 $ki = rg_keys_info($row['key']);
258 if ($ki['ok'] != 1) {
259 rg_internal_error("Invalid key in db!");
260 continue;
349 rg_log("keys_list: rg_uid[uid]=" . $rg_ui['uid']);
350
351 $ret = FALSE;
352 do {
353 $sql = "SELECT * FROM keys WHERE uid = " . $rg_ui['uid']
354 . " ORDER BY itime DESC";
355 $res = rg_sql_query($db, $sql);
356 if ($res === FALSE) {
357 rg_keys_set_error("Cannot query (" . rg_sql_error() . ")");
358 break;
261 359 } }
262 360
263 $t = $ki;
264 $t['itime'] = gmdate("Y-m-d H:i", $row['itime']);
265
266 $t['HTML:operations'] = "[<a href=\"$url"
267 . "&amp;key_id=" . $row['key_id']
268 . "&amp;delete=1\">Delete</a>]";
269
270 $data[] = $t;
271 }
272 rg_sql_free_result($res);
273
274 $ret = rg_template_table("user/keys/list", $data, array());
361 $ret = array();
362 while (($row = rg_sql_fetch_array($res))) {
363 $ki = rg_keys_info($row['key']);
364 if ($ki['ok'] != 1) {
365 rg_internal_error("Invalid key in db!");
366 continue;
367 }
368
369 $t = $ki;
370 $t['key_id'] = $row['key_id'];
371 $t['itime'] = gmdate("Y-m-d H:i", $row['itime']);
372
373 if (empty($row['last_ip']))
374 $t['last_ip'] = "-";
375 else
376 $t['last_ip'] = $row['last_ip'];
377
378 if ($row['last_use'] == 0)
379 $t['last_use'] = "-";
380 else
381 $t['last_use'] = gmdate("Y-m-d H:i", $row['last_use']);
382
383 $ret[] = $t;
384 }
385 rg_sql_free_result($res);
386 } while (0);
275 387
276 388 rg_prof_end("keys_list"); rg_prof_end("keys_list");
277
278 389 return $ret; return $ret;
279 390 } }
280 391
File inc/ssh.inc.php changed (mode: 100644) (index a56e41d..fff3b05)
... ... function rg_ssh_repos($db, $uid)
22 22 { {
23 23 rg_log("ssh_repos"); rg_log("ssh_repos");
24 24
25 echo "\n";
26 25 echo "Repositories (name, creation, disk used/quota):\n"; echo "Repositories (name, creation, disk used/quota):\n";
27 26 $sql = "SELECT * FROM repos" $sql = "SELECT * FROM repos"
28 27 . " WHERE uid = $uid" . " WHERE uid = $uid"
 
... ... function rg_ssh_repos($db, $uid)
38 37 } }
39 38 rg_sql_free_result($res); rg_sql_free_result($res);
40 39
41 echo "\n";
42 40 exit(0); exit(0);
43 41 } }
44 42
 
... ... function rg_ssh_repo($db, $uid, $paras)
46 44 { {
47 45 rg_log("ssh_repo: " . rg_array2string($paras)); rg_log("ssh_repo: " . rg_array2string($paras));
48 46
47 if (empty($paras)) {
48 echo "Please specify repo name.\n";
49 exit(0);
50 }
51
49 52 $repo_name = trim($paras[0]); $repo_name = trim($paras[0]);
50 53
51 54 $rr = array("uid" => $uid, "repo" => $repo_name); $rr = array("uid" => $uid, "repo" => $repo_name);
 
... ... function rg_ssh_repo($db, $uid, $paras)
56 59 } }
57 60
58 61 echo "Repo: " . $ri['name'] . "\n"; echo "Repo: " . $ri['name'] . "\n";
62 echo "Description:\n";
63 $_d = explode("\n", $ri['description']);
64 if (!empty($_d)) {
65 foreach ($_d as $_line)
66 echo " " . $_line . "\n";
67 }
59 68 echo "Creation time: " . gmdate("Y-m-d", $ri['itime']) . " UTC\n"; echo "Creation time: " . gmdate("Y-m-d", $ri['itime']) . " UTC\n";
60 69 echo "Disk used: " . rg_1024($ri['disk_used_mb']) . " MiB\n"; echo "Disk used: " . rg_1024($ri['disk_used_mb']) . " MiB\n";
61 70 echo "Disk quota: " . rg_1024($ri['disk_quota_mb']) . " MiB\n"; echo "Disk quota: " . rg_1024($ri['disk_quota_mb']) . " MiB\n";
62 71 $rights = implode(", ", rg_rights_text("repo", $ri['default_rights'])); $rights = implode(", ", rg_rights_text("repo", $ri['default_rights']));
63 72 echo "Default rights: " . $rights . "\n"; echo "Default rights: " . $rights . "\n";
64 echo "Description: " . $ri['description'] . "\n";
65 73
66 74 if ($ri['master'] > 0) { if ($ri['master'] > 0) {
67 75 $rr = array("repo_id" => $ri['master']); $rr = array("repo_id" => $ri['master']);
 
... ... function rg_ssh_dispatch($db, $uid, $cmd)
84 92 case 'repos': rg_ssh_repos($db, $uid); break; case 'repos': rg_ssh_repos($db, $uid); break;
85 93 case 'repo': rg_ssh_repo($db, $uid, $paras); break; case 'repo': rg_ssh_repo($db, $uid, $paras); break;
86 94 case '': case '':
87 echo "\nWelcome to RocketGit!\n\n";
88 echo "Available commmands: status, repos.\n";
89 echo "\n";
95 echo "Available commmands: status, repos, repo.\n";
90 96 exit(0); exit(0);
91 97 } }
92 98 } }
File inc/struct.inc.php changed (mode: 100644) (index 60e8bfb..66073e6)
... ... $rg_sql_struct[7]['other'] = array(
179 179 . " ON bug_search(repo_id, uid)" . " ON bug_search(repo_id, uid)"
180 180 ); );
181 181
182 $rg_sql_struct[8] = array();
183 $rg_sql_struct[8]['tables'] = array();
184 $rg_sql_struct[8]['other'] = array(
185 "more info for keys: last_use" => "ALTER TABLE keys"
186 . " ADD last_use INT NOT NULL DEFAULT 0",
187 "more info for keys: last_ip" => "ALTER TABLE keys"
188 . " ADD last_ip TEXT NOT NULL DEFAULT ''"
189 );
190
191
182 192 // This must be the last line // This must be the last line
183 193 $rg_sql_schema_ver = count($rg_sql_struct); $rg_sql_schema_ver = count($rg_sql_struct);
184 194
File inc/user.inc.php changed (mode: 100644) (index f50d4e4..26ff599)
... ... function rg_user_forgot_pass_mail_prepare($db, $email)
642 642 $ret['exists'] = 0; $ret['exists'] = 0;
643 643
644 644 $expire = time() + 24 * 3600; $expire = time() + 24 * 3600;
645 $token = rg_id(40);
645 $token = rg_id(20);
646 646
647 647 $r = rg_user_info($db, 0, "", $email); $r = rg_user_info($db, 0, "", $email);
648 648 if ($r['ok'] == 0) { if ($r['ok'] == 0) {
File inc/user/keys/keys.php changed (mode: 100644) (index 9b0edf2..f0c9326)
1 1 <?php <?php
2 2 rg_log("/inc/user/keys/keys"); rg_log("/inc/user/keys/keys");
3 3
4 $errmsg = array();
4 $add_errmsg = array();
5 $del_errmsg = array();
5 6 $_my_more = $more; $_my_more = $more;
6 7
7 8 $_keys = ""; $_keys = "";
 
... ... $_keys = "";
9 10 $key = rg_var_str("key"); $key = rg_var_str("key");
10 11 $key = preg_replace("|[^/A-Za-z0-9 @/+_\.\=,-]|", "", $key); $key = preg_replace("|[^/A-Za-z0-9 @/+_\.\=,-]|", "", $key);
11 12 $key_id = rg_var_uint("key_id"); $key_id = rg_var_uint("key_id");
13 $key_delete_ids = rg_var_str("key_delete_ids");
12 14
13 15 // menu // menu
14 16 $_url = rg_re_url($cop); $_url = rg_re_url($cop);
15 17
16 $_keys = "";
17 $errmsg = array();
18
19 18 if (rg_var_uint("add") == 1) { if (rg_var_uint("add") == 1) {
20 $_r = rg_keys_add($db, $rg_ui, $key);
21 if ($_r === FALSE)
22 $errmsg[] = rg_keys_error();
19 do {
20 if (!rg_token_valid($db, $sid, $token)) {
21 $add_errmsg[] = "Invalid token. Try again.";
22 break;
23 }
24
25 $_r = rg_keys_add($db, $rg_ui, $key);
26 if ($_r === FALSE)
27 $add_errmsg[] = rg_keys_error();
28 } while (0);
23 29 } else if (rg_var_uint("delete") == 1) { } else if (rg_var_uint("delete") == 1) {
24 if (rg_keys_remove($db, $rg_ui, $key_id) !== TRUE)
25 $errmsg[] = rg_keys_error();
30 do {
31 if (!rg_token_valid($db, $sid, $token)) {
32 $del_errmsg[] = "Invalid token. Try again.";
33 break;
34 }
35
36 if (empty($key_delete_ids)) {
37 $del_errmsg[] = "No key selected.";
38 break;
39 }
40
41 if (rg_keys_remove_multi($db, $rg_ui, $key_delete_ids) !== TRUE) {
42 $del_errmsg[] = rg_keys_error();
43 break;
44 }
45 } while (0);
26 46 } }
27 $_my_more['HTML:errmsg'] = rg_template_errmsg($errmsg);
47
48 $_my_more['HTML:add_errmsg'] = rg_template_errmsg($add_errmsg);
49 $_my_more['HTML:del_errmsg'] = rg_template_errmsg($del_errmsg);
28 50
29 51 $_my_more['HTML:add_form'] = rg_template("user/keys/add.html", $_my_more); $_my_more['HTML:add_form'] = rg_template("user/keys/add.html", $_my_more);
30 52
31 $_my_more['HTML:keys'] = rg_keys_list($db, $rg_ui, $_url);
53 $keys_list = rg_keys_list($db, $rg_ui);
54 if ($keys_list === FALSE)
55 $_my_more['HTML:keys'] = rg_warning("Could not load keys. Try later."); // TODO
56 else
57 $_my_more['HTML:keys'] = rg_template_table("user/keys/list", $keys_list, $_my_more);
32 58
33 59 $hints = array(); $hints = array();
34 60 if ($rg_ssh_port != 0) if ($rg_ssh_port != 0)
File inc/user/pass/pass.form.php deleted (index 000930e..0000000)
1 <?php
2 $_chpass_form = '<div class="formarea">' . "\n";
3
4 $_chpass_form .= '<div class="formarea_title">Change password</div><br />' . "\n";
5
6 $_chpass_form .= rg_template_errmsg($errmsg);
7
8 $_chpass_form .= '
9 <form method="post" action="' . rg_re_post($cop) . '">
10 <input type="hidden" name="doit" value="1" />
11 <input type="hidden" name="token" value="' . rg_token_get($db, $sid) . '" />
12
13 <label for="old_pass" class="form_item_title">Old password</label><br />
14 <input type="password" name="old_pass" value="" />
15 <br />
16 <br />
17
18 <label for="pass1" class="form_item_title">New password</label><br />
19 <input type="password" name="pass1" value="" />
20 <br />
21 <br />
22
23 <label for="pass2" class="form_item_title">New password (re-type)</label><br />
24 <input type="password" name="pass2" value="" />
25 <br />
26 <br />
27
28 <input type="submit" name="button" value="Change password" />
29
30 </form>
31 </div>
32 ';
33
34 ?>
File inc/user/pass/pass.php changed (mode: 100644) (index 7b7c9c1..3bbe000)
1 1 <?php <?php
2 2 rg_log("/inc/user/pass/pass"); rg_log("/inc/user/pass/pass");
3 3
4 $my_more = $more;
5
4 6 $errmsg = array(); $errmsg = array();
5 7
6 8 $_pass = ""; $_pass = "";
7 9
10 $old_pass = rg_var_str("old_pass");
11 $pass1 = rg_var_str("pass1");
12 $pass2 = rg_var_str("pass2");
13
8 14 $show_form = 1; $show_form = 1;
9 15 if ($doit == 1) { if ($doit == 1) {
10 $old_pass = rg_var_str("old_pass");
11 $pass1 = rg_var_str("pass1");
12 $pass2 = rg_var_str("pass2");
13
14 16 do { do {
15 17 if (!rg_token_valid($db, $sid, $token)) { if (!rg_token_valid($db, $sid, $token)) {
16 18 $errmsg[] = "invalid token; try again"; $errmsg[] = "invalid token; try again";
 
... ... if ($doit == 1) {
32 34 break; break;
33 35 } }
34 36
35 $_pass .= "Password was changed with success!<br />";
37 $_pass .= rg_ok("Password was changed with success!");
36 38 $show_form = 0; $show_form = 0;
37 39 } while (0); } while (0);
38 40 } }
39 41
40 42 if ($show_form == 1) { if ($show_form == 1) {
41 include($INC . "/user/pass/pass.form.php");
42 $_pass .= $_chpass_form;
43 $my_more['rg_action'] = rg_re_post($cop);
44 $my_more['HTML:errmsg'] = rg_template_errmsg($errmsg);
45 $my_more['rg_form_token'] = rg_token_get($db, $sid);
46 $my_more['old_pass'] = $old_pass;
47 $my_more['pass1'] = $pass1;
48 $my_more['pass2'] = $pass2;
49
50 $_pass .= rg_template("user/pass.html", $my_more);
43 51 } }
44 52
45 53 ?> ?>
46
File inc/util.inc.php changed (mode: 100644) (index 9bdf0f9..6f3f07d)
... ... function rg_menu($a, $rg_ui, $op, $subop)
314 314 $_url = rg_re_url($_info['op']); $_url = rg_re_url($_info['op']);
315 315 //$menu .= "<!-- op=" . $_info['op'] . " url=$_url." . " -->\n"; //$menu .= "<!-- op=" . $_info['op'] . " url=$_url." . " -->\n";
316 316
317 rg_log("\tDEBUG: compare with [" . $_info['op'] . "]");
317 //rg_log("\tDEBUG: compare with [" . $_info['op'] . "]");
318 318 $add = ""; $add = "";
319 319 if (strcmp($_info['op'], "/op/" . $op) == 0) if (strcmp($_info['op'], "/op/" . $op) == 0)
320 320 $add = " class=\"selected\"";; $add = " class=\"selected\"";;
 
... ... function rg_menu($a, $rg_ui, $op, $subop)
330 330 $_text2 = $_info2['text']; $_text2 = $_info2['text'];
331 331 $_url2 = $_url . "/" . $_info2['op']; $_url2 = $_url . "/" . $_info2['op'];
332 332 $add = ""; $add = "";
333 rg_log("\tDEBUG: compare with [" . $_info2['op'] . "]");
333 //rg_log("\tDEBUG: compare with [" . $_info2['op'] . "]");
334 334 if (strcmp($_info2['op'], $subop) == 0) if (strcmp($_info2['op'], $subop) == 0)
335 335 $add = " class=\"selected\"";; $add = " class=\"selected\"";;
336 336 $menu2 .= "\t\t<li><a href=\"" $menu2 .= "\t\t<li><a href=\""
 
... ... function rg_replace_conditionals_block($block, &$stack)
412 412 if ($r === FALSE) if ($r === FALSE)
413 413 return FALSE; return FALSE;
414 414 if ($r === 1) { if ($r === 1) {
415 rg_log("matches: " . rg_array2string($matches));
415 //rg_log("matches: " . rg_array2string($matches));
416 416
417 417 $ret = ""; $ret = "";
418 418 if ($cond) if ($cond)
 
... ... function rg_replace_conditionals_block($block, &$stack)
426 426 } else if (strcmp($matches[2], "{{") == 0) { } else if (strcmp($matches[2], "{{") == 0) {
427 427 //rg_log("{{"); //rg_log("{{");
428 428 } else { } else {
429 rg_log("cond=" . $matches[3]);
429 //rg_log("cond=" . $matches[3]);
430 430 if (empty($matches[3])) { if (empty($matches[3])) {
431 431 $new_cond = FALSE; $new_cond = FALSE;
432 432 } else { } else {
 
... ... function rg_replace_conditionals_block($block, &$stack)
436 436 rg_internal_error("Invalid condition!"); rg_internal_error("Invalid condition!");
437 437 return FALSE; return FALSE;
438 438 } }
439 rg_log("matches2: " . rg_array2string($matches2));
439 //rg_log("matches2: " . rg_array2string($matches2));
440 440 $left = trim($matches2[1]); $left = trim($matches2[1]);
441 441 $op = trim($matches2[3]); $op = trim($matches2[3]);
442 442 $right = trim($matches2[4]); $right = trim($matches2[4]);
443 rg_log("if left=[$left] op=[$op] right=[$right]");
443 //rg_log("if left=[$left] op=[$op] right=[$right]");
444 444 if (empty($op)) { if (empty($op)) {
445 445 $new_cond = empty($left) ? FALSE : TRUE; $new_cond = empty($left) ? FALSE : TRUE;
446 446 } else if (strcmp($op, "==") == 0) { } else if (strcmp($op, "==") == 0) {
 
... ... function rg_template_errmsg($a)
651 651 return rg_template_table("errmsg", $b, array()); return rg_template_table("errmsg", $b, array());
652 652 } }
653 653
654 /*
655 * Show a warning using a template
656 */
657 function rg_warning($msg)
658 {
659 return rg_template("warning.html", array("msg" => $msg));
660 }
661
662 /*
663 * Show an OK message using a template
664 */
665 function rg_ok($msg)
666 {
667 return rg_template("ok.html", array("msg" => $msg));
668 }
669
654 670 /* /*
655 671 * Execute $cmd and returns the output as a string, binary safe * Execute $cmd and returns the output as a string, binary safe
656 672 */ */
File inc/ver.php.in added (mode: 100644) (index 0000000..32beda9)
1 <?php
2
3 $rocketgit_version = "@VER@-@REV@";
4
5 ?>
File rocketgit.spec.in changed (mode: 100644) (index 13b61a4..10fccff)
... ... Requires: shadow-utils, git, postgresql-server, policycoreutils-python
16 16 Light and fast Git hosting solution, similar with Gitorious/GitHub/etc. Light and fast Git hosting solution, similar with Gitorious/GitHub/etc.
17 17
18 18 %pre %pre
19 getent group rocketgit || groupadd -r rocketgit
20 getent passwd rocketgit || useradd -r -g rocketgit -s /bin/bash -m -d /home/rocketgit -c "RocketGit user" rocketgit
19 getent group rocketgit >/dev/null || groupadd -r rocketgit
20 getent passwd rocketgit >/dev/null || useradd -r -g rocketgit -s /bin/bash -m -d /home/rocketgit -c "RocketGit user" rocketgit
21 21 semanage fcontext -a -t httpd_log_t "/var/log/rocketgit-web(/.*)?" || : semanage fcontext -a -t httpd_log_t "/var/log/rocketgit-web(/.*)?" || :
22 22
23 23 %post %post
File root/themes/default/hints/ssh/key.html changed (mode: 100644) (index 0942c5b..dd08f27)
... ... To force the use of this key when you connect to the server,<br />
10 10 add the following lines to ~/.ssh/config (use tab to indent):<br /> add the following lines to ~/.ssh/config (use tab to indent):<br />
11 11 <code> <code>
12 12 Host @@rg_ssh_host@@<br /> Host @@rg_ssh_host@@<br />
13 &nbsp;&nbsp; User rocketgit<br />
13 14 &nbsp;&nbsp; Port @@rg_ssh_port@@<br /> &nbsp;&nbsp; Port @@rg_ssh_port@@<br />
14 15 &nbsp;&nbsp; IdentityFile ~/.ssh/rocketgit1<br /> &nbsp;&nbsp; IdentityFile ~/.ssh/rocketgit1<br />
15 16 </code> </code>
File root/themes/default/index.html changed (mode: 100644) (index 7183332..f3485a7)
11 11 <div id="container"> <div id="container">
12 12
13 13 <div id="header"> <div id="header">
14 <div id="logo_and_user" style="float: right;">
15 <div class="logo">
16 <a href="/"><b>RocketGit</b></a>
17 </div>
14 <table>
15 <tbody>
16 <tr>
17 <td>
18 <div class="logo"><a href="/">RocketGit</a></div>
19 </td>
18 20
19 @@if(@@rg_username@@){{
20 <div class="user">
21 @@rg_username@@
22 </div>
23 }}{{}}
24 </div>
21 @@if(@@rg_username@@){{
22 <td>
23 <div class="user"><a href="/">@@rg_username@@</a></div>
24 </td>
25 }}{{}}
25 26
26 <div id="menus">
27 @@rg_menu@@
28 </div>
27 <td>
28 <div id="menus">
29 @@rg_menu@@
30 </div>
31 </td>
32 </tr>
33 </tbody>
34 </table>
29 35 </div> <!-- header --> </div> <!-- header -->
30 36
31 37 <div id="main_container"> <div id="main_container">
 
35 41 </div> <!-- main_container --> </div> <!-- main_container -->
36 42
37 43 <div id="footer"> <div id="footer">
38 <div style="float: left; padding: 5px;">
44 <table>
45 <tbody>
46 <tr>
47 <td>
39 48 <img src="@@IMG:logo/rg4.png@@" alt="RocketGit" /><br /> <img src="@@IMG:logo/rg4.png@@" alt="RocketGit" /><br />
40 49 <b>RocketGit</b> <b>RocketGit</b>
41 </div>
50 </td>
42 51
43 <div style="float: left; padding: 5px; padding-left: 20px;">
44 <small>Copyright: <a href="http://kernel.embedromix.ro/" target="_new">Catalin(ux) M. BOIE</a></small>
45 </div>
52 <td>
53 Copyright: <a href="http://kernel.embedromix.ro/">Catalin(ux) M. BOIE</a><br />
54 Version: @@rg_version@@
55 </td>
56 </tr>
57 </tbody>
58 </table>
46 59 </div> <!-- footer --> </div> <!-- footer -->
47 60
48 61 </div> <!-- container --> </div> <!-- container -->
File root/themes/default/main.css changed (mode: 100644) (index 599bd72..799f323)
... ... table {
16 16 color: #000000; color: #000000;
17 17 border-spacing: 1px; border-spacing: 1px;
18 18 padding: 1px; padding: 1px;
19 margin-top: 3px;
19 20 } }
20 21
21 22 th, td { th, td {
 
... ... form input[type="submit"] {
49 50
50 51 #container { } #container { }
51 52
52 #logo_and_user {
53 display: inline-block;
53 .logo {
54 padding: 3px 0px;
54 55 } }
55
56 .logo { padding: 3px 0px; }
57 56 .logo a { .logo a {
58 font-size: 14pt;
57 font-size: 11pt;
58 font-weight: bold;
59 59 text-decoration: none; text-decoration: none;
60 60 color: red; color: red;
61 padding: 3px 12px 3px 0px;
61 62 } }
62 63
63 .user { padding: 3px 0px; }
64 .user {
65 padding: 3px 0px;
66 }
67 .user a {
68 font-size: 11pt;
69 font-weight: bold;
70 text-decoration: none;
71 color: #0000FF;
72 padding: 3px 12px 3px 0px;
73 }
64 74
65 75 #menus { #menus {
66 76 display: inline-block; display: inline-block;
 
... ... form input[type="submit"] {
74 84 text-decoration: none; text-decoration: none;
75 85 color: #666666; color: #666666;
76 86 font-size: 11pt; font-size: 11pt;
77 padding: 3px 6px;
78 87 font-weight: bold; font-weight: bold;
88 padding: 3px 12px 3px 0px;
79 89 } }
80 90 .menu ul li a:hover { color: #AAAAAA; } .menu ul li a:hover { color: #AAAAAA; }
81 91 .menu ul li a.selected { color: #BBBBBB; } .menu ul li a.selected { color: #BBBBBB; }
 
... ... form input[type="submit"] {
96 106 .tag a { background-color: #ffffa0; } .tag a { background-color: #ffffa0; }
97 107
98 108 #header { #header {
99 padding: 3px;
100 109 overflow: hidden; overflow: hidden;
101 110 border-bottom: 1px solid #CCCCCC; border-bottom: 1px solid #CCCCCC;
111 background-color: #FFFFFF;
112 padding: 0 15px 0 15px;
113 }
114 #header table {
115 border-collapse: collapse;
116 border: 0;
117 border-spacing: 0;
118 background-color: #FFFFFF;
119 }
120 #header table td {
121 padding: 0 10px 0 0;
122 border: 0px;
102 123 } }
103 124
125
104 126 #main_container { #main_container {
105 127 min-height: 400px; min-height: 400px;
106 128 background-color: #EEEEEE; background-color: #EEEEEE;
 
... ... form input[type="submit"] {
113 135 } }
114 136
115 137 #footer { #footer {
116 clear: both;
117 border-top: 1px solid #CCCCCC;
118 padding: 5px 5px;
119 138 overflow: hidden; overflow: hidden;
139 border-top: 1px solid #CCCCCC;
140 background-color: #FFFFFF;
141 padding: 5px 15px 5px 15px;
142 }
143 #footer table {
144 border-collapse: collapse;
145 border: 0;
146 border-spacing: 0;
147 background-color: #FFFFFF;
148 }
149 #footer table td {
150 padding: 3px 40px 3px 0;
151 border: 0px;
152 font-size: 10pt;
153 line-height: 120%;
120 154 } }
121 155
122 156 .formarea { .formarea {
123 margin-top: 10px;
157 margin-top: 5px;
124 158 border: 1px solid #CCCCCC; border: 1px solid #CCCCCC;
125 159 padding: 5px; padding: 5px;
126 160 border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px;
 
... ... form input[type="submit"] {
135 169 } }
136 170
137 171 #profiling { #profiling {
138 clear: both;
139 172 border-top: 1px solid #cccccc; border-top: 1px solid #cccccc;
140 173 padding: 5px 5px; padding: 5px 5px;
141 174 border-bottom: 1px solid #cccccc; border-bottom: 1px solid #cccccc;
 
... ... form input[type="submit"] {
149 182 } }
150 183
151 184 .form_item_title { .form_item_title {
152 -font-weight: bold;
153 -padding: 2px;
154 185 } }
155 186
156 187 .rg_keys_list { .rg_keys_list {
 
... ... form input[type="submit"] {
303 334 } }
304 335
305 336 .warning { .warning {
306 margin-top: 10px;
337 margin-top: 5px;
307 338 background-color: #FF0000; background-color: #FF0000;
308 339 padding: 5px; padding: 5px;
309 340 border: 1px solid #CCCCCC; border: 1px solid #CCCCCC;
310 341 display: table; display: table;
311 342 } }
312 343
344 .ok {
345 margin-top: 5px;
346 background-color: #00FF00;
347 padding: 5px;
348 border: 1px solid #CCCCCC;
349 display: table;
350 }
351
352 .page_title {
353 margin-top: 5px;
354 font-size: 13pt;
355 font-weight: bold;
356 }
File root/themes/default/ok.html added (mode: 100644) (index 0000000..54b2283)
1 <div class="ok">
2 @@msg@@
3 </div>
File root/themes/default/repo/bug/search/remove.html changed (mode: 100644) (index b032b77..bd79288)
5 5 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
6 6 <input type="hidden" name="name" value="@@search_name@@" /> <input type="hidden" name="name" value="@@search_name@@" />
7 7
8 <input type="submit" name="button" value="Remove [@@search_name@@]" />
8 <input type="submit" name="button" value="Remove search [@@search_name@@]" />
9 9 </form> </form>
File root/themes/default/repo/bug/search/search.html changed (mode: 100644) (index 11e1e0f..3afe7fb)
53 53 <br /> <br />
54 54
55 55 @@if(@@can_save@@ == 1){{ @@if(@@can_save@@ == 1){{
56 <label for="for_all_users" class="form_item_title">Make this search available also for other users?</label><br />
56 <label for="for_all_users" class="form_item_title">Make this search public (available for other users)?</label><br />
57 57 <input type="checkbox" name="for_all_users" @@if(@@for_all_users@@ == 1){{checked="checked"}}{{}} /> <input type="checkbox" name="for_all_users" @@if(@@for_all_users@@ == 1){{checked="checked"}}{{}} />
58 58 <br /> <br />
59 59 <br /> <br />
File root/themes/default/repo/list/header.html changed (mode: 100644) (index e988ebc..79e48b3)
1 <div class="page_title">Repositories</div>
1 2 <table> <table>
2 3 <tr> <tr>
3 4 <th>User / name</th> <th>User / name</th>
File root/themes/default/user/keys/add.html changed (mode: 100644) (index bccab7a..3d06fe9)
2 2
3 3 <div class="formarea_title">Add a new ssh key</div><br /> <div class="formarea_title">Add a new ssh key</div><br />
4 4
5 @@errmsg@@
5 @@add_errmsg@@
6 6
7 7 <form method="post" action="@@rg_action@@"> <form method="post" action="@@rg_action@@">
8 8 <input type="hidden" name="add" value="1" /> <input type="hidden" name="add" value="1" />
File root/themes/default/user/keys/list/footer.html changed (mode: 100644) (index 7aae9f5..f7b135b)
1 1 </table> </table>
2
3 <input type="submit" name="button" value="Delete selected keys" />
4 </form>
2 5 </div> </div>
File root/themes/default/user/keys/list/header.html changed (mode: 100644) (index 62fba12..0d20c77)
1 1 <div class="rg_keys_list"> <div class="rg_keys_list">
2
3 @@del_errmsg@@
4
5 <form method="post" action="@@rg_action@@">
6 <input type="hidden" name="delete" value="1" />
7 <input type="hidden" name="token" value="@@rg_form_token@@" />
8
2 9 <table> <table>
3 10 <tr> <tr>
11 <th>Select</th>
4 12 <th>Date (UTC)</th> <th>Date (UTC)</th>
5 13 <th>Fingerprint</th> <th>Fingerprint</th>
6 14 <th>Comment</th> <th>Comment</th>
7 <th>Operations</th>
15 <th>Last use (UTC)</th>
16 <th>Last IP</th>
8 17 </tr> </tr>
9 18
File root/themes/default/user/keys/list/line.html changed (mode: 100644) (index 712e515..9af8056)
1 1 <!-- @@DUMP-DISABLED@@ --> <!-- @@DUMP-DISABLED@@ -->
2 2 <tr> <tr>
3 <td><input type="checkbox" name="key_delete_ids[@@key_id@@]" /></td>
3 4 <td>@@itime@@</td> <td>@@itime@@</td>
4 5 <td>@@fingerprint@@</td> <td>@@fingerprint@@</td>
5 6 <td>@@comment@@</td> <td>@@comment@@</td>
6 <td>@@operations@@</td>
7 <td>@@last_use@@</td>
8 <td>@@last_ip@@</td>
7 9 </tr> </tr>
8 10
File root/themes/default/user/pass.html added (mode: 100644) (index 0000000..ba0cc9c)
1 <div class="formarea">
2
3 <div class="formarea_title">Change password</div><br />
4
5 @@errmsg@@
6
7 <form method="post" action="@@rg_action@@">
8 <input type="hidden" name="doit" value="1" />
9 <input type="hidden" name="token" value="@@rg_form_token@@" />
10
11 <label for="old_pass" class="form_item_title">Old password</label><br />
12 <input type="password" name="old_pass" value="@@old_pass@@" />
13 <br />
14 <br />
15
16 <label for="pass1" class="form_item_title">New password</label><br />
17 <input type="password" name="pass1" value="@@pass1@@" />
18 <br />
19 <br />
20
21 <label for="pass2" class="form_item_title">New password (re-type)</label><br />
22 <input type="password" name="pass2" value="@@pass2@@" />
23 <br />
24 <br />
25
26 <input type="submit" name="button" value="Change password" />
27
28 </form>
29 </div>
File root/themes/default/warning.html copied from file root/themes/default/repo/tree/nodata.html (similarity 70%) (mode: 100644) (index d5ef081..539b431)
1 1 <div class="warning"> <div class="warning">
2 Empty tree.
2 @@msg@@
3 3 </div> </div>
File scripts/remote.php changed (mode: 100644) (index df1f5a6..963c7db)
... ... require_once($INC . "/struct.inc.php");
14 14 require_once($INC . "/repo.inc.php"); 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 require_once($INC . "/keys.inc.php");
17 18
18 19 rg_prof_start("remote.php"); rg_prof_start("remote.php");
19 20
20 21 rg_log_set_file($rg_log_dir . "/remote.log"); rg_log_set_file($rg_log_dir . "/remote.log");
21 22
22 function fatal($str)
23 function info($str)
23 24 { {
24 25 global $access_type; global $access_type;
25 26
26 27 rg_log("Sending error: " . $str); rg_log("Sending error: " . $str);
27 $str2 = "RocketGit: FATAL ERROR: " . $str . "\n";
28 $str2 = "RocketGit: " . $str . "\n";
28 29 if ($access_type == 2) { // git if ($access_type == 2) { // git
29 30 $str3 = "\n" . $str2; $str3 = "\n" . $str2;
30 31 $len = strlen($str3) + 4; $len = strlen($str3) + 4;
 
... ... function fatal($str)
33 34 } else { // ssh } else { // ssh
34 35 fwrite(STDERR, $str2); fwrite(STDERR, $str2);
35 36 } }
37 }
38
39 function fatal($str)
40 {
41 info("FATAL ERROR: $str");
36 42 exit(1); exit(1);
37 43 } }
38 44
45 umask(0022);
46
39 47 rg_log("Start..."); rg_log("Start...");
40 48 rg_log("_SERVER: " . rg_array2string($_SERVER)); rg_log("_SERVER: " . rg_array2string($_SERVER));
41 49
42 umask(0022);
50 info("Welcome to RocketGit " . $more['rg_version'] . "!");
43 51
44 52 $db = rg_sql_open($rg_sql); $db = rg_sql_open($rg_sql);
45 53 if ($db === FALSE) if ($db === FALSE)
 
... ... if (isset($_SERVER['SSH_CONNECTION'])) {
57 65 $host = ""; $host = "";
58 66
59 67 // first parameter must be uid of the user // first parameter must be uid of the user
60 $uid = @$_SERVER['argv'][1];
61 if (empty($uid))
68 $uid = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 0;
69 if ($uid == 0)
62 70 fatal("uid not provided!"); fatal("uid not provided!");
63 71 rg_log("\tuid is $uid."); rg_log("\tuid is $uid.");
64 72
73 // second parameter must be the ssh key id
74 $key_id = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : 0;
75 if ($key_id == 0)
76 fatal("key_id not provided!");
77 rg_log("\tkey_id is $key_id.");
78
65 79 if (!isset($_SERVER['SSH_ORIGINAL_COMMAND'])) if (!isset($_SERVER['SSH_ORIGINAL_COMMAND']))
66 80 $cmd_repo = ""; $cmd_repo = "";
67 81 else else
 
... ... if (isset($_SERVER['SSH_CONNECTION'])) {
71 85 $ssh_client = getenv("SSH_CLIENT"); $ssh_client = getenv("SSH_CLIENT");
72 86 $_t = explode(" ", $ssh_client); $_t = explode(" ", $ssh_client);
73 87 $ip = $_t[0]; $ip = $_t[0];
88
89 // TODO: This should be put in a queue for performance reasons
90 $_r = rg_keys_update_use($db, $key_id, $ip);
91 if ($_r !== TRUE)
92 rg_internal_error("Cannot update key last_use!");
74 93 } else { } else {
75 94 rg_log("git-daemon connection..."); rg_log("git-daemon connection...");
76 95 $access_type = 2; $access_type = 2;
77 96
78 97 // we have no client info // we have no client info
79 98 $uid = 0; $uid = 0;
99 $key_id = 0;
80 100
81 101 $f = @fopen("php://stdin", "r"); $f = @fopen("php://stdin", "r");
82 102 if ($f === FALSE) if ($f === FALSE)
 
... ... if (($push == 1) && rg_repo_over_limit($ri))
176 196
177 197 // Put in environment all we need // Put in environment all we need
178 198 putenv("ROCKETGIT_UID=" . $uid); putenv("ROCKETGIT_UID=" . $uid);
199 putenv("ROCKETGIT_KEY_ID=" . $key_id);
179 200 putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']); putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']);
180 201 putenv("ROCKETGIT_REPO_RIGHTS=" . $rights); putenv("ROCKETGIT_REPO_RIGHTS=" . $rights);
181 202 putenv("ROCKETGIT_REPO_PATH=" . $repo_path); putenv("ROCKETGIT_REPO_PATH=" . $repo_path);
 
... ... rg_log("Running [$run]...");
204 225 passthru($run, $ret); passthru($run, $ret);
205 226 rg_log("[$run] returned $ret."); rg_log("[$run] returned $ret.");
206 227
228 info("Done. Thank you!");
229
207 230 rg_prof_end("remote.php"); rg_prof_end("remote.php");
208 231 rg_prof_log("rg_log"); rg_prof_log("rg_log");
209 232 ?> ?>
File tests/keys.php changed (mode: 100644) (index d1878bd..8964324)
... ... if ($c === FALSE) {
63 63 echo "Cannot regenerate file: " . rg_keys_error() . "!\n"; echo "Cannot regenerate file: " . rg_keys_error() . "!\n";
64 64 exit(1); exit(1);
65 65 } }
66 $e = "command=\"/usr/bin/php " . $rg_scripts . "/scripts/remote.php 1\"," . $rg_ssh_paras . " aaa 'bbb' first_key\n"
67 . "command=\"/usr/bin/php " . $rg_scripts . "/scripts/remote.php 2\"," . $rg_ssh_paras . " aaa 'bbb' second_key\n";
66 $e = "command=\"/usr/bin/php "
67 . $rg_scripts . "/scripts/remote.php 1 $key_id1\","
68 . $rg_ssh_paras . " aaa 'bbb' first_key\n"
69 . "command=\"/usr/bin/php "
70 . $rg_scripts . "/scripts/remote.php 2 $key_id2\","
71 . $rg_ssh_paras . " aaa 'bbb' second_key\n";
68 72 if (strcmp($c, $e) != 0) { if (strcmp($c, $e) != 0) {
69 73 echo "Generated file does not seems OK!\n"; echo "Generated file does not seems OK!\n";
70 74 echo "e: $e\n"; echo "e: $e\n";
 
... ... if (strcmp($c, $e) != 0) {
77 81
78 82 // delete a key // delete a key
79 83 $rg_ui = array("uid" => 1, "is_admin" => 0); $rg_ui = array("uid" => 1, "is_admin" => 0);
80 $r = rg_keys_remove($db, $rg_ui, $key_id1);
84 $flags = array();
85 $r = rg_keys_remove($db, $rg_ui, $key_id1, $flags);
81 86 if ($r === FALSE) { if ($r === FALSE) {
82 87 echo "Cannot remove key (" . rg_keys_error() . ")!\n"; echo "Cannot remove key (" . rg_keys_error() . ")!\n";
83 88 exit(1); exit(1);
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