| File | Lines added | Lines deleted |
|---|---|---|
| TODO | 86 | 22 |
| TODO.vm | 5 | 0 |
| hooks/pre-receive | 18 | 15 |
| inc/bug.inc.php | 3 | 0 |
| inc/git.inc.php | 3 | 7 |
| inc/mr.inc.php | 4 | 2 |
| inc/repo.inc.php | 8 | 5 |
| inc/ssh.inc.php | 10 | 17 |
| inc/user.inc.php | 4 | 0 |
| inc/user/repo-page.php | 18 | 8 |
| root/index.php | 1 | 1 |
| root/themes/default/hints/repo/anon_push.html | 1 | 1 |
| root/themes/default/hints/repo/clone_owner.html | 0 | 1 |
| root/themes/default/hints/repo/edit_repo_refs_rights.html | 1 | 1 |
| root/themes/default/hints/repo/merge.html | 13 | 8 |
| root/themes/default/index.html | 2 | 1 |
| root/themes/default/main.css | 3 | 2 |
| root/themes/default/msg/push_merge_request.txt | 1 | 1 |
| root/themes/default/repo/add_edit.html | 1 | 1 |
| root/themes/default/repo/main.html | 1 | 1 |
| root/themes/default/repo/mr/list/nodata.html | 1 | 1 |
| root/themes/default/repo/mr/page.html | 1 | 1 |
| root/themes/default/user/home.html | 1 | 0 |
| scripts/remote.php | 34 | 25 |
| tests/.gitignore | 1 | 0 |
| tests/Makefile | 5 | 2 |
| tests/config.php | 1 | 1 |
| tests/http.inc.php | 5 | 6 |
| tests/pr_anon.php | 66 | 0 |
| tests/wh.php | 1 | 1 |
| File TODO changed (mode: 100644) (index 931fa4b..d80e02a) | |||
| 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. | ||
| 7 | 2 | [ ] | [ ] |
| 8 | 3 | ||
| 9 | 4 | == BEFORE NEXT RELEASE == | == BEFORE NEXT RELEASE == |
| 5 | [ ] check 'man git-receive-pack' for gpg (about signed pushes). | ||
| 6 | [ ] I still have to investigate if I can send git messages. | ||
| 7 | [ ] After pushing using anon-push feature, give to the user a link to be able | ||
| 8 | to add a proper subject/body. Else, use the first commit for this. | ||
| 9 | Or, join all commits messages. I think is better. | ||
| 10 | [ ] For repo-refs rights, what happens if reference is empty? | ||
| 11 | Add a text to tell that it means everything. | ||
| 12 | Seems is ok to be empty = allow push - but, check! | ||
| 13 | [ ] Allow users to hide avatars in config. | ||
| 14 | [ ] Add a protection against compression vulnerability. | ||
| 15 | An attacker will make the victim's browser to do a lot of requests | ||
| 16 | trying to guess CSRF tokens inside the HTTP body. | ||
| 17 | We should rate limit the requests or somehow change the CSRF token | ||
| 18 | with every request. Is enough to use a XOR mask over the token, | ||
| 19 | prepended to the token. | ||
| 20 | [ ] Pull request: I must be able to do the merge from web interface. | ||
| 21 | After adding a pull request, and if the src is a fork, we bring | ||
| 22 | the commits into the destination repo to be able to test if the | ||
| 23 | merge will be ok or not. | ||
| 24 | I should inform the user that the merge is ok or not. | ||
| 25 | What to do if it is not? Should I notify the owner that the merge | ||
| 26 | is not working anymore and put it in a state that is hidden from the | ||
| 27 | merge requests that are working? | ||
| 28 | Now I think I accept merge requests only by anonymous pushes. | ||
| 29 | But I should allow them also from web, at a user request. | ||
| 30 | Still have to check how others are doing it. | ||
| 31 | Also, we should have the possibility to close the merge request | ||
| 32 | (for example when is not needed anymore because a fix was already | ||
| 33 | merged); maybe reject with a comment. | ||
| 34 | Default, merge with --no-ff, but allow the merge without it. | ||
| 35 | Decide if the pull namespace is read only or not. | ||
| 36 | GitHub has the following namespace: | ||
| 37 | git fetch origin pull/ID/head:BRANCHNAME | ||
| 38 | How do I create a pull request? | ||
| 39 | - Select the branch from where you want to do the pull request. | ||
| 40 | - Where a contributer is allowed to push? | ||
| 41 | - Select the target branch. | ||
| 42 | - Select "Review" - optional | ||
| 43 | - If selected, show the diff | ||
| 44 | - Add a commit message | ||
| 45 | - Notify commiters? | ||
| 46 | Where should the "Pull requests" menu be? | ||
| 47 | Show some info about the merge request: authors, files, diffstat etc. | ||
| 48 | 4 pieces of information: src/dst repo/branch. | ||
| 49 | Developers can push in their branch, for example: refs/{USER}/ | ||
| 50 | and can make a pull request from there. | ||
| 51 | Add possibility to notify more people that a pull request was created. | ||
| 52 | A user must be able to push other commits next to the ones present | ||
| 53 | in the pull request. | ||
| 54 | Somehow, close a pull request if a user is pushing the changes. | ||
| 55 | Also, close even if a rebase was done. It may be hard. | ||
| 56 | rstacruz: | ||
| 57 | [alias] | ||
| 58 | pr = "!f() { git fetch -fu ${2:-origin} refs/pull/$1/head:pr/$1 && git checkout pr/$1; }; f" | ||
| 59 | [ ] Need to add comments for pull requests. Find a way to propagate them in the | ||
| 60 | git repo? | ||
| 61 | [ ] Because I show the merge request id, somebody can change the commits. | ||
| 62 | Somehow, it should be locked? | ||
| 63 | [ ] Add "Pull request" and allow a user to do it from a branch or a fork. | ||
| 64 | [ ] When a push is taking place, add the repo into a new table to: | ||
| 65 | - recalculate disk space | ||
| 66 | - redo the stats | ||
| 67 | [ ] Look into Travis | ||
| 68 | [ ] Add a prefetched daemon. Example: When user logins, prefetch repo info | ||
| 69 | to be warm in cache. The user for sure will access the repos. | ||
| 70 | Maybe set a permanent cookie to encode the uid and when a user visits | ||
| 71 | login page, prefetch the user info! Cool. Maybe other stuff. | ||
| 72 | [ ] webhooks: still to add for: Pushes, tags, comment, bug creation, | ||
| 73 | pull requests. Does not make sense to encode a lot of info in | ||
| 74 | response because a bot can check by itself by fetching. | ||
| 75 | [ ] Why I cannot push to r1? | ||
| 10 | 76 | [ ] For events, very probably I have to disable the cache. | [ ] For events, very probably I have to disable the cache. |
| 11 | 77 | Scenario: adding a webhook1, add a repo1, add a webhook2, | Scenario: adding a webhook1, add a repo1, add a webhook2, |
| 12 | 78 | add a repo2. webhook2 will not trigger on repo2 creating because | add a repo2. webhook2 will not trigger on repo2 creating because |
| 13 | 79 | only webhook1 is in cache! Very bad! | only webhook1 is in cache! Very bad! |
| 14 | [ ] Add notifications for hook add? | ||
| 80 | More exactly, disable core cache? | ||
| 81 | [ ] Add notifications for hook add? | ||
| 82 | For the user creating the hook is not absolutely necessary. | ||
| 83 | Maybe from a security point of view? But the rest of admins | ||
| 84 | may want to know. I think I will drop this for now. | ||
| 15 | 85 | [ ] Send an e-mail if webhook fails? Flag when configuring webhook? | [ ] Send an e-mail if webhook fails? Flag when configuring webhook? |
| 86 | Store the last curl log in 'wh' table? | ||
| 16 | 87 | [ ] unit test: generate a CA, client cert, server cert, and use openssl | [ ] unit test: generate a CA, client cert, server cert, and use openssl |
| 17 | 88 | s_server to test? Or maybe curl in mode server? Or php in listen | s_server to test? Or maybe curl in mode server? Or php in listen |
| 18 | 89 | mode? | mode? |
| 20 | 91 | [ ] Document webhooks, mostly 'PHP serialize' type. But also other things. | [ ] Document webhooks, mostly 'PHP serialize' type. But also other things. |
| 21 | 92 | [ ] Do not forget that cache.php has its own memory cache! | [ ] Do not forget that cache.php has its own memory cache! |
| 22 | 93 | I must not update the database and expect it to see good values. | I must not update the database and expect it to see good values. |
| 23 | [ ] wh: Add: tag push, issue, merge request | ||
| 24 | 94 | [ ] wh: add also XML, JSON | [ ] wh: add also XML, JSON |
| 25 | 95 | [ ] wh: add other conection types: websocket, socket (low priority) | [ ] wh: add other conection types: websocket, socket (low priority) |
| 26 | 96 | [ ] How "Delete selected" button should be aligned? | [ ] How "Delete selected" button should be aligned? |
| 121 | 191 | [ ] history: add 2fa ssh validation. | [ ] history: add 2fa ssh validation. |
| 122 | 192 | [ ] Add history for totp enrollment. | [ ] Add history for totp enrollment. |
| 123 | 193 | [ ] ionut: Check this to not be send X-PHP-Originating-Script: 0:user.inc.php | [ ] ionut: Check this to not be send X-PHP-Originating-Script: 0:user.inc.php |
| 124 | [ ] VM: Test if IPv4/IPv6 address is shown at login time. | ||
| 125 | 194 | [ ] When listing repos on user homepage, we should not add also the user. | [ ] When listing repos on user homepage, we should not add also the user. |
| 126 | 195 | Check rg_repo_list. | Check rg_repo_list. |
| 127 | 196 | [ ] totp for ssh is not finished yet. remember, totp for ssh seems to be only | [ ] totp for ssh is not finished yet. remember, totp for ssh seems to be only |
| 138 | 207 | [ ] Add max_requests per hour for plans and enforce them. | [ ] Add max_requests per hour for plans and enforce them. |
| 139 | 208 | [ ] Protect login by country/ua? | [ ] Protect login by country/ua? |
| 140 | 209 | [ ] Improve input forms to be friendly with mobile phones: give html5 hints. | [ ] Improve input forms to be friendly with mobile phones: give html5 hints. |
| 141 | [ ] Use guestmount when building VM images? | ||
| 142 | 210 | [ ] Main web application must not have access to e-mail column, maybe others. | [ ] Main web application must not have access to e-mail column, maybe others. |
| 143 | 211 | Only the queue processor must be able to use it. This is to avoid | Only the queue processor must be able to use it. This is to avoid |
| 144 | 212 | XSS and the stealing of sensitive information. | XSS and the stealing of sensitive information. |
| 217 | 285 | [ ] Why 'not github' articles, should be integrated somewhere: | [ ] Why 'not github' articles, should be integrated somewhere: |
| 218 | 286 | http://www.valdyas.org/fading/index.cgi/2015/05/29#no-github | http://www.valdyas.org/fading/index.cgi/2015/05/29#no-github |
| 219 | 287 | http://www.adamhyde.net/why-github-is-bad-for-open-source/ | http://www.adamhyde.net/why-github-is-bad-for-open-source/ |
| 220 | [ ] Add sha1sum of the VM images | ||
| 221 | 288 | [ ] ssh: Show user the entry that must be added for known_hosts | [ ] ssh: Show user the entry that must be added for known_hosts |
| 222 | 289 | [ ] 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 |
| 223 | 290 | [ ] Pass only uid to events, we already have it in cache! | [ ] Pass only uid to events, we already have it in cache! |
| 231 | 298 | [ ] Should we just set no password somehow for ssh access to be able to signal | [ ] Should we just set no password somehow for ssh access to be able to signal |
| 232 | 299 | the user that has no key uploaded? | the user that has no key uploaded? |
| 233 | 300 | [ ] For 'log' and 'tree' we have decorations for links! | [ ] For 'log' and 'tree' we have decorations for links! |
| 234 | [ ] Sign vm images. | ||
| 235 | 301 | [ ] In "Tree" section, seems the path is doubled. | [ ] In "Tree" section, seems the path is doubled. |
| 236 | 302 | [ ] Hint: where in fs you can find the repo. Only for admins? | [ ] Hint: where in fs you can find the repo. Only for admins? |
| 237 | 303 | [ ] Hints should not call rg_template, let next rg_template_table to do it. | [ ] Hints should not call rg_template, let next rg_template_table to do it. |
| 261 | 327 | what chars are invalid/permited (reported by Ionut). | what chars are invalid/permited (reported by Ionut). |
| 262 | 328 | [ ] Security: Link-uri + xss (Ionut) | [ ] Security: Link-uri + xss (Ionut) |
| 263 | 329 | [ ] I am able to disable merge/pull requests? Anon yes, but the other ones? | [ ] I am able to disable merge/pull requests? Anon yes, but the other ones? |
| 330 | Add a new right to to it, by default, allow. | ||
| 264 | 331 | [ ] report1: add disk space | [ ] report1: add disk space |
| 265 | 332 | [ ] Compress logs (when we are short in disk space)? | [ ] Compress logs (when we are short in disk space)? |
| 266 | [ ] Check other filesystems: nils2 etc for virtual machine. | ||
| 267 | 333 | [ ] Add right 'allow bad commit messages'. | [ ] Add right 'allow bad commit messages'. |
| 268 | 334 | [ ] Add a new section in 'Rights' to enforce a regex on the commit message. | [ ] Add a new section in 'Rights' to enforce a regex on the commit message. |
| 269 | 335 | [ ] Merge requests are not ok - still using files. | [ ] Merge requests are not ok - still using files. |
| 270 | 336 | But, we also insert entries in database! | But, we also insert entries in database! |
| 271 | [ ] Need to add comments for merge request. Find a way to propagate them in the | ||
| 272 | git repo? | ||
| 273 | 337 | [ ] Implement 'clone' because is easy. The mrs will be a little bit harder. | [ ] Implement 'clone' because is easy. The mrs will be a little bit harder. |
| 274 | [ ] Because I show the merge request id, somebody can change the commits. | ||
| 275 | Somehow, it should be locked? | ||
| 276 | 338 | [ ] Maybe we should not allow bug creation as anonymous? | [ ] Maybe we should not allow bug creation as anonymous? |
| 277 | 339 | How do the anonymous person will edit it? A cookie? | How do the anonymous person will edit it? A cookie? |
| 278 | 340 | [ ] When a user push something, give them some statistics after. | [ ] When a user push something, give them some statistics after. |
| ... | ... | But, we have a problem with the expiration time! | |
| 742 | 804 | login page with (at least) username pre-filled? Or ask only about "lock ip"? | login page with (at least) username pre-filled? Or ask only about "lock ip"? |
| 743 | 805 | [ ] sess: just mark it as invalid and store it in cache to not connect to | [ ] sess: just mark it as invalid and store it in cache to not connect to |
| 744 | 806 | database? Cron will clean them up. | database? Cron will clean them up. |
| 745 | [ ] Transaction for bugs_max should be shorter. Now is very long. Hm. | ||
| 746 | 807 | [ ] Protect sh scripts to be run as RocketGit user and not other. | [ ] Protect sh scripts to be run as RocketGit user and not other. |
| 747 | 808 | [ ] To not have too many keys in authorized_keys, investigate certificates. | [ ] To not have too many keys in authorized_keys, investigate certificates. |
| 748 | 809 | [ ] Add cache in: | [ ] Add cache in: |
| ... | ... | them after processing is done. | |
| 1058 | 1119 | [ ] Limit number of simultaneously connection per repo and per user. | [ ] Limit number of simultaneously connection per repo and per user. |
| 1059 | 1120 | Maybe also the time! | Maybe also the time! |
| 1060 | 1121 | [ ] Allow multiple virtual hosts, with different configurations. | [ ] Allow multiple virtual hosts, with different configurations. |
| 1061 | [ ] session_time should be set at login time? And/or default s_t should be set from database? | ||
| 1122 | [ ] Config file must be able to be set from a env var, to be able to run | ||
| 1123 | multiple instances of rocketgit on the same server. | ||
| 1124 | [ ] session_time should be set at login time? And/or default s_t should be set | ||
| 1125 | from database? | ||
| 1062 | 1126 | [ ] Do not let user upload an already uploaded key. | [ ] Do not let user upload an already uploaded key. |
| 1063 | 1127 | [ ] Do not permit more than X auth attempts per second. | [ ] Do not permit more than X auth attempts per second. |
| 1064 | 1128 | [ ] See prepare-commit-msg.sample - we can auto add a line to every commit. | [ ] See prepare-commit-msg.sample - we can auto add a line to every commit. |
| 1065 | [ ] Check http://plathrop.tertiusfamily.net/blog/2010/05/11/git-hooks-branch-acls-and-more/ to block updates that have not pull - a la SVN | ||
| 1066 | [ ] Maybe we should mark the repository as dirty, only in the post-receive hook? Or update is the best place? | ||
| 1129 | [ ] Check http://plathrop.tertiusfamily.net/blog/2010/05/11/git-hooks-branch-acls-and-more/ | ||
| 1130 | to block updates that have not pull - a la SVN | ||
| 1131 | [ ] Maybe we should mark the repository as dirty, only in the post-receive | ||
| 1132 | hook? Or update is the best place? | ||
| 1067 | 1133 | [ ] Limit number of commits per push. | [ ] Limit number of commits per push. |
| 1068 | 1134 | [ ] RSS | [ ] RSS |
| 1069 | [ ] Config file must be able to be set from a env var, to be able to run | ||
| 1070 | multiple instances of rocketgit on the same server. | ||
| 1071 | 1135 | [ ] Smart HTTP transport | [ ] Smart HTTP transport |
| 1072 | 1136 | [ ] Move forget pass token into users table. | [ ] Move forget pass token into users table. |
| 1073 | 1137 | [ ] Audit all error messages to not propagate useful info to an attacker. | [ ] Audit all error messages to not propagate useful info to an attacker. |
| File TODO.vm added (mode: 100644) (index 0000000..873fa3e) | |||
| 1 | [ ] Check other filesystems: nils2 etc for virtual machine. | ||
| 2 | [ ] VM: Test if IPv4/IPv6 address is shown at login time. | ||
| 3 | [ ] Use guestmount when building VM images? | ||
| 4 | [ ] Add sha1sum of the VM images | ||
| 5 | [ ] Sign vm images. | ||
| File hooks/pre-receive changed (mode: 100755) (index b6830c8..5b6c7d5) | |||
| 3 | 3 | ||
| 4 | 4 | // | // |
| 5 | 5 | // pre-receive hook | // pre-receive hook |
| 6 | // Does nothing in this moment | ||
| 6 | // Only logs ip and user | ||
| 7 | 7 | // | // |
| 8 | 8 | ||
| 9 | exit(0); | ||
| 10 | |||
| 11 | 9 | error_reporting(E_ALL); | error_reporting(E_ALL); |
| 12 | 10 | ini_set("track_errors", "On"); | ini_set("track_errors", "On"); |
| 13 | 11 | ||
| ... | ... | require_once($INC . "/repo.inc.php"); | |
| 27 | 25 | ||
| 28 | 26 | rg_log_set_file($rg_log_dir . "/hook_pre-receive.log"); | rg_log_set_file($rg_log_dir . "/hook_pre-receive.log"); |
| 29 | 27 | ||
| 30 | $repo_path = getenv("ROCKETGIT_REPO_PATH"); | ||
| 31 | $login_uid = etenv("ROCKETGIT_LOGIN_UID"); | ||
| 28 | $repo_path = getenv('ROCKETGIT_REPO_PATH'); | ||
| 29 | $login_uid = getenv('ROCKETGIT_LOGIN_UID'); | ||
| 30 | $ip = getenv('ROCKETGIT_IP'); | ||
| 31 | $git_host = getenv('ROCKETGIT_HOST'); | ||
| 32 | $info_show = getenv('ROCKETGIT_INFO_SHOW'); | ||
| 32 | 33 | ||
| 33 | 34 | rg_log("Start"); | rg_log("Start"); |
| 34 | 35 | rg_log("_SERVER: " . rg_array2string($_SERVER)); | rg_log("_SERVER: " . rg_array2string($_SERVER)); |
| ... | ... | rg_log("_SERVER: " . rg_array2string($_SERVER)); | |
| 36 | 37 | umask(0022); | umask(0022); |
| 37 | 38 | ||
| 38 | 39 | ||
| 40 | if ($info_show == 0) { | ||
| 41 | rg_git_info('== Welcome to RocketGit! =='); | ||
| 42 | rg_git_info('you are connecting from IP ' . $ip . '.'); | ||
| 43 | } | ||
| 44 | |||
| 45 | // If user does not correct to the correct URL, correct them | ||
| 46 | if (!empty($git_host) && (strcasecmp($git_host, $rg_git_host) != 0)) | ||
| 47 | rg_git_info('Please use ' . $rg_git_host | ||
| 48 | . ' instead of ' . $git_host . '.'); | ||
| 49 | |||
| 50 | exit(0); | ||
| 51 | |||
| 39 | 52 | $f = @fopen("php://stdin", "r"); | $f = @fopen("php://stdin", "r"); |
| 40 | 53 | if ($f === FALSE) { | if ($f === FALSE) { |
| 41 | 54 | rg_log("Error: Cannot open stdin!"); | rg_log("Error: Cannot open stdin!"); |
| ... | ... | fclose($f); | |
| 64 | 77 | $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); | $diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); |
| 65 | 78 | rg_log("Took " . $diff . "ms."); | rg_log("Took " . $diff . "ms."); |
| 66 | 79 | ||
| 67 | /*TODO: replace with event | ||
| 68 | @file_put_contents($repo_path . "/rocketgit/hook-pre-receive", | ||
| 69 | "repo: " . $repo . " ($repo_path)" | ||
| 70 | . "\nat: " . sprintf("%u", $_start) | ||
| 71 | . "\nuid: " . $login_uid | ||
| 72 | . "\npara: $refname $old_rev $new_rev" | ||
| 73 | . "\nTook: " . $diff . "ms" | ||
| 74 | . "\n_SERVER: " . rg_array2string($_SERVER)); | ||
| 75 | */ | ||
| 76 | |||
| 77 | 80 | ?> | ?> |
| File inc/bug.inc.php changed (mode: 100644) (index f77b6e2..057fc14) | |||
| ... | ... | function rg_bug_next_id($db, $repo_id) | |
| 256 | 256 | $row = rg_sql_fetch_array($res); | $row = rg_sql_fetch_array($res); |
| 257 | 257 | $next_bug_id = $row['next_bug_id']; | $next_bug_id = $row['next_bug_id']; |
| 258 | 258 | rg_sql_free_result($res); | rg_sql_free_result($res); |
| 259 | |||
| 260 | $key = 'repo_by_id' . '::' . $repo_id . '::' . 'last_bug_id'; | ||
| 261 | rg_cache_set($key, $next_bug_id, RG_SOCKET_NO_WAIT); | ||
| 259 | 262 | break; | break; |
| 260 | 263 | } | } |
| 261 | 264 | ||
| File inc/git.inc.php changed (mode: 100644) (index 1708276..7746371) | |||
| ... | ... | function rg_git_error() | |
| 23 | 23 | ||
| 24 | 24 | function rg_git_fatal($msg) | function rg_git_fatal($msg) |
| 25 | 25 | { | { |
| 26 | echo "==========\n"; | ||
| 27 | 26 | $x = explode("\n", trim($msg)); | $x = explode("\n", trim($msg)); |
| 28 | 27 | foreach ($x as $line) { | foreach ($x as $line) { |
| 29 | 28 | rg_log("FATAL: $line"); | rg_log("FATAL: $line"); |
| 30 | echo "RocketGit: $line\n"; | ||
| 29 | echo "RocketGit: Error: $line\n"; | ||
| 31 | 30 | } | } |
| 32 | echo "==========\n"; | ||
| 33 | 31 | flush(); | flush(); |
| 34 | 32 | exit(1); | exit(1); |
| 35 | 33 | } | } |
| 36 | 34 | ||
| 37 | 35 | function rg_git_info($msg) | function rg_git_info($msg) |
| 38 | 36 | { | { |
| 39 | echo "==========\n"; | ||
| 40 | 37 | $x = explode("\n", trim($msg)); | $x = explode("\n", trim($msg)); |
| 41 | 38 | foreach ($x as $line) { | foreach ($x as $line) { |
| 42 | 39 | rg_log("INFO: $line"); | rg_log("INFO: $line"); |
| 43 | echo "RocketGit: $line\n"; | ||
| 40 | echo "RocketGit: Info: $line\n"; | ||
| 44 | 41 | } | } |
| 45 | echo "==========\n"; | ||
| 46 | 42 | } | } |
| 47 | 43 | ||
| 48 | 44 | /* | /* |
| ... | ... | function rg_git_update_branch($db, $a) | |
| 1335 | 1331 | rg_git_fatal($a['refname'] . ": " . rg_mr_error()); | rg_git_fatal($a['refname'] . ": " . rg_mr_error()); |
| 1336 | 1332 | $_x = array(); | $_x = array(); |
| 1337 | 1333 | $msg = rg_template("msg/push_merge_request.txt", $_x, FALSE /*xss*/); | $msg = rg_template("msg/push_merge_request.txt", $_x, FALSE /*xss*/); |
| 1338 | rg_git_info($a['refname'] . "\n" . $msg); | ||
| 1334 | rg_git_info($a['refname'] . ':' . "\n" . $msg); | ||
| 1339 | 1335 | ||
| 1340 | 1336 | $history['history_category'] = REPO_CAT_GIT_BRANCH_ANON_PUSH; | $history['history_category'] = REPO_CAT_GIT_BRANCH_ANON_PUSH; |
| 1341 | 1337 | $history['history_message'] = 'Anonymous push to ref ' | $history['history_message'] = 'Anonymous push to ref ' |
| File inc/mr.inc.php changed (mode: 100644) (index 3032737..85d0fe0) | |||
| ... | ... | function rg_mr_condiment(&$row) | |
| 177 | 177 | ||
| 178 | 178 | /* | /* |
| 179 | 179 | * Loads merge requests | * Loads merge requests |
| 180 | * @limit = 0 => no limit | ||
| 180 | 181 | */ | */ |
| 181 | 182 | function rg_mr_load($db, $repo_id, $limit) | function rg_mr_load($db, $repo_id, $limit) |
| 182 | 183 | { | { |
| ... | ... | function rg_mr_load($db, $repo_id, $limit) | |
| 186 | 187 | $sql = "SELECT * FROM merge_requests" | $sql = "SELECT * FROM merge_requests" |
| 187 | 188 | . " WHERE repo_id = @@repo_id@@" | . " WHERE repo_id = @@repo_id@@" |
| 188 | 189 | . " AND done = 0" | . " AND done = 0" |
| 189 | . " ORDER BY itime" | ||
| 190 | . " LIMIT " . $limit; | ||
| 190 | . " ORDER BY itime"; | ||
| 191 | if ($limit > 0) | ||
| 192 | $sql .= " LIMIT " . $limit; | ||
| 191 | 193 | $res = rg_sql_query_params($db, $sql, $params); | $res = rg_sql_query_params($db, $sql, $params); |
| 192 | 194 | if ($res === FALSE) { | if ($res === FALSE) { |
| 193 | 195 | rg_mr_set_error("Cannot load merge requests (" . rg_sql_error() . ")"); | rg_mr_set_error("Cannot load merge requests (" . rg_sql_error() . ")"); |
| File inc/repo.inc.php changed (mode: 100644) (index 747b083..c59a3ce) | |||
| ... | ... | function rg_repo_info($db, $repo_id, $uid, $repo_name) | |
| 693 | 693 | "repo_name" => $repo_name); | "repo_name" => $repo_name); |
| 694 | 694 | ||
| 695 | 695 | if ($repo_id > 0) { | if ($repo_id > 0) { |
| 696 | $c = rg_cache_get("repo_by_id::$repo_id"); | ||
| 696 | $c = rg_cache_get('repo_by_id' . '::' . $repo_id); | ||
| 697 | 697 | if ($c !== FALSE) { | if ($c !== FALSE) { |
| 698 | 698 | $ret = $c; | $ret = $c; |
| 699 | 699 | break; | break; |
| ... | ... | function rg_repo_info($db, $repo_id, $uid, $repo_name) | |
| 745 | 745 | } | } |
| 746 | 746 | //rg_log_ml("CHECK: ret=" . print_r($ret, TRUE)); | //rg_log_ml("CHECK: ret=" . print_r($ret, TRUE)); |
| 747 | 747 | ||
| 748 | rg_cache_set("repo_by_id::$repo_id", $ret, RG_SOCKET_NO_WAIT); | ||
| 748 | if ($ret['exists'] == 1) { | ||
| 749 | rg_cache_set('repo_by_id' . '::' . $ret['repo_id'], | ||
| 750 | $ret, RG_SOCKET_NO_WAIT); | ||
| 749 | 751 | ||
| 750 | if ($ret['exists'] == 1) | ||
| 751 | 752 | rg_cache_set("repo_by_name::$uid::" . $ret['name'], | rg_cache_set("repo_by_name::$uid::" . $ret['name'], |
| 752 | 753 | $ret['repo_id'], RG_SOCKET_NO_WAIT); | $ret['repo_id'], RG_SOCKET_NO_WAIT); |
| 754 | } | ||
| 753 | 755 | ||
| 754 | 756 | break; | break; |
| 755 | 757 | } | } |
| ... | ... | function rg_repo_edit($db, $login_ui, &$new) | |
| 947 | 949 | } | } |
| 948 | 950 | } else { | } else { |
| 949 | 951 | // Test if repo_id is valid | // Test if repo_id is valid |
| 952 | // TODO: also here we must test if we have a dup name! | ||
| 950 | 953 | $ri = rg_repo_info($db, $new['repo_id'], | $ri = rg_repo_info($db, $new['repo_id'], |
| 951 | 954 | $login_ui['uid'], ""); | $login_ui['uid'], ""); |
| 952 | 955 | if ($ri['ok'] != 1) | if ($ri['ok'] != 1) |
| ... | ... | function rg_repo_edit_high_level($db, &$rg) | |
| 1628 | 1631 | $rg['ri']['home'] = rg_re_repopage($rg['login_ui'], | $rg['ri']['home'] = rg_re_repopage($rg['login_ui'], |
| 1629 | 1632 | $rg['ri']['name']); | $rg['ri']['name']); |
| 1630 | 1633 | if ($edit) { | if ($edit) { |
| 1631 | $ret .= rg_template("repo/edit_ok.html", $rg, TRUE /* xss */); | ||
| 1634 | $ret .= rg_template("repo/edit_ok.html", $rg, TRUE /*xss*/); | ||
| 1632 | 1635 | } else { | } else { |
| 1633 | $ret .= rg_template("repo/create_ok.html", $rg, TRUE /* xss */); | ||
| 1636 | $ret .= rg_template("repo/create_ok.html", $rg, TRUE /*xss*/); | ||
| 1634 | 1637 | } | } |
| 1635 | 1638 | ||
| 1636 | 1639 | $load_form = FALSE; | $load_form = FALSE; |
| File inc/ssh.inc.php changed (mode: 100644) (index 25057e5..24f6295) | |||
| ... | ... | function rg_ssh_totp($db, $ip, $uid, $paras) | |
| 286 | 286 | rg_prof_end('ssh_totp'); | rg_prof_end('ssh_totp'); |
| 287 | 287 | } | } |
| 288 | 288 | ||
| 289 | /* | ||
| 290 | * Returns TRUE if we need to stop execution | ||
| 291 | */ | ||
| 289 | 292 | function rg_ssh_dispatch($db, $ip, $uid, $orig_cmd) | function rg_ssh_dispatch($db, $ip, $uid, $orig_cmd) |
| 290 | 293 | { | { |
| 291 | 294 | rg_log('ssh_dispatch orig_cmd=[' . $orig_cmd . ']'); | rg_log('ssh_dispatch orig_cmd=[' . $orig_cmd . ']'); |
| ... | ... | function rg_ssh_dispatch($db, $ip, $uid, $orig_cmd) | |
| 299 | 302 | case 'git-receive-pack': return; | case 'git-receive-pack': return; |
| 300 | 303 | } | } |
| 301 | 304 | ||
| 302 | echo "\n== Welcome to RocketGit! ==\n"; | ||
| 303 | |||
| 304 | $ui = rg_user_info($db, $uid, '', ''); | ||
| 305 | if ($ui['exists'] == 1) | ||
| 306 | echo 'You are connecting as user' | ||
| 307 | . ' \'' . $ui['username'] . '\'.' . "\n"; | ||
| 308 | |||
| 309 | echo 'You are connecting from IP ' . $ip . ".\n"; | ||
| 310 | |||
| 311 | 305 | // First, test if the IP is validated | // First, test if the IP is validated |
| 312 | 306 | switch ($cmd) { | switch ($cmd) { |
| 313 | 307 | case '': break; | case '': break; |
| ... | ... | function rg_ssh_dispatch($db, $ip, $uid, $orig_cmd) | |
| 317 | 311 | if (($r['ok'] == 0) | if (($r['ok'] == 0) |
| 318 | 312 | || (($r['enrolled'] == 1) && (empty($r['ip_list'])))) { | || (($r['enrolled'] == 1) && (empty($r['ip_list'])))) { |
| 319 | 313 | echo 'Error: ' . rg_totp_error() . ".\n"; | echo 'Error: ' . rg_totp_error() . ".\n"; |
| 320 | exit(0); | ||
| 314 | return TRUE; // = we must exit' | ||
| 321 | 315 | } | } |
| 322 | 316 | break; | break; |
| 323 | 317 | } | } |
| 324 | 318 | ||
| 325 | 319 | // Now, we can safely execute the command | // Now, we can safely execute the command |
| 326 | 320 | switch ($cmd) { | switch ($cmd) { |
| 327 | case 'status': rg_ssh_status($db, $uid); | ||
| 328 | case 'repos': rg_ssh_repos($db, $uid); exit(0); | ||
| 329 | case 'repo': rg_ssh_repo($db, $uid, $paras); exit(0); | ||
| 330 | case 'totp': rg_ssh_totp($db, $ip, $uid, $paras); exit(0); | ||
| 321 | case 'status': rg_ssh_status($db, $uid); return TRUE; | ||
| 322 | case 'repos': rg_ssh_repos($db, $uid); return TRUE; | ||
| 323 | case 'repo': rg_ssh_repo($db, $uid, $paras); return TRUE; | ||
| 324 | case 'totp': rg_ssh_totp($db, $ip, $uid, $paras); return TRUE; | ||
| 331 | 325 | case '': | case '': |
| 332 | 326 | echo "Available commmands:\n" | echo "Available commmands:\n" |
| 333 | 327 | . " status - show some status about the user\n" | . " status - show some status about the user\n" |
| 334 | 328 | . " repos - list repos and information about them\n" | . " repos - list repos and information about them\n" |
| 335 | 329 | . " repo - list info about a repo\n" | . " repo - list info about a repo\n" |
| 336 | 330 | . " totp - two-factor authentication commands\n"; | . " totp - two-factor authentication commands\n"; |
| 337 | exit(0); | ||
| 331 | return TRUE; | ||
| 338 | 332 | } | } |
| 339 | 333 | ||
| 340 | // Do not exit(0) from this function because a fetch or push will be | ||
| 341 | // executed after this function's exit. | ||
| 334 | return FALSE; // = continue execution | ||
| 342 | 335 | } | } |
| 343 | 336 | ||
| 344 | 337 | ?> | ?> |
| File inc/user.inc.php changed (mode: 100644) (index 11fea9c..e927c4c) | |||
| ... | ... | function rg_user_edit($db, $d) | |
| 514 | 514 | $row = rg_sql_fetch_array($res); | $row = rg_sql_fetch_array($res); |
| 515 | 515 | rg_sql_free_result($res); | rg_sql_free_result($res); |
| 516 | 516 | ||
| 517 | // More stuff to be cached | ||
| 518 | $d['email_md5'] = md5(strtolower(trim($d['email']))); | ||
| 519 | |||
| 517 | 520 | if ($d['uid'] == 0) { // add | if ($d['uid'] == 0) { // add |
| 518 | 521 | rg_cache_set('user' . '::' . $d['uid'] . '::' . ':info', | rg_cache_set('user' . '::' . $d['uid'] . '::' . ':info', |
| 519 | 522 | $d, RG_SOCKET_NO_WAIT); | $d, RG_SOCKET_NO_WAIT); |
| ... | ... | function rg_user_info($db, $uid, $user, $email) | |
| 674 | 677 | $ret = array_merge($ret, $row); | $ret = array_merge($ret, $row); |
| 675 | 678 | ||
| 676 | 679 | $ret['homepage'] = rg_re_userpage($ret); | $ret['homepage'] = rg_re_userpage($ret); |
| 680 | $ret['email_md5'] = md5(strtolower(trim($ret['email']))); | ||
| 677 | 681 | ||
| 678 | 682 | rg_cache_set('user' . '::' . $ret['uid'] . '::' . 'info', | rg_cache_set('user' . '::' . $ret['uid'] . '::' . 'info', |
| 679 | 683 | $ret, RG_SOCKET_NO_WAIT); | $ret, RG_SOCKET_NO_WAIT); |
| File inc/user/repo-page.php changed (mode: 100644) (index 721b20c..f983453) | |||
| ... | ... | if (strcmp($_subop, "history") == 0) { | |
| 240 | 240 | $_repo_body .= rg_repo_stats($rg); | $_repo_body .= rg_repo_stats($rg); |
| 241 | 241 | } else if (strcmp($_subop, "mr") == 0) { | } else if (strcmp($_subop, "mr") == 0) { |
| 242 | 242 | if ($rg['ri']['git_dir_done'] == 0) { | if ($rg['ri']['git_dir_done'] == 0) { |
| 243 | $_repo_body .= rg_template("repo/no_git_dir.html", $rg, TRUE /* xss */); | ||
| 243 | $_repo_body .= rg_template("repo/no_git_dir.html", | ||
| 244 | $rg, TRUE /*xss*/); | ||
| 244 | 245 | } else { | } else { |
| 245 | $_repo_body .= rg_template("repo/mrs.html", $rg, TRUE /* xss */); | ||
| 246 | $_repo_body .= rg_template("repo/mrs.html", $rg, TRUE /*xss*/); | ||
| 246 | 247 | ||
| 247 | $r = rg_mr_load($db, $rg['ri']['repo_id'], 20); | ||
| 248 | $r = rg_mr_load($db, $rg['ri']['repo_id'], 0 /*no limit*/); | ||
| 248 | 249 | if ($r === FALSE) { | if ($r === FALSE) { |
| 249 | 250 | $_repo_body .= "Error getting merge request list (" | $_repo_body .= "Error getting merge request list (" |
| 250 | 251 | . rg_mr_error() . ")."; | . rg_mr_error() . ")."; |
| 251 | 252 | } else { | } else { |
| 252 | $_repo_body .= rg_template_table("repo/mr/list", $r, $rg); | ||
| 253 | $_repo_body .= rg_template_table("repo/mr/list", | ||
| 254 | $r, $rg); | ||
| 253 | 255 | } | } |
| 254 | 256 | ||
| 255 | 257 | while (1) { | while (1) { |
| 256 | 258 | if (empty($paras)) | if (empty($paras)) |
| 257 | 259 | break; | break; |
| 258 | 260 | ||
| 259 | $mr = preg_replace('/[^0-9a-zA-Z_]/', '', array_shift($paras)); | ||
| 261 | $mr = preg_replace('/[^0-9a-zA-Z_]/', '', | ||
| 262 | array_shift($paras)); | ||
| 260 | 263 | $rg['mr'] = $mr; | $rg['mr'] = $mr; |
| 261 | 264 | $mri = rg_mr_load_one($db, $rg['ri']['repo_id'], $mr); | $mri = rg_mr_load_one($db, $rg['ri']['repo_id'], $mr); |
| 262 | 265 | if ($mri === FALSE) { | if ($mri === FALSE) { |
| 263 | $_repo_body .= "Error getting merge request (" . rg_mr_error() . ")."; | ||
| 266 | $_repo_body .= "Error getting merge request" | ||
| 267 | . " (" . rg_mr_error() . ")."; | ||
| 264 | 268 | break; | break; |
| 265 | 269 | } | } |
| 266 | 270 | ||
| ... | ... | if (strcmp($_subop, "history") == 0) { | |
| 272 | 276 | } | } |
| 273 | 277 | ||
| 274 | 278 | $mri['HTML:diff'] = rg_git_log2listing($_log, $rg, TRUE); | $mri['HTML:diff'] = rg_git_log2listing($_log, $rg, TRUE); |
| 275 | $_repo_body .= rg_template("repo/mr/page.html", $mri, TRUE /* xss */); | ||
| 276 | |||
| 279 | $_repo_body .= rg_template("repo/mr/page.html", $mri, | ||
| 280 | TRUE /*xss*/); | ||
| 277 | 281 | break; | break; |
| 278 | 282 | } | } |
| 283 | |||
| 284 | $hints = array(); | ||
| 285 | $hints[]['HTML:hint'] = rg_template("hints/repo/merge.html", | ||
| 286 | $rg, TRUE /*xss*/); | ||
| 287 | $rg['HTML:hints'] = rg_template_table("hints/list", | ||
| 288 | $hints, $rg); | ||
| 279 | 289 | } | } |
| 280 | 290 | } | } |
| 281 | 291 | ||
| File root/index.php changed (mode: 100644) (index 87616a5..d29d3b0) | |||
| ... | ... | if (strcmp($proto, 'HTTP/1.1') == 0) { | |
| 170 | 170 | $client_have = ''; | $client_have = ''; |
| 171 | 171 | ||
| 172 | 172 | if (strcmp($client_have, $we_have) == 0) { | if (strcmp($client_have, $we_have) == 0) { |
| 173 | rg_log('CACHE: Client has the right version'); | ||
| 173 | rg_log('CACHE: Client has the latest version; no need to resend'); | ||
| 174 | 174 | header('HTTP/1.1 304 Not modified'); | header('HTTP/1.1 304 Not modified'); |
| 175 | 175 | } else { | } else { |
| 176 | 176 | header('ETag: ' . $we_have); | header('ETag: ' . $we_have); |
| File root/themes/default/hints/repo/anon_push.html changed (mode: 100644) (index 3c54e1f..ea83b2c) | |||
| 1 | 1 | You are allowed to anonymously push to this repository.<br /> | You are allowed to anonymously push to this repository.<br /> |
| 2 | 2 | This means that your pushed commits will automatically be transformed into a | This means that your pushed commits will automatically be transformed into a |
| 3 | merge request:<br /> | ||
| 3 | pull request:<br /> | ||
| 4 | 4 | <div class="xcode"> | <div class="xcode"> |
| 5 | 5 | ... clone the repository ...<br /> | ... clone the repository ...<br /> |
| 6 | 6 | ... make some changes and some commits ...<br /> | ... make some changes and some commits ...<br /> |
| File root/themes/default/hints/repo/clone_owner.html changed (mode: 100644) (index cb34d16..1f91434) | |||
| ... | ... | git push origin --tags<br /> | |
| 20 | 20 | ||
| 21 | 21 | If you do not have the project locally, and want to clone it:<br /> | If you do not have the project locally, and want to clone it:<br /> |
| 22 | 22 | <div class="xcode"> | <div class="xcode"> |
| 23 | mkdir local_project_dir<br /> | ||
| 24 | 23 | git clone @@ssh@@ local_project_dir<br /> | git clone @@ssh@@ local_project_dir<br /> |
| 25 | 24 | cd local_project_dir | cd local_project_dir |
| 26 | 25 | </div> | </div> |
| File root/themes/default/hints/repo/edit_repo_refs_rights.html changed (mode: 100644) (index 3e5f9d2..0f5e0f3) | |||
| ... | ... | User=[user1] Reference=[release-.*] Rights=[Non fast-forward] - means that | |
| 14 | 14 | that starts with 'release-', for example 'release-1.0'.<br /> | that starts with 'release-', for example 'release-1.0'.<br /> |
| 15 | 15 | User=[*] Reference=[] Rights=[Anonymous push] Priority=[10] - means that any | User=[*] Reference=[] Rights=[Anonymous push] Priority=[10] - means that any |
| 16 | 16 | user can anonymously push changes that will be automatically | user can anonymously push changes that will be automatically |
| 17 | transformed in a merge request. We recommend to activate it because | ||
| 17 | transformed in a pull request. We recommend to activate it because | ||
| 18 | 18 | it will allow easy contributions to your project.<br /> | it will allow easy contributions to your project.<br /> |
| 19 | 19 | User=[*] Reference=[users/@USER@/] Rights=[Push] Priority=[10] | User=[*] Reference=[users/@USER@/] Rights=[Push] Priority=[10] |
| 20 | 20 | - means that any user can push to his private ref | - means that any user can push to his private ref |
| File root/themes/default/hints/repo/merge.html changed (mode: 100644) (index 4a5d9fa..131d1fb) | |||
| 1 | How to merge?<br /> | ||
| 1 | How to merge on your machine?<br /> | ||
| 2 | 2 | ||
| 3 | 3 | <div class="xcode"> | <div class="xcode"> |
| 4 | git fetch @@url@@ refs/mr/rg_xxxxxxxx<br /> | ||
| 5 | git merge ???<br /> | ||
| 4 | git fetch origin refs/mr/rg_xxxxxxxx:local_branch<br /> | ||
| 5 | git checkout master<br /> | ||
| 6 | git merge local_branch<br /> | ||
| 6 | 7 | </div> | </div> |
| 7 | 8 | <br /> | <br /> |
| 8 | 9 | ||
| 9 | How to "see" all merge requests as branches:<br /> | ||
| 10 | Add, in config file, under the remote you want, a line like this:<br /> | ||
| 10 | How to "see" all pull requests as branches:<br /> | ||
| 11 | Add, in config file (.git/config), under the remote you want, a line like this:<br /> | ||
| 11 | 12 | <div class="xcode"> | <div class="xcode"> |
| 12 | fetch = +refs/namespaces/*:refs/remotes/your_remote_name_for_example_origin/mr/*<br /> | ||
| 13 | fetch = +refs/pr/*:refs/remotes/your_remote_name_for_example_origin/mr/*<br /> | ||
| 14 | </div> | ||
| 15 | After you run a git fetch, you will have all the pull requests locally.<br /> | ||
| 16 | For example, you can merge one of them:<br /> | ||
| 17 | <div class="xcode"> | ||
| 18 | git checkout master<br /> | ||
| 19 | git merge pr/xxxxxxxx | ||
| 13 | 20 | </div> | </div> |
| 14 | After you run a git fetch, you will have all the merge requests locally.<br /> | ||
| 15 | You can do ??? (TODO) | ||
| File root/themes/default/index.html changed (mode: 100644) (index 472dbd5..4c41a42) | |||
| 66 | 66 | Running since: @@first_install_text@@<br /> | Running since: @@first_install_text@@<br /> |
| 67 | 67 | <i>Git was created by Linus Torvalds.</i><br /> | <i>Git was created by Linus Torvalds.</i><br /> |
| 68 | 68 | rocketgit.com site is operated by Embedromix SRL,<br /> | rocketgit.com site is operated by Embedromix SRL,<br /> |
| 69 | RO13505234, J08/979/2000, Brasov, Romania. | ||
| 69 | RO13505234, J08/979/2000, Brasov, Romania.<br /> | ||
| 70 | All data is stored in Germany. | ||
| 70 | 71 | </div> | </div> |
| 71 | 72 | </div> | </div> |
| 72 | 73 | </div> <!-- footer --> | </div> <!-- footer --> |
| File root/themes/default/main.css changed (mode: 100644) (index 945fcc5..6134ee0) | |||
| ... | ... | a { | |
| 38 | 38 | ||
| 39 | 39 | .xcode { | .xcode { |
| 40 | 40 | margin-left: 5px; | margin-left: 5px; |
| 41 | border-left: 1px solid #000; | ||
| 42 | font-size: 11pt; | ||
| 41 | border-left: 4px solid #F00; | ||
| 42 | font-size: 10pt; | ||
| 43 | 43 | padding-left: 5px; | padding-left: 5px; |
| 44 | font-family: monospace; | ||
| 44 | 45 | } | } |
| 45 | 46 | ||
| 46 | 47 | form { margin-top: 5pt } | form { margin-top: 5pt } |
| File root/themes/default/msg/push_merge_request.txt changed (mode: 100644) (index dfa2937..f98a19d) | |||
| 1 | 1 | Because you do not have 'push' rights, your push was | Because you do not have 'push' rights, your push was |
| 2 | transformed into a merge request and awaits approval. | ||
| 2 | transformed into a pull request and awaits approval. | ||
| File root/themes/default/repo/add_edit.html changed (mode: 100644) (index 2564a21..dee1818) | |||
| 4 | 4 | ||
| 5 | 5 | @@errmsg@@ | @@errmsg@@ |
| 6 | 6 | ||
| 7 | <form method="post" action="@@form_url@@/@@if(@@ri::repo_id@@ == 0){{create}}{{edit}}"> | ||
| 7 | <form method="post" action="@@form_url@@"> | ||
| 8 | 8 | <input type="hidden" name="repo_id" value="@@ri::repo_id@@" /> | <input type="hidden" name="repo_id" value="@@ri::repo_id@@" /> |
| 9 | 9 | <input type="hidden" name="master" value="@@ri::master@@" /> | <input type="hidden" name="master" value="@@ri::master@@" /> |
| 10 | 10 | <input type="hidden" name="doit" value="1" /> | <input type="hidden" name="doit" value="1" /> |
| File root/themes/default/repo/main.html changed (mode: 100644) (index 28ba8f2..8fdcfdb) | |||
| 18 | 18 | <ul> | <ul> |
| 19 | 19 | <li@@if(@@per_repo_menu::history@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/history">Last events</a></li> | <li@@if(@@per_repo_menu::history@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/history">Last events</a></li> |
| 20 | 20 | <li@@if(@@per_repo_menu::source@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/source">Source</a></li> | <li@@if(@@per_repo_menu::source@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/source">Source</a></li> |
| 21 | <li@@if(@@per_repo_menu::mr@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/mr">Merge requests</a></li> | ||
| 21 | <li@@if(@@per_repo_menu::mr@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/mr">Pull requests</a></li> | ||
| 22 | 22 | <li@@if(@@per_repo_menu::bug@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/bug">Bugs</a></li> | <li@@if(@@per_repo_menu::bug@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/bug">Bugs</a></li> |
| 23 | 23 | <li@@if(@@per_repo_menu::stats@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/stats">Stats</a></li> | <li@@if(@@per_repo_menu::stats@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/stats">Stats</a></li> |
| 24 | 24 | @@if(@@can_admin@@ == 1){{<li@@if(@@per_repo_menu::admin@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/admin">Admin</a></li>}}{{}} | @@if(@@can_admin@@ == 1){{<li@@if(@@per_repo_menu::admin@@ == 1){{ class="selected"}}{{}}><a href="@@url_repo@@/admin">Admin</a></li>}}{{}} |
| File root/themes/default/repo/mr/list/nodata.html changed (mode: 100644) (index e76821a..7c6476e) | |||
| 1 | 1 | <div class="mess ok"> | <div class="mess ok"> |
| 2 | No merge requests found. | ||
| 2 | No pull requests found. | ||
| 3 | 3 | </div> | </div> |
| File root/themes/default/repo/mr/page.html changed (mode: 100644) (index d704360..b4b543f) | |||
| 1 | 1 | <br /> | <br /> |
| 2 | <b>Merge request @@namespace@@</b> (@@old_rev_short@@ -> @@new_rev_short@@)<br /> | ||
| 2 | <b>Pull request @@namespace@@</b> (@@old_rev_short@@ -> @@new_rev_short@@)<br /> | ||
| 3 | 3 | <b>Ref</b>: @@refname@@<br /> | <b>Ref</b>: @@refname@@<br /> |
| 4 | 4 | <b>Date</b>: @@date_utc@@<br /> | <b>Date</b>: @@date_utc@@<br /> |
| 5 | 5 | @@if(@@can_admin@@ == 1){{<b>IP</b>: @@ip@@<br />}}{{}} | @@if(@@can_admin@@ == 1){{<b>IP</b>: @@ip@@<br />}}{{}} |
| File root/themes/default/user/home.html changed (mode: 100644) (index e6fd4ab..084d7c5) | |||
| 1 | 1 | <div class="main_title"> | <div class="main_title"> |
| 2 | <img src="https://www.gravatar.com/avatar/@@page_ui::email_md5@@?s=64&r=g" width="64" height="64" /> | ||
| 2 | 3 | Home page of user @@page_ui::username@@ (#@@page_ui::uid@@) | Home page of user @@page_ui::username@@ (#@@page_ui::uid@@) |
| 3 | 4 | </div> | </div> |
| File scripts/remote.php changed (mode: 100644) (index 698b48a..bb6bf26) | |||
| ... | ... | rg_log_set_file($rg_log_dir . "/remote.log"); | |
| 26 | 26 | function info($str) | function info($str) |
| 27 | 27 | { | { |
| 28 | 28 | rg_log("Sending: " . $str); | rg_log("Sending: " . $str); |
| 29 | $str2 = "RocketGit: " . $str . "\n"; | ||
| 29 | $str2 = "RocketGit: Info: " . $str . "\n"; | ||
| 30 | 30 | if (isset($_SERVER['SSH_CONNECTION'])) { | if (isset($_SERVER['SSH_CONNECTION'])) { |
| 31 | 31 | // ssh | // ssh |
| 32 | 32 | fwrite(STDERR, $str2); | fwrite(STDERR, $str2); |
| 33 | 33 | } else { | } else { |
| 34 | // git - seems is not working as ssh | ||
| 35 | $str2 = "\n" . $str2; | ||
| 36 | $len = 4 + strlen($str2); | ||
| 37 | echo sprintf("%04x", $len) . $str2; | ||
| 34 | // Keep in mind we did not negotiated yet the side-band feat. | ||
| 35 | // So, seems we cannot send nice messages to the user. | ||
| 38 | 36 | } | } |
| 39 | 37 | } | } |
| 40 | 38 | ||
| 41 | 39 | function fatal($str) | function fatal($str) |
| 42 | 40 | { | { |
| 43 | info("Error: $str"); | ||
| 41 | rg_log("Sending: " . $str); | ||
| 42 | $str2 = "RocketGit: Error: " . $str . "\n"; | ||
| 43 | if (isset($_SERVER['SSH_CONNECTION'])) { | ||
| 44 | // ssh | ||
| 45 | fwrite(STDERR, $str2); | ||
| 46 | } else { | ||
| 47 | echo "\n" . $str2; | ||
| 48 | } | ||
| 44 | 49 | exit(1); | exit(1); |
| 45 | 50 | } | } |
| 46 | 51 | ||
| ... | ... | if (isset($_SERVER['SSH_CONNECTION'])) { | |
| 90 | 95 | $_t = explode(" ", $ssh_client); | $_t = explode(" ", $ssh_client); |
| 91 | 96 | $ip = $_t[0]; | $ip = $_t[0]; |
| 92 | 97 | ||
| 93 | rg_ssh_dispatch($db, $ip, $login_uid, $cmd_repo); | ||
| 98 | info('== Welcome to RocketGit! =='); | ||
| 99 | info('you are connecting from IP ' . $ip . '.'); | ||
| 100 | |||
| 101 | $conn_ui = rg_user_info($db, $login_uid, '', ''); | ||
| 102 | if ($conn_ui['exists'] != 1) | ||
| 103 | fatal("User does not exists (conn)."); | ||
| 104 | info('you are connecting as user \'' . $conn_ui['username'] . '\'.'); | ||
| 105 | |||
| 106 | putenv('ROCKETGIT_INFO_SHOW=1'); | ||
| 94 | 107 | ||
| 108 | $must_exit = rg_ssh_dispatch($db, $ip, $login_uid, $cmd_repo); | ||
| 109 | |||
| 110 | // We do this operation after dispatch to not impact the latency. | ||
| 95 | 111 | // TODO: This should be put in a queue for performance reasons | // TODO: This should be put in a queue for performance reasons |
| 96 | // At the same time, update stats? | ||
| 112 | // At the same time, update stats? events? | ||
| 97 | 113 | $_r = rg_keys_update_use($db, $key_id, $ip); | $_r = rg_keys_update_use($db, $key_id, $ip); |
| 98 | 114 | if ($_r !== TRUE) | if ($_r !== TRUE) |
| 99 | 115 | rg_internal_error("Cannot update key last_use!"); | rg_internal_error("Cannot update key last_use!"); |
| 116 | |||
| 117 | if ($must_exit) { | ||
| 118 | rg_prof_end("remote.php"); | ||
| 119 | rg_prof_log(); | ||
| 120 | exit(0); | ||
| 121 | } | ||
| 100 | 122 | } else { | } else { |
| 101 | 123 | rg_log("git-daemon connection..."); | rg_log("git-daemon connection..."); |
| 102 | 124 | ||
| 103 | 125 | // we have no client info | // we have no client info |
| 104 | 126 | $login_uid = 0; | $login_uid = 0; |
| 105 | 127 | $key_id = 0; | $key_id = 0; |
| 128 | $conn_ui = array('uid' => 0, 'username' => ''); | ||
| 106 | 129 | ||
| 107 | 130 | $line = @fread(STDIN, 8000); | $line = @fread(STDIN, 8000); |
| 108 | 131 | $line_len = strlen($line); | $line_len = strlen($line); |
| ... | ... | if (isset($_SERVER['SSH_CONNECTION'])) { | |
| 119 | 142 | $cmd_repo = trim($v[0]); | $cmd_repo = trim($v[0]); |
| 120 | 143 | $host = isset($v[1]) ? trim(substr($v[1], 5)) : ""; | $host = isset($v[1]) ? trim(substr($v[1], 5)) : ""; |
| 121 | 144 | ||
| 122 | if (strcasecmp($host, $rg_git_host) != 0) | ||
| 123 | info('Warn: Please use ' . $rg_git_host | ||
| 124 | . ' instead of ' . $host . '.'); | ||
| 125 | |||
| 126 | 145 | $ip = getenv("REMOTE_HOST"); | $ip = getenv("REMOTE_HOST"); |
| 146 | |||
| 147 | info('you are connecting as anonymous.'); | ||
| 127 | 148 | } | } |
| 128 | 149 | ||
| 129 | 150 | // Extracts command and computes permissions | // Extracts command and computes permissions |
| ... | ... | if ($owner_ui['ok'] != 1) | |
| 169 | 190 | if ($owner_ui['exists'] != 1) | if ($owner_ui['exists'] != 1) |
| 170 | 191 | fatal("User does not exists (repo)."); | fatal("User does not exists (repo)."); |
| 171 | 192 | ||
| 172 | // Load info about the connecting user, if known | ||
| 173 | if ($login_uid > 0) { | ||
| 174 | $conn_ui = rg_user_info($db, $login_uid, "", ""); | ||
| 175 | if ($conn_ui['exists'] != 1) | ||
| 176 | fatal("User does not exists (conn)."); | ||
| 177 | info('you are connecting as user \'' . $conn_ui['username'] . '\'.'); | ||
| 178 | } else { | ||
| 179 | $conn_ui = array('uid' => 0, 'username' => ''); | ||
| 180 | info('you are connecting as anonymous.'); | ||
| 181 | } | ||
| 182 | |||
| 183 | info('you are connecting from IP ' . $ip . '.'); | ||
| 184 | |||
| 185 | 193 | // Loading info about the repository | // Loading info about the repository |
| 186 | 194 | if (rg_repo_ok($repo) !== TRUE) | if (rg_repo_ok($repo) !== TRUE) |
| 187 | 195 | fatal("Repo is invalid (" . rg_repo_error() . ")"); | fatal("Repo is invalid (" . rg_repo_error() . ")"); |
| ... | ... | putenv("ROCKETGIT_REPO_PATH=" . $repo_path); | |
| 243 | 251 | putenv("ROCKETGIT_REPO_UID=" . $ri['uid']); | putenv("ROCKETGIT_REPO_UID=" . $ri['uid']); |
| 244 | 252 | putenv("ROCKETGIT_IP=$ip"); | putenv("ROCKETGIT_IP=$ip"); |
| 245 | 253 | putenv("ROCKETGIT_ITIME=" . microtime(TRUE)); | putenv("ROCKETGIT_ITIME=" . microtime(TRUE)); |
| 254 | putenv("ROCKETGIT_HOST=" . $host); | ||
| 246 | 255 | if ($push == 1) { | if ($push == 1) { |
| 247 | 256 | $namespace = "rg_" . rg_id(8); | $namespace = "rg_" . rg_id(8); |
| 248 | 257 | rg_log("namespace is $namespace."); | rg_log("namespace is $namespace."); |
| File tests/.gitignore changed (mode: 100644) (index a329ce5..e0e46ea) | |||
| ... | ... | git_bin | |
| 19 | 19 | keys/* | keys/* |
| 20 | 20 | *.pid | *.pid |
| 21 | 21 | ca | ca |
| 22 | pr_anon.git | ||
| File tests/Makefile changed (mode: 100644) (index 6fb4e7c..1154e0a) | |||
| 1 | tests := wh ssh http_totp totp git_log1.sh \ | ||
| 1 | tests := pr_anon wh ssh http_totp totp git_log1.sh \ | ||
| 2 | 2 | http_admin http_bug \ | http_admin http_bug \ |
| 3 | 3 | http_create_account http_login http_settings http_csrf http_top \ | http_create_account http_login http_settings http_csrf http_top \ |
| 4 | 4 | token util log state cache prof db event rights keys user repo git \ | token util log state cache prof db event rights keys user repo git \ |
| ... | ... | all: $(tests) | |
| 10 | 10 | @-ls -l err-* | @-ls -l err-* |
| 11 | 11 | @echo "Do not forget to check for errors in /var/log/rocketgit!" | @echo "Do not forget to check for errors in /var/log/rocketgit!" |
| 12 | 12 | ||
| 13 | pr_anon: | ||
| 14 | php pr_anon.php | ||
| 15 | |||
| 13 | 16 | wh: | wh: |
| 14 | 17 | php wh.php | php wh.php |
| 15 | 18 | ||
| ... | ... | git2: | |
| 98 | 101 | clean: | clean: |
| 99 | 102 | @rm -rf git_log1 *.log *.strace *.strace.* *.out *.lock err-* *.diff \ | @rm -rf git_log1 *.log *.strace *.strace.* *.out *.lock err-* *.diff \ |
| 100 | 103 | http.arond *.pub git2key git2 *.in q_merge_requests/mr-* \ | http.arond *.pub git2key git2 *.in q_merge_requests/mr-* \ |
| 101 | qstats/* repos/* helper helper.pub keys/* ca *.pid | ||
| 104 | qstats/* repos/* helper helper.pub keys/* ca *.pid pr_anon.git | ||
| File tests/config.php changed (mode: 100644) (index 1890788..2375f69) | |||
| ... | ... | $rg_lang = "en"; | |
| 30 | 30 | $rg_cache_enable = FALSE; | $rg_cache_enable = FALSE; |
| 31 | 31 | $rg_event_socket = ""; | $rg_event_socket = ""; |
| 32 | 32 | $rg_ssh_host = 'localhost'; | $rg_ssh_host = 'localhost'; |
| 33 | $rg_ssh_port = 22; | ||
| 33 | $rg_ssh_port = 2222; | ||
| 34 | 34 | $rg_git_host = 'localhost'; | $rg_git_host = 'localhost'; |
| 35 | 35 | $rg_git_port = 9418; | $rg_git_port = 9418; |
| 36 | 36 | ||
| File tests/http.inc.php changed (mode: 100644) (index 94ba37a..8454742) | |||
| ... | ... | function do_req($url, &$data, &$headers) | |
| 23 | 23 | rg_log_ml("do_req url[$url] data=" . print_r($data, TRUE) | rg_log_ml("do_req url[$url] data=" . print_r($data, TRUE) |
| 24 | 24 | . "headers=" . print_r($headers, TRUE)); | . "headers=" . print_r($headers, TRUE)); |
| 25 | 25 | ||
| 26 | if (!strstr($url, '?')) | ||
| 27 | $url .= '?rg_debug=1'; | ||
| 28 | else | ||
| 29 | $url .= '&rg_debug=1'; | ||
| 30 | rg_log('DEBUG: url=' . $url); | ||
| 31 | |||
| 32 | 26 | $c = curl_init($url); | $c = curl_init($url); |
| 33 | 27 | if (count($data) > 0) { | if (count($data) > 0) { |
| 34 | 28 | curl_setopt($c, CURLOPT_POST, 1); | curl_setopt($c, CURLOPT_POST, 1); |
| 35 | 29 | curl_setopt($c, CURLOPT_POSTFIELDS, $data); | curl_setopt($c, CURLOPT_POSTFIELDS, $data); |
| 30 | } else { | ||
| 31 | if (!strstr($url, '?')) | ||
| 32 | $url .= '?rg_debug=1'; | ||
| 33 | else | ||
| 34 | $url .= '&rg_debug=1'; | ||
| 36 | 35 | } | } |
| 37 | 36 | curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE); | curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE); |
| 38 | 37 | // We cannot use this because we will not have a | // We cannot use this because we will not have a |
| File tests/pr_anon.php added (mode: 100644) (index 0000000..bc96e3c) | |||
| 1 | <?php | ||
| 2 | // | ||
| 3 | // Tests pull requests done by anonymous push | ||
| 4 | // | ||
| 5 | error_reporting(E_ALL | E_STRICT); | ||
| 6 | ini_set("track_errors", "On"); | ||
| 7 | |||
| 8 | $INC = dirname(__FILE__) . "/../inc"; | ||
| 9 | require_once(dirname(__FILE__) . "/config.php"); | ||
| 10 | require_once($INC . "/init.inc.php"); | ||
| 11 | require_once($INC . "/user.inc.php"); | ||
| 12 | require_once("helpers.inc.php"); | ||
| 13 | require_once("http.inc.php"); | ||
| 14 | |||
| 15 | rg_log_set_file("pr_anon.log"); | ||
| 16 | |||
| 17 | $rg_sql = "host=localhost user=rocketgit dbname=rocketgit connect_timeout=10"; | ||
| 18 | $rg_no_db = TRUE; | ||
| 19 | require_once("common.php"); | ||
| 20 | |||
| 21 | $_testns = 'pr_anon'; | ||
| 22 | $rg_cache_enable = TRUE; | ||
| 23 | $rg_cache_debug = TRUE; | ||
| 24 | $rg_event_socket = "/var/lib/rocketgit/sockets/event.sock"; | ||
| 25 | |||
| 26 | |||
| 27 | rg_log(''); | ||
| 28 | rg_log("Creating user..."); | ||
| 29 | rg_test_create_user($db, $rg_ui); | ||
| 30 | |||
| 31 | |||
| 32 | rg_log(''); | ||
| 33 | rg_log('Creating a repo'); | ||
| 34 | $repo = array('repo_id' => 0, 'public' => 1); | ||
| 35 | rg_test_create_repo($db, $rg_ui, $repo); | ||
| 36 | |||
| 37 | |||
| 38 | rg_log(''); | ||
| 39 | rg_log('Do an anonymous push...'); | ||
| 40 | system('git init pr_anon.git'); | ||
| 41 | system('cd pr_anon.git; echo "change1" > a'); | ||
| 42 | system('cd pr_anon.git; git add a; git commit -m "change1 desc"'); | ||
| 43 | system('cd pr_anon.git; echo "change2" > a; git commit -a -m "change2 desc"'); | ||
| 44 | //system('cd pr_anon.git; git remote add origin ' | ||
| 45 | // . ' ssh://rocketgit@' . $rg_ssh_host . ':' . $rg_ssh_port | ||
| 46 | // . '/user/' . escapeshellarg($rg_ui['username']) . '/' | ||
| 47 | // . escapeshellarg($repo['name'])); | ||
| 48 | system('cd pr_anon.git; git remote add origin ' | ||
| 49 | . ' git://' . $rg_git_host . ':' . $rg_git_port | ||
| 50 | . '/user/' . escapeshellarg($rg_ui['username']) . '/' | ||
| 51 | . escapeshellarg($repo['name'])); | ||
| 52 | system('cd pr_anon.git; git push origin master'); | ||
| 53 | exit(1); | ||
| 54 | |||
| 55 | |||
| 56 | rg_log(''); | ||
| 57 | rg_log('Login...'); | ||
| 58 | $r = test_login($test_url, $rg_ui, $good_sid); | ||
| 59 | if ($r === FALSE) { | ||
| 60 | rg_log("Cannot login!"); | ||
| 61 | exit(1); | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | rg_log("OK!"); | ||
| 66 | ?> | ||
| File tests/wh.php changed (mode: 100644) (index cab3d90..d704d94) | |||
| ... | ... | $rg_sql = "host=localhost user=rocketgit dbname=rocketgit connect_timeout=10"; | |
| 15 | 15 | $rg_no_db = TRUE; | $rg_no_db = TRUE; |
| 16 | 16 | require_once("common.php"); | require_once("common.php"); |
| 17 | 17 | ||
| 18 | $_testns = 'ssh'; | ||
| 18 | $_testns = 'wh'; | ||
| 19 | 19 | $rg_cache_enable = TRUE; | $rg_cache_enable = TRUE; |
| 20 | 20 | $rg_cache_debug = TRUE; | $rg_cache_debug = TRUE; |
| 21 | 21 | $rg_event_socket = "/var/lib/rocketgit/sockets/event.sock"; | $rg_event_socket = "/var/lib/rocketgit/sockets/event.sock"; |