List of commits:
Subject Hash Author Date (UTC)
Added first payments option; fixes all around 7102aed9f239d529723799171553e8c4bd018440 Catalin(ux) M. BOIE 2023-05-02 22:36:28
Fixed a nasty typo in the build system; doc update; cosmetic 1934732b297d6476be7954fabdcaf9eb87678f5e Catalin(ux) M. BOIE 2022-12-21 12:51:53
Send client features to the builder dcf648353662409b9e39a422228ddb6a7c43358c Catalin(ux) M. BOIE 2022-12-21 11:10:00
Add support for SHA-256 git repos 8b88927d353c7b588909d0b1220c8922b32129c0 Catalin(ux) M. BOIE 2022-12-21 11:03:19
Look-up pkg_repo using pkg_repo uid f2b188b8cb151c376d8ee8c81f8e82c02ed93cd1 Catalin(ux) M. BOIE 2022-12-12 05:29:13
Cosmetic 04ae5ac6b9805198966a21755d1d430ef5b6a6dd Catalin(ux) M. BOIE 2022-12-11 17:17:39
Keep-alive mechanism for builder/worker 7e3add2ab41feefe37a858439934b8599fb30933 Catalin(ux) M. BOIE 2022-12-10 19:36:53
Bumped version to 0.76 09bb0cc92a9dfce513ce1289a22e71faf4ad1fe1 Catalin(ux) M. BOIE 2022-10-22 06:27:35
Cosmetic 45c59081c97489ccccd35efffa522607fee25a63 Catalin(ux) M. BOIE 2022-10-22 05:52:56
Mostly worker stuff ccf3a8d8da2ad1b0d97418fabb5028b40721835f Catalin(ux) M. BOIE 2022-10-22 05:50:04
wh: lambda: seems we cannot pass x-Amz-Client-Context header empty anymore 7f065b0fb6ceed5d2339afd7590f5a795ed3582e Catalin(ux) M. BOIE 2022-10-21 19:33:58
workers: wrong URL for delete a2b2ff5925b1ee9b4a033da93084c008b7af8c64 Catalin(ux) M. BOIE 2022-10-21 16:03:56
Typo 4557595fb985fb2a0a482a387ef0a61293b511ed Catalin(ux) M. BOIE 2022-03-29 17:06:57
Builder improvements 2c27620922c4990454dc3039b2f1c4a86388501f Catalin(ux) M. BOIE 2022-03-29 06:28:16
Extra space in debian/conffiles preventing Debian build 416ed9995151c29bffb4ca3f0f6901aab7cbaa8e Catalin(ux) M. BOIE 2022-03-28 19:36:06
Show global pkg sub repos; cosmetic 43f60158b760b2789261e703ff2fa0781f590e04 Catalin(ux) M. BOIE 2022-03-28 18:21:07
Cosmetic a60d33914b8a1754c84ddc5440533df9b89337ad Catalin(ux) M. BOIE 2022-03-16 07:40:37
Cosmetic 8bb684cb885e0ad0f24519990a564031ea0e43a9 Catalin(ux) M. BOIE 2022-02-19 08:12:45
Set install_id under lock to not get errors 46904e58621450cc164afe769a2aeb597fbaecd8 Catalin(ux) M. BOIE 2022-02-17 18:08:59
Cosmetic bc38d3b0196d5701f75209a3125543ba096fe340 Catalin(ux) M. BOIE 2022-02-16 19:45:29
Commit 7102aed9f239d529723799171553e8c4bd018440 - Added first payments option; fixes all around
Author: Catalin(ux) M. BOIE
Author date (UTC): 2023-05-02 22:36
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2023-05-02 22:36
Parent(s): 1934732b297d6476be7954fabdcaf9eb87678f5e
Signer:
Signing key:
Signing status: N
Tree: 8f053f7d0b086cc7e7b45bf5ca432fbcdc9c01c2
File Lines added Lines deleted
TODO 8 0
debian/changelog 4 0
inc/admin.inc.php 63 0
inc/admin/admin.php 5 0
inc/admin/pay/pay.php 18 0
inc/plan.inc.php 33 23
inc/struct.inc.php 25 1
inc/user.inc.php 6 2
inc/user/home-page.php 11 2
inc/user/packages_deb.inc.php 1 1
inc/user/packages_rpm.inc.php 1 1
inc/user/pay/main.inc.php 180 0
inc/user/pay/pay-core.inc.php 203 0
inc/user/pay/squareup.inc.php 234 0
inc/user/repo-page.php 1 1
inc/user/repo/bug/show/show.php 1 1
inc/wh/http/matrix.inc.php 2 2
rocketgit.spec 4 1
root/index.php 2 1
root/themes/default/admin/menu.html 1 0
root/themes/default/admin/pay/menu.html 5 0
root/themes/default/admin/pay/ok.html 0 0
root/themes/default/admin/pay/squareup.html 27 0
root/themes/default/admin/plans/add_edit.html 5 0
root/themes/default/admin/plans/list/header.html 1 0
root/themes/default/admin/plans/list/line.html 1 0
root/themes/default/generr.html 3 0
root/themes/default/user/pay/form.html 23 0
root/themes/default/user/pay/link-err.html 3 0
root/themes/default/user/pay/redir.html 4 0
samples/sshd-akc.conf 1 0
scripts/builder.php 9 9
scripts/common.sh 3 3
scripts/cron.php 5 0
scripts/rgfs.php 1 1
scripts/worker.php 10 8
selinux/install.sh 2 0
selinux/rocketgit.fc 16 12
techdocs/payment.txt 45 0
File TODO changed (mode: 100644) (index 5969908..c85b863)
22 22 [ ] [ ]
23 23
24 24 == next release == == next release ==
25 [ ] Add in comparison where (country) they are hosted.
25 26 [ ] Anybody with a build can dirty pkg_subrepos? It should not happen. [ ] Anybody with a build can dirty pkg_subrepos? It should not happen.
26 27 [ ] 'is_resource' may not be correct for latest PHP. [ ] 'is_resource' may not be correct for latest PHP.
27 28 [ ] When a new distro is added, the dotrepo is not built automatically! [ ] When a new distro is added, the dotrepo is not built automatically!
 
77 78 [ ] [ ]
78 79
79 80 == Next next release == == Next next release ==
81 [ ] Clone by git (eg ninedogs) failes to checkout files.
82 [ ] I am showing this and I think the second message should not be sent anymore (hm, I think is not mine):
83 RocketGit: Error: you have no IPs validated; run 'ssh rocketgit@ssh.rocketgit.com totp' for help
84 fatal: Could not read from remote repository.
85 Please make sure you have the correct access rights
86 and the repository exists.
87 [ ] If build fails, we should not parse artifcats.
80 88 [ ] Artifacts: set ETag! Also for other downloadable content. [ ] Artifacts: set ETag! Also for other downloadable content.
81 89 [ ] Allow artifacts to be generated only for some branch. [ ] Allow artifacts to be generated only for some branch.
82 90 [ ] Link artifacts with the build job. [ ] Link artifacts with the build job.
File debian/changelog changed (mode: 100644) (index 812c266..f94818f)
1 rocketgit (0.77) unstable; urgency=low
2 * All around fixes.
3 -- Catalin(ux) M. BOIE <catab@embedromix.ro> Mon, 12 Dec 2022 08:00:00 +0200
4
1 5 rocketgit (0.76) unstable; urgency=low rocketgit (0.76) unstable; urgency=low
2 6 * Mostly worker stuff * Mostly worker stuff
3 7 -- Catalin(ux) M. BOIE <catab@embedromix.ro> Sat, 22 Oct 2022 11:00:00 +0300 -- Catalin(ux) M. BOIE <catab@embedromix.ro> Sat, 22 Oct 2022 11:00:00 +0300
File inc/admin.inc.php changed (mode: 100644) (index b098f7c..1f35723)
... ... function rg_admin_settings($db, &$rg, $paras)
1272 1272 return $ret; return $ret;
1273 1273 } }
1274 1274
1275 /*
1276 * Admin ->Settings -> Payments -> squareup
1277 */
1278 function rg_admin_pay_squareup_high_level($db, $rg)
1279 {
1280 rg_log_enter('rg_admin_pay_squareup_high_level');
1281
1282 $ret = '';
1283 $errmsg = array();
1284 $hints = array();
1285 while ($rg['doit'] == 1) {
1286 if (!rg_valid_referer()) {
1287 $errmsg[] = 'invalid referer; try again';
1288 break;
1289 }
1290
1291 if (!rg_token_valid($db, $rg, 'admin_pay_squareup_high_level', FALSE)) {
1292 $errmsg[] = 'invalid token; try again';
1293 break;
1294 }
1295
1296 $bearer = rg_var_str('bearer');
1297 $location_id = rg_var_str('location_id');
1298
1299 $r = rg_state_set($db, 'pay-squareup-bearer', $bearer);
1300 if ($r === FALSE) {
1301 $errmsg[] = 'cannot set state; try again';
1302 break;
1303 }
1304
1305 $r = rg_state_set($db, 'pay-squareup-location_id', $location_id);
1306 if ($r === FALSE) {
1307 $errmsg[] = 'cannot set state; try again';
1308 break;
1309 }
1310
1311 $rg['pay-squareup-bearer'] = $bearer;
1312 $rg['pay-squareup-location_id'] = $location_id;
1313
1314 $ret .= rg_template('admin/pay/ok.html',
1315 $rg, TRUE /*xss*/);
1316 break;
1317 }
1318
1319 // Load defaults
1320 while (1) {
1321 $rg['pay-squareup-bearer'] = rg_state_get($db, 'pay-squareup-bearer');
1322 $rg['pay-squareup-location_id'] = rg_state_get($db, 'pay-squareup-location_id');
1323 break;
1324 }
1325
1326 //$hints[]['HTML:hint'] = rg_template('admin/pay/squareup-hints.html',
1327 // $rg, TRUE /*xss*/);
1328
1329 $rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
1330 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
1331 $rg['rg_form_token'] = rg_token_get($db, $rg, 'admin_pay_squareup_high_level');
1332 $ret .= rg_template('admin/pay/squareup.html', $rg, TRUE /*xss*/);
1333
1334 rg_log_exit();
1335 return $ret;
1336 }
1337
File inc/admin/admin.php changed (mode: 100644) (index 5ff1bc2..6a7e2ed)
... ... case 'mails':
54 54 $_admin_body = $_admin_mails; $_admin_body = $_admin_mails;
55 55 break; break;
56 56
57 case 'pay':
58 include(__DIR__ . '/pay/pay.php');
59 $_admin_body = $_admin_pay;
60 break;
61
57 62 default: default:
58 63 $_admin_body = rg_warning('invalid operation'); $_admin_body = rg_warning('invalid operation');
59 64 break; break;
File inc/admin/pay/pay.php added (mode: 100644) (index 0000000..65340a6)
1 <?php
2 $_admin_pay = '';
3
4 $_op = empty($paras) ? 'squareup' : array_shift($paras);
5 rg_log_debug('_op=' . $_op . ' sparas=' . rg_array2string($paras));
6
7 $rg['admin_pay_menu'][$_op] = 1;
8 $rg['HTML:menu_level2'] = rg_template('admin/pay/menu.html', $rg, TRUE /*xss*/);
9
10 $rg['url_up'] = $rg['url'];
11 $rg['url'] .= '/' . rawurlencode($_subop);
12 switch ($_op) {
13 case 'squareup':
14 $_admin_pay .= rg_admin_pay_squareup_high_level($db, $rg);
15 break;
16 }
17
18 $rg['url'] = $rg['url_up'];
File inc/plan.inc.php changed (mode: 100644) (index c443db4..51c0400)
... ... function rg_plan_edit($db, $d)
46 46 break; break;
47 47
48 48 if ($d['id'] == 0) { // add if ($d['id'] == 0) { // add
49 $sql = "INSERT INTO plans (name, description, disk_mb"
50 . ", users, bw, speed, position"
51 . ", max_public_repos, max_private_repos)"
52 . " VALUES (@@name@@, @@description@@"
53 . ", @@disk_mb@@, @@users@@, @@bw@@"
54 . ", @@speed@@, @@position@@"
55 . ", @@max_public_repos@@, @@max_private_repos@@)"
56 . " RETURNING id";
49 $sql = 'INSERT INTO plans (name, description, disk_mb'
50 . ', users, bw, speed, position'
51 . ', max_public_repos, max_private_repos'
52 . ', prices)'
53 . ' VALUES (@@name@@, @@description@@'
54 . ', @@disk_mb@@, @@users@@, @@bw@@'
55 . ', @@speed@@, @@position@@'
56 . ', @@max_public_repos@@, @@max_private_repos@@'
57 . ', @@prices@@)'
58 . ' RETURNING id';
57 59 } else { // edit } else { // edit
58 $sql = "UPDATE plans"
59 . " SET name = @@name@@"
60 . ", description = @@description@@"
61 . ", disk_mb = @@disk_mb@@"
62 . ", users = @@users@@"
63 . ", bw = @@bw@@"
64 . ", speed = @@speed@@"
65 . ", position = @@position@@"
66 . ", max_public_repos = @@max_public_repos@@"
67 . ", max_private_repos = @@max_private_repos@@"
68 . " WHERE id = @@id@@"
69 . " RETURNING id";
60 $sql = 'UPDATE plans'
61 . ' SET name = @@name@@'
62 . ', description = @@description@@'
63 . ', disk_mb = @@disk_mb@@'
64 . ', users = @@users@@'
65 . ', bw = @@bw@@'
66 . ', speed = @@speed@@'
67 . ', position = @@position@@'
68 . ', max_public_repos = @@max_public_repos@@'
69 . ', max_private_repos = @@max_private_repos@@'
70 . ', prices = @@prices@@'
71 . ' WHERE id = @@id@@'
72 . ' RETURNING id';
70 73 } }
71 74
72 75 $res = rg_sql_query_params($db, $sql, $d); $res = rg_sql_query_params($db, $sql, $d);
 
... ... function rg_plan_cosmetic(&$row)
134 137 $_a = rg_xss_safe(trim($row['description'])); $_a = rg_xss_safe(trim($row['description']));
135 138 $row['HTML:description_nlbr'] = nl2br($_a); $row['HTML:description_nlbr'] = nl2br($_a);
136 139
140 if (empty($row['prices']))
141 $row['prices_nice'] = 'No prices defined';
142 else
143 $row['prices_nice'] = $row['prices'];
144
137 145 $row['exists'] = 1; $row['exists'] = 1;
138 146 } }
139 147
 
... ... function rg_plan_list($db)
162 170 break; break;
163 171 } }
164 172
165 $sql = "SELECT * FROM plans ORDER BY position";
173 $sql = 'SELECT * FROM plans ORDER BY position, name';
166 174 $res = rg_sql_query($db, $sql); $res = rg_sql_query($db, $sql);
167 175 if ($res === FALSE) { if ($res === FALSE) {
168 176 rg_plan_set_error('cannot get plan list'); rg_plan_set_error('cannot get plan list');
 
... ... function rg_plan_edit_high_level($db, &$rg)
331 339 $pi['position'] = "100"; $pi['position'] = "100";
332 340 $pi['max_public_repos'] = "0"; $pi['max_public_repos'] = "0";
333 341 $pi['max_private_repos'] = "0"; $pi['max_private_repos'] = "0";
342 $pi['prices'] = '';
334 343 } }
335 344 } }
336 345
 
... ... function rg_plan_edit_high_level($db, &$rg)
351 360 $pi['position'] = rg_var_uint("pi::position"); $pi['position'] = rg_var_uint("pi::position");
352 361 $pi['max_public_repos'] = rg_var_uint("pi::max_public_repos"); $pi['max_public_repos'] = rg_var_uint("pi::max_public_repos");
353 362 $pi['max_private_repos'] = rg_var_uint("pi::max_private_repos"); $pi['max_private_repos'] = rg_var_uint("pi::max_private_repos");
363 $pi['prices'] = trim(rg_var_str("pi::prices"));
354 364
355 365 if (!rg_valid_referer()) { if (!rg_valid_referer()) {
356 366 $errmsg[] = "invalid referer; try again"; $errmsg[] = "invalid referer; try again";
 
... ... function rg_plan_edit_high_level($db, &$rg)
368 378 break; break;
369 379 } }
370 380
371 $ret .= rg_template("admin/plans/add_ok.html", $rg, TRUE /* xss */);
381 $ret .= rg_template("admin/plans/add_ok.html", $rg, TRUE /*xss*/);
372 382 $load_form = FALSE; $load_form = FALSE;
373 383 break; break;
374 384 } }
 
... ... function rg_plan_edit_high_level($db, &$rg)
377 387 $rg['pi'] = $pi; $rg['pi'] = $pi;
378 388 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg); $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
379 389 $rg['rg_form_token'] = rg_token_get($db, $rg, 'plan_edit_hl'); $rg['rg_form_token'] = rg_token_get($db, $rg, 'plan_edit_hl');
380 $ret .= rg_template("admin/plans/add_edit.html", $rg, TRUE /* xss */);
390 $ret .= rg_template("admin/plans/add_edit.html", $rg, TRUE /*xss*/);
381 391 } }
382 392
383 393 return $ret; return $ret;
File inc/struct.inc.php changed (mode: 100644) (index 03f33a5..1a5f424)
... ... $rg_sql_struct[49]['tables'] = array();
760 760 $rg_sql_struct[49]['other'] = array( $rg_sql_struct[49]['other'] = array(
761 761 'repo_hash' => 'ALTER TABLE repos ADD hash TEXT DEFAULT \'sha1\'' 'repo_hash' => 'ALTER TABLE repos ADD hash TEXT DEFAULT \'sha1\''
762 762 ); );
763
764 $rg_sql_struct[50]['tables'] = array(
765 'payments' => 'CREATE TABLE payments ('
766 . 'id CHAR(16) PRIMARY KEY'
767 . ', uid INT NOT NULL'
768 . ', itime INT NOT NULL'
769 . ', type TEXT NOT NULL'
770 . ', type_extra TEXT NOT NULL'
771 . ', amount INT NOT NULL'
772 . ', currency TEXT NOT NULL'
773 . ', operator TEXT NOT NULL'
774 . ', state TEXT NOT NULL'
775 . ', order_id TEXT NOT NULL'
776 . ', next_try INT NOT NULL)',
777 'payments_history' => 'CREATE TABLE payments_history ('
778 . 'itime INT NOT NULL'
779 . ', uid INT NOT NULL'
780 . ', pay_id CHAR(16) NOT NULL'
781 . ', text TEXT NOT NULL)'
782 );
783 $rg_sql_struct[50]['other'] = array(
784 'plan_prices' => 'ALTER TABLE plans ADD prices TEXT DEFAULT \'\''
785 );
786 $rg_sql_struct_parts['payments_history'] = array();
763 787 // Here 0.77 was released // Here 0.77 was released
764 788
765 // Do not forget to add the new created tables to statistics.
789 // Do not forget to add the new created tables to statistics. Where?
766 790
767 791 // The next line must be after all rg_sql_struct* definitions. // The next line must be after all rg_sql_struct* definitions.
768 792 $rg_sql_schema_ver = count($rg_sql_struct); $rg_sql_schema_ver = count($rg_sql_struct);
File inc/user.inc.php changed (mode: 100644) (index c34e2ad..51e07ab)
... ... require_once(__DIR__ . '/mail.inc.php');
10 10 require_once(__DIR__ . '/plan.inc.php'); require_once(__DIR__ . '/plan.inc.php');
11 11 require_once(__DIR__ . '/totp.inc.php'); require_once(__DIR__ . '/totp.inc.php');
12 12 require_once(__DIR__ . '/stats.inc.php'); require_once(__DIR__ . '/stats.inc.php');
13 require_once(__DIR__ . '/user/pay/main.inc.php');
13 14
14 15 $rg_user_rights = array( $rg_user_rights = array(
15 16 "C" => "Create repository", "C" => "Create repository",
 
... ... function rg_user_edit_high_level($db, $rg)
2160 2161 // TODO: should we just redirect to login page? // TODO: should we just redirect to login page?
2161 2162 // TODO: or to user page if there is no need to confirm the account? // TODO: or to user page if there is no need to confirm the account?
2162 2163 if ($ui['uid'] == 0) if ($ui['uid'] == 0)
2163 $ret = rg_template("user/create_ok.html", $rg, TRUE /* xss */);
2164 $ret = rg_template('user/create_ok.html', $rg, TRUE /*xss*/);
2164 2165 else else
2165 $ret = rg_template("user/edit_ok.html", $rg, TRUE /* xss */);
2166 $ret = rg_template('user/edit_ok.html', $rg, TRUE /*xss*/);
2167
2168 $ret .= rg_pay_needed_high_level($db, $rg);
2169
2166 2170 $load_form = FALSE; $load_form = FALSE;
2167 2171 break; break;
2168 2172 } }
File inc/user/home-page.php changed (mode: 100644) (index 42c2743..fe92104)
1 1 <?php <?php
2 2 $_home = ''; $_home = '';
3 3
4 $ui_login = rg_ui_login();
5
4 6 $ui_page = rg_user_info($db, 0, $user, ''); $ui_page = rg_user_info($db, 0, $user, '');
5 7 if (($ui_page['exists'] == 0) || ($ui_page['suspended'] > 0) if (($ui_page['exists'] == 0) || ($ui_page['suspended'] > 0)
6 8 || ($ui_page['deleted'] > 0)) { || ($ui_page['deleted'] > 0)) {
 
... ... if (($ui_page['exists'] == 0) || ($ui_page['suspended'] > 0)
9 11 } }
10 12 rg_ui_page_set($ui_page); rg_ui_page_set($ui_page);
11 13
12 rg_watch_hl_process($db, $rg, 'user', $ui_page['uid'], 0, $rg['current_url']);
14 rg_watch_hl_process($db, $rg, 'user', $ui_page['uid'], 0, $rg['current_url_esc']);
13 15
14 16 $_home .= rg_template('user/home.html', $rg, TRUE /*xss*/); $_home .= rg_template('user/home.html', $rg, TRUE /*xss*/);
15 17
18 $pay_id = rg_var_re('paid', 'A-Za-z0-9');
19 if (!empty($pay_id)) {
20 $_home .= rg_pay_done_high_level($db, $rg, $pay_id);
21 } else {
22 // If payment is needed, ask the user to pay
23 $_home .= rg_pay_needed_high_level($db, $rg);
24 }
25
16 26 // List of repositories // List of repositories
17 27 $_home .= rg_repo_list($db, $rg, '', $ui_page['uid'], 0); $_home .= rg_repo_list($db, $rg, '', $ui_page['uid'], 0);
18 28
 
... ... $_home .= rg_repo_list($db, $rg, '', $ui_page['uid'], 0);
20 30 // hints // hints
21 31 $hints = array(); $hints = array();
22 32
23 $ui_login = rg_ui_login();
24 33 if ($ui_page['uid'] == $ui_login['uid']) { if ($ui_page['uid'] == $ui_login['uid']) {
25 34 if (empty($ui_login['email'])) if (empty($ui_login['email']))
26 35 $hints[]['HTML:hint'] = rg_template('user/hints/empty_email.html', $hints[]['HTML:hint'] = rg_template('user/hints/empty_email.html',
File inc/user/packages_deb.inc.php changed (mode: 100644) (index ecd4420..a4e9895)
... ... function rg_packages_deb_repo_update_subdir($subrepo_dir, $distro_dir,
557 557 } }
558 558 $list = @json_decode($r, TRUE, 20); $list = @json_decode($r, TRUE, 20);
559 559 if (empty($list)) { if (empty($list)) {
560 $ret['errmsg'] = 'error loading json';
560 $ret['errmsg'] = 'error loading json: ' . json_last_error_msg();
561 561 break; break;
562 562 } }
563 563 } else { } else {
File inc/user/packages_rpm.inc.php changed (mode: 100644) (index 0b2da4e..1e6fb91)
... ... $spec_template = ''
221 221 . "\n" . "\n"
222 222 . '%files' . "\n" . '%files' . "\n"
223 223 . '%attr (-,root,root)' . "\n" . '%attr (-,root,root)' . "\n"
224 . '%attr (@@chmod@@,root,root) /etc/yum.repos.d/*' . "\n" // because we store the password
224 . '%attr (@@chmod@@,root,root) /etc/yum.repos.d/*' . "\n" // protected because we store the password
225 225 . '%config(noreplace) /etc/yum.repos.d/*' . "\n" . '%config(noreplace) /etc/yum.repos.d/*' . "\n"
226 226 . '/etc/pki/rpm-gpg/*' . "\n"; . '/etc/pki/rpm-gpg/*' . "\n";
227 227
File inc/user/pay/main.inc.php added (mode: 100644) (index 0000000..473d26d)
1 <?php
2 include_once(__DIR__ . '/pay-core.inc.php');
3 include_once(__DIR__ . '/squareup.inc.php');
4
5 /*
6 * Generates the payment page
7 */
8 function rg_pay_generate_pay_page($db, $rg, $prices)
9 {
10 do {
11 $rg['pay']['HTML:prices_select'] = rg_pay_prices_select($prices);
12 $rg['rg_form_token'] = rg_token_get($db, $rg, 'user_pay');
13 $rg['errmsg'] = '';
14 $rg['pay_hints'] = '';
15 return rg_template('user/pay/form.html', $rg, TRUE /*xss*/);
16 } while (0);
17 }
18
19 /*
20 * Check if user needs to pay and if needed invite her to pay
21 */
22 function rg_pay_needed_high_level($db, $rg)
23 {
24 rg_log_enter('pay_needed_high_level');
25
26 $ret = '';
27 do {
28 $ui_login = rg_ui_login();
29 if ($ui_login['uid'] == 0)
30 break;
31
32 // TODO: not good! The user may want to switch plans
33 $plan_id = $ui_login['plan_id'];
34
35 $pi = rg_plan_info($db, $plan_id);
36 if ($pi['ok'] != 1) {
37 $ret = rg_template('generr.html', $rg, TRUE /*xss*/);
38 break;
39 }
40 if (empty($pi['prices']))
41 break;
42
43 $rg['pi'] = $pi;
44
45 $doit = rg_var_uint('pay-doit');
46 if ($doit == 1) {
47 // Re-validate plan_id/price
48 // TODO: create payment link
49
50 $new_plan_id = rg_var_uint('plan_id');
51 rg_log_debug('new_plan_id=' . $new_plan_id);
52
53 $new_pi = rg_plan_info($db, $plan_id);
54 if ($new_pi['ok'] != 1) {
55 $ret = rg_template('generr.html', $rg, TRUE /*xss*/);
56 break;
57 }
58 if (empty($new_pi['prices']))
59 break;
60
61 $option = rg_var_str('currency_amount');
62 rg_log_debug('option=' . $option);
63 $t = explode('/', $option);
64 $ym = strcmp($t[0], 'y') == 0 ? 'y' : 'm';
65 $amount = intval($t[1]);
66 $currency = preg_replace('/[^A-Za-z]/', '', $t[2]);
67 $data = array('name' => 'plan ' . $new_pi['name'],
68 'type' => 'plan',
69 'type_id' => $new_plan_id,
70 'interval' => $ym,
71 'amount' => $amount,
72 'currency' => $currency
73 );
74 $r = rg_pay_square_create_link($db, $data);
75 if ($r['ok'] != 1) {
76 $ret = rg_template('user/pay/link-err.html', $rg, TRUE /*xss*/);
77 break;
78 }
79
80 rg_log_debug('Redirecting to ' . $r['redirect']);
81 rg_redirect($r['redirect']);
82 }
83
84 $rg['pay'] = array();
85
86 $pay = rg_pay_user_info($db, $ui_login['uid']);
87 if ($pay['ok'] != 1) {
88 $ret = rg_template('generr.html', $rg, TRUE /*xss*/);
89 break;
90 }
91
92 if (empty($pay['list'])) {
93 $ret = rg_pay_generate_pay_page($db, $rg, $pi['prices']);
94 break;
95 }
96
97 // TODO: check if the last payment covers 'now'
98
99 $ret = rg_pay_generate_pay_page($db, $rg, $pi['prices']);
100 } while (0);
101
102 rg_log_exit();
103 return $ret;
104 }
105
106 /*
107 * Check if user needs to pay and if needed invite her to pay
108 */
109 function rg_pay_done_high_level($db, $rg, $pay_id)
110 {
111 $ret = '';
112 do {
113 if (strlen($pay_id) != 16)
114 break;
115
116 // TODO: mark the payment as 'redirected' to not bother the user after payment
117 // TODO: schedule event to check the payment
118 $rg['pay_id'] = $pay_id;
119 $ret = rg_template('user/pay/redir.html', $rg, TRUE /*xss*/);
120 } while (0);
121 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
122
123 return $ret;
124 }
125
126 /*
127 * Checks if initiated transactions are paid
128 */
129 function rg_pay_update_orders_states($db)
130 {
131 rg_log_enter('pay_update_orders_states');
132
133 $ret = array('ok' => 0);
134 do {
135 $now = time();
136 $params = array('state' => 'init', 'now' => $now);
137 $sql = 'SELECT * FROM payments'
138 . ' WHERE state = @@state@@'
139 . ' AND next_try < @@now@@'
140 . ' ORDER BY next_try'
141 . ' LIMIT 100';
142 $res = rg_sql_query_params($db, $sql, $params);
143 if ($res === FALSE) {
144 $ret['errmsg'] = rg_sql_error();
145 break;
146 }
147 while (($row = rg_sql_fetch_array($res))) {
148 rg_log_debug('Processing row: ' . print_r($row, TRUE));
149
150 $next = time() + 24 * 3600; // TODO: configurable?
151 $r = rg_pay_update_next_try($db, $row['id'], $next);
152 if ($r['ok'] != 1) {
153 $ret['errmsg'] = $r['errmsg'];
154 break;
155 }
156
157 $operator = $row['operator']; unset($row['operator']);
158 if (strcmp($operator, 'squareup') == 0) {
159 $r = rg_pay_square_update_order_state($db, $row);
160 } else {
161 $r['ok'] = 0;
162 $r['errmsg'] = 'invalid operator ' . $operator;
163 rg_internal_error($r['errmsg']);
164 }
165 if ($r['ok'] != 1) {
166 $ret['errmsg'] = $r['errmsg'];
167 break;
168 }
169 }
170 rg_sql_free_result($res);
171 if (isset($ret['errmsg']))
172 break;
173
174 $ret['ok'] = 1;
175 } while (0);
176 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
177
178 rg_log_exit();
179 return $ret;
180 }
File inc/user/pay/pay-core.inc.php added (mode: 100644) (index 0000000..86eff4e)
1 <?php
2 include_once(__DIR__ . '/squareup.inc.php');
3
4 /*
5 * Returns information about the paid account
6 */
7 function rg_pay_user_info($db, $uid)
8 {
9 rg_prof_start('pay_user_info');
10 rg_log_enter('pay_user_info');
11
12 $ret = array('ok' => 0);
13 do {
14 $params = array('uid' => $uid);
15 $sql = 'SELECT * FROM payments WHERE uid = @@uid@@'
16 . ' ORDER BY itime DESC'
17 . ' LIMIT 10';
18 $res = rg_sql_query_params($db, $sql, $params);
19 if ($res === FALSE) {
20 $ret['errmsg'] = 'cannot load payments';
21 break;
22 }
23
24 $ret['list'] = array();
25 while (($row = rg_sql_fetch_array($res))) {
26 $id = $row['id']; unset($row['id']);
27 $ret['list'][$id] = $row;
28 }
29 rg_sql_free_result($res);
30
31 $ret['ok'] = 1;
32 } while (0);
33 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
34
35 rg_log_exit();
36 rg_prof_end('pay_user_info');
37 return $ret;
38 }
39
40 /*
41 * Transforms a space separated list of currencies into a select
42 */
43 function rg_pay_prices_select($prices)
44 {
45 $ret = '<select name="currency_amount" id="currency_amount">' . "\n"; $add = '';
46 $x = explode(' ', $prices);
47 foreach ($x as $p) {
48 $t = explode('/', $p);
49 $per_month = trim($t[0]);
50 $per_year = trim($t[1]);
51 $currency = $t[2];
52
53 $text = $per_year . ' ' . $currency . ' / year';
54 $ret .= $add . '<option value="y/' . $per_year . '/' . $currency . '">' . $text . '</option>';
55 $add = "\n\t";
56
57 $text = $per_month . ' ' . $currency . ' / month';
58 $ret .= $add . '<option value="m/' . $per_month . '/' . $currency . '">' . $text . '</option>';
59 $add = "\n\t";
60 }
61
62 $ret .= "\n" . '</select>';
63
64 return $ret;
65 }
66
67 /*
68 * Adds an entry in the payment history
69 */
70 function rg_pay_history(int $db, int $uid, string $pay_id, array $info)
71 {
72 rg_log_enter('pay_history: pay_id=' . $pay_id);
73
74 $ret = array('ok' => 0);
75 do {
76 $now = time();
77 $params = array('uid' => $uid, 'now' => $now,
78 'pay_id' => $pay_id, 'text' => json_encode($info));
79 $sql = 'INSERT INTO payments_history_' . gmdate('Y_m', $now)
80 . '(pay_id, uid, itime, text)'
81 . ' VALUES(@@pay_id@@, @@uid@@, @@now@@, @@text@@)';
82 $r = rg_sql_query_params($db, $sql, $params);
83 if ($r === FALSE) {
84 $ret['errmsg'] = rg_sql_error();
85 break;
86 }
87
88 $ret['ok'] = 1;
89 } while (0);
90 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
91
92 rg_log_exit();
93 return $ret;
94 }
95
96 /*
97 * Adds a payment
98 * @type: 'plan'
99 * @type_extra[plan]: 'y' (=yearly) or 'm' (= monthly)
100 */
101 function rg_pay_insert($db, $data)
102 {
103 rg_log_enter('pay_insert: data=' . rg_array2string($data));
104
105 $ret = array('ok' => 0);
106 do {
107 // TODO: transaction?
108 $data['itime'] = time();
109 $data['next_try'] = 0;
110 $sql = 'INSERT INTO payments (id, uid, operator'
111 . ', itime, type, type_id, type_extra'
112 . ', amount, currency, state'
113 . ', order_id, next_try)'
114 . ' VALUES (@@pay_id@@, @@uid@@, @@operator@@'
115 . ', @@itime@@, @@type@@, @@type_id@@, @@interval@@'
116 . ', @@amount@@, @@currency@@, @@state@@'
117 . ', @@order_id@@, @@next_try@@)';
118 $r = rg_sql_query_params($db, $sql, $data);
119 if ($r === FALSE) {
120 $ret['errmsg'] = rg_sql_error();
121 break;
122 }
123
124 $r = rg_pay_history($db, $data['uid'], $data['pay_id'],
125 array('ok' => 1, 'text' => 'Payment created'));
126 if ($r['ok'] != 1) {
127 $ret['errmsg'] = $r['errmsg'];
128 break;
129 }
130
131 $ret['ok'] = 1;
132 } while (0);
133 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
134
135 rg_log_exit();
136 return $ret;
137 }
138
139 /*
140 * Update internal state of an order
141 */
142 function rg_pay_update_order_state(int $db, int $uid, string $pay_id,
143 string $state)
144 {
145 rg_log_enter('pay_update_order_state: uid=' . $uid
146 . ' pay_id=' . $pay_id . ' state=' . $state);
147
148 $ret = array('ok' => 0);
149 do {
150 $params = array('uid' => $uid, 'pay_id' => $pay_id,
151 'state' => $state);
152 $sql = 'UPDATE payments SET state = @@state@@'
153 . ' WHERE uid = @@uid@@ AND pay_id = @@pay_id@@';
154 $r = rg_sql_query_params($db, $sql, $data);
155 if ($r === FALSE) {
156 $ret['errmsg'] = rg_sql_error();
157 break;
158 }
159
160 $j = array('ok' => 1,
161 'text' => 'order_id state changed to ' . $state);
162 $r = rg_pay_history($db, $uid, $pay_id, $j);
163 if ($r['ok'] != 1) {
164 $ret['errmsg'] = $r['errmsg'];
165 break;
166 }
167
168 $ret['ok'] = 1;
169 } while (0);
170 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
171
172 rg_log_exit();
173 return $ret;
174 }
175
176 /*
177 * Update next_try (to prevent flooding the operator
178 */
179 function rg_pay_update_next_try(int $db, string $pay_id, int $next)
180 {
181 rg_log_enter('pay_update_next_try: pay_id=' . $pay_id . ' next=' . $next);
182
183 $ret = array('ok' => 0);
184 do {
185 // TODO: transaction?
186
187 $params = array('pay_id' => $pay_id, 'next_try' => $next);
188 $sql = 'UPDATE payments SET next_try = @@next_try@@'
189 . ' WHERE id = @@pay_id@@';
190 $r = rg_sql_query_params($db, $sql, $params);
191 if ($r === FALSE) {
192 $ret['errmsg'] = rg_sql_error();
193 break;
194 }
195
196 $ret['ok'] = 1;
197 } while (0);
198 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
199
200 rg_log_exit();
201 return $ret;
202 }
203
File inc/user/pay/squareup.inc.php added (mode: 100644) (index 0000000..d61f919)
1 <?php
2 // Here are the Square UP functions
3
4 include_once(__DIR__ . '/pay-core.inc.php');
5
6 $rg_pay_square_url = 'https://connect.squareupsandbox.com';
7
8 function rg_pay_square_request(int $db, string $url, array $body)
9 {
10 global $rg_pay_square_url;
11
12 rg_prof_start('pay_square_request');
13 rg_log_enter('pay_square_request');
14
15 $ret = array('ok' => 0);
16 do {
17 $bearer = rg_state_get($db, 'pay-squareup-bearer');
18
19 if (!empty($body))
20 rg_log_debug('body: ' . print_r($body, TRUE));
21
22 $headers = array();
23 $headers[] = 'Content-Type: application/json';
24 $headers[] = 'Square-Version: 2022-12-14';
25 $headers[] = 'Authorization: Bearer ' . $bearer;
26
27 $c = curl_init($rg_pay_square_url . $url);
28 if (!empty($body)) {
29 curl_setopt($c, CURLOPT_POST, 1);
30 curl_setopt($c, CURLOPT_POSTFIELDS, json_encode($body));
31 }
32 curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE);
33 curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
34 curl_setopt($c, CURLOPT_HEADER, 1);
35 curl_setopt($c, CURLOPT_HTTPHEADER, $headers);
36 curl_setopt($c, CURLOPT_USERAGENT, 'RocketGit WebPay');
37 curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 30);
38 curl_setopt($c, CURLOPT_ENCODING, ''); // => use all methods
39 curl_setopt($c, CURLOPT_VERBOSE, TRUE);
40 curl_setopt($c, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
41
42 $err = @fopen('php://temp', 'w');
43 if ($err !== FALSE)
44 curl_setopt($c, CURLOPT_STDERR, $err);
45
46 $r = @curl_exec($c);
47 if ($err !== FALSE) {
48 rewind($err);
49 $ret['err_extra'] = @fread($err, 16 * 4096);
50 fclose($err);
51 //rg_log_debug('err_extra: ' . $ret['err_extra']);
52 }
53
54 if ($r === FALSE) {
55 $ret['errmsg'] = curl_error($c);
56 break;
57 }
58
59 $_x = explode("\r\n\r\n", $r, 2);
60 $ret['headers'] = $_x[0];
61 $t = @json_decode($_x[1], TRUE);
62 if (empty($t)) {
63 rg_internal_error('cannot decode squareup json'
64 . ' [' . $_x[1] . ']: ' . json_last_error_msg());
65 $ret['errmsg'] = 'cannot decode json' . json_last_error_msg();
66 break;
67 }
68 $ret['body'] = $t;
69 $ret['curl_info'] = @curl_getinfo($c);
70 //rg_log('curl_getinfo: ' . rg_array2string($ret['curl_info']));
71 //rg_log_debug('Answer: ' . print_r($ret, TRUE));
72 $ret['ok'] = 1;
73 } while (0);
74 curl_close($c);
75 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
76
77 rg_log_exit();
78 rg_prof_end('pay_square_request');
79 return $ret;
80 }
81
82 function rg_pay_square_create_link(int $db, array $data)
83 {
84 global $rg_pay_square_url;
85
86 rg_prof_start('pay_square_create_link');
87 rg_log_enter('pay_square_create_link');
88
89 $ret = array('ok' => 0);
90 do {
91 $location_id = rg_state_get($db, 'pay-squareup-location_id');
92
93 $ui_login = rg_ui_login();
94
95 $pay_id = rg_id(16);
96 $body = array(
97 'idempotency_key' => $pay_id,
98 'quick_pay' => array(
99 'location_id' => $location_id,
100 'name' => $data['name'],
101 'price_money' => array(
102 'amount' => $data['amount'],
103 'currency' => $data['currency']
104 )
105 ),
106 'checkout_options' => array(
107 'redirect_url' => rg_base_url($db, '', '')
108 . rg_re_userpage($ui_login) . '?paid=' . $pay_id
109 )
110 );
111
112 $r = rg_pay_square_request($db,
113 '/v2/online-checkout/payment-links',
114 $body);
115 if ($r['ok'] != 1) {
116 $ret = $r;
117 break;
118 }
119
120 $url = @$r['body']['payment_link']['url'];
121 if (empty($url)) {
122 $ret['errmsg'] = 'no payment link';
123 break;
124 }
125
126 $order_id = @$r['body']['payment_link']['order_id'];
127 if (empty($order_id)) {
128 $ret['errmsg'] = 'no order_id';
129 break;
130 }
131
132 // Now, prepare the information on our side
133 // TODO: need to store also the id from Square?
134 $data['uid'] = $ui_login['uid'];
135 $data['pay_id'] = $pay_id;
136 $data['operator'] = 'squareup';
137 $data['state'] = 'init';
138 $data['order_id'] = $order_id;
139 $r = rg_pay_insert($db, $data);
140 if ($r['ok'] != 1) {
141 $ret = $r;
142 break;
143 }
144
145 $ret['redirect'] = $url;
146
147 $ret['ok'] = 1;
148 } while (0);
149 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
150
151 rg_log_exit();
152 rg_prof_end('pay_square_create_link');
153 return $ret;
154 }
155
156 function rg_pay_square_get_order_info(int $db, int $uid,
157 string $pay_id, string $order_id)
158 {
159 global $rg_pay_square_url;
160
161 rg_prof_start('pay_square_get_order_info');
162 rg_log_enter('pay_square_get_order_info');
163
164 $ret = array('ok' => 0);
165 do {
166 $body = array();
167 $r = rg_pay_square_request($db,
168 '/v2/orders/' . $order_id,
169 $body);
170 rg_pay_history($db, $uid, $pay_id, $r);
171 if ($r['ok'] != 1) {
172 $ret = $r;
173 break;
174 }
175 if ($r['curl_info']['http_code'] != 200) {
176 $ret['errmsg'] = 'http code ' . $r['curl_info']['http_code'] . ' != 200';
177 break;
178 }
179 $ret['body'] = $r['body'];
180
181 //rg_log_debug('order info: ' . print_r($r, TRUE));
182 $ret['ok'] = 1;
183 } while (0);
184 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
185
186 rg_log_exit();
187 rg_prof_end('pay_square_get_order_info');
188 return $ret;
189 }
190
191 function rg_pay_square_update_order_state(int $db, array $info)
192 {
193 rg_log_enter('pay_square_update_order_state');
194
195 $ret = array('ok' => 1);
196 do {
197 $r = rg_pay_square_get_order_info($db,
198 $info['uid'], $info['id'], $info['order_id']);
199 rg_log_debug('get_order_info returned r[ok]=' . $r['ok']);
200 if ($r['ok'] != 1) {
201 $ret['ok'] = 0;
202 $ret['errmsg'] = $r['errmsg'];
203 break;
204 }
205
206 // update state if needed
207 rg_log_debug('order: ' . print_r($r['body']['order'], TRUE));
208 $state = @$r['body']['order']['state'];
209 if (empty($state)) {
210 $ret['ok'] = 0;
211 $ret['errmsg'] = 'body/order/state is empty';
212 break;
213 }
214 rg_log_debug('state: ' . $state);
215 $new_state = '';
216 if (strcmp($state, 'COMPLETED') == 0)
217 $new_state = 'paid';
218 else if (strcmp($state, 'CANCELED') == 0)
219 $new_state = 'canceled';
220 if (!empty($new_state)) {
221 $r = rg_pay_update_order_state($db, $info['uid'],
222 $info['id'], $new_state);
223 if ($r['ok'] != 1) {
224 $ret['ok'] = 0;
225 $ret['errmsg'] = $r['errmsg'];
226 break;
227 }
228 }
229 } while (0);
230 if ($ret['ok'] != 1) rg_log_debug('error: ' . $ret['errmsg']);
231
232 rg_log_exit();
233 return $ret;
234 }
File inc/user/repo-page.php changed (mode: 100644) (index a529370..dc66fe8)
... ... if (strcmp($_subop, "history") == 0) {
386 386 } }
387 387
388 388 rg_watch_hl_process($db, $rg, 'repo', $rg['ri']['repo_id'], rg_watch_hl_process($db, $rg, 'repo', $rg['ri']['repo_id'],
389 0 /*obj_id2*/, $rg['current_url']);
389 0 /*obj_id2*/, $rg['current_url_esc']);
390 390
391 391 $rg['per_repo_menu'] = $_subop; $rg['per_repo_menu'] = $_subop;
392 392 $rg['HTML:repo_body'] = $_repo_body; $rg['HTML:repo_body'] = $_repo_body;
File inc/user/repo/bug/show/show.php changed (mode: 100644) (index 4e1542a..dd25756)
... ... else
113 113
114 114
115 115 rg_watch_hl_process($db, $rg, 'bug', $rg['ri']['repo_id'], rg_watch_hl_process($db, $rg, 'bug', $rg['ri']['repo_id'],
116 $rg['bug']['bug_id'], $rg['current_url']);
116 $rg['bug']['bug_id'], $rg['current_url_esc']);
117 117
118 118
119 119 // delete/undelete // delete/undelete
File inc/wh/http/matrix.inc.php changed (mode: 100644) (index 3e17adc..b8f47de)
... ... function rg_wh_matrix_send($db, $ev)
46 46 $j = @json_decode($ev1['wh']['out']['body'], TRUE); $j = @json_decode($ev1['wh']['out']['body'], TRUE);
47 47 rg_log_debug('JSON: ' . rg_array2string($j)); rg_log_debug('JSON: ' . rg_array2string($j));
48 48 if ($j === NULL) { if ($j === NULL) {
49 rg_log_debug('cannot decode json; what to do? TODO');
49 rg_log_debug('cannot decode json: ' . json_last_error_msg()); // TODO - what to do?
50 50 break; break;
51 51 } }
52 52 if (isset($j['errcode'])) { if (isset($j['errcode'])) {
 
... ... function rg_wh_matrix_send($db, $ev)
94 94 $j = @json_decode($ev2['wh']['out']['body'], TRUE); $j = @json_decode($ev2['wh']['out']['body'], TRUE);
95 95 rg_log_debug('JSON: ' . rg_array2string($j)); rg_log_debug('JSON: ' . rg_array2string($j));
96 96 if ($j === NULL) { if ($j === NULL) {
97 rg_log_debug('cannot decode json; what to do? TODO');
97 rg_log_debug('cannot decode json: ' . json_last_error_msg()); // TODO: what to do?
98 98 break; break;
99 99 } }
100 100 if (isset($j['errcode'])) { if (isset($j['errcode'])) {
File rocketgit.spec changed (mode: 100644) (index dd6d166..65585c4)
6 6
7 7 Summary: Light and fast Git hosting solution Summary: Light and fast Git hosting solution
8 8 Name: rocketgit Name: rocketgit
9 Version: 0.76
9 Version: 0.77
10 10 Release: 1 Release: 1
11 11 License: AGPLv3+ License: AGPLv3+
12 12 Group: Development/Tools Group: Development/Tools
 
... ... rm -rf ${RPM_BUILD_ROOT}
145 145 %{_unitdir}/* %{_unitdir}/*
146 146
147 147 %changelog %changelog
148 * Mon Dec 12 2022 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.77
149 All around fixes..
150
148 151 * Sat Oct 22 2022 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.76 * Sat Oct 22 2022 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.76
149 152 Mostly worker changes. Mostly worker changes.
150 153
File root/index.php changed (mode: 100644) (index 8aaa579..4368f76)
... ... $rg['https'] = strcmp(rg_var_str('HTTPS'), 'on') == 0 ? 1 : 0;
66 66
67 67 $sparas = rg_var_str('SCRIPT_NAME'); $sparas = rg_var_str('SCRIPT_NAME');
68 68 rg_log(rg_ip() . ' ' . @$_SERVER['REQUEST_METHOD'] . ' ' . $sparas); rg_log(rg_ip() . ' ' . @$_SERVER['REQUEST_METHOD'] . ' ' . $sparas);
69 $rg['current_url'] = rawurlencode($sparas);
69 $rg['current_url'] = $sparas;
70 $rg['current_url_esc'] = rawurlencode($rg['current_url']);
70 71 $rg['url'] = '/op'; $rg['url'] = '/op';
71 72 $paras = explode("/", trim($sparas, "/")); $paras = explode("/", trim($sparas, "/"));
72 73 $_t = empty($paras) ? "" : $paras[0]; $_t = empty($paras) ? "" : $paras[0];
File root/themes/default/admin/menu.html changed (mode: 100644) (index 26920ef..894bd92)
10 10 <li@@if(@@admin_menu::workers@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/workers">Workers</a></li> <li@@if(@@admin_menu::workers@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/workers">Workers</a></li>
11 11 <li@@if(@@admin_menu::distros@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/distros">Distributions</a></li> <li@@if(@@admin_menu::distros@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/distros">Distributions</a></li>
12 12 <li@@if(@@admin_menu::mails@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/mails">Mails</a></li> <li@@if(@@admin_menu::mails@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/mails">Mails</a></li>
13 <li@@if(@@admin_menu::pay@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/pay">Payments</a></li>
13 14 </ul> </ul>
14 15 </div> </div>
15 16 @@menu_level2@@ @@menu_level2@@
File root/themes/default/admin/pay/menu.html added (mode: 100644) (index 0000000..85b50d4)
1 <div class="menu menu3">
2 <ul>
3 <li@@if(@@admin_pay_menu::squareup@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/pay/squareup">Square Up</a></li>
4 </ul>
5 </div>
File root/themes/default/admin/pay/ok.html copied from file root/themes/default/admin/settings/ok.html (similarity 100%)
File root/themes/default/admin/pay/squareup.html added (mode: 100644) (index 0000000..1ffc6f2)
1 <div class="formarea formarea_small">
2
3 <div class="formarea_title">SquareUp settings</div>
4
5 @@errmsg@@
6
7 <form method="post" action="@@url@@">
8 <input type="hidden" name="doit" value="1" />
9 <input type="hidden" name="token" value="@@rg_form_token@@" />
10
11 <p>
12 <label for="bearer">Bearer</label><br />
13 <input type="text" name="bearer" id="bearer" value="@@pay-squareup-bearer@@" size="50" />
14 </p>
15
16 <p>
17 <label for="location_id">Location ID</label><br />
18 <input type="text" name="location_id" id="location_id" value="@@pay-squareup-location_id@@" />
19 </p>
20
21 <p>
22 <input type="submit" value="Update" />
23 </p>
24 </form>
25 </div>
26
27 @@hints@@
File root/themes/default/admin/plans/add_edit.html changed (mode: 100644) (index ae00a34..a544e12)
54 54 <input type="text" name="pi::max_private_repos" id="max_private_repos" value="@@pi::max_private_repos@@" /> <input type="text" name="pi::max_private_repos" id="max_private_repos" value="@@pi::max_private_repos@@" />
55 55 </p> </p>
56 56
57 <p>
58 <label for="prices">Prices (amount_per_month/amount_per_year/CURRENCY1 ...; example: [1299/12990/USD] = $12.99 per month and 129.90 per year)</label><br />
59 <input type="text" name="pi::prices" id="prices" value="@@pi::prices@@" />
60 </p>
61
57 62 <p> <p>
58 63 <input type="submit" name="button" value="@@if(@@pi::id@@ == 0){{Add}}{{Edit}}" /> <input type="submit" name="button" value="@@if(@@pi::id@@ == 0){{Add}}{{Edit}}" />
59 64 </p> </p>
File root/themes/default/admin/plans/list/header.html changed (mode: 100644) (index ce86365..d9880b7)
18 18 <th>Disk (MiB)</th> <th>Disk (MiB)</th>
19 19 <th>Max public repos</th> <th>Max public repos</th>
20 20 <th>Max private repos</th> <th>Max private repos</th>
21 <th>Prices</th>
21 22 <th>Operations</th> <th>Operations</th>
22 23 </tr> </tr>
23 24 </thead> </thead>
File root/themes/default/admin/plans/list/line.html changed (mode: 100644) (index ade8513..1b4c1b8)
9 9 <td>@@if(@@disk_mb@@ == 0){{Unlimited}}{{@@disk_mb@@}}</td> <td>@@if(@@disk_mb@@ == 0){{Unlimited}}{{@@disk_mb@@}}</td>
10 10 <td>@@if(@@max_public_repos@@ == 0){{Unlimited}}{{@@max_public_repos@@}}</td> <td>@@if(@@max_public_repos@@ == 0){{Unlimited}}{{@@max_public_repos@@}}</td>
11 11 <td>@@if(@@max_private_repos@@ == 0){{Unlimited}}{{@@max_private_repos@@}}</td> <td>@@if(@@max_private_repos@@ == 0){{Unlimited}}{{@@max_private_repos@@}}</td>
12 <td>@@prices_nice@@</td>
12 13 <td><a href="/op/admin/plans/edit/@@id@@"><span class="but">Edit</span></a></td> <td><a href="/op/admin/plans/edit/@@id@@"><span class="but">Edit</span></a></td>
13 14 </tr> </tr>
14 15
File root/themes/default/generr.html added (mode: 100644) (index 0000000..970329b)
1 <div class="mess warning">
2 Internal error. We are very sorry. Please try again in 1 minute.
3 </div>
File root/themes/default/user/pay/form.html added (mode: 100644) (index 0000000..73ad4d3)
1 <div class="formarea formarea_small">
2
3 <div class="formarea_title">Payment for plan <i>@@pi::name@@</i></div>
4
5 @@errmsg@@
6
7 <form method="post" action="@@current_url@@">
8 <input type="hidden" name="pay-doit" value="1" />
9 <input type="hidden" name="plan_id" value="@@pi::id@@" />
10 <input type="hidden" name="token" value="@@rg_form_token@@" />
11
12 <p>
13 <label for="currency_amount">Amount and currency</label><br />
14 @@pay::prices_select@@
15 </p>
16
17 <p>
18 <input type="submit" name="button" value="Pay (on external site)" />
19 </p>
20 </form>
21 </div>
22
23 @@pay_hints@@
File root/themes/default/user/pay/link-err.html added (mode: 100644) (index 0000000..01caa5c)
1 <div class="mess error">
2 Cannot create payment link; please try again later.
3 </div>
File root/themes/default/user/pay/redir.html added (mode: 100644) (index 0000000..fddaf6f)
1 <div class="mess ok">
2 Thank you very much for your order!<br />
3 We will send a confirmation by e-mail when the payment is confirmed.
4 </div>
File samples/sshd-akc.conf changed (mode: 100644) (index c32e884..bf4074c)
... ... Match User rocketgit
2 2 AuthorizedKeysCommand /usr/sbin/rg_authorize %f AuthorizedKeysCommand /usr/sbin/rg_authorize %f
3 3 AuthorizedKeysCommandUser rocketgit AuthorizedKeysCommandUser rocketgit
4 4 AuthenticationMethods publickey AuthenticationMethods publickey
5 DisableForwarding yes
5 6
File scripts/builder.php changed (mode: 100644) (index e26fa6a..ad00709)
... ... function rg_process_job($db, &$job)
761 761 //rg_log_debug('workers list: ' . rg_array2string($workers_list)); //rg_log_debug('workers list: ' . rg_array2string($workers_list));
762 762
763 763 // Trying to find a worker in the list of connections // Trying to find a worker in the list of connections
764 $reason = '';
764 $reason = array();
765 765 foreach ($rg_conns as $key => &$i) { foreach ($rg_conns as $key => &$i) {
766 766 if (strcmp($key, 'master') == 0) if (strcmp($key, 'master') == 0)
767 767 continue; continue;
 
... ... function rg_process_job($db, &$job)
769 769 if (!isset($i['ann'])) { if (!isset($i['ann'])) {
770 770 //rg_log($key . ': ' . $jid . ': conn has no announce.'); //rg_log($key . ': ' . $jid . ': conn has no announce.');
771 771 // TODO: close after some time? // TODO: close after some time?
772 $reason .= 'A';
772 $reason[] = 'no_announce';
773 773 continue; continue;
774 774 } }
775 775
776 776 if (empty($i['ann']['env'])) { if (empty($i['ann']['env'])) {
777 777 //rg_log($key . ': ' . $jid . ': conn has no environments.'); //rg_log($key . ': ' . $jid . ': conn has no environments.');
778 $reason .= 'E';
778 $reason[] = 'no env';
779 779 continue; continue;
780 780 } }
781 781
782 782 if (($i['worker_uid'] > 0) && ($i['worker_uid'] != $req['uid'])) { if (($i['worker_uid'] > 0) && ($i['worker_uid'] != $req['uid'])) {
783 783 rg_log($key . ': ' . $jid . ': uids do not match, try next'); rg_log($key . ': ' . $jid . ': uids do not match, try next');
784 $reason .= 'U';
784 $reason[] = 'uids_mismatch';
785 785 continue; continue;
786 786 } }
787 787
 
... ... function rg_process_job($db, &$job)
790 790 if (!isset($workers_list[$k])) { if (!isset($workers_list[$k])) {
791 791 rg_internal_error('Worker ' . $name . ' not found' rg_internal_error('Worker ' . $name . ' not found'
792 792 . ' in workers_list! Strange!'); . ' in workers_list! Strange!');
793 $reason .= 'i';
793 $reason[] = 'worker_not_found';
794 794 continue; continue;
795 795 } }
796 796 $wi = $workers_list[$k]; $wi = $workers_list[$k];
797 797
798 798 if (isset($job['avoid'][$k]) && ($job['avoid'][$k] > time())) { if (isset($job['avoid'][$k]) && ($job['avoid'][$k] > time())) {
799 799 rg_log($key . ': ' . $jid . ': we must avoid worker ' . $name); rg_log($key . ': ' . $jid . ': we must avoid worker ' . $name);
800 $reason .= 'V';
800 $reason[] = 'avoid';
801 801 continue; continue;
802 802 } }
803 803
 
... ... function rg_process_job($db, &$job)
808 808 rg_log($key . ': ' . $jid . ': DEBUG: skip worker ' . $name . ' because' rg_log($key . ': ' . $jid . ': DEBUG: skip worker ' . $name . ' because'
809 809 . ' sent jobs(' . $aj . ')' . ' sent jobs(' . $aj . ')'
810 810 . ' >= workers(' . $wi['workers'] . ')'); . ' >= workers(' . $wi['workers'] . ')');
811 $reason .= 'O';
811 $reason[] = 'jobs/worker';
812 812 continue; continue;
813 813 } }
814 814 } }
 
... ... function rg_process_job($db, &$job)
826 826 break; break;
827 827 } }
828 828 if (!$env_found) { if (!$env_found) {
829 $reason .= 'e';
829 $reason[] = 'env_not_found';
830 830 continue; continue;
831 831 } }
832 832
 
... ... function rg_process_job($db, &$job)
859 859
860 860 // TODO: we should signal this and prevent the call if the list of // TODO: we should signal this and prevent the call if the list of
861 861 // workers does not change. // workers does not change.
862 rg_log('No workers found [' . $reason . ']! Suspend job for 10s');
862 rg_log('No workers found [' . implode(' ', $reason) . ']! Suspend job for 10s');
863 863 $job['next_try'] = time() + 10; $job['next_try'] = time() + 10;
864 864 return TRUE; return TRUE;
865 865 } }
File scripts/common.sh changed (mode: 100644) (index 63ee9ee..3bdaf75)
... ... function check_context()
13 13 fi fi
14 14
15 15 if [ -r /proc/self/attr/current ]; then if [ -r /proc/self/attr/current ]; then
16 grep -q rocketgit_t /proc/self/attr/current
16 grep -a -q rocketgit_t /proc/self/attr/current
17 17 if [ "${?}" != "0" ]; then if [ "${?}" != "0" ]; then
18 echo "SELinux context is not rocketgit_t: `cat /proc/self/attr/current`!"
19 exit 0
18 echo "SELinux context is not rocketgit_t: $(< /proc/self/attr/current)!"
19 exit 1
20 20 fi fi
21 21 fi fi
22 22 } }
File scripts/cron.php changed (mode: 100644) (index 76e432e..e9aeb42)
... ... require_once($INC . '/fixes.inc.php');
17 17 require_once($INC . '/mr.inc.php'); require_once($INC . '/mr.inc.php');
18 18 require_once($INC . '/admin.inc.php'); require_once($INC . '/admin.inc.php');
19 19 require_once($INC . '/stats.inc.php'); require_once($INC . '/stats.inc.php');
20 require_once($INC . '/user/pay/main.inc.php');
20 21 require_once($INC . '/ver.php'); require_once($INC . '/ver.php');
21 22
22 23 $now = time(); $now = time();
 
... ... while (($now >= $today_01) && ($r < $today_01) && (rg_load() < 30)) {
266 267 // TODO: move it as an event after the push // TODO: move it as an event after the push
267 268 rg_mr_queue_process($db); rg_mr_queue_process($db);
268 269
270 $r = rg_pay_update_orders_states($db);
271 if ($r['ok'] != 1)
272 rg_log('update order error: ' . $r['errmsg']);
273
269 274 if (gmdate('Hi') == '0305') if (gmdate('Hi') == '0305')
270 275 rg_clean_logs('/var/log/rocketgit'); rg_clean_logs('/var/log/rocketgit');
271 276
File scripts/rgfs.php changed (mode: 100644) (index 38bcf64..035ac3c)
... ... function xdispatch_one($key, $tlv)
284 284 if ($a['repo_id'] > 0) { if ($a['repo_id'] > 0) {
285 285 $ri = rg_repo_info($s['db'], $a['repo_id'], 0, ''); $ri = rg_repo_info($s['db'], $a['repo_id'], 0, '');
286 286 if ($ri['exists'] != 1) { if ($ri['exists'] != 1) {
287 debug($key, 'invalid repo id ' . $a['repo_id']);
287 debug($key, 'non-existing/no access repo id ' . $a['repo_id']);
288 288 rg_conn_shutdown($key, 2); rg_conn_shutdown($key, 2);
289 289 return; return;
290 290 } }
File scripts/worker.php changed (mode: 100644) (index b29604e..b46c6c3)
... ... function start_worker_build_tools($job, &$reason, &$reason2)
497 497 . "\n" . "\n"
498 498 . 'function rg_cp()' . "\n" . 'function rg_cp()' . "\n"
499 499 . '{' . "\n" . '{' . "\n"
500 . ' rg_op_s cp "${@}"' . "\n"
500 . ' rg_op_s cp "${@}"' . "\n" //. ' rg_op_s strace -s2000 -f -q -tt -o /tmp/cp-${USER}.strace cp "${@}"' . "\n"
501 501 . ' return ${E}' . "\n" . ' return ${E}' . "\n"
502 502 . '}' . "\n" . '}' . "\n"
503 503 . "\n" . "\n"
 
... ... function start_worker_build_tools($job, &$reason, &$reason2)
752 752 . "\n" . "\n"
753 753 . ' local dst_tar_gz="/mnt/rpmbuild/SOURCES/${pkg_name}-${pkg_ver}.tar.gz"' . "\n" . ' local dst_tar_gz="/mnt/rpmbuild/SOURCES/${pkg_name}-${pkg_ver}.tar.gz"' . "\n"
754 754 . ' local dst_spec="/mnt/rpmbuild/SPECS/${spec_file_base}"' . "\n" . ' local dst_spec="/mnt/rpmbuild/SPECS/${spec_file_base}"' . "\n"
755 . ' local rg_log N "DEBUG: dst_spec=${dst_spec}."' . "\n"
755 . ' rg_log N "DEBUG: dst_spec=${dst_spec}."' . "\n"
756 756 . "\n" . "\n"
757 757 . ' rg_log N "Creating tar archive [${dst_tar_gz}]"' . "\n" . ' rg_log N "Creating tar archive [${dst_tar_gz}]"' . "\n"
758 758 . ' rg_log N "Creating tar"' . "\n" . ' rg_log N "Creating tar"' . "\n"
 
... ... function start_worker_build_repo($job, $conf, &$reason, &$reason2)
1034 1034 // Save gpg keys // Save gpg keys
1035 1035 $keys = 0; $keys = 0;
1036 1036 foreach ($job['pkg_repos'] as $pkg_repo_id => $info) { foreach ($job['pkg_repos'] as $pkg_repo_id => $info) {
1037 if ($info['uid'] != $job['uid']) {
1037 if (($job['uid'] != 0) && ($info['uid'] != $job['uid'])) {
1038 1038 rg_log($job['id'] . ': DEBUG: skip storing key for' rg_log($job['id'] . ': DEBUG: skip storing key for'
1039 1039 . ' pkg_repo_id ' . $pkg_repo_id . ' pkg_repo_id ' . $pkg_repo_id
1040 . ' because the uids do not match');
1040 . ' because the uids do not match: '
1041 . ' info[uid]=' . $info['uid']
1042 . ' job[uid]=' . $job['uid']);
1041 1043 continue; continue;
1042 1044 } }
1043 1045
 
... ... function start_worker_build_repo($job, $conf, &$reason, &$reason2)
1357 1359 . ' fi' . "\n" . ' fi' . "\n"
1358 1360 . ' if [ "${job_uid}" = "${pkg_repo_uid}" ]; then' . "\n" . ' if [ "${job_uid}" = "${pkg_repo_uid}" ]; then' . "\n"
1359 1361 . ' rg_op_s mkdir -p "${rgfs}" || break' . "\n" . ' rg_op_s mkdir -p "${rgfs}" || break' . "\n"
1360 . ' rg_cp -av "${rpms_dir}"/*.rpm "${rgfs}/" || break' . "\n"
1362 . ' rg_cp --force --verbose "${rpms_dir}"/*.rpm "${rgfs}/" || break' . "\n"
1361 1363 . ' else' . "\n" // TODO: shouldn't I copy directly to ${rgfs}/${repo_username} if do_sensitive_ops==1? Seems it cannot happen! when we are uid 0, we do not need to copy! . ' else' . "\n" // TODO: shouldn't I copy directly to ${rgfs}/${repo_username} if do_sensitive_ops==1? Seems it cannot happen! when we are uid 0, we do not need to copy!
1362 1364 . ' # "+" is used because it is not allowed in username' . "\n" . ' # "+" is used because it is not allowed in username' . "\n"
1363 1365 . ' rg_op_s mkdir -p "${rgfs}/+pending/${repo_username}" || break' . "\n" . ' rg_op_s mkdir -p "${rgfs}/+pending/${repo_username}" || break' . "\n"
1364 . ' rg_cp -av "${rpms_dir}/${repo_username}"/*.rpm "${rgfs}/+pending/${repo_username}/" || break' . "\n"
1366 . ' rg_cp -v "${rpms_dir}/${repo_username}"/*.rpm "${rgfs}/+pending/${repo_username}/" || break' . "\n"
1365 1367 . ' fi' . "\n" . ' fi' . "\n"
1366 1368 . "\n" . "\n"
1367 1369 . ' if [ "$(do_sensitive_ops)" != "1" ]; then' . "\n" . ' if [ "$(do_sensitive_ops)" != "1" ]; then' . "\n"
 
... ... function start_worker_build_repo($job, $conf, &$reason, &$reason2)
1399 1401 . ' rg_log N "Copying files from ${debs_dir} to ${rgfs}"' . "\n" . ' rg_log N "Copying files from ${debs_dir} to ${rgfs}"' . "\n"
1400 1402 . ' # "+" is used because it is not allowed in username' . "\n" . ' # "+" is used because it is not allowed in username' . "\n"
1401 1403 . ' rg_op_s mkdir -p "${rgfs}/+pending/${job_id}" || break' . "\n" . ' rg_op_s mkdir -p "${rgfs}/+pending/${job_id}" || break' . "\n"
1402 . ' rg_cp -av "${debs_dir}"/* "${rgfs}/+pending/${job_id}/" || break' . "\n"
1404 . ' rg_cp -vR "${debs_dir}"/* "${rgfs}/+pending/${job_id}/" || break' . "\n"
1403 1405 . ' if [ "$(do_sensitive_ops)" != "1" ]; then' . "\n" . ' if [ "$(do_sensitive_ops)" != "1" ]; then' . "\n"
1404 1406 . ' rg_log N "Triggering the rebuild of subrepo"' . "\n" . ' rg_log N "Triggering the rebuild of subrepo"' . "\n"
1405 1407 . ' echo "${pkg_subrepo_id}" >> /mnt/build2/pkg_subrepo_dirty' . "\n" . ' echo "${pkg_subrepo_id}" >> /mnt/build2/pkg_subrepo_dirty' . "\n"
 
... ... function xhandle_one($key, $data)
2122 2124 if (!isset($jobs[$jid]['disk_size_gib'])) if (!isset($jobs[$jid]['disk_size_gib']))
2123 2125 $jobs[$jid]['disk_size_gib'] = '100'; $jobs[$jid]['disk_size_gib'] = '100';
2124 2126 if (!isset($jobs[$jid]['mem_mib'])) if (!isset($jobs[$jid]['mem_mib']))
2125 $jobs[$jid]['mem_mib'] = '2048';
2127 $jobs[$jid]['mem_mib'] = '4096';
2126 2128 if (!isset($jobs[$jid]['cpus'])) if (!isset($jobs[$jid]['cpus']))
2127 2129 $jobs[$jid]['cpus'] = '2'; $jobs[$jid]['cpus'] = '2';
2128 2130 $jobs[$jid]['state'] = RG_JOB_INIT; $jobs[$jid]['state'] = RG_JOB_INIT;
File selinux/install.sh changed (mode: 100755) (index eba076d..b23df8b)
... ... if [ -r selinux/out/${PRJ}-targeted.pp ]; then
4 4 echo "Installing SELinux stuff (PRJ=${PRJ})..." echo "Installing SELinux stuff (PRJ=${PRJ})..."
5 5 mkdir -pv --mode=0755 ${I_USR_SHARE}/selinux/targeted mkdir -pv --mode=0755 ${I_USR_SHARE}/selinux/targeted
6 6 cp -vd selinux/out/${PRJ}-targeted.pp ${I_USR_SHARE}/selinux/targeted/${PRJ}.pp cp -vd selinux/out/${PRJ}-targeted.pp ${I_USR_SHARE}/selinux/targeted/${PRJ}.pp
7 else
8 echo "File [selinux/out/${PRJ}-targeted.pp] not found!"
7 9 fi fi
File selinux/rocketgit.fc changed (mode: 100644) (index 2aaeda0..707c3a3)
3 3 # MLS sensitivity: s0 # MLS sensitivity: s0
4 4 # MCS categories: <none> # MCS categories: <none>
5 5
6 /etc/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_conf_t,s0)
6 # '--' means ordinary file, '-d' directory etc.
7 7
8 /var/log/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_log_t,s0)
8 /etc/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_conf_t,s0)
9 9
10 /var/lib/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_var_t,s0)
11 /var/lib/rocketgit/locks(/.*)? gen_context(system_u:object_r:rocketgit_lock_t,s0)
12 /var/lib/rocketgit/sockets(/.*)? gen_context(system_u:object_r:rocketgit_socket_t,s0)
10 /var/log/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_log_t,s0)
13 11
14 /usr/share/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_usr_t,s0)
12 /var/lib/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_var_t,s0)
13 /var/lib/rocketgit/locks(/.*)? gen_context(system_u:object_r:rocketgit_lock_t,s0)
14 /var/lib/rocketgit/sockets(/.*)? gen_context(system_u:object_r:rocketgit_socket_t,s0)
15 15
16 /usr/share/rocketgit/scripts/worker.(sh|php) gen_context(system_u:object_r:rocketgit_worker_exec_t,s0)
17 /usr/share/rocketgit/scripts(/.*)? -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
18 /usr/share/rocketgit/hooks(/.*)? -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
16 /usr/share/rocketgit(/.*)? gen_context(system_u:object_r:rocketgit_usr_t,s0)
19 17
20 /usr/lib/systemd/system/rocketgit-.*.service gen_context(system_u:object_r:rocketgit_unit_file_t,s0)
18 /usr/share/rocketgit/scripts/worker.(sh|php) -- gen_context(system_u:object_r:rocketgit_worker_exec_t,s0)
19 /usr/share/rocketgit/scripts(/.*)? -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
20 /usr/share/rocketgit/hooks(/.*)? -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
21
22 /usr/lib/systemd/system/rocketgit-.*.service -- gen_context(system_u:object_r:rocketgit_unit_file_t,s0)
23 /usr/lib/systemd/system/rocketgit-.*.socket -- gen_context(system_u:object_r:rocketgit_unit_file_t,s0)
24
25 /usr/sbin/rg_authorize -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
26 /usr/sbin/rg_change_pass -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
21 27
22 /usr/sbin/rg_authorize -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
23 /usr/sbin/rg_change_pass -- gen_context(system_u:object_r:rocketgit_exec_t,s0)
File techdocs/payment.txt added (mode: 100644) (index 0000000..b2a3733)
1 == How payment works? ==
2
3 User selects a plan at sign-up. He is redirect to the home page.
4 When she hits the homepage, she is invited to select an amount
5 (based on period: monthly or yearly). Then she press "Pay" button.
6 We call 'pay_square_create_link' (passing an id which is payments.id)
7 to create a payment link and we redirect the user to it.
8 Sample link: https://sandbox.square.link/u/IgOz82xk
9 The rg id, uid, operator name, 'plan' type and 'y' interval, 'init'
10 state are inserted by calling 'pay_insert' function.
11 pay_needed_high_level
12 pay_square_create_link
13 pay_insert
14 We receive an order_id.
15
16 Next step is to go to the external payment page.
17 Payment takes place.
18 External site redirects back to RocketGit (passing back the payment id).
19 https://rg.embedromix.ro:9003/user/price1?paid=e09964ef29b3d886
20
21 Now, we received the payment id and we thank the user for the purchase.
22 We need to schedule the checking of the payment, as an event, to be able
23 to confirm it and mark it as paid. Should we? I think yes, because only now
24 the user confirmed the payment. Yes, but what if we cannot update the db?
25 Isn't it better to just check all initiated payments? I think yes.
26 We connect to the payment provider and we will check the state of the payment.
27 We also need to be able to compute the last paid day, to not bother the user
28 earlier than needed.
29 How should I compute it? And where to store this info?
30 - case 1, user is paying immediately after sign-up (2023-02-10), pays for 1 month
31 first day not paid is after exactly 1 month (2023-03-10)
32 - case 2, user is paying after some days after sign-up (2023-02-10), pays for 1 month
33 first day not paid is after exactly 1 month (2023-03-10)
34 - what happens if we suspend the account for not paying?
35 we still have resources used. Ask user to pay before unlocking resources?
36
37 TODO:
38 - We need to show correctly 12999 euro as 12.99 euro.
39 1299/12990/USD 1/10/RON -> 1299=12.99/12990=129.90/USD 99=0.99/999=9.99/RON
40 - What if the user does not pay and does not return to rg? We should
41 reuse a previous payment if amount/period/plan match.
42 - What if the user changes the plan on-th-fly?
43 We need to think to multiple scenarios (cheaper plan or a more expensive one).
44 - Should we offer one (last?) month free?
45 -
Date/time (UTC) Type Misc Labels
2023-05-03 04:56 build debian-11-amd64 worker/r1 builder/color=fff worker_elap/25s wait_time/1s date/2023-05-03 time/04:55
2023-05-03 05:00 build fedora-37-x86_64 worker/r1 builder/color=fff worker_elap/187s wait_time/170s date/2023-05-03 time/04:53
2023-05-03 10:42 build fedora-38-x86_64 worker/r1 builder/color=fff worker_elap/70s wait_time/43375s date/2023-05-02 time/22:37
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/rocketgit

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

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

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