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 9c1328fa3c207d9bc109c2dd486999318a215d84

Fixes all over the code; made webhooks generic
Author: Catalin(ux) M. BOIE
Author date (UTC): 2015-12-29 07:40
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2015-12-29 07:40
Parent(s): 43e213676ffb27fabc4d0137337ac6e332185a33
Signing key:
Tree: e610030ec98d14211cd5a990131e036290d2c77e
File Lines added Lines deleted
TODO 87 2
inc/admin.inc.php 7 5
inc/bug.inc.php 7 7
inc/cache.inc.php 1 1
inc/fixes.inc.php 68 0
inc/repo.inc.php 123 105
inc/rights.inc.php 14 11
inc/struct.inc.php 4 0
inc/user/home-page.php 1 1
inc/user/repo-page.php 3 2
inc/user/repo/bug/main.php 1 1
inc/user/repo/bug/show/show.php 1 2
inc/watch.inc.php 12 7
inc/webhooks.inc.php 37 608
rocketgit.spec.in 1 1
root/index.php 1 0
root/themes/default/hints/repo/lock_repo.html 1 5
root/themes/default/index.html 43 48
root/themes/default/main.css 35 50
root/themes/default/user/repo/rights/form_repo.html 1 1
root/themes/default/user/repo/rights/form_repo_path.html 1 1
root/themes/default/user/repo/rights/form_repo_refs.html 1 1
root/themes/default/user/settings/wh/add_edit.html 6 23
root/themes/default/user/settings/wh/hints.html 6 5
root/themes/default/user/settings/wh/list/header.html 0 4
root/themes/default/user/settings/wh/list/line.html 0 4
root/themes/default/watch.html 1 0
scripts/cache.php 9 8
techdocs/cache.txt 4 1
tests/Makefile 3 3
tests/helpers.inc.php 3 3
tests/http.inc.php 3 1
tests/http_bug.php 3 2
tests/repo.php 76 22
tests/wh.php 0 352
File TODO changed (mode: 100644) (index 4de79e0..8708d3a)
1 1 == Where I stopped last time == == Where I stopped last time ==
2 [ ] Fix notes css
2 [ ] When we pass the repo_id as parameter, I must validate the user is allowed
3 to do it!!!
4 [ ] Plan for webhooks:
5 If we do 'include', take care of type to be aonly a-bA-B0-9_!
6 [ ] Do not show 'webhooks' menu if the login user has no rights.
7 This is for when we will allow webhooks per repo.
8 [ ] rg_wh_http_cosmetic is not used. How should we show custom data?
9 Use a custom function?
10 [ ] Check if we have in database a watch with uid == 0!
11 delete from watch_bug where uid = 0;
12 [ ] bugs in cache are indexed by repo_id! Not good!
13 [ ] I do not have rights to del_undex bugs, but I am still getting the
14 token (token_get). Not good.
15 [ ]
3 16
4 17 == BEFORE NEXT RELEASE == == BEFORE NEXT RELEASE ==
18 [ ] Add labels for users and for repos/comments/etc.? [Also] private ones?
19 [ ] I should add "Labels: " in front of labels.
20 [ ] last events: gravatar
21 [ ] last events: 2015-12-27 09:42 n/a Reference refs/heads/master created (290e4f7a70640d79836b3298c47b913484da24de)
22 Why we do not have the user?! Ah, because is anonymous.
23 Should we just say so?
24 [ ] rights: store '*' as equivalent for "all rights". Else, when we will add
25 more rights, they will not be automatically added to the list.
26 [ ] http://r1i:9000/op/settings/wh looks wrong!
27 [ ] "Please login first"/"Login form" are now justified.
28 [ ] Use rg_repo_has_rights.
29 [ ] Do we stop event processing when we change the structure?
30 [ ] wh: add 'listen tcp socket', 'connecting tcp/udp socket', 'ssh', 'mail'
31 hooks.
32 [ ] wh: how to integrate other types of hooks? For example: mail/amazon/etc.
33 Now, I broken it by adding certs to the main wh table, things
34 that do not make sense for other hooks. Are not generic! Bad!
35 Probably I will have to do a 'fix' functin to switch to the new system.
36 [ ] git: do not try to show binary files.
37 [ ] css: 'source'/'bug_body'/'notes'/'mess' was with display: table
38 [ ] css: decide aboud island_row if we do not switch to flex
39 [ ] Adapt HTML title based on content
40 [ ] When showing a commit, add the subject, the body, who commited, gravatar,
41 itime, treeish, last tag/branch etc.
42 [ ] readme and vm: add --data-checksums to initdb! Seems the performance hit
43 is not too big.
44 [ ] rights: split into "List" and "Grant".
45 When editing, should I show the list? Put the edit form above list.
46 [ ] path rights: allow add/delete filenames? Maybe also 'rename' right?
47 Maybe split "Push" into: "Add files", "Delete files", "Change files"
48 [ ] link gravatar with user homepage
49 [ ] add "link" text to the comments, so users can link to comments. and not only.
50 [ ] db: we may want to run CLUSTER on some tables.
51 rights table: type, obj_id, prio, itime
52 [ ] db: event.php to have more rights on users tables than web access.
53 Maybe I can add INSERT/UPDATE on 'users' to web for email column.
54 Maybe use views to separate the rights.
55 [ ] ci: add coccinelle into the mix (next to cppcheck)
56 http://thread.gmane.org/gmane.linux.network/390690
57 [ ] si inca o chestie foarte utila ar fi sa pot accesa fisierul raw, fara line
58 number, pentru a putea da copy la mai multe linii deodata (Gabi B)
59 [ ] o sugestie ar mai fi ca atunci cand sunt deja pe un fisier sa pot accesa
60 istoricul lui (Gabi)
61 [ ] tree: I have no "UP" folder or the list of dirs with links behind.
62 [ ] If a repo changes from public to private or the other way around,
63 I must invalidate the rights cache.
64 [ ] rights: if a user has 'admin/give_rights' rights, allow push?
65 [ ] wh: add prios - we may want to have a hook for storing in s3 and a hook for
66 deployment. Hm.
67 [ ] amazon: CodeDeploy a very nice presentation:
68 https://confluence.atlassian.com/bamboo/using-the-aws-codedeploy-task-750396059.html
69 [ ] amazon: allow deploy to multiple regions
70 [ ] amazon: is clear that i have to use a role and a custom bucket
71 Still investigating how to trigger a CodeDeploy task that will fetch
72 from repo and do the deploy. Not use if is possible.
73 [ ] 2fa: m.google.com/authenticator - also for BlackBerry/iPhone/iPad
74 [ ] At least refs rights are not reorder by priority! Bad!
75 [ ] When editing rights, it is not clear that we are in edit mode!
76 [ ] Markdown (Gabi B)
77 [ ] Editarea bug-urilor pare ca nu merge
78 Search for "2015-12-15 08:59:57.328 3a0126"
79 repo ladacubasme.html - repo_id = 19
80 user DiAngelo - uid 16 - user-ul logat
81 08:59:57.328 3a0126 rg_rights_get: obj_id=19 type=repo owner=16 uid=16 right_id=7
82 [ ] cind rejectez pentru ca nu sint drepturi, ar trebui sa explic ce lipseste.
83 [ ] clarify rg_base, some users may want to change it, but is not ok.
84 [ ] README: for manual install: useradd -G rocketgit rocketgit,
85 ./configure, make, make install, also check rpm spec file.
86 [ ] README assumes that rocketgit is already installed as package.
87 [ ] user metadata: description? homepage? picture?
88 [ ] gravatar: tell user to register!
5 89 [ ] get rid of beteen.html (because of css) [ ] get rid of beteen.html (because of css)
6 [ ] get rid of the div between notes.
7 90 [ ] make sure where we use gmdate to add ' UTC' [ ] make sure where we use gmdate to add ' UTC'
8 91 [ ] rights: "Add bug" should be inserted with prio 30001, [ ] rights: "Add bug" should be inserted with prio 30001,
9 92 so user can forbit adding bugs? so user can forbit adding bugs?
 
... ... But, we have a problem with the expiration time!
832 915 Se pare ca rg_rights_load e folosit doar pentru repo si nu si pentru user. Se pare ca rg_rights_load e folosit doar pentru repo si nu si pentru user.
833 916 rg_rights_set nu are notiunea de prio. rg_rights_set nu are notiunea de prio.
834 917 As vrea ca si owner-ul sa poata sa se limiteze la un anumit set de ip-uri. As vrea ca si owner-ul sa poata sa se limiteze la un anumit set de ip-uri.
918 This means that the rule with all allow must have prion 30000?
835 919 Asta inseamna ca, din start, ar trebui sa adaug o regula pentru owner. Asta inseamna ca, din start, ar trebui sa adaug o regula pentru owner.
836 920 Sa incerc sa schitez partea de admin a user-ilor. Sa incerc sa schitez partea de admin a user-ilor.
837 921
 
... ... them after processing is done.
1306 1390 == Low priority == == Low priority ==
1307 1391 [ ] If a user has no push access and creates merge request, but the owner pushed [ ] If a user has no push access and creates merge request, but the owner pushed
1308 1392 nothing, ssh cloning gives errors about HEAD not found. nothing, ssh cloning gives errors about HEAD not found.
1393 [ ] Add a "Report a bug on this page" - we already have the log_id!
1309 1394
1310 1395
1311 1396 == Graphics == == Graphics ==
File inc/admin.inc.php changed (mode: 100644) (index 0ecfcd0..bbc97d7)
... ... function rg_admin_report1($db, $rg)
371 371 $list = ''; $list = '';
372 372 while (($row = rg_sql_fetch_array($res))) { while (($row = rg_sql_fetch_array($res))) {
373 373 $users++; $users++;
374 $list .= sprintf("%30s %s\n",
375 $row['username'], $row['realname']);
374 $list .= "\t" . $row['username']
375 . "\t" . $row['realname'] . "\n";
376 376 } }
377 377 if ($users) if ($users)
378 $body .= "\nYesterday users (" . $users . "):\n" . $list;
378 $body .= "\nYesterday users (" . $users . "):\n"
379 . $list;
379 380 } }
380 381 rg_sql_free_result($res); rg_sql_free_result($res);
381 382
382 $sql = "SELECT name, description FROM repos"
383 $sql = "SELECT name, description, public FROM repos"
383 384 . " WHERE itime >= $y_start" . " WHERE itime >= $y_start"
384 385 . " AND itime <= $y_end"; . " AND itime <= $y_end";
385 386 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
 
... ... function rg_admin_report1($db, $rg)
392 393 $repos++; $repos++;
393 394 $desc = substr($row['description'], 0, 50); $desc = substr($row['description'], 0, 50);
394 395 $desc = preg_replace('/\s/', ' ', $desc); $desc = preg_replace('/\s/', ' ', $desc);
395 $list .= $row['name'] . " - " . $desc . "\n";
396 $list .= "\t" . $row['name'] . " - " . $desc
397 . ($row['public'] == 1 ? " (public)" : " (private)") . "\n";
396 398 } }
397 399 if ($repos) if ($repos)
398 400 $body .= "\nYesterday repos (" . $repos . "):\n" . $list; $body .= "\nYesterday repos (" . $repos . "):\n" . $list;
File inc/bug.inc.php changed (mode: 100644) (index b441f02..7b60ca6)
... ... function rg_bug_event_add_one($db, $event)
53 53 while (1) { while (1) {
54 54 // lookup user email // lookup user email
55 55 $ui = rg_user_info($db, $event['ui']['uid'], '', ''); $ui = rg_user_info($db, $event['ui']['uid'], '', '');
56 if ($ui['exists'] != 1) {
57 rg_internal_error("User does not exists!");
56 if ($ui['exists'] != 1)
58 57 break; break;
59 }
58 // TODO: maybe test for deleted?
60 59
61 60 // If user is not confirmed, do not send mail // If user is not confirmed, do not send mail
62 61 if ($ui['confirmed'] == 0) { if ($ui['confirmed'] == 0) {
 
... ... function rg_bug_info($db, $repo_id, $bug_id)
352 351 $ret['ok'] = 0; $ret['ok'] = 0;
353 352 $ret['exists'] = 0; $ret['exists'] = 0;
354 353 while (1) { while (1) {
355 $key = $repo_id . "::bugs::" . $bug_id;
354 $key = 'bugs' . '::' . $repo_id . '::' . $bug_id;
356 355 $c = rg_cache_get($key); $c = rg_cache_get($key);
357 356 if ($c !== FALSE) { if ($c !== FALSE) {
358 357 $ret = $c; $ret = $c;
 
... ... function rg_bug_edit($db, $login_ui, $ri, $data)
510 509 'bug' => array( 'bug' => array(
511 510 'who_added' => $login_ui['uid'], 'who_added' => $login_ui['uid'],
512 511 'who_added_text' => $login_ui['username'], 'who_added_text' => $login_ui['username'],
513 'url' => $ri['url_repo'] . '/bug/' . $data['bug_id'],
512 'url' => rg_base_url()
513 . rg_re_bugpage($login_ui, $ri['name'], $data['bug_id']),
514 514 'assigned_to_text' => $assigned_to_text, 'assigned_to_text' => $assigned_to_text,
515 515 'state_text' => rg_bug_state($data['state']))); 'state_text' => rg_bug_state($data['state'])));
516 516 $event = rg_array_merge($event, 'bug', $data); $event = rg_array_merge($event, 'bug', $data);
 
... ... function rg_bug_edit($db, $login_ui, $ri, $data)
531 531 // update cache // update cache
532 532 $data['ok'] = 1; $data['ok'] = 1;
533 533 $data['exists'] = 1; $data['exists'] = 1;
534 $key = $ri['repo_id'] . "::bugs::" . $data['bug_id'];
534 $key = 'bugs' . '::' . $ri['repo_id'] . '::' . $data['bug_id'];
535 535 rg_cache_set($key, $data, RG_SOCKET_NO_WAIT); rg_cache_set($key, $data, RG_SOCKET_NO_WAIT);
536 536
537 537 rg_event_signal_daemon("", 0); rg_event_signal_daemon("", 0);
 
... ... function rg_bug_delete_undelete($db, $who, $repo_id, $bug_id, $op)
588 588 $new['deleted'] = $deleted; $new['deleted'] = $deleted;
589 589 $new['utime'] = $now; $new['utime'] = $now;
590 590 $new['deleted_who'] = $who; $new['deleted_who'] = $who;
591 $key = $repo_id . "::bugs::" . $bug_id;
591 $key = 'bugs' . '::' . $repo_id . '::' . $bug_id;
592 592 rg_cache_merge($key, $new, RG_SOCKET_NO_WAIT); rg_cache_merge($key, $new, RG_SOCKET_NO_WAIT);
593 593
594 594 $ret = TRUE; $ret = TRUE;
File inc/cache.inc.php changed (mode: 100644) (index 4fa2f04..8510000)
... ... function rg_cache_core_merge($ns_var, $list)
99 99 $t = explode("::", $ns_var); $t = explode("::", $ns_var);
100 100 foreach ($t as $token) { foreach ($t as $token) {
101 101 if (!isset($tree[$token])) if (!isset($tree[$token]))
102 return FALSE;
102 $tree[$token] = array();
103 103
104 104 $tree = &$tree[$token]; $tree = &$tree[$token];
105 105 } }
File inc/fixes.inc.php changed (mode: 100644) (index 1c035d6..4dc8d88)
... ... $rg_fixes[1] = array("rg_fixes_user_index_by_id");
16 16 $rg_fixes[2] = array("rg_fixes_repo_index_by_id"); $rg_fixes[2] = array("rg_fixes_repo_index_by_id");
17 17 $rg_fixes[3] = array("rg_fixes_keys_regen"); $rg_fixes[3] = array("rg_fixes_keys_regen");
18 18 $rg_fixes[4] = array("rg_fixes_repos_last_bug_id"); $rg_fixes[4] = array("rg_fixes_repos_last_bug_id");
19 $rg_fixes[5] = array("rg_fixes_wh_ver2");
19 20
20 21 // This must be the last line // This must be the last line
21 22 $rg_fixes_ver = count($rg_fixes); $rg_fixes_ver = count($rg_fixes);
 
... ... function rg_fixes_user_index_by_id($db)
301 302 return $ret; return $ret;
302 303 } }
303 304
305 /*
306 * Move to the more generic webhooks structure
307 */
308 function rg_fixes_wh_ver2($db)
309 {
310 global $rg_repos;
311
312 rg_prof_start("fixes_wh_ver2");
313 rg_log_enter("fixes_wh_ver2");
314
315 $ret = FALSE;
316 while (1) {
317 $sql = "SELECT * FROM webhooks";
318 $res = rg_sql_query($db, $sql);
319 if ($res === FALSE)
320 break;
321
322 $all_fixed = TRUE;
323 while (($row = rg_sql_fetch_array($res))) {
324 $idata = array();
325 $idata['client_cert'] = $row['client_cert'];
326 $idata['client_ca_cert'] = $row['client_ca_cert'];
327 $idata['flags'] = $row['flags'];
328 $idata['itype'] = $row['type'];
329
330 $params = array(
331 'id' => $row['id'],
332 'idata' => serialize($idata)
333 );
334 $sql = 'UPDATE webhooks SET idata = @@idata@@'
335 . ' WHERE id = @@id@@';
336 $res2 = rg_sql_query_params($db, $sql, $params);
337 rg_sql_free_result($res2);
338 if ($res2 === FALSE) {
339 $all_fixed = FALSE;
340 break;
341 }
342 }
343 rg_sql_free_result($res);
344 if ($all_fixed !== TRUE)
345 break;
346
347 // Remove old fileds
348 $all_good = TRUE;
349 $a = array('client_cert', 'client_ca_cert', 'flags', 'type');
350 foreach ($a as $t) {
351 $sql = 'ALTER TABLE webhooks DROP ' . $t;
352 $res = rg_sql_query($db, $sql);
353 if ($res === FALSE) {
354 rg_log('Could not drop ' . $t . '!');
355 $all_good = FALSE;
356 break;
357 }
358 rg_sql_free_result($res);
359 }
360 if (!$all_good)
361 break;
362
363 $ret = TRUE;
364 break;
365 }
366
367 rg_log_exit();
368 rg_prof_end("fixes_wh_ver2");
369 return $ret;
370 }
371
304 372
305 373 /* /*
306 374 * Apply fixes * Apply fixes
File inc/repo.inc.php changed (mode: 100644) (index bd79904..c656ed9)
... ... $rg_repo_rights = array(
41 41 "B" => "Add bugs", "B" => "Add bugs",
42 42 "r" => "Reopen bugs", "r" => "Reopen bugs",
43 43 "d" => "Delete bugs", "d" => "Delete bugs",
44 "C" => "Close bugs"
44 "C" => "Close bugs",
45 'W' => 'Manage hooks'
45 46 ); );
46 47
47 48 // TODO: default rights should go into conf file? // TODO: default rights should go into conf file?
 
... ... rg_rights_register("repo_path", $rg_repo_path_rights, "P",
54 55 rg_rights_register("repo", $rg_repo_rights, "AaB", rg_rights_register("repo", $rg_repo_rights, "AaB",
55 56 FALSE, "rg_repo_rights_inject"); FALSE, "rg_repo_rights_inject");
56 57
58 /*
59 * Returns info about a repo
60 * If you want to lookup by repo_id or uid/repo_name
61 */
62 function rg_repo_info($db, $repo_id, $uid, $repo_name)
63 {
64 rg_prof_start("repo_info");
65 rg_log_enter("repo_info: repo_id=$repo_id uid=$uid repo_name=$repo_name.");
66
67 $ret['ok'] = 0;
68 $ret['exists'] = 0;
69 while(1) {
70 $params = array("uid" => $uid,
71 "repo_id" => $repo_id,
72 "repo_name" => $repo_name);
73
74 if ($repo_id > 0) {
75 $c = rg_cache_get('repo_by_id' . '::' . $repo_id);
76 if (($c !== FALSE) && isset($c['repo_id'])) {
77 $ret = $c;
78 rg_repo_cosmetic($db, $ret);
79 break;
80 }
81
82 $sql = "SELECT * FROM repos WHERE repo_id = @@repo_id@@";
83 } else if (!empty($repo_name)) {
84 $x_repo_id = rg_cache_get("repo_by_name::$uid::$repo_name");
85 if ($x_repo_id !== FALSE) {
86 $ret = rg_repo_info($db, $x_repo_id, $uid, "");
87 break;
88 }
89
90 $sql = "SELECT * FROM repos WHERE uid = @@uid@@"
91 . " AND name = @@repo_name@@";
92 } else {
93 rg_repo_set_error("no repo_id or user/repo specified!");
94 break;
95 }
96
97 $res = rg_sql_query_params($db, $sql, $params);
98 if ($res === FALSE) {
99 rg_repo_set_error("cannot query (" . rg_sql_error() . ")");
100 break;
101 }
102 $rows = rg_sql_num_rows($res);
103 if ($rows > 0)
104 $ret = rg_sql_fetch_array($res);
105 rg_sql_free_result($res);
106
107 if (($rows == 0) && ($repo_id == 0)) {
108 // Repo not found, maybe it was renamed
109 $_repo_id = rg_repo_lookup_by_old_name($db, $uid, $repo_name);
110 if ($_repo_id === FALSE)
111 break;
112
113 if ($_repo_id > 0) {
114 $ret = rg_repo_info($db, $_repo_id, 0, "");
115 break;
116 }
117 }
118
119 $ret['ok'] = 1;
120 if ($rows > 0) {
121 $ret['exists'] = 1;
122 } else {
123 $ret['exists'] = 0;
124 }
125 //rg_log_ml("CHECK: ret=" . print_r($ret, TRUE));
126
127 if ($ret['exists'] == 1) {
128 rg_cache_set('repo_by_id' . '::' . $ret['repo_id'],
129 $ret, RG_SOCKET_NO_WAIT);
130
131 rg_cache_set("repo_by_name::$uid::" . $ret['name'],
132 $ret['repo_id'], RG_SOCKET_NO_WAIT);
133 }
134
135 if ($rows > 0)
136 rg_repo_cosmetic($db, $ret);
137 break;
138 }
139
140 rg_log_exit();
141 rg_prof_end("repo_info");
142 return $ret;
143 }
144
57 145 /* /*
58 146 * Function used to inject rights for a obj_id/type combination * Function used to inject rights for a obj_id/type combination
59 147 * It will be called from rg_rights_get * It will be called from rg_rights_get
 
... ... function rg_repo_rights_inject($db, $obj_id, $type, $owner, $uid)
142 230 return $ret; return $ret;
143 231 } }
144 232
233 /*
234 * Returns TRUE if the login user has @rights rights
235 */
236 function rg_repo_has_rights($db, $rg, $rights)
237 {
238 $x = array();
239 $x['obj_id'] = $rg['ri']['repo_id'];
240 $x['type'] = 'repo';
241 $x['owner'] = $rg['ri']['uid'];
242 $x['uid'] = $rg['login_ui']['uid'];
243 $x['username'] = $rg['login_ui']['username'];
244 $x['needed_rights'] = $rights;
245 $x['ip'] = $rg['ip'];
246 $x['misc'] = '';
247 return rg_rights_allow($db, $x);
248 }
249
145 250 /* /*
146 251 * Bring a ref to a canonical format (refs/x/name) * Bring a ref to a canonical format (refs/x/name)
147 252 * TODO: move to git.inc? * TODO: move to git.inc?
 
... ... function rg_repo_cosmetic($db, &$row)
675 780 $_a = rg_xss_safe(trim($row['description'])); $_a = rg_xss_safe(trim($row['description']));
676 781 $row['HTML:description_nlbr'] = nl2br($_a); $row['HTML:description_nlbr'] = nl2br($_a);
677 782 } else { } else {
678 $row['HTML:description_nlbr'] = '';
783 $row['HTML:description_nlbr'] = 'n/a';
679 784 } }
680 785
681 786 if (isset($row['itime'])) if (isset($row['itime']))
682 $row['HTML:itime_nice'] = gmdate('Y-m-d H:i', $row['itime']);
787 $row['HTML:itime_nice'] = gmdate('Y-m-d', $row['itime']);
683 788
684 789 $_ui = rg_user_info($db, $row['uid'], '', ''); $_ui = rg_user_info($db, $row['uid'], '', '');
685 790 if ($_ui['exists'] == 1) { if ($_ui['exists'] == 1) {
 
... ... function rg_repo_cosmetic($db, &$row)
701 806 $row['disk_used'] = rg_1024($row['disk_used_mb'] * 1024 * 1024); $row['disk_used'] = rg_1024($row['disk_used_mb'] * 1024 * 1024);
702 807 } }
703 808
704 /*
705 * Returns info about a repo
706 * If you want to lookup by repo_id or uid/repo_name
707 */
708 function rg_repo_info($db, $repo_id, $uid, $repo_name)
709 {
710 rg_prof_start("repo_info");
711 rg_log_enter("repo_info: repo_id=$repo_id uid=$uid repo_name=$repo_name.");
712
713 $ret['ok'] = 0;
714 $ret['exists'] = 0;
715 while(1) {
716 $params = array("uid" => $uid,
717 "repo_id" => $repo_id,
718 "repo_name" => $repo_name);
719
720 if ($repo_id > 0) {
721 $c = rg_cache_get('repo_by_id' . '::' . $repo_id);
722 if (($c !== FALSE) && isset($c['repo_id'])) {
723 $ret = $c;
724 rg_repo_cosmetic($db, $ret);
725 break;
726 }
727
728 $sql = "SELECT * FROM repos WHERE repo_id = @@repo_id@@";
729 } else if (!empty($repo_name)) {
730 $x_repo_id = rg_cache_get("repo_by_name::$uid::$repo_name");
731 if ($x_repo_id !== FALSE) {
732 $ret = rg_repo_info($db, $x_repo_id, $uid, "");
733 break;
734 }
735
736 $sql = "SELECT * FROM repos WHERE uid = @@uid@@"
737 . " AND name = @@repo_name@@";
738 } else {
739 rg_repo_set_error("no repo_id or user/repo specified!");
740 break;
741 }
742
743 $res = rg_sql_query_params($db, $sql, $params);
744 if ($res === FALSE) {
745 rg_repo_set_error("cannot query (" . rg_sql_error() . ")");
746 break;
747 }
748 $rows = rg_sql_num_rows($res);
749 if ($rows > 0)
750 $ret = rg_sql_fetch_array($res);
751 rg_sql_free_result($res);
752
753 if (($rows == 0) && ($repo_id == 0)) {
754 // Repo not found, maybe it was renamed
755 $_repo_id = rg_repo_lookup_by_old_name($db, $uid, $repo_name);
756 if ($_repo_id === FALSE)
757 break;
758
759 if ($_repo_id > 0) {
760 $ret = rg_repo_info($db, $_repo_id, 0, "");
761 break;
762 }
763 }
764
765 $ret['ok'] = 1;
766 if ($rows > 0) {
767 $ret['exists'] = 1;
768 } else {
769 $ret['exists'] = 0;
770 }
771 //rg_log_ml("CHECK: ret=" . print_r($ret, TRUE));
772
773 if ($ret['exists'] == 1) {
774 rg_cache_set('repo_by_id' . '::' . $ret['repo_id'],
775 $ret, RG_SOCKET_NO_WAIT);
776
777 rg_cache_set("repo_by_name::$uid::" . $ret['name'],
778 $ret['repo_id'], RG_SOCKET_NO_WAIT);
779 }
780
781 if ($rows > 0)
782 rg_repo_cosmetic($db, $ret);
783 break;
784 }
785
786 rg_log_exit();
787 rg_prof_end("repo_info");
788 return $ret;
789 }
790
791 809 /* /*
792 810 * Delete a repo * Delete a repo
793 811 */ */
 
... ... function rg_repo_edit($db, $login_ui, &$new)
1007 1025 $new['description'] = trim($new['description']); $new['description'] = trim($new['description']);
1008 1026 $new['itime'] = time(); $new['itime'] = time();
1009 1027 $new['uid'] = $login_ui['uid']; $new['uid'] = $login_ui['uid'];
1010 rg_repo_cosmetic($db, $new);
1011 1028
1012 1029 if ($new['repo_id'] == 0) { if ($new['repo_id'] == 0) {
1013 1030 $new['deleted'] = 0; $new['deleted'] = 0;
 
... ... function rg_repo_edit($db, $login_ui, &$new)
1071 1088 'history_category' => $hcat, 'history_category' => $hcat,
1072 1089 'history_message' => $hmess); 'history_message' => $hmess);
1073 1090 $event = rg_array_merge($event, 'ri_old', $ri); $event = rg_array_merge($event, 'ri_old', $ri);
1074 $new['url'] = rg_base_url() . rg_re_repopage($login_ui, $new['name']);
1091 $new['url'] = rg_base_url()
1092 . rg_re_repopage($login_ui, $new['name']);
1075 1093 $event = rg_array_merge($event, 'ri', $new); $event = rg_array_merge($event, 'ri', $new);
1076 1094 $event['ri_old']['description_md5'] = md5($old_description); $event['ri_old']['description_md5'] = md5($old_description);
1077 1095 $event['ri']['description_md5'] = md5($new['description']); $event['ri']['description_md5'] = md5($new['description']);
 
... ... function rg_repo_admin_rights($db, $rg, $type)
1600 1618
1601 1619 // hints // hints
1602 1620 $hints = array(); $hints = array();
1603 $hints[]['HTML:hint'] = rg_template("hints/repo/edit_rights.html", $rg, TRUE /* xss */);
1604 $hints[]['HTML:hint'] = rg_template("hints/repo/edit_" . $type . "_rights.html", $rg, TRUE /* xss */);
1621 $hints[]['HTML:hint'] = rg_template("hints/repo/edit_rights.html",
1622 $rg, TRUE /* xss */);
1623 $hints[]['HTML:hint'] = rg_template("hints/repo/edit_"
1624 . $type . "_rights.html", $rg, TRUE /* xss */);
1605 1625 $ret .= rg_template_table("hints/list", $hints, $rg); $ret .= rg_template_table("hints/list", $hints, $rg);
1606 1626
1607 1627 return $ret; return $ret;
 
... ... function rg_repo_lock_high_level($db, &$rg)
1824 1844 if ($ls['ok'] != 1) if ($ls['ok'] != 1)
1825 1845 break; break;
1826 1846
1827 rg_log('ZZZ: status=' . $ls['status']);
1828 1847 $rg['ri']['next_status'] = 1 - $ls['status']; $rg['ri']['next_status'] = 1 - $ls['status'];
1848 $rg['ri']['reason'] = rg_var_str('ri::reason');
1849 $lock = rg_var_int('ri::lock');
1850 rg_log('ZZZ: status=' . $ls['status']);
1851 rg_log('ZZZ: lock=' . $lock);
1829 1852
1830 if ($rg['doit'] != 1) {
1831 $rg['ri']['reason'] = '';
1853 if ($rg['doit'] != 1)
1832 1854 break; break;
1833 }
1834
1835 $reason = rg_var_str('ri::reason');
1836 $lock = rg_var_str('ri::lock');
1837 rg_log('ZZZ: lock=' . $lock);
1838 1855
1839 1856 if (!rg_valid_referer()) { if (!rg_valid_referer()) {
1840 1857 $errmsg[] = "invalid referer; try again"; $errmsg[] = "invalid referer; try again";
 
... ... function rg_repo_lock_high_level($db, &$rg)
1848 1865 } }
1849 1866
1850 1867 $r = rg_repo_lock($db, $rg['ri']['repo_id'], $r = rg_repo_lock($db, $rg['ri']['repo_id'],
1851 $rg['login_ui']['uid'], $lock, $reason);
1868 $rg['login_ui']['uid'], $lock, $rg['ri']['reason']);
1852 1869 if ($r === FALSE) { if ($r === FALSE) {
1853 1870 $errmsg[] = rg_repo_error(); $errmsg[] = rg_repo_error();
1854 1871 break; break;
 
... ... function rg_repo_admin($db, &$rg, $paras)
1898 1915 $rg['allow_lock_repo'] = 0; $rg['allow_lock_repo'] = 0;
1899 1916 $rg['allow_grant_rights'] = 0; $rg['allow_grant_rights'] = 0;
1900 1917 $rg['allow_delete_repo'] = 0; $rg['allow_delete_repo'] = 0;
1918
1901 1919 $x = array(); $x = array();
1902 1920 $x['obj_id'] = $rg['ri']['repo_id']; $x['obj_id'] = $rg['ri']['repo_id'];
1903 1921 $x['type'] = 'repo'; $x['type'] = 'repo';
 
... ... function rg_repo_admin($db, &$rg, $paras)
1941 1959 break; break;
1942 1960
1943 1961 case 'lock': case 'lock':
1944 $rg['form_url'] = $rg['url_repo'] . "/admin/lock";
1962 $rg['form_url'] = $rg['ri']['url_repo'] . "/admin/lock";
1945 1963 $ret .= rg_repo_lock_high_level($db, $rg); $ret .= rg_repo_lock_high_level($db, $rg);
1946 1964 break; break;
1947 1965
1948 1966 default: default:
1949 $rg['form_url'] = $rg['url_repo'] . "/admin";
1967 $rg['form_url'] = $rg['ri']['url_repo'] . "/admin";
1950 1968 $ret .= rg_repo_edit_high_level($db, $rg); $ret .= rg_repo_edit_high_level($db, $rg);
1951 1969 break; break;
1952 1970 } }
File inc/rights.inc.php changed (mode: 100644) (index 0509c04..463f801)
... ... function rg_rights_get($db, $obj_id, $type, $owner, $uid, $right_id)
333 333 $a['can_be_deleted'] = 0; $a['can_be_deleted'] = 0;
334 334 $a['rights'] = rg_rights_all($type); $a['rights'] = rg_rights_all($type);
335 335 $a['description'] = 'Autogenerated (owner)'; $a['description'] = 'Autogenerated (owner)';
336 rg_rights_cosmetic($db, $a);
337 336
338 337 $r[] = $a; $r[] = $a;
339 338 } }
 
... ... function rg_rights_get($db, $obj_id, $type, $owner, $uid, $right_id)
350 349 } }
351 350
352 351 // now, filter by uid and right_id // now, filter by uid and right_id
352 $r2 = array();
353 353 foreach ($r as $k => $v) { foreach ($r as $k => $v) {
354 354 if (($right_id > 0) && ($v['right_id'] != $right_id)) if (($right_id > 0) && ($v['right_id'] != $right_id))
355 355 continue; continue;
356 356
357 357 if (($uid == -1) || ($v['uid'] == $uid) || ($v['uid'] == 0)) if (($uid == -1) || ($v['uid'] == $uid) || ($v['uid'] == 0))
358 $ret['list'][] = $v;
358 $r2[] = $v;
359 359 } }
360 360
361 361 // sorting by prio // sorting by prio
362 uasort($r, 'rg_rights_sort_helper');
362 uasort($r2, 'rg_rights_sort_helper');
363 363
364 364 // cosmetic // cosmetic
365 rg_log_ml('before cosmetic: ' . print_r($r, TRUE));
366 foreach ($r as $index => &$row)
365 //rg_log_ml('DEBUG: before cosmetic: ' . print_r($r2, TRUE));
366 foreach ($r2 as $index => &$row)
367 367 rg_rights_cosmetic($db, $row); rg_rights_cosmetic($db, $row);
368 368
369 $ret['list'] = $r;
369 $ret['list'] = $r2;
370 370 $ret['ok'] = 1; $ret['ok'] = 1;
371 371 break; break;
372 372 } }
 
... ... function rg_rights_test($list, $needed_rights, $ip, $misc)
662 662 { {
663 663 global $rg_rights_cmp_func; global $rg_rights_cmp_func;
664 664
665 rg_log_enter("rg_rights_test: needed_rights=$needed_rights ip=$ip"
666 . " misc=$misc list:" . rg_array2string($list));
665 rg_log_enter("rights_test: needed_rights=$needed_rights ip=$ip"
666 . " misc=" . $misc);
667 rg_log_ml('DEBUG list: ' . print_r($list, TRUE));
667 668
668 669 $ret = FALSE; $ret = FALSE;
669 670 while (1) { while (1) {
 
... ... function rg_rights_test($list, $needed_rights, $ip, $misc)
710 711 rg_log("[$r] != [$needed1]! Continue."); rg_log("[$r] != [$needed1]! Continue.");
711 712 continue; continue;
712 713 } }
713 //rg_log("[$r] = [$needed1]! Allow.");
714 rg_log("[$r] = [$needed1]! Allow.");
714 715 $have_a_match = TRUE; $have_a_match = TRUE;
715 716 break; break;
716 717 } }
717 718 if ($have_a_match === FALSE) if ($have_a_match === FALSE)
718 719 continue; continue;
719 720
721 rg_log('DEBUG: rule ' . $k . ' matched.');
720 722 $ret = TRUE; $ret = TRUE;
721 723 break; break;
722 724 } }
723 725
724 726 break; break;
725 727 } }
726 //rg_log("DEBUG: rights_test returns " . ($ret === FALSE ? "!allow" : "allow"));
728 rg_log("DEBUG: rights_test returns " . ($ret === FALSE ? "deny" : "allow"));
727 729
728 730 rg_log_exit(); rg_log_exit();
729 731 return $ret; return $ret;
 
... ... function rg_rights_allow($db, $a)
757 759 continue; continue;
758 760
759 761 $_old = $e['misc']; $_old = $e['misc'];
760 $e['misc'] = str_replace('@USER@', $username, $e['misc']);
762 $e['misc'] = str_replace('@USER@',
763 $username, $e['misc']);
761 764 rg_log("DEBUG [" . $_old . "] -> [" . $e['misc'] . "]"); rg_log("DEBUG [" . $_old . "] -> [" . $e['misc'] . "]");
762 765 } }
763 766 //rg_log_ml("DEBUG: r[list]=" . print_r($r['list'], TRUE)); //rg_log_ml("DEBUG: r[list]=" . print_r($r['list'], TRUE));
File inc/struct.inc.php changed (mode: 100644) (index 17caffa..09c3ed3)
... ... $rg_sql_struct[36]['other'] = array(
497 497 "ALTER TABLE keys ADD last_cmd TEXT NOT NULL DEFAULT ''", "ALTER TABLE keys ADD last_cmd TEXT NOT NULL DEFAULT ''",
498 498 'wh_last_output' => 'wh_last_output' =>
499 499 "ALTER TABLE webhooks ADD last_output TEXT NOT NULL DEFAULT ''", "ALTER TABLE webhooks ADD last_output TEXT NOT NULL DEFAULT ''",
500 'wh_htype' =>
501 "ALTER TABLE webhooks ADD htype TEXT NOT NULL DEFAULT 'http'",
502 'wh_idata' =>
503 "ALTER TABLE webhooks ADD idata TEXT NOT NULL DEFAULT ''",
500 504 'watch_repo_i_uid' => "CREATE INDEX watch_repo_i_uid on watch_repo(uid)", 'watch_repo_i_uid' => "CREATE INDEX watch_repo_i_uid on watch_repo(uid)",
501 505 'watch_bug_i_uid' => "CREATE INDEX watch_bug_i_uid on watch_repo(uid)", 'watch_bug_i_uid' => "CREATE INDEX watch_bug_i_uid on watch_repo(uid)",
502 506 'watch_user_i_uid' => "CREATE INDEX watch_user_i_uid on watch_repo(uid)" 'watch_user_i_uid' => "CREATE INDEX watch_user_i_uid on watch_repo(uid)"
File inc/user/home-page.php changed (mode: 100644) (index 10c677e..67b5d07)
... ... if ($rg['page_ui']['exists'] == 0) {
10 10 } }
11 11
12 12 rg_watch_hl_process($db, $rg, 'user', $rg['page_ui']['uid'], rg_watch_hl_process($db, $rg, 'user', $rg['page_ui']['uid'],
13 0, $rg['page_ui']['homepage']);
13 0, $rg['current_url']);
14 14
15 15 $_home .= rg_template('user/home.html', $rg, TRUE /*xss*/); $_home .= rg_template('user/home.html', $rg, TRUE /*xss*/);
16 16
File inc/user/repo-page.php changed (mode: 100644) (index f61f99a..969eeef)
... ... if (strcmp($_subop, "history") == 0) {
140 140 $ref = $type_ref['ref_path']; $ref = $type_ref['ref_path'];
141 141 $rg = array_merge($rg, $type_ref); $rg = array_merge($rg, $type_ref);
142 142
143 $bt = rg_git_branches_and_tags($repo_path, $rg['url_repo'],
143 $bt = rg_git_branches_and_tags($repo_path, $rg['ri']['url_repo'],
144 144 $type_ref['ref_url']); $type_ref['ref_url']);
145 145 $rg = array_merge($rg, $bt); $rg = array_merge($rg, $bt);
146 146
 
... ... if (strcmp($_subop, "history") == 0) {
289 289 } }
290 290 } }
291 291
292 rg_watch_hl_process($db, $rg, 'repo', $rg['ri']['repo_id'], 0, $rg['url_repo']);
292 rg_watch_hl_process($db, $rg, 'repo', $rg['ri']['repo_id'], 0 /*obj_id2*/,
293 $rg['current_url']);
293 294
294 295 $rg['per_repo_menu'][$_subop] = 1; $rg['per_repo_menu'][$_subop] = 1;
295 296 $rg['HTML:repo_body'] = $_repo_body; $rg['HTML:repo_body'] = $_repo_body;
File inc/user/repo/bug/main.php changed (mode: 100644) (index 62ad7fd..d203662)
... ... default: // show - go directly to a bug
96 96 $rg['bug'] = array(); $rg['bug'] = array();
97 97 $rg['bug']['bug_id'] = $bug_id; $rg['bug']['bug_id'] = $bug_id;
98 98 if ($bug_id > 0) { if ($bug_id > 0) {
99 $rg['bug']['url'] = $rg['url_repo'] . "/bug/"
99 $rg['bug']['url'] = $rg['ri']['url_repo'] . "/bug/"
100 100 . $rg['bug']['bug_id']; . $rg['bug']['bug_id'];
101 101 include($INC . "/user/repo/bug/show/show.php"); include($INC . "/user/repo/bug/show/show.php");
102 102 $_bug_body .= $_bug_show; $_bug_body .= $_bug_show;
File inc/user/repo/bug/show/show.php changed (mode: 100644) (index eedff28..6b55358)
... ... else
122 122 $rg['HTML:notes'] = rg_template_table("repo/bug/list_note", $notes, $rg); $rg['HTML:notes'] = rg_template_table("repo/bug/list_note", $notes, $rg);
123 123
124 124
125 // watch
126 125 rg_watch_hl_process($db, $rg, 'bug', $rg['ri']['repo_id'], rg_watch_hl_process($db, $rg, 'bug', $rg['ri']['repo_id'],
127 $rg['bug']['bug_id'], $rg['url_repo']);
126 $rg['bug']['bug_id'], $rg['current_url']);
128 127
129 128
130 129 // delete/undelete // delete/undelete
File inc/watch.inc.php changed (mode: 100644) (index 1f0d9d4..1ade19d)
... ... function rg_watch_load($db, $type, $uid, $obj_id1, $obj_id2)
35 35 . '::' . $obj_id1 . '::' . $obj_id2; . '::' . $obj_id1 . '::' . $obj_id2;
36 36 $c = rg_cache_get($key); $c = rg_cache_get($key);
37 37 if ($c !== FALSE) { if ($c !== FALSE) {
38 rg_log('DEBUG: c=' . $c . '.');
39 38 $ret = $c; $ret = $c;
40 39 break; break;
41 40 } }
 
... ... function rg_watch_load_by_obj_id($db, $type, $obj_id1, $obj_id2)
253 252 function rg_watch_hl_process($db, &$rg, $type, $obj_id1, $obj_id2, $url) function rg_watch_hl_process($db, &$rg, $type, $obj_id1, $obj_id2, $url)
254 253 { {
255 254 rg_prof_start('watch_hl_process'); rg_prof_start('watch_hl_process');
256 rg_log_enter('watch_hl_process');
255 rg_log_enter('watch_hl_process type=' . $type);
257 256
258 257 $ret = FALSE; $ret = FALSE;
259 258 $rg['HTML:watch_form'] = ''; $rg['HTML:watch_form'] = '';
 
... ... function rg_watch_hl_process($db, &$rg, $type, $obj_id1, $obj_id2, $url)
276 275 if ($watch === FALSE) if ($watch === FALSE)
277 276 break; break;
278 277
279 if (rg_var_uint('watch_doit') == 1) {
278 // It is our watch? Please note that we may have multiple
279 // watches on the same page: think bugs.
280 $passed_type = rg_var_str('watch_type');
281 $ours = strcmp($passed_type, $type) == 0;
282
283 if ((rg_var_uint('watch_doit') == 1) && $ours) {
280 284 if (!rg_valid_referer()) { if (!rg_valid_referer()) {
281 285 rg_watch_set_error('invalid referer; try again'); rg_watch_set_error('invalid referer; try again');
282 286 break; break;
283 287 } }
284 288
285 if (!rg_token_valid($db, $rg, 'watch', FALSE)) {
289 if (!rg_token_valid($db, $rg, 'watch_' . $type, FALSE)) {
286 290 rg_watch_set_error('invalid token; try again'); rg_watch_set_error('invalid token; try again');
287 291 break; break;
288 292 } }
 
... ... function rg_watch_hl_process($db, &$rg, $type, $obj_id1, $obj_id2, $url)
297 301
298 302 rg_log('DEBUG: watch=' . $watch . ' next_value=' . $next_value); rg_log('DEBUG: watch=' . $watch . ' next_value=' . $next_value);
299 303 $rg['watch'] = array( $rg['watch'] = array(
304 'type' => $type,
300 305 'url' => $url, 'url' => $url,
301 306 'next_value' => $next_value); 'next_value' => $next_value);
302 $rg['rg_form_token_tag'] = 'watch';
303 $rg['rg_form_token'] = rg_token_get($db, $rg, 'watch');
307 $rg['rg_form_token_tag'] = 'watch_' . $type;
308 $rg['rg_form_token'] = rg_token_get($db, $rg, 'watch_' . $type);
304 309 $rg['HTML:watch_form'] = rg_template('watch.html', $rg['HTML:watch_form'] = rg_template('watch.html',
305 310 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
306 311
307 if (rg_var_uint('watch_doit') != 1) {
312 if ((rg_var_uint('watch_doit') != 1) || !$ours) {
308 313 $ret = TRUE; $ret = TRUE;
309 314 break; break;
310 315 } }
File inc/webhooks.inc.php changed (mode: 100644) (index 4dee10c..1878445)
... ... require_once($INC . "/util.inc.php");
3 3 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
4 4 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
5 5 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
6
7 $rg_wh_error = "";
8
9 function rg_wh_set_error($str)
10 {
11 global $rg_wh_error;
12
13 $rg_wh_error = $str;
14 rg_log($str);
15 }
16
17 function rg_wh_error()
18 {
19 global $rg_wh_error;
20 return $rg_wh_error;
21 }
22
23 $rg_wh_functions = array(
24 10000 => 'rg_wh_send',
25 10001 => 'rg_wh_send_one'
26 );
27 rg_event_register_functions($rg_wh_functions);
28
29 /*
30 * Helper for rg_wh_send
31 */
32 function rg_wh_send_one($db, $event)
33 {
34 rg_prof_start('wh_send_helper');
35
36 $wh = &$event['wh'];
37 $info = &$wh['info'];
38
39 rg_log_ml('wh_send_one: event: ' . print_r($event, TRUE));
40 if ($event['debug'] == 1)
41 rg_log_ml('XXX DEBUG: wh[data]=' . print_r($wh['data'], TRUE));
42
43 $headers = array();
44
45 while (!empty($info['key'])) {
46 if ($info['type'] == 0)
47 break;
48
49 $headers[] = 'X-RocketGit-Signature: '
50 . hash_hmac('sha512', $wh['data'], $info['key']);
51 break;
52 }
53
54 $c = curl_init($info['url']);
55 curl_setopt($c, CURLOPT_POST, 1);
56 curl_setopt($c, CURLOPT_POSTFIELDS, $wh['data']);
57 curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE);
58 curl_setopt($c, CURLOPT_FOLLOWLOCATION, 0); // TODO: really?
59 curl_setopt($c, CURLOPT_HEADER, 1);
60 curl_setopt($c, CURLOPT_HTTPHEADER, $headers);
61 curl_setopt($c, CURLOPT_USERAGENT, 'RocketGit WebHook');
62 curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 30);
63 curl_setopt($c, CURLOPT_ENCODING, ''); // => use all methods
64 curl_setopt($c, CURLOPT_VERBOSE, TRUE);
65 curl_setopt($c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
66 curl_setopt($c, CURLOPT_CERTINFO, TRUE);
67 // Else, a second wh, without client cert can use the connection:
68 curl_setopt($c, CURLOPT_FORBID_REUSE, TRUE);
69
70 $err = @fopen('php://temp', 'w');
71 if ($err !== FALSE)
72 curl_setopt($c, CURLOPT_STDERR, $err);
73
74 if (strchr($info['flags'], 'I'))
75 curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
76
77 if (strchr($info['flags'], 'H'))
78 curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 0); // TODO verify 0 is a good value (default 2)
79
80 $ret = FALSE;
81 $cert_file = FALSE;
82 $ca_file = FALSE;
83 while (1) {
84 $xid = rg_id(8);
85
86 if (!empty($info['client_cert'])) {
87 rg_log('DEBUG: will provide client cert...');
88 $f = 'wh-' . $event['ui']['uid'] . '-' . $wh['id'] . '-client-' . $xid;
89 $cert_file = rg_tmp_file($f, $info['client_cert']);
90 if ($cert_file === FALSE)
91 break;
92
93 curl_setopt($c, CURLOPT_SSLCERT, $cert_file);
94 } else {
95 rg_log('DEBUG: will NOT provide client cert...');
96 // TODO: Somehow, without next line, the cert is still sent!
97 curl_setopt($c, CURLOPT_SSLCERT, FALSE);
98 }
99
100 if (!empty($info['client_ca_cert'])) {
101 $f = 'wh-' . $event['ui']['uid'] . '-' . $wh['id'] . '-ca-' . $xid;
102 $ca_file = rg_tmp_file($f, $info['client_ca_cert']);
103 if ($ca_file === FALSE)
104 break;
105
106 curl_setopt($c, CURLOPT_CAINFO, $ca_file);
107 } else {
108 curl_setopt($c, CURLOPT_CAINFO, FALSE);
109 }
110
111 $r = curl_exec($c);
112
113 if ($err !== FALSE) {
114 rewind($err);
115 $xerr = @fread($err, 16 * 4096);
116 fclose($err);
117 rg_log_ml($xerr);
118 }
119
120 if ($r === FALSE) {
121 rg_log('Cannot execute curl: ' . curl_error($c));
122 $_info = curl_getinfo($c);
123 rg_log_ml('Debug: ' . print_r($_info, TRUE));
124
125 if ($event['debug'] == 1)
126 rg_cache_set('DEBUG::' . $event['ui']['uid']
127 . '::webhooks::' . $info['opaque']
128 . '::' . $wh['id'],
129 'BAD', RG_SOCKET_NO_WAIT);
130 break;
131 }
132
133 $xerr = &$r;
134 rg_log_ml('Answer: ' . print_r($r, TRUE));
135
136 if ($event['debug'] == 1)
137 rg_cache_set('DEBUG::' . $event['ui']['uid']
138 . '::webhooks::' . $info['opaque']
139 . '::' . $wh['id'],
140 'OK', RG_SOCKET_NO_WAIT);
141
142 $ret = array();
143 break;
144 }
145 curl_close($c);
146
147 if ($cert_file !== FALSE)
148 @unlink($cert_file);
149
150 if ($ca_file !== FALSE)
151 @unlink($ca_file);
152
153 rg_wh_set_last_output($db, $event['ui']['uid'], $wh['id'],
154 substr($xerr, 0, 4096));
155
156 rg_prof_end('wh_send_helper');
157 return $ret;
158 }
159
160 /*
161 * Generic function which will be called when a webhook must be posted
162 */
163 function rg_wh_send($db, $event)
164 {
165 rg_prof_start('wh_send');
166
167 rg_log_ml('wh_send: event: ' . print_r($event, TRUE));
168
169 // First, get the list of hooks
170 $r = rg_wh_list($db, $event['ui']['uid']);
171 if ($r['ok'] != 1)
172 return FALSE;
173
174 // Filter them by repo_id
175 $real_list = array();
176 foreach ($r['list'] as $id => $info) {
177 if (($info['repo_id'] > 0)
178 && ($event['ri']['repo_id'] != $info['repo_id'])) {
179 rg_log('hook is not for this repo');
180 continue;
181 }
182
183 // If the web hook does not contain our type, skip it
184 if (!strchr($info['events'], $event['wh_event'])) {
185 rg_log($event['wh_event'] . ' is not present in ' . $info['events']);
186 continue;
187 }
188
189 $real_list[] = $id;
190 }
191
192 // Something to do?
193 if (empty($real_list))
194 return array();
195
196 $cache = array();
197 $wh = array();
198 $ret = array();
199 foreach ($real_list as $id) {
200 $wh['info'] = $r['list'][$id];
201 $wh['id'] = $id;
202
203 $type = $wh['info']['type'];
204 if (!isset($cache[$type])) {
205 switch ($type) {
206 case 0: // http post
207 $cache[$type] = &$event['wh_data'];
208 break;
209
210 case 1: // php serialize
211 $cache[$type] = serialize($event['wh_data']);
212 break;
213
214 default:
215 rg_log('Unknown type ' . $type . '!');
216 $cache[$type] = '';
217 break;
218 }
219 }
220 $wh['data'] = $cache[$type];
221
222 $x = $event;
223 $x['category'] = 10001;
224 $x['wh'] = $wh;
225 $ret[] = $x;
226 }
227
228 rg_prof_end('wh_send');
229 return $ret;
230 }
231
232 $rg_wh_types = array(
233 0 => 'HTTP (application/x-www-form-urlencoded)',
234 1 => 'PHP serialize'
235 );
236 /*
237 * Transforms a type into HTML select
238 */
239 function rg_wh_select_type($type)
240 {
241 global $rg_wh_types;
242
243 $ret = '<select name="wh::type" id="type">';
244 foreach ($rg_wh_types as $_type => $name) {
245 $add = '';
246 if ($_type == $type)
247 $add = ' selected';
248
249 $ret .= '<option value="' . $_type . '"' . $add . '>'
250 . $name
251 . '</option>' . "\n";
252 }
253 $ret .= '</select>' . "\n";
254
255 return $ret;
256 }
257
258 /*
259 * Returns type text based on id
260 */
261 function rg_wh_type($type)
262 {
263 global $rg_wh_types;
264
265 foreach ($rg_wh_types as $_type => $name)
266 if ($_type == $type)
267 return $name;
268 }
269
270 $rg_wh_events = array(
271 'C' => 'Create repository',
272 'P' => 'Push',
273 'B' => 'Create branch'
274 );
275 /*
276 * Generates event list as html
277 */
278 function rg_wh_check_events($events)
279 {
280 global $rg_wh_events;
281
282 $ret = '<fieldset>';
283 $ret .= '<legend>Select trigger events</legend>';
284 $br = '';
285 foreach ($rg_wh_events as $id => $name) {
286 $add = '';
287 if (strchr($events, $id))
288 $add = ' checked="checked"';
289
290 $ret .= $br
291 . '<input type="checkbox" name="wh::events[' . $id . ']"'
292 . ' id="events-' . $id . '"'
293 . $add . ' />'
294 . "\n"
295 . '<label for="events-' . $id . '">' . $name . '</label>';
296 $br = '<br />' . "\n";
297 }
298 $ret .= '</fieldset>' . "\n";
299
300 return $ret;
301 }
302
303 /*
304 * Generates an events list as text
305 */
306 function rg_wh_events($events)
307 {
308 global $rg_wh_events;
309
310 $a = array();
311 foreach ($rg_wh_events as $id => $name) {
312 if (strchr($events, $id))
313 $a[] = $name;
314 }
315
316 return implode(', ', $a);
317 }
318
319 $rg_wh_flags = array(
320 'I' => 'Do not verify the server certificate',
321 'H' => 'Do not verify the server hostname'
322 );
323 /*
324 * Generates flags list
325 */
326 function rg_wh_check_flags($flags)
327 {
328 global $rg_wh_flags;
329
330 $ret = '<fieldset>';
331 $ret .= '<legend>Flags</legend>';
332 $br = '';
333 foreach ($rg_wh_flags as $id => $name) {
334 $add = '';
335 if (strchr($flags, $id))
336 $add = ' checked="checked"';
337
338 $ret .= $br
339 . '<input type="checkbox" name="wh::flags[' . $id . ']"'
340 . ' id="flags-' . $id . '"'
341 . $add . ' />'
342 . "\n"
343 . '<label for="flags-' . $id . '">' . $name . '</label>';
344 $br = '<br />' . "\n";
345 }
346 $ret .= '</fieldset>' . "\n";
347
348 return $ret;
349 }
350
351 /*
352 * Generates a flags list as text
353 */
354 function rg_wh_flags($flags)
355 {
356 global $rg_wh_flags;
357
358 $a = array();
359 foreach ($rg_wh_flags as $id => $name) {
360 if (strchr($flags, $id))
361 $a[] = $name;
362 }
363
364 return implode(', ', $a);
365 }
366
367 /*
368 * Some cosmetics applied to a webhook
369 */
370 function rg_wh_cosmetic(&$list)
371 {
372 foreach ($list as $id => &$row) {
373 if (isset($row['itime']))
374 $row['itime_nice'] = gmdate('Y-m-d H:i', $row['itime']);
375
376 if (isset($row['description']))
377 $row['HTML:description_nice'] =
378 nl2br(rg_xss_safe($row['description']));
379
380 if (isset($row['type']))
381 $row['type_text'] = rg_wh_type($row['type']);
382
383 if (isset($row['events']))
384 $row['events_text'] = rg_wh_events($row['events']);
385
386 if (isset($row['flags']))
387 $row['flags_text'] = rg_wh_flags($row['flags']);
388
389 if (isset($row['client_cert']))
390 $row['HTML:client_cert_short'] =
391 empty($row['client_cert']) ?
392 '' : nl2br(rg_xss_safe(substr($row['client_cert'], 0, 32))) . '...';
393
394 if (isset($row['client_ca_cert']))
395 $row['HTML:client_ca_cert_short'] =
396 empty($row['client_ca_cert']) ?
397 '' : nl2br(rg_xss_safe(substr($row['client_ca_cert'], 0, 32))) . '...';
398
399 if (isset($row['last_output']))
400 $row['HTML:last_output_nice'] =
401 nl2br(rg_xss_safe($row['last_output']));
402 }
403 }
404
405 /*
406 * Set last_output field of a webhook
407 */
408 function rg_wh_set_last_output($db, $uid, $id, $output)
409 {
410 rg_prof_start('wh_set_last_output');
411 rg_log_enter('wh_set_last_output id=$id');
412
413 $ret = FALSE;
414 while (1) {
415 $params = array('id' => $id, 'last_output' => $output);
416 $sql = 'UPDATE webhooks'
417 . ' SET last_output = @@last_output@@'
418 . ' WHERE id = @@id@@';
419 $res = rg_sql_query_params($db, $sql, $params);
420 if ($res === FALSE) {
421 rg_wh_set_error('cannot insert/update data');
422 break;
423 }
424 rg_sql_free_result($res);
425
426 $key = 'user' . '::' . $uid . '::' . 'wh' . '::' . 'list'
427 . '::' . $id . '::' . 'last_output';
428 rg_cache_set($key, $output, RG_SOCKET_NO_WAIT);
429
430 $ret = TRUE;
431 break;
432 }
433
434 rg_log_exit();
435 rg_prof_end('wh_set_last_output');
436 return $ret;
437 }
438
439 /*
440 * Returns a list of webhooks associated with a user
441 * @repo_id may be 0 => hooks installed on user account
442 */
443 function rg_wh_list($db, $uid)
444 {
445 rg_prof_start('wh_list');
446 rg_log_enter('wh_list');
447
448 $ret = array('ok' => 0, 'list' => array());
449 while (1) {
450 $key = 'user' . '::' . $uid . '::' . 'wh';
451 $r = rg_cache_get($key);
452 if (($r !== FALSE) && isset($r['LIST_LOADED'])) {
453 $ret['list'] = $r['list'];
454 $ret['ok'] = 1;
455 break;
456 }
457
458 $params = array('uid' => $uid);
459 $sql = 'SELECT * FROM webhooks'
460 . ' WHERE uid = @@uid@@';
461 $res = rg_sql_query_params($db, $sql, $params);
462 if ($res === FALSE) {
463 rg_wh_set_error('cannot load data');
464 break;
465 }
466
467 while (($row = rg_sql_fetch_array($res))) {
468 $id = $row['id'];
469
470 $ret['list'][$id] = $row;
471 }
472 rg_sql_free_result($res);
473
474 $a = array('LIST_LOADED' => 1, 'list' => $ret['list']);
475 rg_cache_merge($key, $a, RG_SOCKET_NO_WAIT);
476 $ret['ok'] = 1;
477 break;
478 }
479
480 rg_log_exit();
481 rg_prof_end('wh_list');
482 return $ret;
483 }
484
485 /*
486 * Adds/edits a webhook
487 */
488 function rg_wh_add($db, $uid, $data)
489 {
490 rg_prof_start('wh_add');
491 rg_log_enter('wh_add');
492
493 $ret = array('ok' => 0);
494 while (1) {
495 $params = $data;
496 $params['uid'] = $uid;
497 $params['itime'] = time();
498
499 if ($data['id'] == 0)
500 $sql = 'INSERT INTO webhooks (uid, repo_id, itime, events'
501 . ', url, client_cert, client_ca_cert, flags'
502 . ', add_ip, description, key, opaque)'
503 . ' VALUES (@@uid@@, @@repo_id@@, @@itime@@'
504 . ', @@events@@, @@url@@, @@client_cert@@'
505 . ', @@client_ca_cert@@, @@flags@@, @@add_ip@@'
506 . ', @@description@@, @@key@@, @@opaque@@)'
507 . ' RETURNING id';
508 else
509 $sql = 'UPDATE webhooks'
510 . ' SET events = @@events@@'
511 . ', url = @@url@@'
512 . ', client_cert = @@client_cert@@'
513 . ', client_ca_cert = @@client_ca_cert@@'
514 . ', flags = @@flags@@'
515 . ', type = @@type@@'
516 . ', description = @@description@@'
517 . ', key = @@key@@'
518 . ', opaque = @@opaque@@'
519 . ' WHERE uid = @@uid@@'
520 . ' AND id = @@id@@';
521
522 $res = rg_sql_query_params($db, $sql, $params);
523 if ($res === FALSE) {
524 rg_wh_set_error('cannot insert/update data');
525 break;
526 }
527 if ($data['id'] == 0)
528 $row = rg_sql_fetch_array($res);
529 rg_sql_free_result($res);
530
531 if ($data['id'] == 0)
532 $params['id'] = $row['id'];
533 $key = 'user' . '::' . $uid . '::' . 'wh' . '::' . 'list'
534 . '::' . $params['id'];
535 rg_cache_merge($key, $params, RG_SOCKET_NO_WAIT);
536
537 $ret['ok'] = 1;
538 break;
539 }
540
541 rg_log_exit();
542 rg_prof_end('wh_add');
543 return $ret;
544 }
545
546 /*
547 * Removes a list of webhooks
548 */
549 function rg_wh_remove($db, $uid, $list)
550 {
551 rg_prof_start('wh_remove');
552 rg_log_enter('wh_remove');
553
554 $ret = array('ok' => 0);
555 while (1) {
556 if (empty($list)) {
557 rg_wh_set_error('you did not select anything');
558 break;
559 }
560
561 $my_list = array();
562 foreach ($list as $id => $junk)
563 $my_list[] = sprintf("%u", $id);
564
565 $params = array('uid' => $uid);
566 $sql_list = implode(', ', $my_list);
567
568 $sql = 'DELETE FROM webhooks'
569 . ' WHERE uid = @@uid@@'
570 . ' AND id IN (' . $sql_list . ')';
571 $res = rg_sql_query_params($db, $sql, $params);
572 if ($res === FALSE) {
573 rg_wh_set_error('cannot remove webhooks');
574 break;
575 }
576 rg_sql_free_result($res);
577
578 foreach ($my_list as $junk => $id) {
579 $key = 'user' . '::' . $uid . '::' . 'wh'
580 . '::' . 'list' . '::' . $id;
581 rg_cache_unset($key, RG_SOCKET_NO_WAIT);
582 }
583
584 $ret['ok'] = 1;
585 break;
586 }
587
588 rg_log_exit();
589 rg_prof_end('wh_remove');
590 return $ret;
591 }
6 require_once($INC . "/wh/http.inc.php");
592 7
593 8 /* /*
594 9 * High level function to list the webhooks * High level function to list the webhooks
 
... ... function rg_wh_add_high_level($db, $rg, $paras)
661 76 // We need the id in any case // We need the id in any case
662 77 $rg['wh']['id'] = rg_var_str('wh::id'); $rg['wh']['id'] = rg_var_str('wh::id');
663 78
79 $rg['wh']['htype'] = rg_var_str('wh::htype');
80 if (empty($rg['wh']['htype'])) {
81 $ret .= rg_wh_htypes($rg);
82 $show_form = FALSE;
83 }
84
664 85 $add = rg_var_uint('add'); $add = rg_var_uint('add');
665 86 while ($add == 1) { while ($add == 1) {
666 87 $rg['wh']['repo_id'] = rg_var_uint('wh::repo_id'); $rg['wh']['repo_id'] = rg_var_uint('wh::repo_id');
667 88 $rg['wh']['itime'] = time(); $rg['wh']['itime'] = time();
668 89 $rg['wh']['events'] = rg_var_a2s('wh::events'); // TODO $rg['wh']['events'] = rg_var_a2s('wh::events'); // TODO
669 90 $rg['wh']['url'] = rg_var_str('wh::url'); $rg['wh']['url'] = rg_var_str('wh::url');
670 $rg['wh']['type'] = rg_var_uint('wh::type');
671 $rg['wh']['client_cert'] = trim(rg_var_str('wh::client_cert'));
672 $rg['wh']['client_ca_cert'] = trim(rg_var_str('wh::client_ca_cert'));
673 $rg['wh']['flags'] = rg_var_a2s('wh::flags');
674 91 $rg['wh']['add_ip'] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; $rg['wh']['add_ip'] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
675 92 $rg['wh']['description'] = rg_var_str('wh::description'); $rg['wh']['description'] = rg_var_str('wh::description');
676 93 $rg['wh']['opaque'] = rg_var_str('wh::opaque'); $rg['wh']['opaque'] = rg_var_str('wh::opaque');
677 94 $rg['wh']['key'] = rg_var_str('wh::key'); $rg['wh']['key'] = rg_var_str('wh::key');
95 rg_wh_fill_vars($rg);
678 96
679 // TODO: validate here the paras
680 if ((strncasecmp($rg['wh']['url'], "http", 4) != 0)
681 || (strncasecmp($rg['wh']['url'], "https", 5) != 0)) {
682 $errmsg[] = 'invalid protocol; only http and https supported now';
97 rg_log('DEBUG: before validate_vars');
98 $r = rg_wh_validate_vars($rg, $errmsg);
99 if ($r !== TRUE)
683 100 break; break;
684 }
685 101
102 rg_log('DEBUG: before valid_referer');
686 103 if (!rg_valid_referer()) { if (!rg_valid_referer()) {
687 104 $errmsg[] = 'invalid referer; try again'; $errmsg[] = 'invalid referer; try again';
688 105 break; break;
 
... ... function rg_wh_add_high_level($db, $rg, $paras)
717 134 $rg['wh']['id'] = 0; $rg['wh']['id'] = 0;
718 135 $rg['wh']['events'] = ''; $rg['wh']['events'] = '';
719 136 $rg['wh']['url'] = ''; $rg['wh']['url'] = '';
720 $rg['wh']['type'] = 0;
721 $rg['wh']['client_cert'] = '';
722 $rg['wh']['client_ca_cert'] = '';
723 $rg['wh']['flags'] = '';
724 137 $rg['wh']['description'] = ''; $rg['wh']['description'] = '';
725 138 $rg['wh']['opaque'] = ''; $rg['wh']['opaque'] = '';
726 139 $rg['wh']['key'] = ''; $rg['wh']['key'] = '';
140 rg_wh_default_paras($rg);
727 141 } }
728 142 } }
729 143
144 rg_wh_add_form($rg);
145
146 $hints = array();
147 $hints[]['HTML:hint'] = rg_template('user/settings/wh/hints.html',
148 $rg, TRUE /*xss*/);
149 rg_wh_fill_hints($rg, $hints);
150 $rg['HTML:hints'] = rg_template_table("hints/list", $hints, $rg);
151
152
730 153 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg); $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
731 $rg['HTML:check_flags'] = rg_wh_check_flags($rg['wh']['flags']);
732 154 $rg['HTML:check_events'] = rg_wh_check_events($rg['wh']['events']); $rg['HTML:check_events'] = rg_wh_check_events($rg['wh']['events']);
733 $rg['HTML:select_type'] = rg_wh_select_type($rg['wh']['type']);
734 155 $rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_add'); $rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_add');
735 156 $ret .= rg_template('user/settings/wh/add_edit.html', $ret .= rg_template('user/settings/wh/add_edit.html',
736 157 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
 
... ... function rg_wh_high_level($db, $rg, $paras)
750 171 rg_log_enter('wh_high_level'); rg_log_enter('wh_high_level');
751 172
752 173 $ret = ''; $ret = '';
174 while (1) {
175 $op = empty($paras) ? 'list' : array_shift($paras);
176 $rg['menu']['wh'][$op] = 1;
753 177
754 $op = empty($paras) ? 'list' : array_shift($paras);
755 $rg['menu']['wh'][$op] = 1;
178 $ret .= rg_template('user/settings/wh/menu.html',
179 $rg, TRUE /*xss*/);
180
181 switch ($op) {
182 case 'add':
183 $ret .= rg_wh_add_high_level($db, $rg, $paras);
184 break;
756 185
757 rg_log("DEBUG: op=$op");
758 $ret .= rg_template('user/settings/wh/menu.html', $rg, TRUE /*xss*/);
186 default:
187 $ret .= rg_wh_list_high_level($db, $rg, $paras);
188 break;
189 }
759 190
760 switch ($op) {
761 case 'add': $ret .= rg_wh_add_high_level($db, $rg, $paras); break;
762 default: $ret .= rg_wh_list_high_level($db, $rg, $paras); break;
191 break;
763 192 } }
764 193
765 194 rg_log_exit(); rg_log_exit();
File rocketgit.spec.in changed (mode: 100644) (index ae6dc6d..10ac459)
... ... Source: http://kernel.embedromix.ro/us/rocketgit/%{name}-%{version}.tar.gz
13 13 URL: http://kernel.embedromix.ro/us/ URL: http://kernel.embedromix.ro/us/
14 14 BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
15 15 BuildArch: noarch BuildArch: noarch
16 Requires: httpd, php, php-cli, php-pgsql, php-mbstring, xinetd
16 Requires: httpd, mod_ssl, php, php-cli, php-pgsql, php-mbstring, xinetd
17 17 Requires: git, cronie Requires: git, cronie
18 18 Requires: util-linux Requires: util-linux
19 19 # SELinux stuff # SELinux stuff
File root/index.php changed (mode: 100644) (index 45b3b17..5c96d93)
... ... $rg['debug'] = rg_var_uint('rg_debug');
54 54 // We have variable 'vv' passed from webserver - build 'op' and rest of paras // We have variable 'vv' passed from webserver - build 'op' and rest of paras
55 55 $sparas = rg_var_str("vv"); $sparas = rg_var_str("vv");
56 56 rg_log("DEBUG: sparas=$sparas"); rg_log("DEBUG: sparas=$sparas");
57 $rg['current_url'] = rawurlencode($sparas);
57 58 $rg['url'] = "/op"; $rg['url'] = "/op";
58 59 $paras = explode("/", trim($sparas, "/")); $paras = explode("/", trim($sparas, "/"));
59 60 $_t = empty($paras) ? "" : $paras[0]; $_t = empty($paras) ? "" : $paras[0];
File root/themes/default/hints/repo/lock_repo.html changed (mode: 100644) (index 3bc1e43..9872dc2)
1 1 When a repository is locked, only the users that have "Lock" rights will be When a repository is locked, only the users that have "Lock" rights will be
2 2 able to push into it.<br /> able to push into it.<br />
3 <br />
4
5 3 You may want to lock a repo to repair bad pushes.<br /> You may want to lock a repo to repair bad pushes.<br />
6 <br />
7
8 Any feedback regarding what more this feature should do is really appreciated!
4 Any feedback regarding what more this feature should do is really appreciated!<br />
File root/themes/default/index.html changed (mode: 100644) (index 4c41a42..963cc24)
11 11 <div id="container"> <div id="container">
12 12
13 13 <div id="header"> <div id="header">
14 <div id="header_fake_table">
15 <div class="logo">
16 <a href="/">RocketGit</a>
17 </div>
14 <div class="logo">
15 <a href="/">RocketGit</a>
16 </div>
18 17
19 <div class="main_menu">
20 @@if(@@login_ui::uid@@ != 0){{
21 <a href="@@login_ui::homepage@@">Me</a>
22 }}
23 <a href="/op/features">Features</a>
24 <a href="/op/discover">Discover</a>
25 <a href="/op/download">Download</a>
26 <a href="/op/pricing">Pricing</a>
27 <a href="/op/tos">ToS</a>
28 <a href="/op/donate">Donate</a>
29 @@if(@@login_ui::uid@@ != 0){{
30 <a href="/op/suggestion">Suggestion</a>
31 <a href="/op/repo">My repositories</a>
32 <a href="/op/settings">Settings</a>
33 @@if(@@login_ui::is_admin@@ == 1){{<a href="/op/admin">Admin</a>}}
34 <a href="/op/logout?token=@@logout_token@@">Logout</a>
35 }}{{
36 <a href="/op/create_account">Create account</a>
37 <a href="/op/login">Login</a>
38 }}
39 </div>
18 <div class="main_menu">
19 @@if(@@login_ui::uid@@ != 0){{
20 <a href="@@login_ui::homepage@@">Me</a>
21 }}
22 <a href="/op/features">Features</a>
23 <a href="/op/discover">Discover</a>
24 <a href="/op/download">Download</a>
25 <a href="/op/pricing">Pricing</a>
26 <a href="/op/tos">ToS</a>
27 <a href="/op/donate">Donate</a>
28 @@if(@@login_ui::uid@@ != 0){{
29 <a href="/op/suggestion">Suggestion</a>
30 <a href="/op/repo">My repositories</a>
31 <a href="/op/settings">Settings</a>
32 @@if(@@login_ui::is_admin@@ == 1){{<a href="/op/admin">Admin</a>}}
33 <a href="/op/logout?token=@@logout_token@@">Logout</a>
34 }}{{
35 <a href="/op/create_account">Create account</a>
36 <a href="/op/login">Login</a>
37 }}
40 38 </div> </div>
41 39 </div> <!-- header --> </div> <!-- header -->
42 40
43 <div id="main_container">
44 <div id="main">
45 @@rg_body@@
46 </div>
47 </div> <!-- main_container -->
41 <div id="main">
42 @@rg_body@@
43 </div>
48 44
49 45 <div id="footer"> <div id="footer">
50 <div id="footer_fake_table">
51 <div id="footer_logo">
46 <div id="footer_logo">
47 <div class="logo_image">
52 48 <img src="@@IMG:logo/rg6.png@@" alt="RocketGit logo" /> <img src="@@IMG:logo/rg6.png@@" alt="RocketGit logo" />
49 </div>
50 <div class="logo">
51 <a href="/">RocketGit</a>
53 52 <br /> <br />
54 <div class="logo">
55 <a href="/">RocketGit</a>
56 <br />
57 Rocket your launch!
58 </div>
53 Rocket your launch!
59 54 </div> </div>
55 </div>
60 56
61 <div id="footer_info">
62 For any information, please contact us at
63 <a href="mailto:in@rocketgit.com">in@rocketgit.com</a>.<br />
64 Copyright: <a href="http://kernel.embedromix.ro/" target="_blank">Catalin(ux) M. BOIE</a><br />
65 Software version: @@rg_version@@<br />
66 Running since: @@first_install_text@@<br />
67 <i>Git was created by Linus Torvalds.</i><br />
68 rocketgit.com site is operated by Embedromix SRL,<br />
69 RO13505234, J08/979/2000, Brasov, Romania.<br />
70 All data is stored in Germany.
71 </div>
57 <div id="footer_info">
58 For any information, please contact us at
59 <a href="mailto:in@rocketgit.com">in@rocketgit.com</a>.<br />
60 Copyright: <a href="http://kernel.embedromix.ro/" target="_blank">Catalin(ux) M. BOIE</a><br />
61 Software version: @@rg_version@@<br />
62 Running since: @@first_install_text@@<br />
63 <i>Git was created by Linus Torvalds.</i><br />
64 rocketgit.com site is operated by Embedromix SRL,<br />
65 RO13505234, J08/979/2000, Brasov, Romania.<br />
66 All data is stored in Germany.
72 67 </div> </div>
73 68 </div> <!-- footer --> </div> <!-- footer -->
74 69
File root/themes/default/main.css changed (mode: 100644) (index 9d98cdb..af15e47)
... ... table {
21 21 background-color: #eeeeee; background-color: #eeeeee;
22 22 color: #000000; color: #000000;
23 23 padding: 1px; padding: 1px;
24 margin-top: 3px;
24 margin-top: 5px;
25 margin-left: auto;
26 margin-right: auto;
25 27 } }
26 28
27 29 th, td { th, td {
 
... ... form fieldset { margin-top: 5pt; padding: 3pt; }
85 87
86 88 legend { padding: 0px 2pt; } legend { padding: 0px 2pt; }
87 89
88 #container {
89 width: 100%;
90 height: 100%;
91 display: table;
92 xxx-border-collapse: separate;
93 xxx-border-spacing: 10px;
94 }
95
96 90 .logo { .logo {
97 91 font-size: 16pt; font-size: 16pt;
98 92 font-weight: bold; font-weight: bold;
 
... ... legend { padding: 0px 2pt; }
100 94 color: yellow; color: yellow;
101 95 font-style: italic; font-style: italic;
102 96 line-height: 120%; line-height: 120%;
103 display: table-cell;
104 97 vertical-align: middle; vertical-align: middle;
105 98 } }
106 99 .logo a { .logo a {
 
... ... legend { padding: 0px 2pt; }
126 119 .main_menu a:hover { color: #F00; } .main_menu a:hover { color: #F00; }
127 120
128 121 .menus { .menus {
129 display: table-row;
122 display: flex;
130 123 } }
131 124
132 125 .menu { .menu {
133 126 background-color: #999; background-color: #999;
134 padding: 3px 0px;
127 display: flex;
128 flex-flow: row nowrap;
129 flex-grow: 0;
135 130 } }
136 .menu ul { list-style-type: none; }
131 .menu ul { list-style-type: none; display: flex; }
137 132 .menu ul li { .menu ul li {
138 display: table-cell;
133 display: flex;
139 134 padding: 2px 0px; padding: 2px 0px;
140 135 } }
141 136 .menu ul li a { .menu ul li a {
 
... ... legend { padding: 0px 2pt; }
159 154 font-weight: bold; font-weight: bold;
160 155 padding-bottom: 5px; padding-bottom: 5px;
161 156 border-bottom: 2px solid #F00; border-bottom: 2px solid #F00;
162 xxx-width: 70%;
163 margin-left: auto;
164 margin-right: auto;
165 157 } }
166 158
167 159 .junk {} .junk {}
168 160
169 .branches_and_tags { padding: 3px 0px; margin: 3px 0px; }
161 .branches_and_tags { margin: 3px 0px; }
170 162 .branches_and_tags a { .branches_and_tags a {
171 163 padding: 3px 3px; padding: 3px 3px;
172 164 color: #000; color: #000;
 
... ... legend { padding: 0px 2pt; }
178 170 .tag a { background-color: #ffffa0; } .tag a { background-color: #ffffa0; }
179 171
180 172
181 #main_container {
182 width: 80%;
183 margin-left: auto;
184 margin-right: auto;
185 display: table-row;
173 #container {
174 width: 100%;
175 height: 100%;
176 display: flex;
177 flex-flow: column nowrap;
178 justify-content: space-between;
179 xxx-align-content: center;
180 align-items: stretch;
186 181 } }
187 182
188 183 #main { #main {
 
... ... legend { padding: 0px 2pt; }
192 187 margin-left: auto; margin-left: auto;
193 188 margin-right: auto; margin-right: auto;
194 189 line-height: 120%; line-height: 120%;
195 display: table;
196 190 text-align: center; text-align: center;
191 display: flex;
192 flex-flow: column nowrap;
193 flex-grow: 1;
197 194 } }
198 195
199 196 #header { #header {
 
... ... legend { padding: 0px 2pt; }
201 198 box-shadow: 0px 4px 6px #666; box-shadow: 0px 4px 6px #666;
202 199 margin-bottom: 6px; margin-bottom: 6px;
203 200 line-height: 120%; line-height: 120%;
204 display: table-row;
205 width: 100%;
206 height: 28pt;
207 xxx-position: fixed;
208 }
209 #header_fake_table {
210 display: table;
211 width: 100%;
201 display: flex;
202 flex-flow: row wrap;
203 justify-content: space-between;
204 align-items: center;
212 205 } }
213 206
214 207 #footer { #footer {
215 208 background-color: #888888; background-color: #888888;
216 display: table-row;
217 vertical-align: bottom;
218 width: 100%;
219 height: 120pt;
220 209 box-shadow: 0px -4px 6px #666666; box-shadow: 0px -4px 6px #666666;
221 }
222 #footer_fake_table {
223 display: table;
224 width: 100%;
210 margin-top: 6px;
211 display: flex;
212 flex-flow: row wrap;
213 align-content: space-around;
225 214 } }
226 215 #footer_logo { #footer_logo {
227 padding: 10px 0;
216 padding: 10px;
228 217 text-align: center; text-align: center;
229 display: table-cell;
230 218 width: 190pt; width: 190pt;
231 219 } }
232 #footer_logo img { margin-left: auto; margin-right: auto; display: table-cell; }
220 #footer_img {
221 margin-left: auto;
222 margin-right: auto;
223 }
233 224 #footer_info { #footer_info {
234 225 color: #ffffff; color: #ffffff;
235 padding: 5px;
236 padding-left: 20px;
226 padding: 10px;
237 227 font-size: 11pt; font-size: 11pt;
238 228 line-height: 115%; line-height: 115%;
239 display: table-cell;
240 229 vertical-align: top; vertical-align: top;
241 230 } }
242 231
 
... ... legend { padding: 0px 2pt; }
297 286 border: 1px solid #cccccc; border: 1px solid #cccccc;
298 287 padding: 3px; padding: 3px;
299 288 margin-top: 5px; margin-top: 5px;
300 display: table;
301 289 } }
302 290
303 291 .diff {} .diff {}
 
... ... legend { padding: 0px 2pt; }
424 412 border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px;
425 413 border: 1px solid #cccccc; border: 1px solid #cccccc;
426 414 line-height: 120%; line-height: 120%;
427 display: table;
428 415 } }
429 416
430 417 .bug_description { .bug_description {
 
... ... legend { padding: 0px 2pt; }
438 425
439 426 .notes { .notes {
440 427 margin-top: 5px; margin-top: 5px;
441 display: table;
442 428 } }
443 429
444 430 .note { .note {
 
... ... legend { padding: 0px 2pt; }
460 446 .mess { .mess {
461 447 margin-top: 5px; margin-top: 5px;
462 448 padding: 5px; padding: 5px;
463 display: table;
464 449 box-shadow: 0px 2px 3px #666666; box-shadow: 0px 2px 3px #666666;
465 450 } }
466 451
File root/themes/default/user/repo/rights/form_repo.html changed (mode: 100644) (index 56a5016..8789324)
1 1 <div class="formarea"> <div class="formarea">
2 2
3 <div class="formarea_title">Grant repo rights</div>
3 <div class="formarea_title">@@if(@@right_id@@ == 0){{Grant repo rights}}{{Edit repo rights}}</div>
4 4
5 5 @@errmsg@@ @@errmsg@@
6 6
File root/themes/default/user/repo/rights/form_repo_path.html changed (mode: 100644) (index 563db66..0010dd5)
1 1 <div class="formarea"> <div class="formarea">
2 2
3 <div class="formarea_title">Grant path rights</div>
3 <div class="formarea_title">@@if(@@right_id@@ == 0){{Grant path rights}}{{Edit path rights}}</div>
4 4
5 5 @@errmsg@@ @@errmsg@@
6 6
File root/themes/default/user/repo/rights/form_repo_refs.html changed (mode: 100644) (index 7b34f78..ab8fdcb)
1 1 <div class="formarea"> <div class="formarea">
2 2
3 <div class="formarea_title">Grant refs rights</div>
3 <div class="formarea_title">@@if(@@right_id@@ == 0){{Grant refs rights}}{{Edit refs rights}}</div>
4 4
5 5 @@errmsg@@ @@errmsg@@
6 6
File root/themes/default/user/settings/wh/add_edit.html changed (mode: 100644) (index f53fa18..c216628)
1 1 <div class="formarea"> <div class="formarea">
2 2
3 <div class="formarea_title">@@if(@@wh::id@@ == 0){{Add}}{{Edit}} a webhook</div>
3 <div class="formarea_title">@@if(@@wh::id@@ == 0){{Add}}{{Edit}} a webhook (type <i>@@wh::htype@@</i>)</div>
4 4
5 5 @@errmsg@@ @@errmsg@@
6 6
7 7 <form method="post" action="/op/settings/wh/add"> <form method="post" action="/op/settings/wh/add">
8 8 <input type="hidden" name="add" value="1" /> <input type="hidden" name="add" value="1" />
9 <input type="hidden" name="wh::htype" value="@@wh::htype@@" />
9 10 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
10 11
11 12 <p> <p>
12 <label for="url">URL (example: https://my_server_dot_com/hook.cgi; only http/https are supported)</label><br />
13 <label for="url">URL (example: https://my_server_dot_tld/hook.cgi)</label><br />
13 14 <input type="text" name="wh::url" id="url" value="@@wh::url@@" size="80" /> <input type="text" name="wh::url" id="url" value="@@wh::url@@" size="80" />
14 15 </p> </p>
15 16
16 <p>
17 <label for="type">Type</label><br />
18 @@select_type@@
19 </p>
20
21 17 @@check_events@@ @@check_events@@
22 18
23 @@check_flags@@
24
25 19 <p> <p>
26 20 <label for="description">Description</label><br /> <label for="description">Description</label><br />
27 21 <textarea name="wh::description" id="description" rows="3" cols="80"> <textarea name="wh::description" id="description" rows="3" cols="80">
 
39 33 <input type="text" name="wh::opaque" id="opaque" value="@@wh::opaque@@" size="80" /> <input type="text" name="wh::opaque" id="opaque" value="@@wh::opaque@@" size="80" />
40 34 </p> </p>
41 35
42 <p>
43 <label for="client_cert">Optional concatenated certificate and key used to
44 authenticate us to the server (PEM format, no password)</label><br />
45 <textarea name="wh::client_cert" id="client_cert" rows="3" cols="80">
46 @@wh::client_cert@@
47 </textarea>
48 </p>
49
50 <p>
51 <label for="client_ca_cert">Optional certificate(s) used to authenticate your server (PEM format, no password)</label><br />
52 <textarea name="wh::client_ca_cert" id="client_ca_cert" rows="3" cols="80">
53 @@wh::client_ca_cert@@
54 </textarea>
55 </p>
36 @@custom_form@@
56 37
57 38 <input type="submit" name="button" value="@@if(@@wh::id@@ == 0){{Add}}{{Edit}}" /> <input type="submit" name="button" value="@@if(@@wh::id@@ == 0){{Add}}{{Edit}}" />
58 39
59 40 </form> </form>
60 41 </div> </div>
42
43 @@hints@@
File root/themes/default/user/settings/wh/hints.html changed (mode: 100644) (index 602ac04..92baad0)
... ... Webhooks helps you to trigger some actions on your server when an event
2 2 happens with you repositories.<br /> happens with you repositories.<br />
3 3 <br /> <br />
4 4
5 Key: a string used to "sign" the requests to your server. You can create it
6 using any character you want: letters, digits and any symbol.<br />
5 HMAC SHA512 key: it is a string that will be used to sign the payload;
6 this way you can be sure that the server knows the secret and you can go on to
7 process the request. You can use any character you want: letters, digits and
8 any symbol.<br />
7 9 The server will create a HMAC over the payload using SHA512 and will add The server will create a HMAC over the payload using SHA512 and will add
8 HTTP header <i>X-RocketGit-Signature: &lt;signature&gt;</i>. It is
10 a HTTP header: <i>X-RocketGit-Signature: &lt;signature&gt;</i>. It is
9 11 recommended to verify it before parsing the body, for security reasons. recommended to verify it before parsing the body, for security reasons.
10 It is not generated for <i>application/x-www-form-urlencoded</i> type.<br />
11 <br />
12 It is not generated for <i>application/x-www-form-urlencoded</i> encoding.<br />
File root/themes/default/user/settings/wh/list/header.html changed (mode: 100644) (index f73ac84..218df89)
13 13 <th>Events</th> <th>Events</th>
14 14 <th>URL</th> <th>URL</th>
15 15 <th>Description</th> <th>Description</th>
16 <th>Client cert</th>
17 <th>CA cert</th>
18 <th>Type</th>
19 <th>Flags</th>
20 16 <th>Add IP</th> <th>Add IP</th>
21 17 <th>Last output</th> <th>Last output</th>
22 18 </tr> </tr>
File root/themes/default/user/settings/wh/list/line.html changed (mode: 100644) (index e1db639..8333bc0)
4 4 <td>@@events_text@@</td> <td>@@events_text@@</td>
5 5 <td>@@url@@</td> <td>@@url@@</td>
6 6 <td>@@description@@</td> <td>@@description@@</td>
7 <td>@@client_cert_short@@</td>
8 <td>@@client_ca_cert_short@@</td>
9 <td>@@type_text@@</td>
10 <td>@@flags_text@@</td>
11 7 <td>@@add_ip@@</td> <td>@@add_ip@@</td>
12 8 <td><small>@@last_output_nice@@</small></td> <td><small>@@last_output_nice@@</small></td>
13 9 </tr> </tr>
File root/themes/default/watch.html changed (mode: 100644) (index 74a0708..16dd14e)
1 1 <form method="post" action="@@watch::url@@"> <form method="post" action="@@watch::url@@">
2 <input type="hidden" name="watch_type" value="@@watch::type@@" />
2 3 <input type="hidden" name="watch_doit" value="1" /> <input type="hidden" name="watch_doit" value="1" />
3 4 <input type="hidden" name="watch" value="@@watch::next_value@@" /> <input type="hidden" name="watch" value="@@watch::next_value@@" />
4 5 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
File scripts/cache.php changed (mode: 100644) (index 6b9b850..00955bf)
... ... function rg_handle_command($k, &$conn_table, $cmd)
201 201 } }
202 202
203 203 if ($no_wait === FALSE) { if ($no_wait === FALSE) {
204 rg_log($k . ': DEBUG: enqueue: ' . $buf);
204 205 $s['send'] .= $buf; $s['send'] .= $buf;
205 206 $conn_table['w'][$k] = $s['socket']; $conn_table['w'][$k] = $s['socket'];
206 207 } }
 
... ... function rg_handle_recv($k, &$conn_table)
223 224 return; return;
224 225 } }
225 226
226 rg_log("Received data on key $k [$buf]...");
227 rg_log($k . ':DEBUG: received: ' . $buf);
227 228
228 229 $s['recv'] .= $buf; $s['recv'] .= $buf;
229 230 $s['close_at'] = time() + 30; $s['close_at'] = time() + 30;
 
... ... $conn_table['r']['master'] = $master;
339 340 do { do {
340 341 rg_log_buffer_clear(); rg_log_buffer_clear();
341 342
342 rg_log_ml("conn_table: " . print_r($conn_table, TRUE));
343 //rg_log_ml("conn_table: " . print_r($conn_table, TRUE));
343 344
344 345 $r2 = $conn_table['r']; $w2 = $conn_table['w']; $ex = array(); $r2 = $conn_table['r']; $w2 = $conn_table['w']; $ex = array();
345 346 $r = @socket_select($r2, $w2, $ex, 5); $r = @socket_select($r2, $w2, $ex, 5);
346 347 if ($r === FALSE) if ($r === FALSE)
347 348 rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!"); rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!");
348 349 if ($r > 0) { if ($r > 0) {
349 if (!empty($r2))
350 rg_log_ml('r2: ' . print_r($r2, TRUE));
351 if (!empty($w2))
352 rg_log_ml('w2: ' . print_r($w2, TRUE));
353 if (!empty($ex))
354 rg_log_ml('ex: ' . print_r($ex, TRUE));
350 //if (!empty($r2))
351 // rg_log_ml('r2: ' . print_r($r2, TRUE));
352 //if (!empty($w2))
353 // rg_log_ml('w2: ' . print_r($w2, TRUE));
354 //if (!empty($ex))
355 // rg_log_ml('ex: ' . print_r($ex, TRUE));
355 356
356 357 foreach ($r2 as $key => $socket) { foreach ($r2 as $key => $socket) {
357 358 if (strcmp($key, "master") == 0) { if (strcmp($key, "master") == 0) {
File techdocs/cache.txt changed (mode: 100644) (index 4a5fdfc..e69f04c)
... ... state $var
5 5 user $uid user $uid
6 6 info info
7 7 keys $key_id keys $key_id
8 wh $wh_id
8
9 wh $uid
10 list
11 $wh_id
9 12
10 13 username_to_uid $username username_to_uid $username
11 14
File tests/Makefile changed (mode: 100644) (index dddf9ee..7a20f07)
1 tests := pr_anon wh ssh http_totp totp git_log1.sh \
1 tests := pr_anon wh_http ssh http_totp totp git_log1.sh \
2 2 http_admin http_bug \ http_admin http_bug \
3 3 http_create_account http_login http_settings http_csrf http_top \ http_create_account http_login http_settings http_csrf http_top \
4 4 token util log state cache prof db event rights keys user repo git \ token util log state cache prof db event rights keys user repo git \
 
... ... all: $(tests)
13 13 pr_anon: pr_anon:
14 14 php pr_anon.php php pr_anon.php
15 15
16 wh:
17 php wh.php
16 wh_http:
17 php wh_http.php
18 18
19 19 ssh: ssh:
20 20 php ssh.php php ssh.php
File tests/helpers.inc.php changed (mode: 100644) (index 9c94f42..fd6e29d)
... ... function rg_test_sc_generate($db, $rg_ui, $good_sid)
280 280 /* /*
281 281 * Helper for adding a webhook * Helper for adding a webhook
282 282 */ */
283 function rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra)
283 function rg_test_wh_add_edit($db, $rg_ui, $good_sid, $htype, $extra)
284 284 { {
285 285 global $test_url; global $test_url;
286 286
287 287 rg_log("Loading webhook add form..."); rg_log("Loading webhook add form...");
288 $data = array();
288 $data = array('wh::htype' => $htype);
289 289 $headers = array("Cookie: sid=" . $good_sid); $headers = array("Cookie: sid=" . $good_sid);
290 290 $r = do_req($test_url . "/op/settings/wh/add", $data, $headers); $r = do_req($test_url . "/op/settings/wh/add", $data, $headers);
291 291 if ($r === FALSE) { if ($r === FALSE) {
 
... ... function rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra)
310 310 } }
311 311
312 312 if (!strstr($r['body'], 'with success')) { if (!strstr($r['body'], 'with success')) {
313 rg_log_ml('r[body]: ' . print_r($r['body']));
313 rg_log_ml('r[body]: ' . print_r($r['body'], TRUE));
314 314 rg_log('Cannot add webhook (no \'with success\' message)!'); rg_log('Cannot add webhook (no \'with success\' message)!');
315 315 exit(1); exit(1);
316 316 } }
File tests/http.inc.php changed (mode: 100644) (index a23e94a..9fa5465)
... ... function do_req($url, &$data, &$headers)
97 97
98 98 // Check if a '@@' is present // Check if a '@@' is present
99 99 if (strstr($ret['body'], '@@')) { if (strstr($ret['body'], '@@')) {
100 rg_log_ml("Bad @@! body=" . print_r($ret['body'], TRUE));
100 $t = explode('@@', $ret['body']);
101 $t = explode("\n", $t[1]);
102 rg_log_ml("We have unresolved variables: [" . $t[0] . "]!");
101 103 exit(1); exit(1);
102 104 } }
103 105
File tests/http_bug.php changed (mode: 100644) (index 16e5693..ee186f6)
... ... for ($i = 0; $i <= 1; $i++) {
240 240 rg_log('Cannot load bug form.'); rg_log('Cannot load bug form.');
241 241 exit(1); exit(1);
242 242 } }
243 $token = $r['tokens']['bug_watch'];
243 $token = $r['tokens']['watch_bug'];
244 244
245 245 rg_log("Posting (un)watch bug form..."); rg_log("Posting (un)watch bug form...");
246 $data = array('token' => $token, 'watch_doit' => 1, 'watch' => $i,
246 $data = array('token' => $token, 'watch_type' => 'bug',
247 'watch_doit' => 1, 'watch' => $i,
247 248 '_test' => 'post-watch-' . $i); '_test' => 'post-watch-' . $i);
248 249 $r = do_req($test_url . $url, $data, $headers); $r = do_req($test_url . $url, $data, $headers);
249 250 if ($r === FALSE) { if ($r === FALSE) {
File tests/repo.php changed (mode: 100644) (index 0ad7c28..037efa3)
... ... $sql = "DELETE FROM rights WHERE uid = 12";
36 36 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
37 37 rg_sql_free_result($res); rg_sql_free_result($res);
38 38
39 rg_log("rg_repo_path 1");
39
40 rg_log('');
41 rg_log_enter("rg_repo_path 1");
40 42 $e = $rg_repos . "/by_id/11/22/33/44/11223344/repos/by_id/55.git"; $e = $rg_repos . "/by_id/11/22/33/44/11223344/repos/by_id/55.git";
41 43 $c = rg_repo_path_by_id(0x11223344, 55); $c = rg_repo_path_by_id(0x11223344, 55);
42 44 if (strcmp($c, $e) != 0) { if (strcmp($c, $e) != 0) {
43 45 rg_log("rg_repo_path 1 is not working correctly: c=$c e=$e."); rg_log("rg_repo_path 1 is not working correctly: c=$c e=$e.");
44 46 exit(1); exit(1);
45 47 } }
48 rg_log_exit();
49
46 50
47 rg_log("rg_repo_path 2");
51 rg_log('');
52 rg_log_enter('rg_repo_path 2');
48 53 $e = $rg_repos . "/by_id/00/00/00/02/00000002/repos/by_id/55.git"; $e = $rg_repos . "/by_id/00/00/00/02/00000002/repos/by_id/55.git";
49 54 $c = rg_repo_path_by_id(2, 55); $c = rg_repo_path_by_id(2, 55);
50 55 if (strcmp($c, $e) != 0) { if (strcmp($c, $e) != 0) {
51 56 rg_log("rg_repo_path 2 is not working correctly: c=$c e=$e."); rg_log("rg_repo_path 2 is not working correctly: c=$c e=$e.");
52 57 exit(1); exit(1);
53 58 } }
59 rg_log_exit();
60
54 61
55 rg_log("test if repo_allow works correctly (0)");
62 rg_log('');
63 rg_log_enter('test if repo_allow works correctly (0)');
56 64 $rg_repo_allow = 'A-Za-z0-9'; $rg_repo_allow = 'A-Za-z0-9';
57 65 $v = "xx"; $v = "xx";
58 66 $c = rg_repo_ok($v); $c = rg_repo_ok($v);
 
... ... if ($c !== TRUE) {
60 68 rg_log("repo_allow problem for valid repo [$v] (c=$c)."); rg_log("repo_allow problem for valid repo [$v] (c=$c).");
61 69 exit(1); exit(1);
62 70 } }
71 rg_log_exit();
63 72
64 rg_log("test if repo_allow works correctly (1)");
73
74 rg_log('');
75 rg_log_enter('test if repo_allow works correctly (1)');
65 76 $rg_repo_allow = 'A-Za-z0-9'; $rg_repo_allow = 'A-Za-z0-9';
66 77 $v = "eyhtmcmet_"; $v = "eyhtmcmet_";
67 78 $c = rg_repo_ok($v); $c = rg_repo_ok($v);
 
... ... if ($c !== FALSE) {
69 80 rg_log("repo_allow problem for '_' in [$v] (c=$c)."); rg_log("repo_allow problem for '_' in [$v] (c=$c).");
70 81 exit(1); exit(1);
71 82 } }
83 rg_log_exit();
84
72 85
73 rg_log("test if repo_allow works correctly (2)");
86 rg_log('');
87 rg_log_enter('test if repo_allow works correctly (2)');
74 88 $rg_repo_allow = 'A-Za-z0-9_.-'; $rg_repo_allow = 'A-Za-z0-9_.-';
75 89 $v = ".e&y.h-tmcmet&_.-"; $v = ".e&y.h-tmcmet&_.-";
76 90 $c = rg_repo_ok($v); $c = rg_repo_ok($v);
 
... ... if ($c !== FALSE) {
78 92 rg_log("repo_allow problem for '&'."); rg_log("repo_allow problem for '&'.");
79 93 exit(1); exit(1);
80 94 } }
95 rg_log_exit();
81 96
82 rg_log("check if we allow '..'");
97
98 rg_log('');
99 rg_log_enter('check if we allow \'..\'');
83 100 $rg_repo_allow = 'A-Za-z0-9_.-'; $rg_repo_allow = 'A-Za-z0-9_.-';
84 101 $v = "a..b"; $v = "a..b";
85 102 $c = rg_repo_ok($v); $c = rg_repo_ok($v);
 
... ... if ($c !== FALSE) {
87 104 rg_log("repo_allow problem for '..'."); rg_log("repo_allow problem for '..'.");
88 105 exit(1); exit(1);
89 106 } }
107 rg_log_exit();
108
90 109
91 rg_log("check len test");
110 rg_log('');
111 rg_log_enter('check len test');
92 112 $v = "0123456789A"; $v = "0123456789A";
93 113 $rg_repo_allow = 'A-Za-z0-9'; $rg_repo_allow = 'A-Za-z0-9';
94 114 $rg_repo_max_len = 10; $rg_repo_max_len = 10;
 
... ... if ($c !== FALSE) {
97 117 rg_log("repo_ok: max length is not enforced!"); rg_log("repo_ok: max length is not enforced!");
98 118 exit(1); exit(1);
99 119 } }
120 rg_log_exit();
100 121
122
123 rg_log('');
101 124 $uid = time(); $uid = time();
102 rg_log("Inserting a fake user uid=$uid");
125 rg_log_enter('Inserting a fake user uid=' . $uid);
103 126 $sql = "INSERT INTO users (uid, username, realname, salt, pass, email, itime, suspended" $sql = "INSERT INTO users (uid, username, realname, salt, pass, email, itime, suspended"
104 127 . ", rights)" . ", rights)"
105 128 . " VALUES ($uid, 'user-$uid', 'realname-$uid', '', '', '', $uid, 0" . " VALUES ($uid, 'user-$uid', 'realname-$uid', '', '', '', $uid, 0"
 
... ... if ($rg_ui['exists'] != 1) {
114 137 rg_log("Cannot load user info!"); rg_log("Cannot load user info!");
115 138 exit(1); exit(1);
116 139 } }
140 rg_log_exit();
141
117 142
118 // create fake user 12
143 rg_log('');
144 rg_log_enter('creating fake user 12');
119 145 $_uid = 12; $_uid = 12;
120 146 rg_log("Inserting a fake user uid=$_uid"); rg_log("Inserting a fake user uid=$_uid");
121 147 $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) {
127 153 rg_log("Cannot insert user uid $_uid (" . rg_sql_error() . ")!"); rg_log("Cannot insert user uid $_uid (" . rg_sql_error() . ")!");
128 154 exit(1); exit(1);
129 155 } }
156 rg_log_exit();
157
130 158
131 159 $rg_repo_allow = $old_allow; $rg_repo_allow = $old_allow;
132 160 $rg_repo_max_len = 50; $rg_repo_max_len = 50;
 
... ... if ($ri['exists'] != 1) {
141 169 exit(1); exit(1);
142 170 } }
143 171
144 rg_log("Clean repos folder...");
172
173 rg_log('');
174 rg_log_enter('Cleaning repos folder...');
145 175 $r = rg_exec("rm -rf base/*"); $r = rg_exec("rm -rf base/*");
146 176 if ($r['ok'] != 1) { if ($r['ok'] != 1) {
147 177 rg_log("Failed to clean base folder."); rg_log("Failed to clean base folder.");
148 178 exit(1); exit(1);
149 179 } }
180 rg_log_exit();
181
150 182
151 rg_log("Creating git folder.");
183 rg_log('');
184 rg_log_enter('Creating git folder.');
152 185 $e = array(); $e = array();
153 186 $e['ui'] = array(); $e['ui'] = array();
154 187 $e['ui']['uid'] = $rg_ui['uid']; $e['ui']['uid'] = $rg_ui['uid'];
 
... ... if ($r === FALSE) {
158 191 rg_log("Cannot create storage dir (" . rg_repo_error() . ")!"); rg_log("Cannot create storage dir (" . rg_repo_error() . ")!");
159 192 exit(1); exit(1);
160 193 } }
194 rg_log_exit();
161 195
162 rg_log("test giving rights");
196
197 rg_log('');
198 rg_log_enter('test giving rights');
163 199 $a = array(); $a = array();
164 200 $a['right_id'] = 0; $a['right_id'] = 0;
165 201 $a['obj_id'] = $ri['repo_id']; $a['obj_id'] = $ri['repo_id'];
 
... ... $a['misc'] = "";
172 208 $a['description'] = "desc <>"; $a['description'] = "desc <>";
173 209 $v = rg_rights_set($db, "repo", $a); $v = rg_rights_set($db, "repo", $a);
174 210 if ($v === FALSE) { if ($v === FALSE) {
175 rg_log("Cannot give rights (1)!");
211 rg_log("Cannot give rights (1): " . rg_rights_error() . "!");
176 212 exit(1); exit(1);
177 213 } }
214 rg_log_exit();
215
178 216
179 rg_log("non-owner gets correct rights: 'A' is from injected rights.");
217 rg_log('');
218 rg_log_enter("non-owner gets correct rights: 'A' is from injected rights.");
180 219 $a = array(); $a = array();
181 220 $a['right_id'] = 0; $a['right_id'] = 0;
182 221 $a['obj_id'] = $ri['repo_id']; $a['obj_id'] = $ri['repo_id'];
 
... ... if ($r !== TRUE) {
192 231 rg_log("Cannot set rights (" . rg_rights_error() . ")!"); rg_log("Cannot set rights (" . rg_rights_error() . ")!");
193 232 exit(1); exit(1);
194 233 } }
195 $e = "AaB"; // will not match the above right but the one injected
196 $r = rg_rights_get($db, $ri['repo_id'], "repo", $uid /*owner */, $a['uid'] /* user */, 0);
197 $c = isset($r['list'][0]['rights']) ? $r['list'][0]['rights'] : "_BAD_";
234 $e = "Aa"; // will not match the above right but the one injected
235 $r = rg_rights_get($db, $ri['repo_id'], "repo", $uid /*owner */,
236 $a['uid'] /*user*/, 0 /*right_id*/);
237 $copy = $r['list'];
238 $first = array_shift($copy);
239 $c = isset($first['rights']) ? $first['rights'] : "_BAD_";
198 240 if (strcmp($c, $e) != 0) { if (strcmp($c, $e) != 0) {
241 rg_log_ml("rights_get: r=" . print_r($r, TRUE));
199 242 rg_log("Non-owner (uid " . $a['uid']. ") did not get correct rights: c=$c e=$e."); rg_log("Non-owner (uid " . $a['uid']. ") did not get correct rights: c=$c e=$e.");
200 rg_log_ml("r=" . print_r($r, TRUE));
201 243 exit(1); exit(1);
202 244 } }
245 rg_log_exit();
203 246
204 rg_log("owner can set separate rights for him");
247 rg_log('');
248 rg_log_enter("owner can set separate rights for him");
205 249 $a = array(); $a = array();
206 250 $a['right_id'] = 0; $a['right_id'] = 0;
207 251 $a['obj_id'] = $ri['repo_id']; $a['obj_id'] = $ri['repo_id'];
 
... ... if ($v === FALSE) {
217 261 rg_log("Owner cannot set separate rights for him!"); rg_log("Owner cannot set separate rights for him!");
218 262 exit(1); exit(1);
219 263 } }
264 rg_log_exit();
220 265
221 rg_log("list1");
266 rg_log('');
267 rg_log_enter('list1');
222 268 $r = rg_rights_load($db, $ri['repo_id'], "repo"); $r = rg_rights_load($db, $ri['repo_id'], "repo");
223 269 if ($r === FALSE) { if ($r === FALSE) {
224 270 rg_log("Cannot list rights (" . rg_repo_error() . ")"); rg_log("Cannot list rights (" . rg_repo_error() . ")");
 
... ... if (count($r) != 3) {
230 276 exit(1); exit(1);
231 277 } }
232 278 // TODO: we should test if expected fields are returned! // TODO: we should test if expected fields are returned!
279 rg_log_exit();
280
233 281
234 rg_log("Testing the rename of the repos");
282 rg_log('');
283 rg_log_enter('Testing the rename of the repos');
235 284 $repo_name = "renameA"; $repo_name = "renameA";
236 285 $rg_repos = "repos"; $rg_repos = "repos";
237 286 $_path = rg_repo_path_by_id($uid, $repo_id); $_path = rg_repo_path_by_id($uid, $repo_id);
 
... ... if ($r === FALSE) {
266 315 rg_log("Cannot rename repository (" . rg_repo_error() . ")!"); rg_log("Cannot rename repository (" . rg_repo_error() . ")!");
267 316 exit(1); exit(1);
268 317 } }
318 rg_log_exit();
269 319
270 // disk size
320
321 rg_log('');
322 rg_log_enter('disk size');
271 323 $size = rg_repo_size("size", TRUE); $size = rg_repo_size("size", TRUE);
272 324 $e = 13; $e = 13;
273 325 if ($size != $e) { if ($size != $e) {
274 326 rg_log("Dir 'size' has an unexpected size ($e != $r)!"); rg_log("Dir 'size' has an unexpected size ($e != $r)!");
275 327 exit(1); exit(1);
276 328 } }
329 rg_log_exit();
330
277 331
278 332 rg_sql_close($db); rg_sql_close($db);
279 333
File tests/wh.php deleted (index 9c902f0..0000000)
1 <?php
2 error_reporting(E_ALL | E_STRICT);
3 ini_set("track_errors", "On");
4
5 $INC = dirname(__FILE__) . "/../inc";
6 require_once(dirname(__FILE__) . "/config.php");
7 require_once($INC . "/init.inc.php");
8 require_once($INC . "/user.inc.php");
9 require_once("helpers.inc.php");
10 require_once("http.inc.php");
11
12 rg_log_set_file("wh.log");
13
14 $rg_sql = "host=localhost user=rocketgit dbname=rocketgit connect_timeout=10";
15 $rg_no_db = TRUE;
16 require_once("common.php");
17
18 $_testns = 'wh';
19 $rg_cache_enable = TRUE;
20 $rg_cache_debug = TRUE;
21 $rg_event_socket = "/var/lib/rocketgit/sockets/event.sock";
22
23 $port1 = 64000 + (rand(0, 100000) + time()) % 1000;
24 $port2 = $port1 + 1;
25 $port3 = $port2 + 1;
26 rg_log('port1=' . $port1 . ' port2=' . $port2 . ' port3=' . $port3);
27
28 function clean()
29 {
30 system('fuser -k -9 wh-stunnel-1.log 1>/dev/null 2>&1');
31 system('fuser -k -9 wh-stunnel-2.log 1>/dev/null 2>&1');
32 system('fuser -k -9 wh-stunnel-3.log 1>/dev/null 2>&1');
33
34 @unlink('wh-stunnel.conf-1.tmp');
35 @unlink('wh-stunnel.conf-2.tmp');
36 @unlink('wh-stunnel.conf-3.tmp');
37 }
38 register_shutdown_function('clean');
39
40
41 rg_log('');
42 rg_log('Generating certificates...');
43 $r = shell_exec('./ca.sh wh');
44 if (!strstr($r, 'CA_SH_OK')) {
45 rg_log_ml('r: ' . print_r($r, TRUE));
46 rg_log('Cannot generate certificates!');
47 exit(1);
48 }
49
50
51 rg_log('');
52 rg_log('Preparing stunnel conf file...');
53 $x = file_get_contents('wh-stunnel.conf');
54 if ($x === FALSE) {
55 rg_log('Cannot load conf file');
56 exit(1);
57 }
58
59 $y = str_replace('@@port@@', $port1, $x);
60 $y = str_replace('@@verify@@', '2', $y);
61 $y = str_replace('@@id@@', '1', $y);
62 file_put_contents('wh-stunnel.conf-1.tmp', $y);
63
64 $y = str_replace('@@port@@', $port2, $x);
65 $y = str_replace('@@verify@@', '2', $y);
66 $y = str_replace('@@id@@', '2', $y);
67 file_put_contents('wh-stunnel.conf-2.tmp', $y);
68
69 $y = str_replace('@@port@@', $port3, $x);
70 $y = str_replace('@@verify@@', '0', $y);
71 $y = str_replace('@@id@@', '3', $y);
72 file_put_contents('wh-stunnel.conf-3.tmp', $y);
73
74
75 rg_log('');
76 rg_log('Starting stunnel1...');
77 $pid = pcntl_fork();
78 if ($pid == -1) {
79 rg_log('Cannot fork');
80 exit(1);
81 }
82 if ($pid == 0) { //child
83 $r = exec('stunnel wh-stunnel.conf-1.tmp 2>/dev/null');
84 exit(0);
85 }
86 rg_log('Started stunnel with pid ' . $pid);
87
88
89 rg_log('');
90 rg_log('Starting stunnel2...');
91 $pid = pcntl_fork();
92 if ($pid == -1) {
93 rg_log('Cannot fork');
94 exit(1);
95 }
96 if ($pid == 0) { //child
97 $r = exec('stunnel wh-stunnel.conf-2.tmp 2>/dev/null');
98 exit(0);
99 }
100 rg_log('Started stunnel with pid ' . $pid);
101
102
103 rg_log('');
104 rg_log('Starting stunnel3...');
105 $pid = pcntl_fork();
106 if ($pid == -1) {
107 rg_log('Cannot fork');
108 exit(1);
109 }
110 if ($pid == 0) { //child
111 $r = exec('stunnel wh-stunnel.conf-3.tmp 2>/dev/null');
112 exit(0);
113 }
114 rg_log('Started stunnel with pid ' . $pid);
115
116
117 rg_log('');
118 rg_log("Creating a user...");
119 rg_test_create_user($db, $rg_ui);
120 $key1 = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $port1;
121 $key2 = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $port2;
122 $key3 = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $port3;
123
124
125 rg_log('');
126 rg_log('Login...');
127 $r = test_login($test_url, $rg_ui, $good_sid);
128 if ($r === FALSE) {
129 rg_log("Cannot login!");
130 exit(1);
131 }
132
133
134 rg_log('');
135 rg_log('Registering webhook1...');
136 $extra = array(
137 'wh::url' => 'https://localhost:' . $port1 . '/wh.html',
138 'wh::type' => 0,
139 'wh::events[C]' => 'on',
140 'wh::events[P]' => 'on',
141 'wh::events[B]' => 'on',
142 'wh::description' => 'description1 <xss>',
143 'wh::key' => 'key1 <xss>',
144 'wh::opaque' => $port1,
145 'wh::client_cert' => '',
146 'wh::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem')
147 );
148 rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra);
149
150
151 rg_log('');
152 rg_log('Registering webhook2...');
153 $extra = array(
154 'wh::url' => 'https://localhost:' . $port2 . '/wh.html',
155 'wh::type' => 1,
156 'wh::events[C]' => 'on',
157 'wh::events[P]' => 'on',
158 'wh::events[B]' => 'on',
159 'wh::description' => 'description1 <xss>',
160 'wh::key' => 'key2 <xss>',
161 'wh::opaque' => $port2,
162 'wh::client_cert' => file_get_contents('ca/wh/certs/client.pem')
163 . file_get_contents('ca/wh/private/client.key'),
164 'wh::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem')
165 );
166 rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra);
167
168
169 rg_log('');
170 rg_log('Registering webhook3...');
171 $extra = array(
172 'wh::url' => 'https://localhost:' . $port3 . '/wh.html',
173 'wh::type' => 1,
174 'wh::events[C]' => 'on',
175 'wh::events[P]' => 'on',
176 'wh::events[B]' => 'on',
177 'wh::description' => 'description1 <xss>',
178 'wh::key' => 'key2 <xss>',
179 'wh::opaque' => $port3,
180 'wh::client_cert' => '',
181 'wh::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem')
182 );
183 rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra);
184
185
186 rg_log('Finding out the ids...');
187 for ($i = 0; $i < 10; $i++) {
188 $r = rg_cache_get('user::' . $rg_ui['uid'] . '::wh');
189 if ($r !== FALSE)
190 break;
191 sleep(1);
192 }
193 if ($r === FALSE) {
194 rg_log('Cannot get id from cache');
195 exit(1);
196 }
197 rg_log_ml('r=' . print_r($r, TRUE));
198 $t = array_keys($r);
199 $wh_id1 = $t[0];
200 $wh_id2 = $t[1];
201 $wh_id3 = $t[2];
202 rg_log('wh_id1=' . $wh_id1);
203 rg_log('wh_id2=' . $wh_id2);
204 rg_log('wh_id3=' . $wh_id3);
205
206
207 rg_log('');
208 rg_log('Creating a repo and waiting for trigger');
209 $repo = array();
210 rg_test_create_repo($db, $rg_ui, $repo);
211
212
213 rg_log('');
214 rg_log('Testing if the curl posted with success (wh1)');
215 for ($i = 0; $i < 10; $i++) {
216 $r = rg_cache_get($key1 . '::' . $wh_id1);
217 rg_log_ml('cache: ' . $r);
218 if ($r !== FALSE)
219 break;
220 sleep(1);
221 }
222 if ($r === FALSE) {
223 rg_log('Seems the event does not set the cache!');
224 exit(1);
225 }
226 if (strcmp($r, "BAD") != 0) {
227 rg_log('Seems wh1 executed correctly without client'
228 . ' cert (r=' . $r . ')!');
229 exit(1);
230 }
231
232
233 rg_log('');
234 rg_log('Testing if the curl posted with success (wh2)');
235 for ($i = 0; $i < 10; $i++) {
236 $r = rg_cache_get($key2 . '::' . $wh_id2);
237 rg_log_ml('cache: ' . print_r($r, TRUE));
238 if ($r !== FALSE)
239 break;
240 sleep(1);
241 }
242 if (strcmp($r, "OK") != 0) {
243 rg_log('Seems wh2 did not returned success'
244 . ' (r=' . $r . ')!');
245 exit(1);
246 }
247
248
249 rg_log('');
250 rg_log('Testing if the curl posted with success (wh3)');
251 for ($i = 0; $i < 10; $i++) {
252 $r = rg_cache_get($key3 . '::' . $wh_id3);
253 rg_log_ml('cache: ' . print_r($r, TRUE));
254 if ($r !== FALSE)
255 break;
256 sleep(1);
257 }
258 if (strcmp($r, "OK") != 0) {
259 rg_log('Seems wh3 did not returned success'
260 . ' (r=' . $r . ')!');
261 exit(1);
262 }
263
264
265 rg_log('');
266 rg_log('Testing the edit of webhook1...');
267 $extra = array(
268 'wh::url' => 'https://localhost:' . $port1 . '/wh.html',
269 'wh::id' => $wh_id1,
270 'wh::type' => 1,
271 'wh::flags[I]' => 'on',
272 'wh::events[C]' => 'on',
273 'wh::events[B]' => 'on',
274 'wh::description' => 'desc2 <xss>',
275 'wh::key' => 'another key <xss>',
276 'wh::opaque' => 'xxx',
277 'wh::client_cert' => 'abc <xss>',
278 'wh::client_ca_cert' => 'zzz <xss>'
279 );
280 rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra);
281 $sql = "SELECT * FROM webhooks WHERE uid = " . $rg_ui['uid']
282 . " AND id = " . $wh_id1;
283 $res = rg_sql_query($db, $sql);
284 $row = rg_sql_fetch_array($res);
285 rg_sql_free_result($res);
286 $key = 'user' . '::' . $rg_ui['uid'] . '::' . 'wh' . '::' . $wh_id1;
287 rg_cache_core_unset($key); // else we will get previous copy!
288 $c = rg_cache_get($key);
289 $list = array('flags' => 'I', 'events' => 'CB', 'type' => '1',
290 'description' => 'desc2 <xss>', 'key' => 'another key <xss>',
291 'opaque' => 'xxx', 'client_cert' => 'abc <xss>',
292 'client_ca_cert' => 'zzz <xss>');
293 foreach ($list as $k => $v) {
294 if (strcmp($row[$k], $v) != 0) {
295 rg_log_ml('row: ' . print_r($row, TRUE));
296 rg_log("db: Seems that [$k] has not been updated [" . $row[$k] . "] != " . $v);
297 exit(1);
298 }
299
300 if (strcmp($c[$k], $v) != 0) {
301 rg_log_ml('c: ' . print_r($c, TRUE));
302 rg_log("cache: Seems that [$k] has not been updated [" . $c[$k] . "] != " . $v);
303 exit(1);
304 }
305 }
306
307
308 rg_log('');
309 rg_log_enter('Testing the delete - loading form...');
310 $data = array();
311 $headers = array("Cookie: sid=" . $good_sid);
312 $r = do_req($test_url . "/op/settings/wh/list", $data, $headers);
313 if ($r === FALSE) {
314 rg_log("Cannot load list form.");
315 exit(1);
316 }
317 if (!isset($r['tokens']['wh_list'])) {
318 rg_log_ml('tokens: ' . print_r($r['tokens'], TRUE));
319 rg_log('Cannot find wh_list token!');
320 exit(1);
321 }
322 $good_token = $r['tokens']['wh_list'];
323 $data = array( 'delete' => 1,
324 'token' => $good_token,
325 'delete_list[' . $wh_id1 . ']' => 'on');
326 $r = do_req($test_url . "/op/settings/wh/list", $data, $headers);
327 if (!strstr($r['body'], 'deleted with success')) {
328 rg_log_ml('r[body]: ' . print_r($r['body'], TRUE));
329 rg_log("Cannot delete webhook!");
330 exit(1);
331 }
332 $sql = "SELECT id FROM webhooks WHERE id = " . $wh_id1;
333 $res = rg_sql_query($db, $sql);
334 $rows = rg_sql_num_rows($res);
335 rg_sql_free_result($res);
336 if ($rows != 0) {
337 rg_log("Cannot delete webhook - sql still returns data!");
338 exit(1);
339 }
340 $key = 'user::' . $rg_ui['uid'] . '::wh::' . $wh_id1;
341 rg_cache_core_unset($key); // else we will get data from local mem!
342 $r = rg_cache_get($key);
343 if (strcmp($r, '') != 0) {
344 rg_log_ml($key . ': ' . print_r($r, TRUE));
345 rg_log('Deleted webhooks are still in cache!');
346 exit(1);
347 }
348 rg_log_exit();
349
350
351 rg_log("OK!");
352 ?>
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