Subject | Hash | Author | Date (UTC) |
---|---|---|---|
Added 'lock repo' feature | 64c5b48e8f769d5f4357ecba80529d649d65df6f | Catalin(ux) M. BOIE | 2015-12-11 17:28:47 |
trim description - eles an empty line will show up | e512914d92723c7f8aecab4fcf99edbffbc8e795 | Catalin(ux) M. BOIE | 2015-12-08 19:15:40 |
First draft for Amazon | 8eb80fe68d9586688e4b9b16f0cd80f936501af8 | Catalin(ux) M. BOIE | 2015-12-08 18:47:17 |
Add 'watch' button for user; corrected 'watch' bugs | 73ca78916920d60c12725c709d136e80238aa1eb | Catalin(ux) M. BOIE | 2015-12-07 19:49:48 |
TODO updates, log last webhook output | 24895c5ccb8c47315bd6897f2a60f9c8c3b3d6b1 | Catalin(ux) M. BOIE | 2015-12-06 17:04:56 |
keys: add some caching and prevent updating first_use if not necessary | 35a152bc27fb1791f3f9d8ad1287c3847ed334a1 | Catalin(ux) M. BOIE | 2015-12-05 17:21:19 |
Deal correctly with cache regarding last_bug_id | 705351cdea6af55f9dd61de0d85d41b8ac33fc88 | Catalin(ux) M. BOIE | 2015-12-03 21:01:08 |
Settle to Affero GPLv3+ | 679d4032059256a01610e65cbff5496d32d9fc7d | Catalin(ux) M. BOIE | 2015-12-03 19:40:12 |
Missing Affero | dee2c08fc8a0371ac37f6f00bf7f3e2e01f92e92 | Catalin(ux) M. BOIE | 2015-12-03 19:36:10 |
DO not show 2fa hint for a visiting user | 4ff8837ef0f45572592f1d81724737b3732a046a | Catalin(ux) M. BOIE | 2015-12-03 17:25:24 |
Let the user choose the e-mail, no defaults should be suggested | 09450741613a407c09bb465bff8a3c19c565df9a | Catalin(ux) M. BOIE | 2015-12-02 18:12:08 |
Pass uid for all events; more fixes for unit tests | 866e43baf739ae7072949559d1c7e089c086af76 | Catalin(ux) M. BOIE | 2015-11-19 19:28:26 |
404 http error was receive for showing blobs ending in .php or .html | ff87d956360a86e88a751d4c391585c84bb1e132 | Catalin(ux) M. BOIE | 2015-11-18 20:32:50 |
When creating an array, last_bug_id is set now correctly | f679840c7ac3879aae69f488c561a5bd73ce71f1 | Catalin(ux) M. BOIE | 2015-11-18 19:14:48 |
We allow empty description for bugs | c5a1b4057963eac575cc3d0d4872c4519fea80b0 | Catalin(ux) M. BOIE | 2015-11-18 18:26:39 |
Show the repo # on main repo page | c72f4d8627ab577a92c5531ed7afb9e55a6bfd1b | Catalin(ux) M. BOIE | 2015-11-18 18:25:00 |
Bumped version to 0.42 | 8e9fab68ff08040402c0aa25539d1e8b29258f7d | Catalin(ux) M. BOIE | 2015-11-18 18:14:40 |
Renamed the virtual machines files | 040c9f3a87826a52713b3b5f48d19c83236f8aa8 | Catalin(ux) M. BOIE | 2015-11-18 18:13:57 |
Admin user must not confirm the account by e-mail | 0a81a2824087d9dcd2d1981c860946fd49cc8bf7 | Catalin(ux) M. BOIE | 2015-11-18 18:04:26 |
Bump the version to 0.41 | 363368555480d4c79c13867805c59541fd59e37c | Catalin(ux) M. BOIE | 2015-11-18 16:37:16 |
File | Lines added | Lines deleted |
---|---|---|
inc/repo.inc.php | 203 | 0 |
inc/ssh.inc.php | 31 | 0 |
inc/struct.inc.php | 4 | 1 |
root/themes/default/hints/repo/lock_repo.html | 8 | 0 |
root/themes/default/repo/lock.html | 23 | 0 |
root/themes/default/repo/unlock_ok.html | 3 | 0 |
root/themes/default/user/repo/deny_lock.html | 3 | 0 |
root/themes/default/user/repo/menu.html | 1 | 0 |
scripts/remote.php | 14 | 0 |
techdocs/amazon-CodeDeploy.txt | 0 | 0 |
File inc/repo.inc.php changed (mode: 100644) (index 2cafd36..c77d822) | |||
... | ... | $rg_repo_rights = array( | |
35 | 35 | "A" => "Access repo", | "A" => "Access repo", |
36 | 36 | "E" => "Create/edit repo", | "E" => "Create/edit repo", |
37 | 37 | "D" => "Delete repo", | "D" => "Delete repo", |
38 | 'K' => 'Lock repo', | ||
38 | 39 | "G" => "Grant rights", | "G" => "Grant rights", |
39 | 40 | "a" => "Access bug tracker", | "a" => "Access bug tracker", |
40 | 41 | "B" => "Add bugs", | "B" => "Add bugs", |
... | ... | define('REPO_CAT_GIT_BRANCH_DELETE', 40); | |
216 | 217 | define('REPO_CAT_GIT_BRANCH_UPDATE', 41); | define('REPO_CAT_GIT_BRANCH_UPDATE', 41); |
217 | 218 | define('REPO_CAT_GIT_BRANCH_CREATE', 42); | define('REPO_CAT_GIT_BRANCH_CREATE', 42); |
218 | 219 | define('REPO_CAT_GIT_BRANCH_ANON_PUSH', 43); | define('REPO_CAT_GIT_BRANCH_ANON_PUSH', 43); |
220 | define('REPO_CAT_LOCK', 50); | ||
221 | define('REPO_CAT_UNLOCK', 51); | ||
219 | 222 | ||
220 | 223 | $rg_repo_error = ""; | $rg_repo_error = ""; |
221 | 224 | ||
... | ... | function rg_repo_git_done($db, $repo_id) | |
1304 | 1307 | return $ret; | return $ret; |
1305 | 1308 | } | } |
1306 | 1309 | ||
1310 | /* | ||
1311 | * Returns the status of a repo | ||
1312 | */ | ||
1313 | function rg_repo_lock_status($db, $repo_id) | ||
1314 | { | ||
1315 | rg_prof_start('repo_lock_status'); | ||
1316 | rg_log_enter('repo_lock_status'); | ||
1317 | |||
1318 | $ret = array(); | ||
1319 | $ret['ok'] = 0; | ||
1320 | while (1) { | ||
1321 | $key = 'locks' . '::' . 'repos' . '::' . $repo_id; | ||
1322 | $c = rg_cache_get($key); | ||
1323 | if ($c !== FALSE) { | ||
1324 | $ret = $c; | ||
1325 | $ret['ok'] = 1; | ||
1326 | break; | ||
1327 | } | ||
1328 | |||
1329 | $params = array('repo_id' => $repo_id); | ||
1330 | $sql = 'SELECT * FROM repo_locks' | ||
1331 | . ' WHERE repo_id = @@repo_id@@'; | ||
1332 | $res = rg_sql_query_params($db, $sql, $params); | ||
1333 | if ($res === FALSE) { | ||
1334 | rg_repo_set_error('cannot get lock status'); | ||
1335 | break; | ||
1336 | } | ||
1337 | $rows = rg_sql_num_rows($res); | ||
1338 | if ($rows == 0) { | ||
1339 | $ret['status'] = 0; | ||
1340 | } else { | ||
1341 | $ret = rg_sql_fetch_array($res); | ||
1342 | $ret['status'] = 1; | ||
1343 | } | ||
1344 | rg_sql_free_result($res); | ||
1345 | |||
1346 | rg_cache_set($key, $ret, RG_SOCKET_NO_WAIT); | ||
1347 | |||
1348 | $ret['ok'] = 1; | ||
1349 | break; | ||
1350 | } | ||
1351 | |||
1352 | rg_log_exit(); | ||
1353 | rg_prof_end('repo_lock_status'); | ||
1354 | return $ret; | ||
1355 | } | ||
1356 | |||
1357 | /* | ||
1358 | * Locks/unlocks a repo | ||
1359 | * @lock: 1 = lock, 0 = unlock | ||
1360 | */ | ||
1361 | function rg_repo_lock($db, $repo_id, $uid, $lock, $reason) | ||
1362 | { | ||
1363 | rg_prof_start('repo_lock'); | ||
1364 | rg_log_enter('repo_lock'); | ||
1365 | |||
1366 | $ret = FALSE; | ||
1367 | while (1) { | ||
1368 | $si = rg_repo_lock_status($db, $repo_id); | ||
1369 | if ($si['ok'] != 1) | ||
1370 | break; | ||
1371 | |||
1372 | // If we already are in the same state as the passed one | ||
1373 | if ($si['status'] == $lock) { | ||
1374 | $ret = TRUE; | ||
1375 | break; | ||
1376 | } | ||
1377 | |||
1378 | $params = array( | ||
1379 | 'itime' => time(), | ||
1380 | 'repo_id' => $repo_id, | ||
1381 | 'uid' => $uid, | ||
1382 | 'reason' => $reason); | ||
1383 | if ($lock == 1) | ||
1384 | $sql = 'INSERT INTO repo_locks (repo_id, uid, itime)' | ||
1385 | . ' VALUES (@@repo_id@@, @@uid@@, @@itime@@)'; | ||
1386 | else | ||
1387 | $sql = 'DELETE FROM repo_locks' | ||
1388 | . ' WHERE repo_id = @@repo_id@@'; | ||
1389 | $res = rg_sql_query_params($db, $sql, $params); | ||
1390 | if ($res === FALSE) { | ||
1391 | rg_repo_set_error('db lock/unlock error'); | ||
1392 | break; | ||
1393 | } | ||
1394 | |||
1395 | $key = 'locks' . '::' . 'repos' . '::' . $repo_id; | ||
1396 | if ($lock == 1) { | ||
1397 | $params['status'] = 1; | ||
1398 | rg_cache_set($key, $params, RG_SOCKET_NO_WAIT); | ||
1399 | } else { | ||
1400 | rg_cache_unset($key, RG_SOCKET_NO_WAIT); | ||
1401 | } | ||
1402 | |||
1403 | $h = array('ri' => array(), 'ui' => array()); | ||
1404 | $h['ri']['repo_id'] = $repo_id; | ||
1405 | $h['ui']['uid'] = $uid; | ||
1406 | $h['history_category'] = $lock == 1 ? REPO_CAT_LOCK : REPO_CAT_UNLOCK; | ||
1407 | $h['history_message'] = 'Repository ' . | ||
1408 | ($lock == 1 ? 'locked' : 'unlocked') . ': ' . $reason; | ||
1409 | rg_repo_history_insert($db, $h); | ||
1410 | |||
1411 | $ret = TRUE; | ||
1412 | break; | ||
1413 | } | ||
1414 | |||
1415 | rg_log_exit(); | ||
1416 | rg_prof_end('repo_lock'); | ||
1417 | return $ret; | ||
1418 | } | ||
1419 | |||
1307 | 1420 | /* | /* |
1308 | 1421 | * High level function for Repo -> Admin -> Rights -> Repo/Refs/Path rights menu. | * High level function for Repo -> Admin -> Rights -> Repo/Refs/Path rights menu. |
1309 | 1422 | */ | */ |
... | ... | function rg_repo_edit_high_level($db, &$rg) | |
1660 | 1773 | return $ret; | return $ret; |
1661 | 1774 | } | } |
1662 | 1775 | ||
1776 | /* | ||
1777 | * High level function for locking a repo | ||
1778 | */ | ||
1779 | function rg_repo_lock_high_level($db, &$rg) | ||
1780 | { | ||
1781 | rg_log_enter("rg_repo_lock_high_level"); | ||
1782 | |||
1783 | $ret = ""; | ||
1784 | |||
1785 | $errmsg = array(); | ||
1786 | while (1) { | ||
1787 | $x = array(); | ||
1788 | $x['obj_id'] = $rg['ri']['repo_id']; | ||
1789 | $x['type'] = 'repo'; | ||
1790 | $x['owner'] = $rg['ri']['uid']; | ||
1791 | $x['uid'] = $rg['login_ui']['uid']; | ||
1792 | $x['username'] = $rg['login_ui']['username']; | ||
1793 | $x['needed_rights'] = 'K'; | ||
1794 | $x['ip'] = $rg['ip']; | ||
1795 | $x['misc'] = ''; | ||
1796 | if (rg_rights_allow($db, $x) !== TRUE) { | ||
1797 | $ret .= rg_template("user/repo/deny_lock.html", | ||
1798 | $rg, TRUE /*xss*/); | ||
1799 | break; | ||
1800 | } | ||
1801 | |||
1802 | $ls = rg_repo_lock_status($db, $rg['ri']['repo_id']); | ||
1803 | if ($ls['ok'] != 1) | ||
1804 | break; | ||
1805 | |||
1806 | rg_log('ZZZ: status=' . $ls['status']); | ||
1807 | $rg['ri']['next_status'] = 1 - $ls['status']; | ||
1808 | |||
1809 | if ($rg['doit'] != 1) { | ||
1810 | $rg['ri']['reason'] = ''; | ||
1811 | break; | ||
1812 | } | ||
1813 | |||
1814 | $reason = rg_var_str('ri::reason'); | ||
1815 | $lock = rg_var_str('ri::lock'); | ||
1816 | rg_log('ZZZ: lock=' . $lock); | ||
1817 | |||
1818 | if (!rg_valid_referer()) { | ||
1819 | $errmsg[] = "invalid referer; try again"; | ||
1820 | break; | ||
1821 | } | ||
1822 | |||
1823 | if (!rg_token_valid($db, $rg, 'repo_lock_hl', FALSE)) { | ||
1824 | // TODO: replace all of these with a template | ||
1825 | $errmsg[] = "invalid token; try again."; | ||
1826 | break; | ||
1827 | } | ||
1828 | |||
1829 | $r = rg_repo_lock($db, $rg['ri']['repo_id'], | ||
1830 | $rg['login_ui']['uid'], $lock, $reason); | ||
1831 | if ($r === FALSE) { | ||
1832 | $errmsg[] = rg_repo_error(); | ||
1833 | break; | ||
1834 | } | ||
1835 | |||
1836 | if ($lock == 1) | ||
1837 | $t = 'repo/lock_ok.html'; | ||
1838 | else | ||
1839 | $t = 'repo/unlock_ok.html'; | ||
1840 | $ret .= rg_template($t, $rg, TRUE /*xss*/); | ||
1841 | |||
1842 | // clean form | ||
1843 | $rg['ri']['reason'] = ''; | ||
1844 | $rg['ri']['next_status'] = 1 - $lock; | ||
1845 | break; | ||
1846 | } | ||
1847 | |||
1848 | $rg['HTML:errmsg'] = rg_template_errmsg($errmsg); | ||
1849 | $rg['rg_form_token'] = rg_token_get($db, $rg, 'repo_lock_hl'); | ||
1850 | $hints = array(); | ||
1851 | $hints[]['HTML:hint'] = rg_template("hints/repo/lock_repo.html", | ||
1852 | $rg, TRUE /*xss*/); | ||
1853 | $rg['HTML:repo_lock_hints'] = rg_template_table("hints/list", | ||
1854 | $hints, $rg); | ||
1855 | $ret .= rg_template("repo/lock.html", $rg, TRUE /*xss*/); | ||
1856 | |||
1857 | rg_log_exit(); | ||
1858 | return $ret; | ||
1859 | } | ||
1860 | |||
1663 | 1861 | /* | /* |
1664 | 1862 | * High level function for 'Repo -> Admin' menu | * High level function for 'Repo -> Admin' menu |
1665 | 1863 | */ | */ |
... | ... | function rg_repo_admin($db, &$rg, $paras) | |
1691 | 1889 | $ret .= rg_repo_admin_delete($db, $rg); | $ret .= rg_repo_admin_delete($db, $rg); |
1692 | 1890 | break; | break; |
1693 | 1891 | ||
1892 | case 'lock': | ||
1893 | $rg['form_url'] = $rg['url_repo'] . "/admin/lock"; | ||
1894 | $ret .= rg_repo_lock_high_level($db, $rg); | ||
1895 | break; | ||
1896 | |||
1694 | 1897 | default: | default: |
1695 | 1898 | $rg['form_url'] = $rg['url_repo'] . "/admin"; | $rg['form_url'] = $rg['url_repo'] . "/admin"; |
1696 | 1899 | $ret .= rg_repo_edit_high_level($db, $rg); | $ret .= rg_repo_edit_high_level($db, $rg); |
File inc/ssh.inc.php changed (mode: 100644) (index 24f6295..7ef5d14) | |||
... | ... | function rg_ssh_repo($db, $uid, $paras) | |
86 | 86 | echo 'Master: ' . 'Error getting info' . "\n"; | echo 'Master: ' . 'Error getting info' . "\n"; |
87 | 87 | } | } |
88 | 88 | } | } |
89 | |||
90 | echo 'Description:' . "\n"; | ||
91 | $_d = explode("\n", $ri['description']); | ||
92 | foreach ($_d as $_line) | ||
93 | echo ' ' . $_line . "\n"; | ||
94 | |||
95 | $ls = rg_repo_lock_status($db, $ri['repo_id']); | ||
96 | if ($ls['ok'] == 1) { | ||
97 | if ($ls['status'] == 0) { | ||
98 | echo 'Repository is not locked.' . "\n"; | ||
99 | } else { | ||
100 | $_ui = rg_user_info($db, $ls['uid'], '', ''); | ||
101 | if ($_ui['exists'] == 1) | ||
102 | $_u = $_ui['username']; | ||
103 | else | ||
104 | $_u = '?'; | ||
105 | |||
106 | $reason = ''; | ||
107 | $_r = explode("\n", $ls['reason']); | ||
108 | foreach ($_r as $_line) | ||
109 | $reason .= ' ' . $_line . "\n"; | ||
110 | |||
111 | echo 'Repository has been locked by user ' . $_u | ||
112 | . ' at ' | ||
113 | . gmdate('Y-m-d H:i', $ls['itime']) . ' UTC.' | ||
114 | . ' Reason:' . "\n" | ||
115 | . $reason . "\n"; | ||
116 | } | ||
117 | } else { | ||
118 | echo 'Error: cannot get info about the lock status!' . "\n"; | ||
119 | } | ||
89 | 120 | } | } |
90 | 121 | ||
91 | 122 | /* | /* |
File inc/struct.inc.php changed (mode: 100644) (index cf54505..17caffa) | |||
... | ... | $rg_sql_struct[35]['other'] = array( | |
485 | 485 | $rg_sql_struct[36]['tables'] = array( | $rg_sql_struct[36]['tables'] = array( |
486 | 486 | 'watch_user' => "CREATE TABLE watch_user (" | 'watch_user' => "CREATE TABLE watch_user (" |
487 | 487 | . "uid INT NOT NULL" | . "uid INT NOT NULL" |
488 | . ", watch_uid INT NOT NULL)" | ||
488 | . ", watch_uid INT NOT NULL)", | ||
489 | 'repo_locks' => "CREATE TABLE repo_locks" | ||
490 | . " (repo_id INT PRIMARY KEY, itime INT NOT NULL DEFAULT 0" | ||
491 | . ", uid INT NOT NULL DEFAULT 0)" | ||
489 | 492 | ); | ); |
490 | 493 | $rg_sql_struct[36]['other'] = array( | $rg_sql_struct[36]['other'] = array( |
491 | 494 | 'users drop double unique constriaint' => | 'users drop double unique constriaint' => |
File root/themes/default/hints/repo/lock_repo.html added (mode: 100644) (index 0000000..3bc1e43) | |||
1 | When a repository is locked, only the users that have "Lock" rights will be | ||
2 | able to push into it.<br /> | ||
3 | <br /> | ||
4 | |||
5 | You may want to lock a repo to repair bad pushes.<br /> | ||
6 | <br /> | ||
7 | |||
8 | Any feedback regarding what more this feature should do is really appreciated! |
File root/themes/default/repo/lock.html added (mode: 100644) (index 0000000..cf8c9b1) | |||
1 | <div class="formarea"> | ||
2 | |||
3 | <div class="formarea_title">@@if(@@ri::next_status@@ == 1){{Lock repository}}{{Unlock repository}}</div> | ||
4 | |||
5 | @@errmsg@@ | ||
6 | |||
7 | <form method="post" action="@@form_url@@"> | ||
8 | <input type="hidden" name="repo_id" value="@@ri::repo_id@@" /> | ||
9 | <input type="hidden" name="doit" value="1" /> | ||
10 | <input type="hidden" name="token" value="@@rg_form_token@@" /> | ||
11 | <input type="hidden" name="ri::lock" value="@@ri::next_status@@" /> | ||
12 | |||
13 | <p> | ||
14 | <label for="reason">Reason (optional)</label><br /> | ||
15 | <textarea name="ri::reason" id="reason" rows="4" cols="30">@@ri::reason@@</textarea> | ||
16 | </p> | ||
17 | |||
18 | <input type="submit" name="button" value="@@if(@@ri::next_status@@ == 1){{Lock}}{{Unlock}}" /> | ||
19 | |||
20 | </form> | ||
21 | </div> | ||
22 | |||
23 | @@repo_lock_hints@@ |
File root/themes/default/repo/unlock_ok.html added (mode: 100644) (index 0000000..8c9ec6e) | |||
1 | <div class="mess ok"> | ||
2 | Repository has been successfully unlocked. | ||
3 | </div> |
File root/themes/default/user/repo/deny_lock.html added (mode: 100644) (index 0000000..936cc9c) | |||
1 | <div class="mess error"> | ||
2 | You are not allowed to lock this repo. | ||
3 | </div> |
File root/themes/default/user/repo/menu.html changed (mode: 100644) (index 453d8be..b344642) | |||
5 | 5 | <li@@if(@@menu::repo::refs_rights@@ == 1){{ class="selected"}}><a href="@@url_repo@@/admin/refs_rights">Refs rights</a></li> | <li@@if(@@menu::repo::refs_rights@@ == 1){{ class="selected"}}><a href="@@url_repo@@/admin/refs_rights">Refs rights</a></li> |
6 | 6 | <li@@if(@@menu::repo::path_rights@@ == 1){{ class="selected"}}><a href="@@url_repo@@/admin/path_rights">Path rights</a></li> | <li@@if(@@menu::repo::path_rights@@ == 1){{ class="selected"}}><a href="@@url_repo@@/admin/path_rights">Path rights</a></li> |
7 | 7 | <li@@if(@@menu::repo::delete@@ == 1){{ class="selected"}}><a href="@@url_repo@@/admin/delete">Delete</a></li> | <li@@if(@@menu::repo::delete@@ == 1){{ class="selected"}}><a href="@@url_repo@@/admin/delete">Delete</a></li> |
8 | <li@@if(@@menu::repo::lock@@ == 1){{ class="selected"}}><a href="@@url_repo@@/admin/lock">Lock</a></li> | ||
8 | 9 | </ul> | </ul> |
9 | 10 | </div> | </div> |
File scripts/remote.php changed (mode: 100644) (index f86204f..d2d7a93) | |||
... | ... | if ($ri['exists'] != 1) | |
201 | 201 | if ($ri['deleted'] == 1) | if ($ri['deleted'] == 1) |
202 | 202 | fatal("Repo has been deleted!"); | fatal("Repo has been deleted!"); |
203 | 203 | ||
204 | $ls = rg_repo_lock_status($db, $ri['repo_id']); | ||
205 | if ($ls['ok'] != 1) | ||
206 | fatal('Could not get lock status: ' . rg_repo_error()); | ||
207 | if (($ls['status'] == 1) && ($conn_ui['uid'] != $ls['uid'])) { | ||
208 | $_u = rg_user_info($db, $ls['uid'], '', ''); | ||
209 | if ($_u['exists'] == 1) | ||
210 | $_user = $_u['username']; | ||
211 | else | ||
212 | $_user = '?'; | ||
213 | fatal('Repository has been locked user ' . $_user | ||
214 | . ' at ' . gmdate('Y-m-d H:i', $ls['itime']) . ' UTC.' | ||
215 | . ' Reason: ' . $ls['reason']); | ||
216 | } | ||
217 | |||
204 | 218 | $repo_path = rg_repo_path_by_id($owner_ui['uid'], $ri['repo_id']); | $repo_path = rg_repo_path_by_id($owner_ui['uid'], $ri['repo_id']); |
205 | 219 | rg_log("repo_path=$repo_path."); | rg_log("repo_path=$repo_path."); |
206 | 220 |
File techdocs/amazon-CodeDeploy.txt copied from file root/themes/default/errmsg/nodata.html (similarity 100%) |