[ckan-changes] commit/ckan: 4 new changesets

Bitbucket commits-noreply at bitbucket.org
Mon Sep 5 18:13:41 UTC 2011


4 new changesets in ckan:

http://bitbucket.org/okfn/ckan/changeset/c0fa838378aa/
changeset:   c0fa838378aa
branch:      feature-1307-recaptcha
user:        zephod
date:        2011-09-05 20:07:47
summary:     [captcha][m]: Implement recaptcha for user signup.
affected #:  4 files (1.1 KB)

--- a/ckan/config/deployment.ini_tmpl	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/config/deployment.ini_tmpl	Mon Sep 05 19:07:47 2011 +0100
@@ -168,6 +168,10 @@
 #ckan.default_roles.System = {"visitor": ["anon_editor"], "logged_in": ["editor"]}
 #ckan.default_roles.AuthorizationGroup = {"visitor": ["reader"], "logged_in": ["reader"]}
 
+## Ckan public and private recaptcha keys [localhost]
+#ckan.recaptcha.publickey = 
+#ckan.recaptcha.privatekey = 
+
 # Logging configuration
 [loggers]
 keys = root, ckan, ckanext


--- a/ckan/controllers/user.py	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/controllers/user.py	Mon Sep 05 19:07:47 2011 +0100
@@ -12,6 +12,7 @@
 from ckan.logic import check_access, get_action
 from ckan.logic import tuplize_dict, clean_dict, parse_params
 from ckan.logic.schema import user_new_form_schema, user_edit_form_schema 
+from ckan.lib.captcha import check_recaptcha, CaptchaError
 
 log = logging.getLogger(__name__)
 
@@ -140,6 +141,7 @@
             data_dict = clean_dict(unflatten(
                 tuplize_dict(parse_params(request.params))))
             context['message'] = data_dict.get('log_message', '')
+            check_recaptcha(request)
             user = get_action('user_create')(context, data_dict)
             h.redirect_to(controller='user', action='read', id=user['name'])
         except NotAuthorized:
@@ -148,6 +150,10 @@
             abort(404, _('User not found'))
         except DataError:
             abort(400, _(u'Integrity Error'))
+        except CaptchaError:
+            error_msg = _(u'Bad Captcha. Please try again.')
+            h.flash_error(error_msg)
+            return self.new(data_dict)
         except ValidationError, e:
             errors = e.error_dict
             error_summary = e.error_summary


--- a/ckan/lib/app_globals.py	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/lib/app_globals.py	Mon Sep 05 19:07:47 2011 +0100
@@ -34,4 +34,7 @@
         self.package_hide_extras = config.get('package_hide_extras', '').split()
 
         self.openid_enabled = asbool(config.get('openid_enabled', 'true'))
+
+        self.recaptcha_publickey = config.get('ckan.recaptcha.publickey', '')
+        self.recaptcha_privatekey = config.get('ckan.recaptcha.privatekey', '')
         


--- a/ckan/templates/user/new_user_form.html	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/templates/user/new_user_form.html	Mon Sep 05 19:07:47 2011 +0100
@@ -34,6 +34,18 @@
         <dt><label class="field_opt" for="password2">Password (repeat):</label></dt><dd><input type="password" name="password2" value="" /></dd>
 
+        <dd py:if="g.recaptcha_publickey">
+          <script type="text/javascript"
+            src="http://www.google.com/recaptcha/api/challenge?k=${g.recaptcha_publickey}">
+          </script>
+          <noscript>
+            <iframe src="http://www.google.com/recaptcha/api/noscript?k=${g.recaptcha_publickey}"
+              height="300" width="500" frameborder="0"></iframe><br/>
+            <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+            <input type="hidden" name="recaptcha_response_field" value="manual_challenge" />
+          </noscript>
+        </dd>
+
     </dl></fieldset>
 


http://bitbucket.org/okfn/ckan/changeset/2646cf63bb23/
changeset:   2646cf63bb23
branch:      feature-1307-recaptcha
user:        zephod
date:        2011-09-05 20:08:17
summary:     [close-branch]:
affected #:  0 files (0 bytes)

http://bitbucket.org/okfn/ckan/changeset/2c31fe24e1c9/
changeset:   2c31fe24e1c9
user:        zephod
date:        2011-09-05 20:09:18
summary:     [merge,from-branch]: Trivial merge from completed feature.
affected #:  4 files (1.1 KB)

--- a/ckan/config/deployment.ini_tmpl	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/config/deployment.ini_tmpl	Mon Sep 05 19:09:18 2011 +0100
@@ -168,6 +168,10 @@
 #ckan.default_roles.System = {"visitor": ["anon_editor"], "logged_in": ["editor"]}
 #ckan.default_roles.AuthorizationGroup = {"visitor": ["reader"], "logged_in": ["reader"]}
 
+## Ckan public and private recaptcha keys [localhost]
+#ckan.recaptcha.publickey = 
+#ckan.recaptcha.privatekey = 
+
 # Logging configuration
 [loggers]
 keys = root, ckan, ckanext


--- a/ckan/controllers/user.py	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/controllers/user.py	Mon Sep 05 19:09:18 2011 +0100
@@ -12,6 +12,7 @@
 from ckan.logic import check_access, get_action
 from ckan.logic import tuplize_dict, clean_dict, parse_params
 from ckan.logic.schema import user_new_form_schema, user_edit_form_schema 
+from ckan.lib.captcha import check_recaptcha, CaptchaError
 
 log = logging.getLogger(__name__)
 
@@ -140,6 +141,7 @@
             data_dict = clean_dict(unflatten(
                 tuplize_dict(parse_params(request.params))))
             context['message'] = data_dict.get('log_message', '')
+            check_recaptcha(request)
             user = get_action('user_create')(context, data_dict)
             h.redirect_to(controller='user', action='read', id=user['name'])
         except NotAuthorized:
@@ -148,6 +150,10 @@
             abort(404, _('User not found'))
         except DataError:
             abort(400, _(u'Integrity Error'))
+        except CaptchaError:
+            error_msg = _(u'Bad Captcha. Please try again.')
+            h.flash_error(error_msg)
+            return self.new(data_dict)
         except ValidationError, e:
             errors = e.error_dict
             error_summary = e.error_summary


--- a/ckan/lib/app_globals.py	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/lib/app_globals.py	Mon Sep 05 19:09:18 2011 +0100
@@ -34,4 +34,7 @@
         self.package_hide_extras = config.get('package_hide_extras', '').split()
 
         self.openid_enabled = asbool(config.get('openid_enabled', 'true'))
+
+        self.recaptcha_publickey = config.get('ckan.recaptcha.publickey', '')
+        self.recaptcha_privatekey = config.get('ckan.recaptcha.privatekey', '')
         


--- a/ckan/templates/user/new_user_form.html	Mon Sep 05 18:22:26 2011 +0100
+++ b/ckan/templates/user/new_user_form.html	Mon Sep 05 19:09:18 2011 +0100
@@ -34,6 +34,18 @@
         <dt><label class="field_opt" for="password2">Password (repeat):</label></dt><dd><input type="password" name="password2" value="" /></dd>
 
+        <dd py:if="g.recaptcha_publickey">
+          <script type="text/javascript"
+            src="http://www.google.com/recaptcha/api/challenge?k=${g.recaptcha_publickey}">
+          </script>
+          <noscript>
+            <iframe src="http://www.google.com/recaptcha/api/noscript?k=${g.recaptcha_publickey}"
+              height="300" width="500" frameborder="0"></iframe><br/>
+            <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+            <input type="hidden" name="recaptcha_response_field" value="manual_challenge" />
+          </noscript>
+        </dd>
+
     </dl></fieldset>
 


http://bitbucket.org/okfn/ckan/changeset/41ddf753d5f7/
changeset:   41ddf753d5f7
user:        rgrp
date:        2011-09-05 20:13:19
summary:     [merge,in-branch][s]: merge in default (dread's latest changes and zephod's fix with recaptcha).
affected #:  7 files (2.7 KB)

--- a/ckan/controllers/api.py	Mon Sep 05 19:09:18 2011 +0100
+++ b/ckan/controllers/api.py	Mon Sep 05 19:13:19 2011 +0100
@@ -4,7 +4,7 @@
 from webob.multidict import UnicodeMultiDict
 
 from ckan.lib.base import BaseController, response, c, _, gettext, request
-from ckan.lib.helpers import json
+from ckan.lib.helpers import json, date_str_to_datetime
 import ckan.model as model
 import ckan.rating
 from ckan.lib.search import query_for, QueryOptions, SearchError, DEFAULT_OPTIONS
@@ -396,7 +396,7 @@
             elif request.params.has_key('since_time'):
                 since_time_str = request.params['since_time']
                 try:
-                    since_time = model.strptimestamp(since_time_str)
+                    since_time = date_str_to_datetime(since_time_str)
                 except ValueError, inst:
                     return self._finish_bad_request('ValueError: %s' % inst)
             else:


--- a/ckan/controllers/package.py	Mon Sep 05 19:09:18 2011 +0100
+++ b/ckan/controllers/package.py	Mon Sep 05 19:13:19 2011 +0100
@@ -14,6 +14,7 @@
 
 from ckan.logic import get_action, check_access
 from ckan.logic.schema import package_form_schema
+from ckan.lib.helpers import date_str_to_datetime
 from ckan.lib.base import request, c, BaseController, model, abort, h, g, render
 from ckan.lib.base import etag_cache, response, redirect, gettext
 from ckan.authz import Authorizer
@@ -195,7 +196,7 @@
                 context['revision_id'] = revision_ref
             else:
                 try:
-                    date = model.strptimestamp(revision_ref)
+                    date = date_str_to_datetime(revision_ref)
                     context['revision_date'] = date
                 except TypeError, e:
                     abort(400, _('Invalid revision format: %r') % e.args)


--- a/ckan/model/__init__.py	Mon Sep 05 19:09:18 2011 +0100
+++ b/ckan/model/__init__.py	Mon Sep 05 19:13:19 2011 +0100
@@ -1,4 +1,6 @@
 import warnings
+import logging
+
 from pylons import config
 from sqlalchemy import MetaData, __version__ as sqav
 from sqlalchemy.schema import Index
@@ -22,9 +24,11 @@
 from package_relationship import *
 from changeset import Changeset, Change, Changemask
 import ckan.migration
-from ckan.lib.helpers import OrderedDict
+from ckan.lib.helpers import OrderedDict, datetime_to_date_str
 from vdm.sqlalchemy.base import SQLAlchemySession
 
+log = logging.getLogger(__name__)
+
 # set up in init_model after metadata is bound
 version_table = None
 
@@ -285,6 +289,7 @@
     raises ValueError if any of the numbers are out of range.
     '''
     # TODO: METHOD DEPRECATED - use ckan.lib.helpers.date_str_to_datetime
+    log.warn('model.strptimestamp is deprecated - use ckan.lib.helpers.date_str_to_datetime instead')
     import datetime, re
     return datetime.datetime(*map(int, re.split('[^\d]', s)))
 
@@ -293,15 +298,18 @@
     a pretty printed string, use ckan.lib.helpers.render_datetime.
     '''
     # TODO: METHOD DEPRECATED - use ckan.lib.helpers.datetime_to_date_str
+    log.warn('model.strftimestamp is deprecated - use ckan.lib.helpers.datetime_to_date_str instead')
     return t.isoformat()
 
 def revision_as_dict(revision, include_packages=True, include_groups=True,ref_package_by='name'):
     revision_dict = OrderedDict((
         ('id', revision.id),
-        ('timestamp', strftimestamp(revision.timestamp)),
+        ('timestamp', datetime_to_date_str(revision.timestamp)),
         ('message', revision.message),
         ('author', revision.author),
-        ('approved_timestamp',revision.approved_timestamp)
+        ('approved_timestamp',
+         datetime_to_date_str(revision.approved_timestamp) \
+         if revision.approved_timestamp else None),
         ))
     if include_packages:
         revision_dict['packages'] = [getattr(pkg, ref_package_by) \


--- a/ckan/tests/functional/api/model/test_revisions.py	Mon Sep 05 19:09:18 2011 +0100
+++ b/ckan/tests/functional/api/model/test_revisions.py	Mon Sep 05 19:13:19 2011 +0100
@@ -13,14 +13,17 @@
     reuse_common_fixtures = True
     
     def test_register_get_ok(self):
-        # Check mock register behaviour.
+        # Comparison list - newest first
+        revs = model.Session.query(model.Revision).\
+               order_by(model.Revision.timestamp.desc()).all()
+        assert revs
+
+        # Check list of revisions
         offset = self.revision_offset()
         res = self.app.get(offset, status=200)
-        revs = model.Session.query(model.Revision).all()
-        assert revs, 'There are no revisions in the model.'
-        res_dict = self.data_from_res(res)
-        for rev in revs:
-            assert rev.id in res_dict, (rev.id, res_dict)
+        revs_result = self.data_from_res(res)
+
+        assert_equal(revs_result, [rev.id for rev in revs])
 
     def test_entity_get_ok(self):
         rev = model.repo.history().all()[-2] # 2nd revision is the creation of pkgs
@@ -44,6 +47,13 @@
         res = self.app.get(offset, status=404)
         self.assert_json_response(res, 'Not found')
 
+    def test_entity_get_301(self):
+        # see what happens when you miss the ID altogether
+        revision_id = ''
+        offset = self.revision_offset(revision_id)
+        res = self.app.get(offset, status=301)
+        # redirects "/api/revision/" to "/api/revision"
+
 class TestRevisionsVersion1(Version1TestCase, RevisionsTestCase): pass
 class TestRevisionsVersion2(Version2TestCase, RevisionsTestCase): pass
 class TestRevisionsUnversioned(UnversionedTestCase, RevisionsTestCase): pass


--- a/ckan/tests/functional/api/test_package_search.py	Mon Sep 05 19:09:18 2011 +0100
+++ b/ckan/tests/functional/api/test_package_search.py	Mon Sep 05 19:13:19 2011 +0100
@@ -322,18 +322,6 @@
         res_dict = self.data_from_res(res)
         assert res_dict['count'] == 1, res_dict
 
-    def test_strftimestamp(self):
-        import datetime
-        t = datetime.datetime(2012, 3, 4, 5, 6, 7, 890123)
-        s = model.strftimestamp(t)
-        assert s == "2012-03-04T05:06:07.890123", s
-
-    def test_strptimestamp(self):
-        import datetime
-        s = "2012-03-04T05:06:07.890123"
-        t = model.strptimestamp(s)
-        assert t == datetime.datetime(2012, 3, 4, 5, 6, 7, 890123), t
-
 class TestPackageSearchApi1(Api1TestCase, PackageSearchApiTestCase): pass
 class TestPackageSearchApi2(Api2TestCase, PackageSearchApiTestCase): pass
 class TestPackageSearchApiUnversioned(PackageSearchApiTestCase, ApiUnversionedTestCase): pass


--- a/ckan/tests/functional/api/test_revision_search.py	Mon Sep 05 19:09:18 2011 +0100
+++ b/ckan/tests/functional/api/test_revision_search.py	Mon Sep 05 19:13:19 2011 +0100
@@ -1,3 +1,5 @@
+from ckan.lib.helpers import datetime_to_date_str
+
 from ckan.tests.functional.api.base import *
 from ckan.tests import TestController as ControllerTestCase
 
@@ -46,7 +48,7 @@
         revs = model.Session.query(model.Revision).all()
         # Check since time of first.
         rev_first = revs[-1]
-        params = "?since_time=%s" % model.strftimestamp(rev_first.timestamp)
+        params = "?since_time=%s" % datetime_to_date_str(rev_first.timestamp)
         res = self.app.get(offset+params, status=200)
         res_list = self.data_from_res(res)
         assert rev_first.id not in res_list
@@ -54,7 +56,7 @@
             assert rev.id in res_list, (rev.id, res_list)
         # Check since time of last.
         rev_last = revs[0]
-        params = "?since_time=%s" % model.strftimestamp(rev_last.timestamp)
+        params = "?since_time=%s" % datetime_to_date_str(rev_last.timestamp)
         res = self.app.get(offset+params, status=200)
         res_list = self.data_from_res(res)
         assert res_list == [], res_list


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ckan/tests/models/test_revision.py	Mon Sep 05 19:13:19 2011 +0100
@@ -0,0 +1,44 @@
+import datetime
+
+from nose.tools import assert_equal
+
+from ckan.tests import *
+import ckan.model as model
+
+# NB Lots of revision tests are part of vdm. No need to repeat those here.
+
+class TestRevision:
+    @classmethod
+    def setup_class(cls):
+        # Create a test package
+        rev = model.repo.new_revision()
+        rev.author = 'Tester'
+        rev.timestamp = datetime.datetime(2020, 1, 1)
+        rev.approved_timestamp = datetime.datetime(2020, 1, 2)
+        rev.message = 'Test message'
+        pkg = model.Package(name='testpkg')
+        model.Session.add(pkg)
+        model.Session.commit()
+        model.Session.remove()
+
+        revs = model.Session.query(model.Revision).\
+               order_by(model.Revision.timestamp.desc()).all()
+        cls.rev = revs[0] # newest
+
+    @classmethod
+    def teardown_class(cls):
+        model.repo.rebuild_db()
+
+    def test_revision_as_dict(self):
+        rev_dict = model.revision_as_dict(self.rev,
+                                          include_packages=True,
+                                          include_groups=True,
+                                          ref_package_by='name')
+        
+        assert_equal(rev_dict['id'], self.rev.id)
+        assert_equal(rev_dict['author'], self.rev.author)
+        assert_equal(rev_dict['timestamp'], '2020-01-01T00:00:00')
+        assert_equal(rev_dict['approved_timestamp'], '2020-01-02T00:00:00')
+        assert_equal(rev_dict['message'], self.rev.message)
+        assert_equal(rev_dict['packages'], [u'testpkg'])
+

Repository URL: https://bitbucket.org/okfn/ckan/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.




More information about the ckan-changes mailing list