File TODO changed (mode: 100644) (index 279f1f2..931fa4b) |
1 |
1 |
== Where I stopped last time == |
== Where I stopped last time == |
|
2 |
|
[ ] Seems that somehow I managed to arrive at |
|
3 |
|
'http://r1i:9000/op/repo/create/create'! Not good! |
|
4 |
|
I think by creating repositories. |
|
5 |
|
[ ] wh test is not working. |
|
6 |
|
[ ] rg_debug is sent twice for wh.php unit testing. |
2 |
7 |
[ ] |
[ ] |
3 |
8 |
|
|
4 |
9 |
== BEFORE NEXT RELEASE == |
== BEFORE NEXT RELEASE == |
|
10 |
|
[ ] For events, very probably I have to disable the cache. |
|
11 |
|
Scenario: adding a webhook1, add a repo1, add a webhook2, |
|
12 |
|
add a repo2. webhook2 will not trigger on repo2 creating because |
|
13 |
|
only webhook1 is in cache! Very bad! |
|
14 |
|
[ ] Add notifications for hook add? |
|
15 |
|
[ ] Send an e-mail if webhook fails? Flag when configuring webhook? |
|
16 |
|
[ ] unit test: generate a CA, client cert, server cert, and use openssl |
|
17 |
|
s_server to test? Or maybe curl in mode server? Or php in listen |
|
18 |
|
mode? |
|
19 |
|
[ ] Clean 'tmp' folder. |
|
20 |
|
[ ] Document webhooks, mostly 'PHP serialize' type. But also other things. |
|
21 |
|
[ ] Do not forget that cache.php has its own memory cache! |
|
22 |
|
I must not update the database and expect it to see good values. |
|
23 |
|
[ ] wh: Add: tag push, issue, merge request |
|
24 |
|
[ ] wh: add also XML, JSON |
|
25 |
|
[ ] wh: add other conection types: websocket, socket (low priority) |
|
26 |
|
[ ] How "Delete selected" button should be aligned? |
|
27 |
|
[ ] Use rg_var_a2s for checkboxes. |
|
28 |
|
[ ] http://www.w3.org/TR/clipboard-apis/ |
|
29 |
|
1. maybe support javascript copy API |
|
30 |
|
2. The boxes with a border on the left would be nice for hints. |
|
31 |
|
[ ] Evaluate https://www.gnu.org/software/repo-criteria.html |
|
32 |
|
Also in Compare.txt |
5 |
33 |
[ ] When I am in "My repositories" and I am doing a search, other users' |
[ ] When I am in "My repositories" and I am doing a search, other users' |
6 |
34 |
repositories are shown. |
repositories are shown. |
7 |
35 |
[ ] In user/home-page.php, in hints section, add a message when the user is |
[ ] In user/home-page.php, in hints section, add a message when the user is |
8 |
36 |
low on scratch codes. Not hint. |
low on scratch codes. Not hint. |
9 |
|
[ ] If 'rg_debug'? is defined, do not send mails. |
|
10 |
37 |
[ ] test with "short" (0 prepended) codes in unit testing. |
[ ] test with "short" (0 prepended) codes in unit testing. |
11 |
38 |
For scs, done, test for devices? This is a little bit harder. |
For scs, done, test for devices? This is a little bit harder. |
12 |
39 |
[ ] totp:ssh: do we need a command to remove a set of scratch codes? |
[ ] totp:ssh: do we need a command to remove a set of scratch codes? |
13 |
40 |
Something like 'remove-sc [<itime>]'. If <itime> is missing, list the |
Something like 'remove-sc [<itime>]'. If <itime> is missing, list the |
14 |
41 |
sets. The IP must be authorized? |
sets. The IP must be authorized? |
15 |
|
[ ] http hook: use curl's CURLOPT_SSLCERT to authenticate to the client server. |
|
16 |
42 |
[ ] In report, just show the newly added repos, not the totals. Totals in body. |
[ ] In report, just show the newly added repos, not the totals. Totals in body. |
17 |
43 |
[ ] Apply to become a member of Software Freedom Conservancy? |
[ ] Apply to become a member of Software Freedom Conservancy? |
18 |
|
[ ] Why do we index 'users' by 'username'?! Seems wrong! |
|
|
44 |
|
[ ] Why do we have an index by 'users.username'?! Seems wrong! |
19 |
45 |
[ ] totp: add sc for ssh! |
[ ] totp: add sc for ssh! |
20 |
46 |
Should I validate one after asking the user to store them safe? |
Should I validate one after asking the user to store them safe? |
21 |
47 |
Think about power down before scratch codes hit the printer. |
Think about power down before scratch codes hit the printer. |
22 |
48 |
[ ] Get rid of {{}} stuff. |
[ ] Get rid of {{}} stuff. |
23 |
|
[ ] Some other menus were added, we must load all this pages. |
|
|
49 |
|
[ ] Some other menus were added, we must load all this pages in unit tests. |
24 |
50 |
At least totp/{list,enroll,sc}. |
At least totp/{list,enroll,sc}. |
25 |
51 |
[ ] I inconsistently use /op/repo/create and /user/catab/settings! |
[ ] I inconsistently use /op/repo/create and /user/catab/settings! |
26 |
52 |
Why not /user/catab/repo/create? |
Why not /user/catab/repo/create? |
|
63 |
89 |
[ ] Report number of lines of code (and how much a project worth) and |
[ ] Report number of lines of code (and how much a project worth) and |
64 |
90 |
number of other type of documents. |
number of other type of documents. |
65 |
91 |
[ ] Add some flags for users: "Coming from GitHub", to be able to give |
[ ] Add some flags for users: "Coming from GitHub", to be able to give |
66 |
|
tailored hints. |
|
|
92 |
|
specific hints. |
67 |
93 |
[ ] totp: warn user that if a token is not validated for 1 month will be deleted? |
[ ] totp: warn user that if a token is not validated for 1 month will be deleted? |
68 |
94 |
[ ] totp: allow prefix for IP addresses. |
[ ] totp: allow prefix for IP addresses. |
69 |
95 |
[ ] totp: think about authorizing a push, not the ip (ip may be dynamic). |
[ ] totp: think about authorizing a push, not the ip (ip may be dynamic). |
|
83 |
109 |
the browser. |
the browser. |
84 |
110 |
[ ] Document how to deny non ascii filenames using repo_path. |
[ ] Document how to deny non ascii filenames using repo_path. |
85 |
111 |
[ ] When a right denies access, also output the description of that right. |
[ ] When a right denies access, also output the description of that right. |
|
112 |
|
Maybe add a new box for the text to be shown to the user? |
86 |
113 |
[ ] Tell clear that rg can be used also for books, articles, documentation etc. |
[ ] Tell clear that rg can be used also for books, articles, documentation etc. |
87 |
114 |
[ ] Include uid in namespace path to avoid clashes with other users? |
[ ] Include uid in namespace path to avoid clashes with other users? |
88 |
115 |
[ ] ssh: show the fingerprint of the used key? |
[ ] ssh: show the fingerprint of the used key? |
|
103 |
130 |
'password/token', right? Also, for https, I cannot provide the token, |
'password/token', right? Also, for https, I cannot provide the token, |
104 |
131 |
only user/pass. Maybe appending token to the pass. |
only user/pass. Maybe appending token to the pass. |
105 |
132 |
[ ] Can I remove the redirect after login (that means another request)? |
[ ] Can I remove the redirect after login (that means another request)? |
|
133 |
|
Adding a user is pretty light, we should allow the redirect. |
106 |
134 |
[ ] In the report, send also stats about the events, especially the failed ones. |
[ ] In the report, send also stats about the events, especially the failed ones. |
107 |
135 |
[ ] Document backup procedure. |
[ ] Document backup procedure. |
108 |
136 |
[ ] "Forgot password": rate limit it! |
[ ] "Forgot password": rate limit it! |
|
129 |
157 |
Instruct user to remove the token if the phone is lost. But, remind |
Instruct user to remove the token if the phone is lost. But, remind |
130 |
158 |
user that the account may not be compromised without pass. |
user that the account may not be compromised without pass. |
131 |
159 |
[ ] totp: think about loosing the phone. |
[ ] totp: think about loosing the phone. |
132 |
|
[ ] totp: warn about time desync; maybe ask the user to press the 'sync' in |
|
133 |
|
the mobile app. |
|
134 |
160 |
[ ] totp: what if I encrypt key with the password and decrypt only at login? |
[ ] totp: what if I encrypt key with the password and decrypt only at login? |
135 |
161 |
(If somebody steals the database, will not have the keys). |
(If somebody steals the database, will not have the keys). |
136 |
162 |
Cannot do. We need it also at push by ssh. |
Cannot do. We need it also at push by ssh. |
137 |
163 |
[ ] totp: hints for ssh |
[ ] totp: hints for ssh |
138 |
164 |
[ ] totp: Implement 2 factor auth |
[ ] totp: Implement 2 factor auth |
139 |
|
(check https://korg.wiki.kernel.org/userdoc/gitolite_2fa) |
|
|
165 |
|
(check https://korg.wiki.kernel.org/userdoc/gitolite_2fa). Done! |
140 |
166 |
[ ] Use PAM (man pam_start) to be able to use any type of auth, including LDAP. |
[ ] Use PAM (man pam_start) to be able to use any type of auth, including LDAP. |
141 |
167 |
[ ] http://www.cybertec.at/shrinking-the-storage-footprint-of-data/ |
[ ] http://www.cybertec.at/shrinking-the-storage-footprint-of-data/ |
142 |
168 |
[ ] Allow repo admins/owners to delete notes/bugs/etc. |
[ ] Allow repo admins/owners to delete notes/bugs/etc. |
|
152 |
178 |
[ ] I should show some plan 'islands' when you create the account |
[ ] I should show some plan 'islands' when you create the account |
153 |
179 |
so the user will know the disk space and bandwidth. |
so the user will know the disk space and bandwidth. |
154 |
180 |
[ ] In a table, if nothing can be deleted, do not show the delete button. |
[ ] In a table, if nothing can be deleted, do not show the delete button. |
155 |
|
[ ] web hooks: start with a http post to a user server. |
|
156 |
|
warn the user if is not working? |
|
157 |
181 |
[ ] When giving some users rights to your repo, do not spam them with |
[ ] When giving some users rights to your repo, do not spam them with |
158 |
182 |
messages. The user must agree to be spammed. Best, no notification |
messages. The user must agree to be spammed. Best, no notification |
159 |
183 |
is ever issued. User may go to project to activate them if s/he wants. |
is ever issued. User may go to project to activate them if s/he wants. |
|
196 |
220 |
[ ] Add sha1sum of the VM images |
[ ] Add sha1sum of the VM images |
197 |
221 |
[ ] ssh: Show user the entry that must be added for known_hosts |
[ ] ssh: Show user the entry that must be added for known_hosts |
198 |
222 |
[ ] LDAP: http://mageconfig.blogspot.ro/2014/06/configure-gitgerrit-with-open-ldap-for.html |
[ ] LDAP: http://mageconfig.blogspot.ro/2014/06/configure-gitgerrit-with-open-ldap-for.html |
199 |
|
[ ] Leave alone the ssh key comment! More exactly, do not convert unk chars. |
|
200 |
223 |
[ ] Pass only uid to events, we already have it in cache! |
[ ] Pass only uid to events, we already have it in cache! |
201 |
224 |
[ ] 'confirmed' should be built in the event handlers not in callers. |
[ ] 'confirmed' should be built in the event handlers not in callers. |
202 |
225 |
It is already checked in rg_mail_template! |
It is already checked in rg_mail_template! |
|
225 |
248 |
[ ] Allow creating tags/branches on web interface. |
[ ] Allow creating tags/branches on web interface. |
226 |
249 |
[ ] Use a separate template for main rocketgit.com site. The other users |
[ ] Use a separate template for main rocketgit.com site. The other users |
227 |
250 |
should not see the same pages. |
should not see the same pages. |
228 |
|
[ ] git-filter-branch is very powerful: offer it to the clients! |
|
|
251 |
|
[ ] git-filter-branch is very powerful: offer it to the users! |
229 |
252 |
[ ] word-break: break-all; pentru tabelele cu cod. asta permite wrap-ul |
[ ] word-break: break-all; pentru tabelele cu cod. asta permite wrap-ul |
230 |
253 |
oriunde - still needed?! |
oriunde - still needed?! |
231 |
254 |
[ ] Backup for rg2! |
[ ] Backup for rg2! |
|
300 |
323 |
[ ] Before custom hooks, allow enforcing a custom regex for a commit. |
[ ] Before custom hooks, allow enforcing a custom regex for a commit. |
301 |
324 |
[ ] rg_repo_delete trebuie sa stearga si rights si bugs si notes si bug files |
[ ] rg_repo_delete trebuie sa stearga si rights si bugs si notes si bug files |
302 |
325 |
si watch-uri. |
si watch-uri. |
303 |
|
[ ] For unit testing, we need to pass a debug para in http requests and the |
|
304 |
|
mails to be saved in a folder, so we can parse them and verify them. |
|
305 |
326 |
[ ] Expose "git reflog". |
[ ] Expose "git reflog". |
306 |
327 |
[ ] Should I allow state select when adding a bug? Better to consider it open? |
[ ] Should I allow state select when adding a bug? Better to consider it open? |
307 |
328 |
[ ] Add regex for label filtering, maybe for other fields? |
[ ] Add regex for label filtering, maybe for other fields? |
308 |
329 |
[ ] Add regex for search? |
[ ] Add regex for search? |
309 |
330 |
[ ] When showing diff, for the list of files, make links to chunks inside page. |
[ ] When showing diff, for the list of files, make links to chunks inside page. |
|
331 |
|
Already done? |
310 |
332 |
[ ] php-opcache in docs? |
[ ] php-opcache in docs? |
311 |
333 |
[ ] Drop OUTPUT to prevent some attacks? Document in README? |
[ ] Drop OUTPUT to prevent some attacks? Document in README? |
312 |
334 |
[ ] Seems I cache not set values: first_install is still "?"! |
[ ] Seems I cache not set values: first_install is still "?"! |
|
... |
... |
mails to be saved in a folder, so we can parse them and verify them. |
325 |
347 |
[ ] HTTP_X_FORWARDED_FOR variable as this data is effectively user input and |
[ ] HTTP_X_FORWARDED_FOR variable as this data is effectively user input and |
326 |
348 |
therefore susceptible to spoofing. |
therefore susceptible to spoofing. |
327 |
349 |
[ ] Try to remove non critical queries from main page loading. Just schedule |
[ ] Try to remove non critical queries from main page loading. Just schedule |
328 |
|
the operations for later. |
|
|
350 |
|
the operations for later (register_shutdown_function?). |
329 |
351 |
[ ] We should not delete the tokens. They will be cleaned hourly? |
[ ] We should not delete the tokens. They will be cleaned hourly? |
330 |
352 |
[ ] Remove all texts from code and move them to templates. |
[ ] Remove all texts from code and move them to templates. |
331 |
353 |
[ ] Storing password in database must apply multiple hashes. Check owasp. |
[ ] Storing password in database must apply multiple hashes. Check owasp. |
|
... |
... |
But, we have a problem with the expiration time! |
473 |
495 |
[ ] repos.disk_quota_mb must be dropped and do a look-up in plan. |
[ ] repos.disk_quota_mb must be dropped and do a look-up in plan. |
474 |
496 |
[ ] Integrate max_public/private_repos into HL. |
[ ] Integrate max_public/private_repos into HL. |
475 |
497 |
[ ] Allow specifying base language for a project. |
[ ] Allow specifying base language for a project. |
|
498 |
|
[ ] Add country when creating a user? |
476 |
499 |
[ ] When changing db structure, invalidate all caches. |
[ ] When changing db structure, invalidate all caches. |
477 |
500 |
[ ] When we will switch to C, check UTF-8 validation. |
[ ] When we will switch to C, check UTF-8 validation. |
478 |
501 |
[ ] Check http://blog.wikichoon.com/2014/04/github-doesnt-support-pull-request.html |
[ ] Check http://blog.wikichoon.com/2014/04/github-doesnt-support-pull-request.html |
|
... |
... |
But, we have a problem with the expiration time! |
528 |
551 |
private dir. |
private dir. |
529 |
552 |
- "USER" is the user that is logged in. Maybe find a better string |
- "USER" is the user that is logged in. Maybe find a better string |
530 |
553 |
because we may have a user "USER". |
because we may have a user "USER". |
531 |
|
- Also limit by IP and by time. |
|
|
554 |
|
- Also limit by time. |
532 |
555 |
- We have a problem: some rights do not map correctly to the plan above. |
- We have a problem: some rights do not map correctly to the plan above. |
533 |
556 |
For example, A(admin) etc. Seems we need to have >2 categories. |
For example, A(admin) etc. Seems we need to have >2 categories. |
534 |
557 |
- Also, we will have problems classifying a project as public or private. |
- Also, we will have problems classifying a project as public or private. |
|
... |
... |
But, we have a problem with the expiration time! |
598 |
621 |
[ ] Check http://nvie.com/posts/a-successful-git-branching-model/ |
[ ] Check http://nvie.com/posts/a-successful-git-branching-model/ |
599 |
622 |
[ ] After resetting password, go to the login form, with user pre-filed so |
[ ] After resetting password, go to the login form, with user pre-filed so |
600 |
623 |
the user can cache the password. |
the user can cache the password. |
601 |
|
[ ] Add number of bugs multiplied with a value to total disk space. |
|
|
624 |
|
[ ] Add number of bugs multiplied with a factor to total disk space. |
|
625 |
|
Same for any row in the database. Should we do it? |
602 |
626 |
[ ] How should I verify repo rights? |
[ ] How should I verify repo rights? |
603 |
627 |
if (admin) |
if (admin) |
604 |
628 |
if (owner) |
if (owner) |
File inc/repo.inc.php changed (mode: 100644) (index d97d4af..747b083) |
... |
... |
require_once($INC . "/git.inc.php"); |
7 |
7 |
require_once($INC . "/rights.inc.php"); |
require_once($INC . "/rights.inc.php"); |
8 |
8 |
require_once($INC . "/prof.inc.php"); |
require_once($INC . "/prof.inc.php"); |
9 |
9 |
require_once($INC . "/events.inc.php"); |
require_once($INC . "/events.inc.php"); |
|
10 |
|
require_once($INC . "/webhooks.inc.php"); |
10 |
11 |
|
|
11 |
12 |
$rg_repo_refs_rights = array( |
$rg_repo_refs_rights = array( |
12 |
13 |
"F" => "Fetch", |
"F" => "Fetch", |
|
... |
... |
function rg_repo_event_new($db, $event) |
274 |
275 |
$x['notification'] .= "-notify"; |
$x['notification'] .= "-notify"; |
275 |
276 |
$ret[] = $x; |
$ret[] = $x; |
276 |
277 |
|
|
|
278 |
|
// webhook |
|
279 |
|
$x = $event; |
|
280 |
|
$x['category'] = 10000; |
|
281 |
|
$x['prio'] = 50; |
|
282 |
|
$x['wh_event'] = 'C'; // see rg_wh_events array |
|
283 |
|
$ri = &$event['ri']; |
|
284 |
|
$x['wh_data'] = array( |
|
285 |
|
'name' => $ri['name'], |
|
286 |
|
'public' => $ri['public'], |
|
287 |
|
'description' => $ri['description'], |
|
288 |
|
'itime' => $ri['itime'], |
|
289 |
|
'license' => $ri['license'] |
|
290 |
|
); |
|
291 |
|
$ret[] = $x; |
|
292 |
|
|
277 |
293 |
// add a history entry |
// add a history entry |
278 |
294 |
$x = $event; |
$x = $event; |
279 |
295 |
$x['category'] = 3006; |
$x['category'] = 3006; |
|
... |
... |
function rg_repo_event_notify_user($db, $event) |
458 |
474 |
{ |
{ |
459 |
475 |
rg_prof_start("repo_event_notify_user"); |
rg_prof_start("repo_event_notify_user"); |
460 |
476 |
|
|
461 |
|
$r = rg_mail_template("mail/user/repo/" . $event['op'], $event); |
|
462 |
|
if ($r === FALSE) |
|
463 |
|
return FALSE; |
|
|
477 |
|
$ret = FALSE; |
|
478 |
|
while (1) { |
|
479 |
|
if ($event['debug'] == 1) { |
|
480 |
|
rg_cache_set('DEBUG::repo_event_notify_user', $event, 0); |
|
481 |
|
$ret = array(); |
|
482 |
|
break; |
|
483 |
|
} |
|
484 |
|
|
|
485 |
|
$r = rg_mail_template("mail/user/repo/" . $event['op'], $event); |
|
486 |
|
if ($r === FALSE) |
|
487 |
|
break; |
|
488 |
|
|
|
489 |
|
$ret = array(); |
|
490 |
|
break; |
|
491 |
|
} |
464 |
492 |
|
|
465 |
493 |
rg_prof_end("repo_event_notify_user"); |
rg_prof_end("repo_event_notify_user"); |
466 |
|
return array(); |
|
|
494 |
|
return $ret; |
467 |
495 |
} |
} |
468 |
496 |
|
|
469 |
497 |
/* |
/* |
|
... |
... |
function rg_repo_edit($db, $login_ui, &$new) |
908 |
936 |
|
|
909 |
937 |
if ($new['repo_id'] == 0) { |
if ($new['repo_id'] == 0) { |
910 |
938 |
// Check if name is already taken |
// Check if name is already taken |
911 |
|
$ri = rg_repo_info($db, 0, $login_ui['uid'], $new['name']); |
|
|
939 |
|
$ri = rg_repo_info($db, 0, $login_ui['uid'], |
|
940 |
|
$new['name']); |
912 |
941 |
if ($ri['ok'] != 1) |
if ($ri['ok'] != 1) |
913 |
942 |
break; |
break; |
914 |
943 |
if ($ri['exists'] == 1) { |
if ($ri['exists'] == 1) { |
915 |
|
rg_repo_set_error("name already taken; choose a different one"); |
|
|
944 |
|
rg_repo_set_error('name already taken;' |
|
945 |
|
. ' choose a different one'); |
916 |
946 |
break; |
break; |
917 |
947 |
} |
} |
918 |
948 |
} else { |
} else { |
|
... |
... |
function rg_repo_edit($db, $login_ui, &$new) |
922 |
952 |
if ($ri['ok'] != 1) |
if ($ri['ok'] != 1) |
923 |
953 |
break; |
break; |
924 |
954 |
if ($ri['exists'] != 1) { |
if ($ri['exists'] != 1) { |
925 |
|
rg_repo_set_error("repo " . $new['repo_id'] . " does not exists."); |
|
|
955 |
|
rg_repo_set_error('repo ' . $new['repo_id'] |
|
956 |
|
. ' does not exists.'); |
926 |
957 |
break; |
break; |
927 |
958 |
} |
} |
928 |
959 |
} |
} |
|
... |
... |
function rg_repo_edit($db, $login_ui, &$new) |
976 |
1007 |
if ($new['repo_id'] == 0) { |
if ($new['repo_id'] == 0) { |
977 |
1008 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
978 |
1009 |
if ($row === FALSE) { |
if ($row === FALSE) { |
979 |
|
rg_repo_set_error("cannot fetch row: " . rg_sql_error()); |
|
|
1010 |
|
rg_repo_set_error('cannot fetch row'); |
980 |
1011 |
break; |
break; |
981 |
1012 |
} |
} |
982 |
1013 |
} |
} |
|
... |
... |
function rg_repo_edit($db, $login_ui, &$new) |
1025 |
1056 |
rg_cache_set("repo_by_name::" . $login_ui['uid'] . "::" |
rg_cache_set("repo_by_name::" . $login_ui['uid'] . "::" |
1026 |
1057 |
. $new['name'], $new['repo_id'], RG_SOCKET_NO_WAIT); |
. $new['name'], $new['repo_id'], RG_SOCKET_NO_WAIT); |
1027 |
1058 |
|
|
1028 |
|
rg_event_signal_daemon("", 0); |
|
|
1059 |
|
rg_event_signal_daemon('', 0); |
1029 |
1060 |
|
|
1030 |
1061 |
$ret = TRUE; |
$ret = TRUE; |
1031 |
1062 |
break; |
break; |
File inc/totp.inc.php changed (mode: 100644) (index 96502f1..2dbebcd) |
... |
... |
function rg_totp_set_last_use($db, $uid, $id, $tc, $ts) |
269 |
269 |
. ', conf = @@conf@@' |
. ', conf = @@conf@@' |
270 |
270 |
. ' WHERE uid = @@uid@@' |
. ' WHERE uid = @@uid@@' |
271 |
271 |
. ' AND id = @@id@@'; |
. ' AND id = @@id@@'; |
272 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
273 |
|
if ($res === FALSE) { |
|
274 |
|
rg_totp_set_error('cannot update last used (' . rg_sql_error()); |
|
|
272 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
273 |
|
if ($res === FALSE) { |
|
274 |
|
rg_totp_set_error('cannot update last used (' . rg_sql_error()); |
275 |
275 |
break; |
break; |
276 |
|
} |
|
277 |
|
rg_sql_free_result($res); |
|
|
276 |
|
} |
|
277 |
|
rg_sql_free_result($res); |
278 |
278 |
|
|
279 |
279 |
$key = 'user' . '::' . $uid . '::' . 'login_tokens' |
$key = 'user' . '::' . $uid . '::' . 'login_tokens' |
280 |
280 |
. '::' . 'device' . '::' . $id; |
. '::' . 'device' . '::' . $id; |
|
... |
... |
function rg_totp_device_list($db, $uid) |
311 |
311 |
break; |
break; |
312 |
312 |
} |
} |
313 |
313 |
|
|
314 |
|
$ret = array(); |
|
315 |
|
$ret['ok'] = 0; |
|
316 |
|
|
|
317 |
314 |
$params = array('uid' => $uid); |
$params = array('uid' => $uid); |
318 |
315 |
$sql = 'SELECT * FROM login_tokens' |
$sql = 'SELECT * FROM login_tokens' |
319 |
316 |
. ' WHERE uid = @@uid@@' |
. ' WHERE uid = @@uid@@' |
|
... |
... |
function rg_totp_enroll($db, $uid, $name, $secret, $ip, $conf) |
443 |
440 |
break; |
break; |
444 |
441 |
} |
} |
445 |
442 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
446 |
|
rg_sql_free_result($res); |
|
|
443 |
|
rg_sql_free_result($res); |
447 |
444 |
|
|
448 |
445 |
$params['id'] = $row['id']; |
$params['id'] = $row['id']; |
449 |
446 |
rg_totp_cosmetic($params); |
rg_totp_cosmetic($params); |
|
... |
... |
function rg_totp_add_ip($db, $uid, $token_id, $ip, $expire_ts) |
484 |
481 |
rg_totp_set_error('cannot insert login token ip; try again later'); |
rg_totp_set_error('cannot insert login token ip; try again later'); |
485 |
482 |
break; |
break; |
486 |
483 |
} |
} |
487 |
|
rg_sql_free_result($res); |
|
|
484 |
|
rg_sql_free_result($res); |
488 |
485 |
|
|
489 |
486 |
unset($params['uid']); |
unset($params['uid']); |
490 |
487 |
$eip = str_replace(':', '_', $ip); |
$eip = str_replace(':', '_', $ip); |
|
... |
... |
function rg_totp_del_ip($db, $uid, $ip) |
528 |
525 |
break; |
break; |
529 |
526 |
} |
} |
530 |
527 |
$aff = rg_sql_affected_rows($res); |
$aff = rg_sql_affected_rows($res); |
531 |
|
rg_sql_free_result($res); |
|
|
528 |
|
rg_sql_free_result($res); |
532 |
529 |
|
|
533 |
530 |
$ret['ok'] = 1; |
$ret['ok'] = 1; |
534 |
531 |
|
|
|
... |
... |
function rg_totp_remove($db, $uid, $list) |
704 |
701 |
break; |
break; |
705 |
702 |
} |
} |
706 |
703 |
|
|
707 |
|
rg_log_exit(); |
|
|
704 |
|
rg_log_exit(); |
708 |
705 |
rg_prof_end('totp_remove'); |
rg_prof_end('totp_remove'); |
709 |
706 |
return $ret; |
return $ret; |
710 |
707 |
} |
} |
|
... |
... |
function rg_totp_sc_generate($db, $uid, $count) |
872 |
869 |
rg_totp_set_error('cannot insert scratch codes; try again later'); |
rg_totp_set_error('cannot insert scratch codes; try again later'); |
873 |
870 |
break; |
break; |
874 |
871 |
} |
} |
875 |
|
rg_sql_free_result($res); |
|
|
872 |
|
rg_sql_free_result($res); |
876 |
873 |
|
|
877 |
874 |
rg_totp_cosmetic($params); |
rg_totp_cosmetic($params); |
878 |
875 |
$key = 'user' . '::' . $uid . '::' . 'login_tokens' |
$key = 'user' . '::' . $uid . '::' . 'login_tokens' |
|
... |
... |
function rg_totp_sc_remove($db, $uid, $itime, $token) |
921 |
918 |
break; |
break; |
922 |
919 |
} |
} |
923 |
920 |
|
|
924 |
|
rg_log_exit(); |
|
|
921 |
|
rg_log_exit(); |
925 |
922 |
rg_prof_end('totp_sc_remove'); |
rg_prof_end('totp_sc_remove'); |
926 |
923 |
return $ret; |
return $ret; |
927 |
924 |
} |
} |
|
... |
... |
function rg_totp_sc_remove_list($db, $uid, $list) |
969 |
966 |
break; |
break; |
970 |
967 |
} |
} |
971 |
968 |
|
|
972 |
|
rg_log_exit(); |
|
|
969 |
|
rg_log_exit(); |
973 |
970 |
rg_prof_end('totp_sc_remove_list'); |
rg_prof_end('totp_sc_remove_list'); |
974 |
971 |
return $ret; |
return $ret; |
975 |
972 |
} |
} |
|
... |
... |
function rg_totp_unenroll($db, $uid) |
1008 |
1005 |
$params = array('uid' => $uid); |
$params = array('uid' => $uid); |
1009 |
1006 |
$list = array('login_tokens', 'login_tokens_ip', 'scratch_codes'); |
$list = array('login_tokens', 'login_tokens_ip', 'scratch_codes'); |
1010 |
1007 |
foreach ($list as $t) { |
foreach ($list as $t) { |
1011 |
|
$sql = 'DELETE FROM ' . $t |
|
|
1008 |
|
$sql = 'DELETE FROM ' . $t |
1012 |
1009 |
. ' WHERE uid = @@uid@@'; |
. ' WHERE uid = @@uid@@'; |
1013 |
1010 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
1014 |
1011 |
if (!$res) { |
if (!$res) { |
|
... |
... |
function rg_totp_list_high_level($db, $rg, $paras) |
1238 |
1235 |
} else { |
} else { |
1239 |
1236 |
$rg['rg_form_token'] = rg_token_get($db, $rg, 'login_tokens_list'); |
$rg['rg_form_token'] = rg_token_get($db, $rg, 'login_tokens_list'); |
1240 |
1237 |
$rg['HTML:del_errmsg'] = rg_template_errmsg($del_errmsg); |
$rg['HTML:del_errmsg'] = rg_template_errmsg($del_errmsg); |
1241 |
|
$ret .= rg_template_table('user/settings/totp/list', $r['list'], $rg); |
|
|
1238 |
|
$ret .= rg_template_table('user/settings/totp/list', |
|
1239 |
|
$r['list'], $rg); |
1242 |
1240 |
} |
} |
1243 |
1241 |
|
|
1244 |
1242 |
rg_log_exit(); |
rg_log_exit(); |
|
... |
... |
function rg_totp_enroll_high_level($db, $rg, $paras) |
1256 |
1254 |
|
|
1257 |
1255 |
$now = time(); |
$now = time(); |
1258 |
1256 |
|
|
1259 |
|
$rg['totp'] = array(); |
|
1260 |
|
|
|
1261 |
1257 |
$ret = ''; |
$ret = ''; |
1262 |
1258 |
$errmsg = array(); |
$errmsg = array(); |
1263 |
1259 |
|
|
1264 |
|
$rg['totp']['name'] = rg_var_str('totp::name'); |
|
1265 |
|
|
|
1266 |
1260 |
$enroll = rg_var_uint('enroll'); |
$enroll = rg_var_uint('enroll'); |
1267 |
1261 |
while ($enroll == 1) { |
while ($enroll == 1) { |
1268 |
1262 |
$name = rg_var_str('totp::name'); |
$name = rg_var_str('totp::name'); |
|
... |
... |
function rg_totp_enroll_high_level($db, $rg, $paras) |
1317 |
1311 |
$secret = rg_totp_base32_generate(16); |
$secret = rg_totp_base32_generate(16); |
1318 |
1312 |
} |
} |
1319 |
1313 |
|
|
|
1314 |
|
$rg['totp'] = array(); |
1320 |
1315 |
$rg['totp']['name'] = $name; |
$rg['totp']['name'] = $name; |
1321 |
1316 |
$rg['totp']['ver'] = $ver; |
$rg['totp']['ver'] = $ver; |
1322 |
1317 |
$rg['totp']['secret'] = $secret; |
$rg['totp']['secret'] = $secret; |
|
... |
... |
function rg_totp_enroll_high_level($db, $rg, $paras) |
1330 |
1325 |
} |
} |
1331 |
1326 |
|
|
1332 |
1327 |
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg); |
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg); |
1333 |
|
|
|
1334 |
1328 |
$rg['rg_form_token'] = rg_token_get($db, $rg, 'user_totp_enroll'); |
$rg['rg_form_token'] = rg_token_get($db, $rg, 'user_totp_enroll'); |
1335 |
|
rg_log_ml('DEBUG rg: ' . print_r($rg, TRUE)); |
|
1336 |
1329 |
$ret .= rg_template('user/settings/totp/enroll.html', $rg, TRUE /*xss*/); |
$ret .= rg_template('user/settings/totp/enroll.html', $rg, TRUE /*xss*/); |
1337 |
1330 |
|
|
1338 |
1331 |
rg_log_exit(); |
rg_log_exit(); |
File inc/webhooks.inc.php added (mode: 100644) (index 0000000..5da2344) |
|
1 |
|
<?php |
|
2 |
|
require_once($INC . "/util.inc.php"); |
|
3 |
|
require_once($INC . "/log.inc.php"); |
|
4 |
|
require_once($INC . "/sql.inc.php"); |
|
5 |
|
require_once($INC . "/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('flags=' . $info['flags']); |
|
40 |
|
|
|
41 |
|
$headers = array(); |
|
42 |
|
|
|
43 |
|
$c = curl_init($info['url']); |
|
44 |
|
curl_setopt($c, CURLOPT_POST, 1); |
|
45 |
|
curl_setopt($c, CURLOPT_POSTFIELDS, $wh['data']); |
|
46 |
|
curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE); |
|
47 |
|
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 0); |
|
48 |
|
curl_setopt($c, CURLOPT_HEADER, 1); |
|
49 |
|
curl_setopt($c, CURLOPT_HTTPHEADER, $headers); |
|
50 |
|
curl_setopt($c, CURLOPT_USERAGENT, 'RocketGit WebHook'); |
|
51 |
|
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 30); |
|
52 |
|
curl_setopt($c, CURLOPT_ENCODING, ''); // => use all methods |
|
53 |
|
curl_setopt($c, CURLOPT_VERBOSE, TRUE); |
|
54 |
|
curl_setopt($c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); |
|
55 |
|
$err = @fopen('php://temp', 'w'); |
|
56 |
|
if ($err !== FALSE) |
|
57 |
|
curl_setopt($c, CURLOPT_STDERR, $err); |
|
58 |
|
|
|
59 |
|
if (strchr($info['flags'], 'I')) |
|
60 |
|
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE); |
|
61 |
|
|
|
62 |
|
if (strchr($info['flags'], 'H')) |
|
63 |
|
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, FALSE); |
|
64 |
|
|
|
65 |
|
$ret = FALSE; |
|
66 |
|
$cert_file = FALSE; |
|
67 |
|
$ca_file = FALSE; |
|
68 |
|
while (1) { |
|
69 |
|
if (!empty($info['client_cert'])) { |
|
70 |
|
$f = 'wh-' . $event['ui']['uid'] . '-' . $wh['id'] . '-client'; |
|
71 |
|
$cert_file = rg_tmp_file($f, $info['client_cert']); |
|
72 |
|
if ($cert_file === FALSE) |
|
73 |
|
break; |
|
74 |
|
|
|
75 |
|
curl_setopt($c, CURLOPT_SSLCERT, $cert_file); |
|
76 |
|
} |
|
77 |
|
|
|
78 |
|
if (!empty($info['client_ca_cert'])) { |
|
79 |
|
$f = 'wh-' . $event['ui']['uid'] . '-' . $wh['id'] . '-ca'; |
|
80 |
|
$ca_file = rg_tmp_file($f, $info['client_ca_cert']); |
|
81 |
|
if ($ca_file === FALSE) |
|
82 |
|
break; |
|
83 |
|
|
|
84 |
|
curl_setopt($c, CURLOPT_CAINFO, $ca_file); |
|
85 |
|
} |
|
86 |
|
|
|
87 |
|
$r = curl_exec($c); |
|
88 |
|
if ($r === FALSE) { |
|
89 |
|
rg_log('Cannot execute curl: ' . curl_error($c)); |
|
90 |
|
$info = curl_getinfo($c); |
|
91 |
|
rg_log_ml('Debug: ' . print_r($info, TRUE)); |
|
92 |
|
|
|
93 |
|
if ($event['debug'] == 1) |
|
94 |
|
rg_cache_set('DEBUG::webhooks::' . $event['ui']['uid'] |
|
95 |
|
. '::' . $wh['id'], |
|
96 |
|
'BAD', RG_SOCKET_NO_WAIT); |
|
97 |
|
break; |
|
98 |
|
} |
|
99 |
|
|
|
100 |
|
rg_log_ml('Answer: ' . print_r($r, TRUE)); |
|
101 |
|
|
|
102 |
|
if ($err !== FALSE) { |
|
103 |
|
rewind($err); |
|
104 |
|
$xerr = @fread($err, 4 * 4096); |
|
105 |
|
fclose($err); |
|
106 |
|
rg_log_ml('xerr = ' . $xerr); |
|
107 |
|
} |
|
108 |
|
|
|
109 |
|
if ($event['debug'] == 1) |
|
110 |
|
rg_cache_set('DEBUG::webhooks::' . $event['ui']['uid'] |
|
111 |
|
. '::' . $wh['id'], |
|
112 |
|
'OK', RG_SOCKET_NO_WAIT); |
|
113 |
|
|
|
114 |
|
$ret = array(); |
|
115 |
|
break; |
|
116 |
|
} |
|
117 |
|
curl_close($c); |
|
118 |
|
|
|
119 |
|
if ($cert_file !== FALSE) |
|
120 |
|
@unlink($cert_file); |
|
121 |
|
|
|
122 |
|
if ($ca_file !== FALSE) |
|
123 |
|
@unlink($ca_file); |
|
124 |
|
|
|
125 |
|
rg_prof_end('wh_send_helper'); |
|
126 |
|
return $ret; |
|
127 |
|
} |
|
128 |
|
|
|
129 |
|
/* |
|
130 |
|
* Generic function which will be called when a webhook must be posted |
|
131 |
|
*/ |
|
132 |
|
function rg_wh_send($db, $event) |
|
133 |
|
{ |
|
134 |
|
rg_prof_start('wh_send'); |
|
135 |
|
|
|
136 |
|
rg_log_ml('event: ' . print_r($event, TRUE)); |
|
137 |
|
|
|
138 |
|
// First, get the list of hooks |
|
139 |
|
$r = rg_wh_list($db, $event['ui']['uid']); |
|
140 |
|
if ($r['ok'] != 1) |
|
141 |
|
return FALSE; |
|
142 |
|
|
|
143 |
|
// Filter them by repo_id |
|
144 |
|
$real_list = array(); |
|
145 |
|
foreach ($r['list'] as $id => $info) { |
|
146 |
|
if (($info['repo_id'] != 0) |
|
147 |
|
&& ($event['ri']['repo_id'] != $info['repo_id'])) { |
|
148 |
|
rg_log('hook is not for this repo'); |
|
149 |
|
continue; |
|
150 |
|
} |
|
151 |
|
|
|
152 |
|
// If the web hook does not contain our type, skip it |
|
153 |
|
if (!strchr($info['events'], $event['wh_event'])) { |
|
154 |
|
rg_log($event['wh_event'] . ' is not present in ' . $info['events']); |
|
155 |
|
continue; |
|
156 |
|
} |
|
157 |
|
|
|
158 |
|
$real_list[] = $id; |
|
159 |
|
} |
|
160 |
|
|
|
161 |
|
// Something to do? |
|
162 |
|
if (empty($real_list)) |
|
163 |
|
return array(); |
|
164 |
|
|
|
165 |
|
$cache = array(); |
|
166 |
|
$wh = array(); |
|
167 |
|
$ret = array(); |
|
168 |
|
foreach ($real_list as $id) { |
|
169 |
|
$wh['info'] = $r['list'][$id]; |
|
170 |
|
$wh['id'] = $id; |
|
171 |
|
|
|
172 |
|
$type = $wh['info']['type']; |
|
173 |
|
if (!isset($cache[$type])) { |
|
174 |
|
switch ($type) { |
|
175 |
|
case 0: // http post |
|
176 |
|
$cache[$type] = &$event['wh_data']; |
|
177 |
|
break; |
|
178 |
|
|
|
179 |
|
case 1: // php serialize |
|
180 |
|
$cache[$type] = array( |
|
181 |
|
'data' => serialize($event['wh_data'])); |
|
182 |
|
break; |
|
183 |
|
|
|
184 |
|
default: |
|
185 |
|
rg_log('Unknown type ' . $type . '!'); |
|
186 |
|
$cache[$type] = ''; |
|
187 |
|
break; |
|
188 |
|
} |
|
189 |
|
} |
|
190 |
|
$wh['data'] = $cache[$type]; |
|
191 |
|
|
|
192 |
|
$x = $event; |
|
193 |
|
$x['category'] = 10001; |
|
194 |
|
$x['wh'] = $wh; |
|
195 |
|
$ret[] = $x; |
|
196 |
|
} |
|
197 |
|
|
|
198 |
|
rg_prof_end('wh_send'); |
|
199 |
|
return $ret; |
|
200 |
|
} |
|
201 |
|
|
|
202 |
|
$rg_wh_types = array( |
|
203 |
|
0 => 'HTTP (application/x-www-form-urlencoded)', |
|
204 |
|
1 => 'PHP serialize' |
|
205 |
|
); |
|
206 |
|
/* |
|
207 |
|
* Transforms a type into HTML select |
|
208 |
|
*/ |
|
209 |
|
function rg_wh_select_type($type) |
|
210 |
|
{ |
|
211 |
|
global $rg_wh_types; |
|
212 |
|
|
|
213 |
|
$ret = '<select name="wh::type" id="type">'; |
|
214 |
|
foreach ($rg_wh_types as $_type => $name) { |
|
215 |
|
$add = ''; |
|
216 |
|
if ($_type == $type) |
|
217 |
|
$add = ' selected'; |
|
218 |
|
|
|
219 |
|
$ret .= '<option value="' . $_type . '"' . $add . '>' |
|
220 |
|
. $name |
|
221 |
|
. '</option>' . "\n"; |
|
222 |
|
} |
|
223 |
|
$ret .= '</select>' . "\n"; |
|
224 |
|
|
|
225 |
|
return $ret; |
|
226 |
|
} |
|
227 |
|
|
|
228 |
|
/* |
|
229 |
|
* Returns type text based on id |
|
230 |
|
*/ |
|
231 |
|
function rg_wh_type($type) |
|
232 |
|
{ |
|
233 |
|
global $rg_wh_types; |
|
234 |
|
|
|
235 |
|
foreach ($rg_wh_types as $_type => $name) |
|
236 |
|
if ($_type == $type) |
|
237 |
|
return $name; |
|
238 |
|
} |
|
239 |
|
|
|
240 |
|
$rg_wh_events = array( |
|
241 |
|
'C' => 'Create repository', |
|
242 |
|
'P' => 'Push', |
|
243 |
|
'B' => 'Create branch' |
|
244 |
|
); |
|
245 |
|
/* |
|
246 |
|
* Generates event list as html |
|
247 |
|
*/ |
|
248 |
|
function rg_wh_check_events($events) |
|
249 |
|
{ |
|
250 |
|
global $rg_wh_events; |
|
251 |
|
|
|
252 |
|
$ret = '<fieldset>'; |
|
253 |
|
$ret .= '<legend>Select trigger events</legend>'; |
|
254 |
|
$br = ''; |
|
255 |
|
foreach ($rg_wh_events as $id => $name) { |
|
256 |
|
$add = ''; |
|
257 |
|
if (strchr($events, $id)) |
|
258 |
|
$add = ' checked="checked"'; |
|
259 |
|
|
|
260 |
|
$ret .= $br |
|
261 |
|
. '<input type="checkbox" name="wh::events[' . $id . ']"' |
|
262 |
|
. ' id="events-' . $id . '"' |
|
263 |
|
. $add . ' />' |
|
264 |
|
. "\n" |
|
265 |
|
. '<label for="events-' . $id . '">' . $name . '</label>'; |
|
266 |
|
$br = '<br />' . "\n"; |
|
267 |
|
} |
|
268 |
|
$ret .= '</fieldset>' . "\n"; |
|
269 |
|
|
|
270 |
|
return $ret; |
|
271 |
|
} |
|
272 |
|
|
|
273 |
|
/* |
|
274 |
|
* Generates an events list as text |
|
275 |
|
*/ |
|
276 |
|
function rg_wh_events($events) |
|
277 |
|
{ |
|
278 |
|
global $rg_wh_events; |
|
279 |
|
|
|
280 |
|
$a = array(); |
|
281 |
|
foreach ($rg_wh_events as $id => $name) { |
|
282 |
|
if (strchr($events, $id)) |
|
283 |
|
$a[] = $name; |
|
284 |
|
} |
|
285 |
|
|
|
286 |
|
return implode(', ', $a); |
|
287 |
|
} |
|
288 |
|
|
|
289 |
|
$rg_wh_flags = array( |
|
290 |
|
'I' => 'Do not verify the certificate', |
|
291 |
|
'H' => 'Do not verify the hostname' |
|
292 |
|
); |
|
293 |
|
/* |
|
294 |
|
* Generates flags list |
|
295 |
|
*/ |
|
296 |
|
function rg_wh_check_flags($flags) |
|
297 |
|
{ |
|
298 |
|
global $rg_wh_flags; |
|
299 |
|
|
|
300 |
|
$ret = '<fieldset>'; |
|
301 |
|
$ret .= '<legend>Flags</legend>'; |
|
302 |
|
$br = ''; |
|
303 |
|
foreach ($rg_wh_flags as $id => $name) { |
|
304 |
|
$add = ''; |
|
305 |
|
if (strchr($flags, $id)) |
|
306 |
|
$add = ' checked="checked"'; |
|
307 |
|
|
|
308 |
|
$ret .= $br |
|
309 |
|
. '<input type="checkbox" name="wh::flags[' . $id . ']"' |
|
310 |
|
. ' id="flags-' . $id . '"' |
|
311 |
|
. $add . ' />' |
|
312 |
|
. "\n" |
|
313 |
|
. '<label for="flags-' . $id . '">' . $name . '</label>'; |
|
314 |
|
$br = '<br />' . "\n"; |
|
315 |
|
} |
|
316 |
|
$ret .= '</fieldset>' . "\n"; |
|
317 |
|
|
|
318 |
|
return $ret; |
|
319 |
|
} |
|
320 |
|
|
|
321 |
|
/* |
|
322 |
|
* Generates a flags list as text |
|
323 |
|
*/ |
|
324 |
|
function rg_wh_flags($flags) |
|
325 |
|
{ |
|
326 |
|
global $rg_wh_flags; |
|
327 |
|
|
|
328 |
|
$a = array(); |
|
329 |
|
foreach ($rg_wh_flags as $id => $name) { |
|
330 |
|
if (strchr($flags, $id)) |
|
331 |
|
$a[] = $name; |
|
332 |
|
} |
|
333 |
|
|
|
334 |
|
return implode(', ', $a); |
|
335 |
|
} |
|
336 |
|
|
|
337 |
|
/* |
|
338 |
|
* Some cosmetics applied to a webhook |
|
339 |
|
*/ |
|
340 |
|
function rg_wh_cosmetic(&$list) |
|
341 |
|
{ |
|
342 |
|
foreach ($list as $id => &$row) { |
|
343 |
|
if (isset($row['itime'])) |
|
344 |
|
$row['itime_nice'] = gmdate('Y-m-d H:i', $row['itime']); |
|
345 |
|
|
|
346 |
|
if (isset($row['description'])) |
|
347 |
|
$row['HTML:description_nice'] = |
|
348 |
|
nl2br(rg_xss_safe($row['description'])); |
|
349 |
|
|
|
350 |
|
if (isset($row['type'])) |
|
351 |
|
$row['type_text'] = rg_wh_type($row['type']); |
|
352 |
|
|
|
353 |
|
if (isset($row['events'])) |
|
354 |
|
$row['events_text'] = rg_wh_events($row['events']); |
|
355 |
|
|
|
356 |
|
if (isset($row['flags'])) |
|
357 |
|
$row['flags_text'] = rg_wh_flags($row['flags']); |
|
358 |
|
|
|
359 |
|
if (isset($row['client_cert'])) |
|
360 |
|
$row['HTML:client_cert_short'] = |
|
361 |
|
empty($row['client_cert']) ? |
|
362 |
|
'' : nl2br(rg_xss_safe(substr($row['client_cert'], 0, 32))) . '...'; |
|
363 |
|
|
|
364 |
|
if (isset($row['client_ca_cert'])) |
|
365 |
|
$row['HTML:client_ca_cert_short'] = |
|
366 |
|
empty($row['client_ca_cert']) ? |
|
367 |
|
'' : nl2br(rg_xss_safe(substr($row['client_ca_cert'], 0, 32))) . '...'; |
|
368 |
|
} |
|
369 |
|
} |
|
370 |
|
|
|
371 |
|
/* |
|
372 |
|
* Returns a list of webhooks associated with a user |
|
373 |
|
* @repo_id may be 0 => hooks installed on user account |
|
374 |
|
*/ |
|
375 |
|
function rg_wh_list($db, $uid) |
|
376 |
|
{ |
|
377 |
|
rg_prof_start('wh_list'); |
|
378 |
|
rg_log_enter('wh_list'); |
|
379 |
|
|
|
380 |
|
$ret = array('ok' => 0, 'list' => array()); |
|
381 |
|
while (1) { |
|
382 |
|
$key = 'user' . '::' . $uid . '::' . 'wh'; |
|
383 |
|
$r = rg_cache_get($key); |
|
384 |
|
if ($r !== FALSE) { |
|
385 |
|
$ret['list'] = $r; |
|
386 |
|
$ret['ok'] = 1; |
|
387 |
|
break; |
|
388 |
|
} |
|
389 |
|
|
|
390 |
|
$params = array('uid' => $uid); |
|
391 |
|
$sql = 'SELECT * FROM webhooks' |
|
392 |
|
. ' WHERE uid = @@uid@@'; |
|
393 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
394 |
|
if ($res === FALSE) { |
|
395 |
|
rg_wh_set_error('cannot load data'); |
|
396 |
|
break; |
|
397 |
|
} |
|
398 |
|
|
|
399 |
|
while (($row = rg_sql_fetch_array($res))) { |
|
400 |
|
$id = $row['id']; |
|
401 |
|
|
|
402 |
|
$ret['list'][$id] = $row; |
|
403 |
|
} |
|
404 |
|
rg_sql_free_result($res); |
|
405 |
|
|
|
406 |
|
rg_cache_set($key, $ret['list'], RG_SOCKET_NO_WAIT); |
|
407 |
|
$ret['ok'] = 1; |
|
408 |
|
break; |
|
409 |
|
} |
|
410 |
|
|
|
411 |
|
rg_log_exit(); |
|
412 |
|
rg_prof_end('wh_list'); |
|
413 |
|
return $ret; |
|
414 |
|
} |
|
415 |
|
|
|
416 |
|
/* |
|
417 |
|
* Adds/edits a webhook |
|
418 |
|
*/ |
|
419 |
|
function rg_wh_add($db, $uid, $data) |
|
420 |
|
{ |
|
421 |
|
rg_prof_start('wh_add'); |
|
422 |
|
rg_log_enter('wh_add'); |
|
423 |
|
|
|
424 |
|
$ret = array('ok' => 0); |
|
425 |
|
while (1) { |
|
426 |
|
$params = $data; |
|
427 |
|
$params['uid'] = $uid; |
|
428 |
|
$params['itime'] = time(); |
|
429 |
|
|
|
430 |
|
if ($data['id'] == 0) |
|
431 |
|
$sql = 'INSERT INTO webhooks (uid, repo_id, itime, events' |
|
432 |
|
. ', url, client_cert, client_ca_cert, flags' |
|
433 |
|
. ', add_ip, description)' |
|
434 |
|
. ' VALUES (@@uid@@, @@repo_id@@, @@itime@@' |
|
435 |
|
. ', @@events@@, @@url@@, @@client_cert@@' |
|
436 |
|
. ', @@client_ca_cert@@, @@flags@@, @@add_ip@@' |
|
437 |
|
. ', @@description@@)' |
|
438 |
|
. ' RETURNING id'; |
|
439 |
|
else |
|
440 |
|
$sql = 'UPDATE webhooks' |
|
441 |
|
. ' SET events = @@events@@' |
|
442 |
|
. ', url = @@url@@' |
|
443 |
|
. ', client_cert = @@client_cert@@' |
|
444 |
|
. ', client_ca_cert = @@client_ca_cert@@' |
|
445 |
|
. ', flags = @@flags@@' |
|
446 |
|
. ', type = @@type@@' |
|
447 |
|
. ', description = @@description@@' |
|
448 |
|
. ' WHERE uid = @@uid@@' |
|
449 |
|
. ' AND id = @@id@@'; |
|
450 |
|
|
|
451 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
452 |
|
if ($res === FALSE) { |
|
453 |
|
rg_wh_set_error('cannot insert/update data'); |
|
454 |
|
break; |
|
455 |
|
} |
|
456 |
|
if ($data['id'] == 0) |
|
457 |
|
$row = rg_sql_fetch_array($res); |
|
458 |
|
rg_sql_free_result($res); |
|
459 |
|
|
|
460 |
|
if ($data['id'] == 0) |
|
461 |
|
$params['id'] = $row['id']; |
|
462 |
|
$key = 'user' . '::' . $uid . '::' . 'wh' |
|
463 |
|
. '::' . $params['id']; |
|
464 |
|
rg_cache_set($key, $params, RG_SOCKET_NO_WAIT); |
|
465 |
|
|
|
466 |
|
$ret['ok'] = 1; |
|
467 |
|
break; |
|
468 |
|
} |
|
469 |
|
|
|
470 |
|
rg_log_exit(); |
|
471 |
|
rg_prof_end('wh_add'); |
|
472 |
|
return $ret; |
|
473 |
|
} |
|
474 |
|
|
|
475 |
|
/* |
|
476 |
|
* Removes a list of webhooks |
|
477 |
|
*/ |
|
478 |
|
function rg_wh_remove($db, $uid, $list) |
|
479 |
|
{ |
|
480 |
|
rg_prof_start('wh_remove'); |
|
481 |
|
rg_log_enter('wh_remove'); |
|
482 |
|
|
|
483 |
|
$ret = array('ok' => 0); |
|
484 |
|
while (1) { |
|
485 |
|
if (empty($list)) { |
|
486 |
|
rg_wh_set_error('you did not select anything'); |
|
487 |
|
break; |
|
488 |
|
} |
|
489 |
|
|
|
490 |
|
$my_list = array(); |
|
491 |
|
foreach ($list as $id => $junk) |
|
492 |
|
$my_list[] = sprintf("%u", $id); |
|
493 |
|
|
|
494 |
|
$params = array('uid' => $uid); |
|
495 |
|
$sql_list = implode(', ', $my_list); |
|
496 |
|
|
|
497 |
|
$sql = 'DELETE FROM webhooks' |
|
498 |
|
. ' WHERE uid = @@uid@@' |
|
499 |
|
. ' AND id IN (' . $sql_list . ')'; |
|
500 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
501 |
|
if ($res === FALSE) { |
|
502 |
|
rg_wh_set_error('cannot remove webhooks'); |
|
503 |
|
break; |
|
504 |
|
} |
|
505 |
|
rg_sql_free_result($res); |
|
506 |
|
|
|
507 |
|
foreach ($my_list as $junk => $id) { |
|
508 |
|
$key = 'user' . '::' . $uid . '::' . 'wh' . '::' . $id; |
|
509 |
|
rg_cache_unset($key, RG_SOCKET_NO_WAIT); |
|
510 |
|
} |
|
511 |
|
|
|
512 |
|
$ret['ok'] = 1; |
|
513 |
|
break; |
|
514 |
|
} |
|
515 |
|
|
|
516 |
|
rg_log_exit(); |
|
517 |
|
rg_prof_end('wh_remove'); |
|
518 |
|
return $ret; |
|
519 |
|
} |
|
520 |
|
|
|
521 |
|
/* |
|
522 |
|
* High level function to list the webhooks |
|
523 |
|
*/ |
|
524 |
|
function rg_wh_list_high_level($db, $rg, $paras) |
|
525 |
|
{ |
|
526 |
|
rg_prof_start('wh_list_high_level'); |
|
527 |
|
rg_log_enter('wh_list_high_level'); |
|
528 |
|
|
|
529 |
|
$ret = ''; |
|
530 |
|
|
|
531 |
|
$errmsg = array(); |
|
532 |
|
|
|
533 |
|
$delete = rg_var_uint('delete'); |
|
534 |
|
while ($delete == 1) { |
|
535 |
|
if (!rg_valid_referer()) { |
|
536 |
|
$errmsg[] = 'invalid referer; try again'; |
|
537 |
|
break; |
|
538 |
|
} |
|
539 |
|
|
|
540 |
|
if (!rg_token_valid($db, $rg, 'wh_list', FALSE)) { |
|
541 |
|
$errmsg[] = 'invalid token; try again.'; |
|
542 |
|
break; |
|
543 |
|
} |
|
544 |
|
|
|
545 |
|
$list = rg_var_str("delete_list"); |
|
546 |
|
$r = rg_wh_remove($db, $rg['login_ui']['uid'], $list); |
|
547 |
|
if ($r['ok'] !== 1) { |
|
548 |
|
$errmsg[] = 'cannot delete: ' . rg_wh_error(); |
|
549 |
|
break; |
|
550 |
|
} |
|
551 |
|
|
|
552 |
|
$ret .= rg_template('user/settings/wh/delete_ok.html', |
|
553 |
|
$rg, TRUE /*xss*/); |
|
554 |
|
break; |
|
555 |
|
} |
|
556 |
|
|
|
557 |
|
$r = rg_wh_list($db, $rg['login_ui']['uid']); |
|
558 |
|
if ($r['ok'] !== 1) { |
|
559 |
|
$rg['errmsg'] = rg_wh_error(); |
|
560 |
|
$ret .= rg_template('user/settings/wh/list_err.html', |
|
561 |
|
$rg, TRUE /*xss*/); |
|
562 |
|
} else { |
|
563 |
|
rg_wh_cosmetic($r['list']); |
|
564 |
|
//rg_log_ml("DEBUG: r[list]: " . print_r($r['list'], TRUE)); |
|
565 |
|
$rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_list'); |
|
566 |
|
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg); |
|
567 |
|
$ret .= rg_template_table('user/settings/wh/list', |
|
568 |
|
$r['list'], $rg); |
|
569 |
|
} |
|
570 |
|
|
|
571 |
|
rg_log_exit(); |
|
572 |
|
rg_prof_end('wh_list_high_level'); |
|
573 |
|
return $ret; |
|
574 |
|
} |
|
575 |
|
|
|
576 |
|
/* |
|
577 |
|
* High level function to add/edit a web hook |
|
578 |
|
*/ |
|
579 |
|
function rg_wh_add_high_level($db, $rg, $paras) |
|
580 |
|
{ |
|
581 |
|
rg_prof_start('wh_add_high_level'); |
|
582 |
|
rg_log_enter('wh_add_high_level'); |
|
583 |
|
|
|
584 |
|
$ret = ''; |
|
585 |
|
$errmsg = array(); |
|
586 |
|
$show_form = TRUE; |
|
587 |
|
|
|
588 |
|
$rg['wh'] = array(); |
|
589 |
|
// We need the id in any case |
|
590 |
|
$rg['wh']['id'] = rg_var_str('wh::id'); |
|
591 |
|
|
|
592 |
|
$add = rg_var_uint('add'); |
|
593 |
|
while ($add == 1) { |
|
594 |
|
$rg['wh']['repo_id'] = rg_var_uint('wh::repo_id'); |
|
595 |
|
$rg['wh']['itime'] = time(); |
|
596 |
|
$rg['wh']['events'] = rg_var_a2s('wh::events'); // TODO |
|
597 |
|
$rg['wh']['url'] = rg_var_str('wh::url'); |
|
598 |
|
$rg['wh']['type'] = rg_var_uint('wh::type'); |
|
599 |
|
$rg['wh']['client_cert'] = trim(rg_var_str('wh::client_cert')); |
|
600 |
|
$rg['wh']['client_ca_cert'] = trim(rg_var_str('wh::client_ca_cert')); |
|
601 |
|
$rg['wh']['flags'] = rg_var_a2s('wh::flags'); |
|
602 |
|
$rg['wh']['add_ip'] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; |
|
603 |
|
$rg['wh']['description'] = rg_var_str('wh::description'); |
|
604 |
|
|
|
605 |
|
// TODO: validate here the paras |
|
606 |
|
if ((strncasecmp($rg['wh']['url'], "http", 4) != 0) |
|
607 |
|
|| (strncasecmp($rg['wh']['url'], "https", 5) != 0)) { |
|
608 |
|
$errmsg[] = 'invalid protocol; only http and https supported now'; |
|
609 |
|
break; |
|
610 |
|
} |
|
611 |
|
|
|
612 |
|
if (!rg_valid_referer()) { |
|
613 |
|
$errmsg[] = 'invalid referer; try again'; |
|
614 |
|
break; |
|
615 |
|
} |
|
616 |
|
|
|
617 |
|
if (!rg_token_valid($db, $rg, 'wh_add', FALSE)) { |
|
618 |
|
$errmsg[] = 'invalid token; try again.'; |
|
619 |
|
break; |
|
620 |
|
} |
|
621 |
|
|
|
622 |
|
$r = rg_wh_add($db, $rg['login_ui']['uid'], $rg['wh']); |
|
623 |
|
if ($r['ok'] !== 1) { |
|
624 |
|
$errmsg[] = rg_wh_error(); |
|
625 |
|
break; |
|
626 |
|
} |
|
627 |
|
|
|
628 |
|
$ret .= rg_template('user/settings/wh/edit_ok.html', |
|
629 |
|
$rg, TRUE /*xss*/); |
|
630 |
|
|
|
631 |
|
$show_form = FALSE; |
|
632 |
|
break; |
|
633 |
|
} |
|
634 |
|
|
|
635 |
|
if ($show_form) { |
|
636 |
|
// defaults |
|
637 |
|
if ($add == 0) { |
|
638 |
|
// TODO: if edit, load data based on id |
|
639 |
|
if ($rg['wh']['id'] > 0) { |
|
640 |
|
rg_log('TODO: edit is not yet implemented'); |
|
641 |
|
} else { |
|
642 |
|
// here is clear an add |
|
643 |
|
$rg['wh']['id'] = 0; |
|
644 |
|
$rg['wh']['events'] = ''; |
|
645 |
|
$rg['wh']['url'] = ''; |
|
646 |
|
$rg['wh']['type'] = 0; |
|
647 |
|
$rg['wh']['client_cert'] = ''; |
|
648 |
|
$rg['wh']['client_ca_cert'] = ''; |
|
649 |
|
$rg['wh']['flags'] = ''; |
|
650 |
|
$rg['wh']['description'] = ''; |
|
651 |
|
} |
|
652 |
|
} |
|
653 |
|
|
|
654 |
|
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg); |
|
655 |
|
$rg['HTML:check_flags'] = rg_wh_check_flags($rg['wh']['flags']); |
|
656 |
|
$rg['HTML:check_events'] = rg_wh_check_events($rg['wh']['events']); |
|
657 |
|
$rg['HTML:select_type'] = rg_wh_select_type($rg['wh']['type']); |
|
658 |
|
$rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_add'); |
|
659 |
|
$ret .= rg_template('user/settings/wh/add_edit.html', |
|
660 |
|
$rg, TRUE /*xss*/); |
|
661 |
|
} |
|
662 |
|
|
|
663 |
|
rg_log_exit(); |
|
664 |
|
rg_prof_end('wh_add_high_level'); |
|
665 |
|
return $ret; |
|
666 |
|
} |
|
667 |
|
|
|
668 |
|
/* |
|
669 |
|
* Main HL function for webhooks |
|
670 |
|
*/ |
|
671 |
|
function rg_wh_high_level($db, $rg, $paras) |
|
672 |
|
{ |
|
673 |
|
rg_prof_start('wh_high_level'); |
|
674 |
|
rg_log_enter('wh_high_level'); |
|
675 |
|
|
|
676 |
|
$ret = ''; |
|
677 |
|
|
|
678 |
|
$op = empty($paras) ? 'list' : array_shift($paras); |
|
679 |
|
$rg['menu']['wh'][$op] = 1; |
|
680 |
|
|
|
681 |
|
rg_log("DEBUG: op=$op"); |
|
682 |
|
$ret .= rg_template('user/settings/wh/menu.html', $rg, TRUE /*xss*/); |
|
683 |
|
|
|
684 |
|
switch ($op) { |
|
685 |
|
case 'add': $ret .= rg_wh_add_high_level($db, $rg, $paras); break; |
|
686 |
|
default: $ret .= rg_wh_list_high_level($db, $rg, $paras); break; |
|
687 |
|
} |
|
688 |
|
|
|
689 |
|
rg_log_exit(); |
|
690 |
|
rg_prof_end('wh_high_level'); |
|
691 |
|
return $ret; |
|
692 |
|
} |
|
693 |
|
|
|
694 |
|
?> |
File tests/wh.php added (mode: 100644) (index 0000000..cab3d90) |
|
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 = 'ssh'; |
|
19 |
|
$rg_cache_enable = TRUE; |
|
20 |
|
$rg_cache_debug = TRUE; |
|
21 |
|
$rg_event_socket = "/var/lib/rocketgit/sockets/event.sock"; |
|
22 |
|
$port = 64000; |
|
23 |
|
|
|
24 |
|
|
|
25 |
|
function clean($pid) |
|
26 |
|
{ |
|
27 |
|
rg_log("Killing pid $pid..."); |
|
28 |
|
$r = posix_kill($pid, SIGQUIT); |
|
29 |
|
if ($r === FALSE) |
|
30 |
|
rg_log('Fail to kill!'); |
|
31 |
|
|
|
32 |
|
system('fuser -k wh-stunnel.log'); |
|
33 |
|
} |
|
34 |
|
|
|
35 |
|
|
|
36 |
|
rg_log(''); |
|
37 |
|
rg_log('Generating certificates...'); |
|
38 |
|
$r = shell_exec('./ca.sh wh'); |
|
39 |
|
if (!strstr($r, 'CA_SH_OK')) { |
|
40 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
|
41 |
|
rg_log('Cannot generate certificates!'); |
|
42 |
|
exit(1); |
|
43 |
|
} |
|
44 |
|
|
|
45 |
|
|
|
46 |
|
rg_log(''); |
|
47 |
|
rg_log('Starting stunnel1...'); |
|
48 |
|
$pid = pcntl_fork(); |
|
49 |
|
if ($pid == -1) { |
|
50 |
|
rg_log('Cannot fork1'); |
|
51 |
|
exit(1); |
|
52 |
|
} |
|
53 |
|
if ($pid == 0) { //child |
|
54 |
|
$r = exec('stunnel wh-stunnel.conf 2>/dev/null'); |
|
55 |
|
exit(0); |
|
56 |
|
} |
|
57 |
|
register_shutdown_function('clean', $pid); |
|
58 |
|
|
|
59 |
|
|
|
60 |
|
rg_log(''); |
|
61 |
|
rg_log("Creating a user..."); |
|
62 |
|
rg_test_create_user($db, $rg_ui); |
|
63 |
|
$key = 'DEBUG::webhooks::' . $rg_ui['uid']; |
|
64 |
|
|
|
65 |
|
|
|
66 |
|
rg_log(''); |
|
67 |
|
rg_log('Login...'); |
|
68 |
|
$r = test_login($test_url, $rg_ui, $good_sid); |
|
69 |
|
if ($r === FALSE) { |
|
70 |
|
rg_log("Cannot login!"); |
|
71 |
|
exit(1); |
|
72 |
|
} |
|
73 |
|
|
|
74 |
|
|
|
75 |
|
rg_log(''); |
|
76 |
|
rg_log('Registering webhook1...'); |
|
77 |
|
$extra = array('wh::url' => 'https://localhost:' . $port . '/wh.html', |
|
78 |
|
'wh::type' => 0, |
|
79 |
|
'wh::events[C]' => 'on', |
|
80 |
|
'wh::events[P]' => 'on', |
|
81 |
|
'wh::events[B]' => 'on', |
|
82 |
|
'wh::description' => 'description1 <xss>', |
|
83 |
|
'wh::client_cert' => '', |
|
84 |
|
'wh::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem') |
|
85 |
|
); |
|
86 |
|
rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra); |
|
87 |
|
|
|
88 |
|
|
|
89 |
|
rg_log(''); |
|
90 |
|
rg_log('Registering webhook2...'); |
|
91 |
|
$extra = array('wh::url' => 'https://localhost:' . $port . '/wh.html', |
|
92 |
|
'wh::type' => 0, |
|
93 |
|
'wh::events[C]' => 'on', |
|
94 |
|
'wh::events[P]' => 'on', |
|
95 |
|
'wh::events[B]' => 'on', |
|
96 |
|
'wh::description' => 'description <xss>', |
|
97 |
|
'wh::client_cert' => file_get_contents('ca/wh/certs/client.pem') |
|
98 |
|
. file_get_contents('ca/wh/private/client.key'), |
|
99 |
|
'wh::client_ca_cert' => file_get_contents('ca/wh/certs/cacert.pem') |
|
100 |
|
); |
|
101 |
|
rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra); |
|
102 |
|
|
|
103 |
|
|
|
104 |
|
rg_log('Finding out the ids...'); |
|
105 |
|
for ($i = 0; $i < 10; $i++) { |
|
106 |
|
$r = rg_cache_get('user::' . $rg_ui['uid'] . '::wh'); |
|
107 |
|
if ($r !== FALSE) |
|
108 |
|
break; |
|
109 |
|
sleep(1); |
|
110 |
|
} |
|
111 |
|
if ($r === FALSE) { |
|
112 |
|
rg_log('Cannot get id from cache'); |
|
113 |
|
exit(1); |
|
114 |
|
} |
|
115 |
|
rg_log_ml('r=' . print_r($r, TRUE)); |
|
116 |
|
$t = array_keys($r); |
|
117 |
|
$wh_id1 = $t[0]; |
|
118 |
|
$wh_id2 = $t[1]; |
|
119 |
|
rg_log('wh_id1=' . $wh_id1); |
|
120 |
|
rg_log('wh_id2=' . $wh_id2); |
|
121 |
|
|
|
122 |
|
|
|
123 |
|
rg_log(''); |
|
124 |
|
rg_log('Creating a repo and waiting for trigger'); |
|
125 |
|
rg_log("rg_debug=$rg_debug."); |
|
126 |
|
$repo = array(); |
|
127 |
|
rg_test_create_repo($db, $rg_ui, $repo); |
|
128 |
|
|
|
129 |
|
|
|
130 |
|
rg_log(''); |
|
131 |
|
rg_log('Testing if the curl posted with success'); |
|
132 |
|
for ($i = 0; $i < 10; $i++) { |
|
133 |
|
$r = rg_cache_get($key. '::' . $wh_id1); |
|
134 |
|
rg_log_ml('cache: ' . $r); |
|
135 |
|
if ($r !== FALSE) |
|
136 |
|
break; |
|
137 |
|
sleep(1); |
|
138 |
|
} |
|
139 |
|
if ($r === FALSE) { |
|
140 |
|
rg_log('Seems the event does not set the cache!'); |
|
141 |
|
exit(1); |
|
142 |
|
} |
|
143 |
|
if (strcmp($r, "BAD") != 0) { |
|
144 |
|
rg_log('Seems the webhook executed correctly without client cert!'); |
|
145 |
|
exit(1); |
|
146 |
|
} |
|
147 |
|
|
|
148 |
|
|
|
149 |
|
rg_log(''); |
|
150 |
|
rg_log('Testing if the curl posted with success'); |
|
151 |
|
for ($i = 0; $i < 10; $i++) { |
|
152 |
|
$r = rg_cache_get($key. '::' . $wh_id2); |
|
153 |
|
if ($r !== FALSE) |
|
154 |
|
break; |
|
155 |
|
rg_log_ml('cache: ' . print_r($r, TRUE)); |
|
156 |
|
sleep(1); |
|
157 |
|
} |
|
158 |
|
if (strcmp($r, "OK") != 0) { |
|
159 |
|
rg_log('Seems the webhook did not returned success!'); |
|
160 |
|
exit(1); |
|
161 |
|
} |
|
162 |
|
|
|
163 |
|
|
|
164 |
|
rg_log(''); |
|
165 |
|
rg_log('Testing the edit of webhook1...'); |
|
166 |
|
$extra = array('wh::url' => 'https://localhost:' . $port . '/wh.html', |
|
167 |
|
'wh::id' => $wh_id1, |
|
168 |
|
'wh::type' => 1, |
|
169 |
|
'wh::flags[I]' => 'on', |
|
170 |
|
'wh::events[C]' => 'on', |
|
171 |
|
'wh::events[B]' => 'on', |
|
172 |
|
'wh::description' => 'desc2', |
|
173 |
|
'wh::client_cert' => 'abc', |
|
174 |
|
'wh::client_ca_cert' => 'zzz' |
|
175 |
|
); |
|
176 |
|
rg_test_wh_add_edit($db, $rg_ui, $good_sid, $extra); |
|
177 |
|
$sql = "SELECT * FROM webhooks WHERE uid = " . $rg_ui['uid'] |
|
178 |
|
. " AND id = " . $wh_id1; |
|
179 |
|
$res = rg_sql_query($db, $sql); |
|
180 |
|
$row = rg_sql_fetch_array($res); |
|
181 |
|
rg_sql_free_result($res); |
|
182 |
|
$key1 = 'user' . '::' . $rg_ui['uid'] . '::' . 'wh' . '::' . $wh_id1; |
|
183 |
|
rg_cache_core_unset($key1); // else we will get previous copy! |
|
184 |
|
$c = rg_cache_get($key1); |
|
185 |
|
$list = array('flags' => 'I', 'events' => 'CB', 'type' => '1', |
|
186 |
|
'description' => 'desc2', 'client_cert' => 'abc', |
|
187 |
|
'client_ca_cert' => 'zzz'); |
|
188 |
|
foreach ($list as $k => $v) { |
|
189 |
|
if (strcmp($row[$k], $v) != 0) { |
|
190 |
|
rg_log_ml('row: ' . print_r($row, TRUE)); |
|
191 |
|
rg_log("db: Seems that $k was not updated [" . $row[$k] . "] != " . $v); |
|
192 |
|
exit(1); |
|
193 |
|
} |
|
194 |
|
|
|
195 |
|
if (strcmp($c[$k], $v) != 0) { |
|
196 |
|
rg_log_ml('c: ' . print_r($c, TRUE)); |
|
197 |
|
rg_log("cache: Seems that $k was not updated [" . $c[$k] . "] != " . $v); |
|
198 |
|
exit(1); |
|
199 |
|
} |
|
200 |
|
} |
|
201 |
|
|
|
202 |
|
|
|
203 |
|
rg_log(''); |
|
204 |
|
rg_log_enter('Testing the delete - loading form...'); |
|
205 |
|
$data = array(); |
|
206 |
|
$headers = array("Cookie: sid=" . $good_sid); |
|
207 |
|
$r = do_req($test_url . "/op/settings/wh/list", $data, $headers); |
|
208 |
|
if ($r === FALSE) { |
|
209 |
|
rg_log("Cannot load list form."); |
|
210 |
|
exit(1); |
|
211 |
|
} |
|
212 |
|
if (!isset($r['tokens']['wh_list'])) { |
|
213 |
|
rg_log_ml('tokens: ' . print_r($r['tokens'], TRUE)); |
|
214 |
|
rg_log('Cannot find wh_list token!'); |
|
215 |
|
exit(1); |
|
216 |
|
} |
|
217 |
|
$good_token = $r['tokens']['wh_list']; |
|
218 |
|
$data = array( 'delete' => 1, |
|
219 |
|
'token' => $good_token, |
|
220 |
|
'delete_list[' . $wh_id1 . ']' => 'on'); |
|
221 |
|
$r = do_req($test_url . "/op/settings/wh/list", $data, $headers); |
|
222 |
|
if (!strstr($r['body'], 'deleted with success')) { |
|
223 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
|
224 |
|
rg_log("Cannot delete webhook!"); |
|
225 |
|
exit(1); |
|
226 |
|
} |
|
227 |
|
$sql = "SELECT id FROM webhooks WHERE id = " . $wh_id1; |
|
228 |
|
$res = rg_sql_query($db, $sql); |
|
229 |
|
$rows = rg_sql_num_rows($res); |
|
230 |
|
rg_sql_free_result($res); |
|
231 |
|
if ($rows != 0) { |
|
232 |
|
rg_log("Cannot delete webhook - sql still returns data!"); |
|
233 |
|
exit(1); |
|
234 |
|
} |
|
235 |
|
$key = 'user::' . $rg_ui['uid'] . '::wh::' . $wh_id1; |
|
236 |
|
rg_cache_core_unset($key); // else we will get data from local mem! |
|
237 |
|
$r = rg_cache_get($key); |
|
238 |
|
if (strcmp($r, '') != 0) { |
|
239 |
|
rg_log_ml($key . ': ' . print_r($r, TRUE)); |
|
240 |
|
rg_log('Deleted webhooks are still in cache!'); |
|
241 |
|
exit(1); |
|
242 |
|
} |
|
243 |
|
rg_log_exit(); |
|
244 |
|
|
|
245 |
|
|
|
246 |
|
rg_log("OK!"); |
|
247 |
|
?> |