# HG changeset patch # User Mads Kiilerich # Date 2016-05-02 23:40:56 # Node ID 6feed82b76a3cf8b17a9611e690a370dd4890693 # Parent f33cc4af706ba781dbf9a866b45caa37cafcb5a9 # Parent 10a5a5f1bdf6f18a1d29a31156c9d7a6993368ec Merge stable diff --git a/.hgsigs b/.hgsigs --- a/.hgsigs +++ b/.hgsigs @@ -1,2 +1,3 @@ 9b3e9e242f5c97cc0c7657e5ac93dce7de61ca16 0 iQEcBAABAgAGBQJWDuAdAAoJEJ1bI/kYT6UUAlYH/ReCa7Im5tvy+ot5oAc7xey/O2rCVHp2h6i82tTWK/0i9EaS4DP+eTbAjV4WJA4qWF5DPenEJ3X9JhrTLNvGkR0f7lUqiFVMTJ472YlSsvIWg38gVFruzwk1cODRfq72o8ERYcRSfzrL4cDpIqjEd/vVVCV/gKVvPmzr4/FED/ZmS0X6T9gxWJo/eWSuLNAxHHtE/pCWDO3XEe+iOm+hHjkyz4Hn2r9/+ucrirnzycH6DnYO/kWvQzBnzgMjJm+1rLZ5cfU89V8zfhv6z0pd8CHZfpKGc2Z8EwVJq9LR+M4/76uDlYXx7IfZAxhRNqN6MC+yvPmDo3382dNr7Wkopi0= 9bf8eb837e785b6856ccfac264e977ce3ebe1535 0 iQEcBAABAgAGBQJW5XaVAAoJEJ1bI/kYT6UUbeMH/AsGg21jTc0tTT+228T+WfrfkbxrPkkULQF/Eo3ChlrhnFZ5B1y7ellSx6XGas7yKpqHHtNmrVwY3KBfUaYEljML/osEt1kvM6JGcd0vDbAW1uA2sdJR2AXmf32MjguFVhmYi9Lj79WYtgg241YGPe4dH0ompNFVqazNxCfmDBZijzSkF57FURMpV2e6+MyNq0txSo9Q82eALy0GAIX7NKQcxtynxG9ETzVzuVpeNE9MEZh0ObbUtPGezd55GXXcVqI8ZEurZwf6KHnd5M+5wxIZf84gM/k4QgQbRiIxNj4QfVmTZlVNSkC7PwSbF8twZPjlAprwldYvMi/c7ZVocEY= +a84d40e9481fcea4dafadee86b03f0dd401527d6 0 iQEcBAABAgAGBQJXJ4XhAAoJEJ1bI/kYT6UUKaIH/i33ZiT95pWF3pHEftgrZWvMwvz9tAuoHgf7ntkIUPnxfNteXKw8FiKcSQ9f8I41VyML+rqsnBBIfltJknfoqTV+9jNkHwc62OfcqQ3RbBDXQbcSi1CHn2ihJiZadqiKEyUw7JJqOMyWp+AWQyywcF/ea+pwXPJG5A2fd4vnBWHSxhD+6Ig1KipZNORzZY7fAec185M7NOZCZC+5qOLIkoQZaGq+D2Aipx5eZkpgFd4W+0LQY1ywMV5CiOY1OG0mry7l6NfIZvPY9Kiwg37G6ZUi8fhwVvn6Y8UACcAnWunBfKt9PWK0rAgNyJ9HDk/+3S5g6HcNKUb6YRTzEcLshIc= diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -62,5 +62,5 @@ ad0ce803b40cb17fc3988373052943e041030b02 c6e32714336345403adf76abb6ebf9b8116fcdc7 0.2.1 14f488a5dc4ca6647bc6acf12534fd137e968aa8 0.2.2 9b3e9e242f5c97cc0c7657e5ac93dce7de61ca16 0.3 -250f8150c4bb0ca00dcb92f49ce9a475545863e8 0.3.1 9bf8eb837e785b6856ccfac264e977ce3ebe1535 0.3.1 +a84d40e9481fcea4dafadee86b03f0dd401527d6 0.3.2 diff --git a/CONTRIBUTORS b/CONTRIBUTORS --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -4,15 +4,20 @@ List of contributors to Kallithea projec Takumi IINO 2012-2016 Unity Technologies 2012-2016 Andrew Shadura 2012 2014-2016 + Dominik Ruf 2012 2014-2016 Thomas De Schampheleire 2014-2016 + Étienne Gilli 2015-2016 Jan Heylen 2015-2016 + Robert Martinez 2015-2016 Robert Rauch 2015-2016 Søren Løvborg 2015-2016 Angel Ezquerra 2016 Asterios Dimitriou 2016 + Konstantin Veretennicov 2016 + Oscar Curero 2016 Robert James Dennington 2016 + YFdyh000 2016 Aras Pranckevičius 2012-2013 2015 - Dominik Ruf 2012 2014-2015 Sean Farley 2013-2015 Christian Oyarzun 2014-2015 Joseph Rivera 2014-2015 @@ -27,7 +32,6 @@ List of contributors to Kallithea projec Denis Blanchette 2015 duanhongyi 2015 EriCSN Chang 2015 - Étienne Gilli 2015 Grzegorz Krason 2015 Jiří Suchan 2015 Kazunari Kobayashi 2015 @@ -42,7 +46,6 @@ List of contributors to Kallithea projec Nick High 2015 Niemand Jedermann 2015 Peter Vitt 2015 - Robert Martinez 2015 Ronny Pfannschmidt 2015 Sam Jaques 2015 Tuux 2015 diff --git a/docs/setup.rst b/docs/setup.rst --- a/docs/setup.rst +++ b/docs/setup.rst @@ -139,6 +139,7 @@ or in the admin panel you can check the .. _ldap-setup: + Setting up LDAP support ----------------------- @@ -411,8 +412,7 @@ reverse-proxy setup with basic auth: Setting metadata in container/reverse-proxy -''''''''''''''''''''''''''''''''''''''''''' - +""""""""""""""""""""""""""""""""""""""""""" When a new user account is created on the first login, Kallithea has no information about the user's email and full name. So you can set some additional request headers like in the example below. In this example the user is authenticated via Kerberos and an Apache diff --git a/kallithea/controllers/changeset.py b/kallithea/controllers/changeset.py --- a/kallithea/controllers/changeset.py +++ b/kallithea/controllers/changeset.py @@ -421,11 +421,11 @@ class ChangesetController(BaseRepoContro 'repository.admin') @jsonify def delete_comment(self, repo_name, comment_id): - co = ChangesetComment.get(comment_id) - if not co: - raise HTTPBadRequest() + co = ChangesetComment.get_or_404(comment_id) + if co.repo.repo_name != repo_name: + raise HTTPNotFound() owner = co.author.user_id == c.authuser.user_id - repo_admin = h.HasRepoPermissionAny('repository.admin') + repo_admin = h.HasRepoPermissionAny('repository.admin')(repo_name) if h.HasPermissionAny('hg.admin')() or repo_admin or owner: ChangesetCommentsModel().delete(comment=co) Session().commit() diff --git a/kallithea/controllers/pullrequests.py b/kallithea/controllers/pullrequests.py --- a/kallithea/controllers/pullrequests.py +++ b/kallithea/controllers/pullrequests.py @@ -487,7 +487,7 @@ class PullrequestsController(BaseRepoCon #only owner or admin can update it owner = pull_request.owner.user_id == c.authuser.user_id repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) - if not (h.HasPermissionAny('hg.admin') or repo_admin or owner): + if not (h.HasPermissionAny('hg.admin')() or repo_admin or owner): raise HTTPForbidden() _form = PullRequestPostForm()().to_python(request.POST) @@ -814,7 +814,7 @@ class PullrequestsController(BaseRepoCon owner = co.author.user_id == c.authuser.user_id repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) - if h.HasPermissionAny('hg.admin') or repo_admin or owner: + if h.HasPermissionAny('hg.admin')() or repo_admin or owner: ChangesetCommentsModel().delete(comment=co) Session().commit() return True diff --git a/kallithea/lib/auth.py b/kallithea/lib/auth.py --- a/kallithea/lib/auth.py +++ b/kallithea/lib/auth.py @@ -759,6 +759,16 @@ class LoginRequired(object): if request.method not in ['GET', 'HEAD', 'POST', 'PUT']: raise HTTPMethodNotAllowed() + # Also verify the _method override. This is only permitted in POST + # requests, and can specify PUT or DELETE. + _method = request.params.get('_method') + if _method is None: + pass # no override, no problem + elif request.method == 'POST' and _method.upper() in ['PUT', 'DELETE']: + pass # permitted override + else: + raise HTTPMethodNotAllowed() + # Make sure CSRF token never appears in the URL. If so, invalidate it. if secure_form.token_key in request.GET: log.error('CSRF key leak detected') diff --git a/kallithea/lib/vcs/backends/base.py b/kallithea/lib/vcs/backends/base.py --- a/kallithea/lib/vcs/backends/base.py +++ b/kallithea/lib/vcs/backends/base.py @@ -123,9 +123,6 @@ class BaseRepository(object): for topnode, dirs, files in tip.walk('/'): for f in files: size += tip.get_file_size(f.path) - for dir in dirs: - for f in files: - size += tip.get_file_size(f.path) except RepositoryError as e: pass diff --git a/kallithea/templates/about.html b/kallithea/templates/about.html --- a/kallithea/templates/about.html +++ b/kallithea/templates/about.html @@ -31,15 +31,20 @@
  • Copyright © 2012–2016, Takumi IINO
  • Copyright © 2012–2016, Unity Technologies
  • Copyright © 2012, 2014–2016, Andrew Shadura
  • +
  • Copyright © 2012, 2014–2016, Dominik Ruf
  • Copyright © 2014–2016, Thomas De Schampheleire
  • +
  • Copyright © 2015–2016, Étienne Gilli
  • Copyright © 2015–2016, Jan Heylen
  • +
  • Copyright © 2015–2016, Robert Martinez
  • Copyright © 2015–2016, Robert Rauch
  • Copyright © 2015–2016, Søren Løvborg
  • Copyright © 2016, Angel Ezquerra
  • Copyright © 2016, Asterios Dimitriou
  • +
  • Copyright © 2016, Konstantin Veretennicov
  • +
  • Copyright © 2016, Oscar Curero
  • Copyright © 2016, Robert James Dennington
  • +
  • Copyright © 2016, YFdyh000
  • Copyright © 2012–2013, 2015, Aras Pranckevičius
  • -
  • Copyright © 2012, 2014–2015, Dominik Ruf
  • Copyright © 2014–2015, Christian Oyarzun
  • Copyright © 2014–2015, Joseph Rivera
  • Copyright © 2014–2015, Michal Čihař
  • @@ -54,7 +59,6 @@
  • Copyright © 2015, Denis Blanchette
  • Copyright © 2015, duanhongyi
  • Copyright © 2015, EriCSN Chang
  • -
  • Copyright © 2015, Étienne Gilli
  • Copyright © 2015, Grzegorz Krason
  • Copyright © 2015, Jiří Suchan
  • Copyright © 2015, Kazunari Kobayashi
  • @@ -69,7 +73,6 @@
  • Copyright © 2015, Nick High
  • Copyright © 2015, Niemand Jedermann
  • Copyright © 2015, Peter Vitt
  • -
  • Copyright © 2015, Robert Martinez
  • Copyright © 2015, Ronny Pfannschmidt
  • Copyright © 2015, Sam Jaques
  • Copyright © 2015, Tuux
  • diff --git a/kallithea/templates/admin/settings/settings_global.html b/kallithea/templates/admin/settings/settings_global.html --- a/kallithea/templates/admin/settings/settings_global.html +++ b/kallithea/templates/admin/settings/settings_global.html @@ -28,11 +28,11 @@ ${h.form(url('admin_settings_global'), m
    ${h.textarea('ga_code', cols=80, rows=10)} - ${_('HTML (possibly with\ - JavaScript and/or CSS) that will be added to the bottom\ - of every page. This can be used for web analytics\ - systems like Google Analytics or Piwik, but also to\ - perform instance-specific customizations like adding a\ + ${_('HTML (possibly with \ + JavaScript and/or CSS) that will be added to the bottom \ + of every page. This can be used for web analytics \ + systems like Google Analytics or Piwik, but also to \ + perform instance-specific customizations like adding a \ project banner at the top of every page.')}
    diff --git a/kallithea/templates/changelog/changelog.html b/kallithea/templates/changelog/changelog.html --- a/kallithea/templates/changelog/changelog.html +++ b/kallithea/templates/changelog/changelog.html @@ -183,27 +183,26 @@ ${self.repo_context_bar('changelog', c.f if ($checked_checkboxes.length > 0) { $checked_checkboxes.first().parent('td').append($singlerange); var singlerange = $singlerange.prop('checked'); - var rev_end = $checked_checkboxes.first().prop('name').substr(0, 12); + var rev_end = $checked_checkboxes.first().prop('name'); if ($checked_checkboxes.length > 1 || singlerange) { - var rev_start = $checked_checkboxes.last().prop('name').substr(0, 12); + var rev_start = $checked_checkboxes.last().prop('name'); $('#rev_range_container').prop('href', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}', 'revision': rev_start + '...' + rev_end})); $('#rev_range_container').html( - _TM['Show Selected Changesets {0} → {1}'].format(rev_start, rev_end)); + _TM['Show Selected Changesets {0} → {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12))); $('#rev_range_container').show(); $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home', {'repo_name': '${c.repo_name}', 'rev_start': rev_start, 'rev_end': rev_end})); - $('#open_new_pr').html(_TM['Open New Pull Request for {0} → {1}'].format(rev_start, rev_end)); + $('#open_new_pr').html(_TM['Open New Pull Request for {0} → {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12))); } else { $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home', {'repo_name': '${c.repo_name}', 'rev_end': rev_end})); - $('#open_new_pr').html(_TM['Open New Pull Request from {0}'].format(rev_end)); + $('#open_new_pr').html(_TM['Open New Pull Request from {0}'].format(rev_end.substr(0, 12))); } - $('#rev_range_clear').show(); $('#compare_fork').hide(); diff --git a/kallithea/tests/vcs/test_git.py b/kallithea/tests/vcs/test_git.py --- a/kallithea/tests/vcs/test_git.py +++ b/kallithea/tests/vcs/test_git.py @@ -382,6 +382,22 @@ class GitChangesetTest(unittest.TestCase for revision, path, size in to_check: self._test_file_size(revision, path, size) + def _test_dir_size(self, revision, path, size): + node = self.repo.get_changeset(revision).get_node(path) + self.assertEqual(node.size, size) + + def test_dir_size(self): + to_check = ( + ('5f2c6ee195929b0be80749243c18121c9864a3b3', '/', 674076), + ('7ab37bc680b4aa72c34d07b230c866c28e9fc204', '/', 674049), + ('6892503fb8f2a552cef5f4d4cc2cdbd13ae1cd2f', '/', 671830), + ) + for revision, path, size in to_check: + self._test_dir_size(revision, path, size) + + def test_repo_size(self): + self.assertEqual(self.repo.size, 674076) + def test_file_history(self): # we can only check if those revisions are present in the history # as we cannot update this test every time file is changed diff --git a/kallithea/tests/vcs/test_hg.py b/kallithea/tests/vcs/test_hg.py --- a/kallithea/tests/vcs/test_hg.py +++ b/kallithea/tests/vcs/test_hg.py @@ -344,6 +344,23 @@ class MercurialChangesetTest(unittest.Te for revision, path, size in to_check: self._test_file_size(revision, path, size) + def _test_dir_size(self, revision, path, size): + node = self.repo.get_changeset(revision).get_node(path) + self.assertFalse(node.is_file()) + self.assertEqual(node.size, size) + + def test_dir_size(self): + to_check = ( + ('96507bd11ecc', '/', 682421), + ('a53d9201d4bc', '/', 682410), + ('90243de06161', '/', 682006), + ) + for revision, path, size in to_check: + self._test_dir_size(revision, path, size) + + def test_repo_size(self): + self.assertEqual(self.repo.size, 682421) + def test_file_history(self): # we can only check if those revisions are present in the history # as we cannot update this test every time file is changed