[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