[ckan-changes] commit/ckan: 3 new changesets
Bitbucket
commits-noreply at bitbucket.org
Tue Jul 26 14:07:28 UTC 2011
3 new changesets in ckan:
http://bitbucket.org/okfn/ckan/changeset/5c1c0d7ae4ad/
changeset: 5c1c0d7ae4ad
branch: feature-1229-db-out-of-controllers
user: amercader
date: 2011-07-26 14:00:28
summary: [logic,forms] Move user edit, including forms
affected #: 10 files (9.0 KB)
--- a/ckan/controllers/user.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/controllers/user.py Tue Jul 26 13:00:28 2011 +0100
@@ -10,10 +10,11 @@
from ckan.lib.navl.dictization_functions import DataError, unflatten
from ckan.logic import NotFound, NotAuthorized, ValidationError
from ckan.logic import tuplize_dict, clean_dict, parse_params
-from ckan.logic.schema import user_form_schema
+from ckan.logic.schema import user_new_form_schema, user_edit_form_schema
import ckan.logic.action.get as get
import ckan.logic.action.create as create
+import ckan.logic.action.update as update
log = logging.getLogger(__name__)
@@ -23,12 +24,20 @@
class UserController(BaseController):
## hooks for subclasses
- user_form = 'user/new_user_form.html'
+ new_user_form = 'user/new_user_form.html'
+ edit_user_form = 'user/edit_user_form.html'
- def _form_to_db_schema(self):
- return user_form_schema()
+ def _new_form_to_db_schema(self):
+ return user_new_form_schema()
- def _db_to_form_schema(self):
+ def _db_to_new_form_schema(self):
+ '''This is an interface to manipulate data from the database
+ into a format suitable for the form (optional)'''
+
+ def _edit_form_to_db_schema(self):
+ return user_edit_form_schema()
+
+ def _db_to_edit_form_schema(self):
'''This is an interface to manipulate data from the database
into a format suitable for the form (optional)'''
@@ -71,7 +80,7 @@
'user': c.user or c.author}
data_dict = {'id':id,
- 'user':c.userobj}
+ 'user_obj':c.userobj}
try:
user_dict = get.user_show(context,data_dict)
except NotFound:
@@ -98,7 +107,7 @@
def new(self, data=None, errors=None, error_summary=None):
context = {'model': model, 'session': model.Session,
'user': c.user or c.author,
- 'schema': self._form_to_db_schema(),
+ 'schema': self._new_form_to_db_schema(),
'save': 'save' in request.params}
auth_for_create = Authorizer().am_authorized(c, model.Action.USER_CREATE, model.System())
@@ -114,7 +123,7 @@
vars = {'data': data, 'errors': errors, 'error_summary': error_summary}
self._setup_template_variables(context)
- c.form = render(self.user_form, extra_vars=vars)
+ c.form = render(self.new_user_form, extra_vars=vars)
return render('user/new.html')
def _save_new(self, context):
@@ -135,6 +144,77 @@
error_summary = e.error_summary
return self.new(data_dict, errors, error_summary)
+ def edit(self, id, data=None, errors=None, error_summary=None):
+ context = {'model': model, 'session': model.Session,
+ 'user': c.user or c.author,
+ 'preview': 'preview' in request.params,
+ 'save': 'save' in request.params,
+ 'schema': self._edit_form_to_db_schema(),
+ }
+ data_dict = {'id': id}
+
+ if (context['save'] or context['preview']) and not data:
+ return self._save_edit(id, context)
+
+ try:
+ old_data = get.user_show(context, data_dict)
+
+ schema = self._db_to_edit_form_schema()
+ if schema:
+ old_data, errors = validate(old_data, schema)
+
+ c.display_name = old_data.get('display_name')
+ c.user_name = old_data.get('name')
+
+ data = data or old_data
+
+ except NotAuthorized:
+ abort(401, _('Unauthorized to edit user %s') % '')
+
+ user_obj = context.get('user_obj')
+
+ if not (ckan.authz.Authorizer().is_sysadmin(unicode(c.user)) or c.user == user_obj.name):
+ abort(401, _('User %s not authorized to edit %s') % (str(c.user), id))
+
+ errors = errors or {}
+ vars = {'data': data, 'errors': errors, 'error_summary': error_summary}
+
+ self._setup_template_variables(context)
+
+ c.form = render(self.edit_user_form, extra_vars=vars)
+
+ return render('user/edit.html')
+
+ def _save_edit(self, id, context):
+ try:
+ data_dict = clean_dict(unflatten(
+ tuplize_dict(parse_params(request.params))))
+ context['message'] = data_dict.get('log_message', '')
+ data_dict['id'] = id
+ user = update.user_update(context, data_dict)
+
+ if context['preview']:
+ about = request.params.getone('about')
+ c.preview = self._format_about(about)
+ c.user_about = about
+ c.full_name = request.params.get('fullname','')
+ c.email = request.params.getone('email')
+
+ return self.edit(id, data_dict)
+
+ h.redirect_to(controller='user', action='read', id=user['id'])
+ except NotAuthorized:
+ abort(401, _('Unauthorized to edit user %s') % id)
+ except NotFound, e:
+ abort(404, _('User not found'))
+ except DataError:
+ abort(400, _(u'Integrity Error'))
+ except ValidationError, e:
+ errors = e.error_dict
+ error_summary = e.error_summary
+ return self.edit(id, data_dict, errors, error_summary)
+
+
def login(self):
return render('user/login.html')
@@ -162,58 +242,6 @@
response.delete_cookie("ckan_display_name")
response.delete_cookie("ckan_apikey")
return render('user/logout.html')
-
- def edit(self, id=None):
- if id is not None:
- user = model.User.get(id)
- else:
- user = model.User.by_name(c.user)
- if user is None:
- abort(404)
- currentuser = model.User.by_name(c.user)
- if not (ckan.authz.Authorizer().is_sysadmin(unicode(c.user)) or user == currentuser):
- abort(401)
- c.userobj = user
- if not 'save' in request.params and not 'preview' in request.params:
- c.user_about = user.about
- c.user_fullname = user.fullname
- c.user_email = user.email
- elif 'preview' in request.params:
- about = request.params.getone('about')
- c.preview = self._format_about(about)
- c.user_about = about
- c.user_fullname = request.params.getone('fullname')
- c.user_email = request.params.getone('email')
- elif 'save' in request.params:
- try:
- about = request.params.getone('about')
- if 'http://' in about or 'https://' in about:
- msg = _('Edit not allowed as it looks like spam. Please avoid links in your description.')
- h.flash_error(msg)
- c.user_about = about
- c.user_fullname = request.params.getone('fullname')
- c.user_email = request.params.getone('email')
- return render('user/edit.html')
- user.about = about
- user.fullname = request.params.getone('fullname')
- user.email = request.params.getone('email')
- try:
- password = self._get_form_password()
- if password:
- user.password = password
- except ValueError, ve:
- h.flash_error(ve)
- return render('user/edit.html')
- except Exception, inst:
- model.Session.rollback()
- raise
- else:
- model.Session.commit()
- h.flash_notice(_("Your account has been updated."))
- response.set_cookie("ckan_display_name", user.display_name)
- h.redirect_to(controller='user', action='read', id=user.id)
-
- return render('user/edit.html')
def request_reset(self):
if request.method == 'POST':
--- a/ckan/lib/dictization/model_save.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/lib/dictization/model_save.py Tue Jul 26 13:00:28 2011 +0100
@@ -301,11 +301,11 @@
model = context['model']
session = context['session']
- user = context.get('userobj')
+ user = context.get('user_obj')
User = model.User
if user:
- user_dict['id'] = user.id
+ user_dict['id'] = user.id
user = table_dict_save(user_dict, User, context)
--- a/ckan/logic/action/get.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/logic/action/get.py Tue Jul 26 13:00:28 2011 +0100
@@ -300,14 +300,14 @@
model = context['model']
id = data_dict.get('id',None)
- provided_user = data_dict.get('user',None)
+ provided_user = data_dict.get('user_obj',None)
if id:
user = model.User.get(id)
- context['user'] = user
+ context['user_obj'] = user
if user is None:
raise NotFound
elif provided_user:
- context['user'] = user = provided_user
+ context['user_obj'] = user = provided_user
else:
return None
--- a/ckan/logic/action/update.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/logic/action/update.py Tue Jul 26 13:00:28 2011 +0100
@@ -11,13 +11,16 @@
package_to_api2,
group_dictize,
group_to_api1,
- group_to_api2)
+ group_to_api2,
+ user_dictize)
from ckan.lib.dictization.model_save import (group_api_to_dict,
package_api_to_dict,
group_dict_save,
- package_dict_save)
+ package_dict_save,
+ user_dict_save)
from ckan.logic.schema import (default_update_group_schema,
- default_update_package_schema)
+ default_update_package_schema,
+ default_update_user_schema)
from ckan.lib.navl.dictization_functions import validate
log = logging.getLogger(__name__)
@@ -276,6 +279,44 @@
return group_dictize(group, context)
+def user_update(context, data_dict):
+ '''Updates the user's details'''
+
+ model = context['model']
+ user = context['user']
+ preview = context.get('preview', False)
+ schema = context.get('schema') or default_update_user_schema()
+ id = data_dict['id']
+
+ user_obj = model.User.get(id)
+ context['user_obj'] = user_obj
+ if user_obj is None:
+ raise NotFound('User was not found.')
+
+ if not (ckan.authz.Authorizer().is_sysadmin(unicode(user)) or user == user_obj.name):
+ raise NotAuthorized( _('User %s not authorized to edit %s') % (str(user), id))
+
+ data, errors = validate(data_dict, schema, context)
+ if errors:
+ model.Session.rollback()
+ raise ValidationError(errors, group_error_summary(errors))
+
+ if not preview:
+ rev = model.repo.new_revision()
+ rev.author = user
+ if 'message' in context:
+ rev.message = context['message']
+ else:
+ rev.message = _(u'REST API: Update user %s') % data.get('name')
+
+ user = user_dict_save(data, context)
+
+ if not preview:
+ model.repo.commit()
+ return user_dictize(user, context)
+
+ return data
+
## Modifications for rest api
def package_update_rest(context, data_dict):
--- a/ckan/logic/schema.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/logic/schema.py Tue Jul 26 13:00:28 2011 +0100
@@ -25,7 +25,8 @@
user_password_validator,
user_both_passwords_entered,
user_passwords_match,
- user_password_not_empty)
+ user_password_not_empty,
+ user_about_validator)
from formencode.validators import OneOf
import ckan.model
@@ -198,7 +199,7 @@
'fullname': [ignore_missing, unicode],
'password': [user_password_validator, user_password_not_empty, ignore_missing, unicode],
'email': [ignore_missing, unicode],
- 'about': [ignore_missing, unicode],
+ 'about': [ignore_missing, user_about_validator, unicode],
'created': [ignore],
'openid': [ignore],
'apikey': [ignore],
@@ -206,7 +207,7 @@
}
return schema
-def user_form_schema():
+def user_new_form_schema():
schema = default_user_schema()
schema['password1'] = [unicode,user_both_passwords_entered,user_password_validator,user_passwords_match]
@@ -214,3 +215,19 @@
return schema
+def user_edit_form_schema():
+ schema = default_user_schema()
+
+ schema['name'] = [ignore_missing]
+ schema['password1'] = [unicode,user_both_passwords_entered,user_password_validator,user_passwords_match]
+ schema['password2'] = [unicode]
+
+ return schema
+
+def default_update_user_schema():
+ schema = default_user_schema()
+
+ schema['name'] = [ignore_missing]
+
+ return schema
+
--- a/ckan/logic/validators.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/logic/validators.py Tue Jul 26 13:00:28 2011 +0100
@@ -217,3 +217,9 @@
password = data.get(('password',),None)
if not password:
errors[key].append(_('Missing value'))
+
+def user_about_validator(value,context):
+ if 'http://' in value or 'https://' in value:
+ raise Invalid(_('Edit not allowed as it looks like spam. Please avoid links in your description.'))
+
+ return value
--- a/ckan/templates/user/edit.html Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/templates/user/edit.html Tue Jul 26 13:00:28 2011 +0100
@@ -11,51 +11,27 @@
<div py:match="content"><h2>
- Edit User: ${c.userobj.display_name} (${c.userobj.name})
+ Edit User: ${c.display_name} (${c.user_name})
<a href="#preview" py:if="c.preview">(skip to preview)</a></h2>
- <form id="user-edit" action="" method="post" class="simple-form"
- xmlns:py="http://genshi.edgewall.org/"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- >
- <fieldset>
- <legend>Base details</legend>
- <label for="fullname">Full name:</label>
- <input name="fullname" value="${c.user_fullname}" /><br/>
-
- <label for="email">E-Mail:</label>
- <input name="email" value="${c.user_email}" /><br/>
- </fieldset>
- <fieldset>
- <legend>Change your password</legend>
- <label for="password1">Password:</label>
- <input type="password" name="password1" value="" />
- <br/>
- <label for="password2">Password (repeat):</label>
- <input type="password" name="password2" value="" />
- <br/>
- </fieldset>
- <label for="about">About user:</label>
- <textarea id="about" rows="5" name="about" cols="60">${c.user_about}</textarea>
- <p class="small" i18n:msg="">You can use <a href="http://daringfireball.net/projects/markdown/syntax">Markdown formatting</a> here.</p>
-
- <div>
- <input name="preview" type="submit" value="Preview" />
- ${h.submit('save', _('Save'))}
- </div>
- </form><div id="preview" style="margin-left: 20px;" py:if="c.preview"><hr /><h2>Preview</h2>
- <h4>Full name: ${c.user_fullname}</h4>
+ <h4>Full name: ${c.full_name}</h4>
+ <h4>Email: ${c.email}</h4><div style="border: 2px dashed red; padding: 5px;">
${c.preview}
</div></div>
+
+ ${Markup(c.form)}
+
+
</div>
+
<xi:include href="layout.html" /></html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ckan/templates/user/edit_user_form.html Tue Jul 26 13:00:28 2011 +0100
@@ -0,0 +1,42 @@
+<form id="user-edit" action="" method="post"
+ py:attrs="{'class':'has-errors'} if errors else {}"
+ xmlns:i18n="http://genshi.edgewall.org/i18n"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+<div class="error-explanation" py:if="error_summary">
+<h2>Errors in form</h2>
+<p>The form contains invalid entries:</p>
+<ul>
+ <li py:for="key, error in error_summary.items()">${"%s: %s" % (key, error)}</li>
+</ul>
+</div>
+ <fieldset>
+ <legend>Base details</legend>
+ <dl>
+ <dt><label for="fullname">Full name:</label></dt>
+ <dd><input type="text" name="fullname" value="${data.get('fullname','')}" /></dd>
+
+ <dt><label for="email">E-Mail:</label></dt>
+ <dd><input type="text" name="email" value="${data.get('email','')}" /></dd>
+ </dl>
+ </fieldset>
+ <fieldset>
+ <legend>Change your password</legend>
+ <dl>
+ <dt><label for="password1">Password:</label></dt>
+ <dd><input type="password" name="password1" value="" /></dd>
+ <dt><label for="password2">Password (repeat):</label></dt>
+ <dd><input type="password" name="password2" value="" /></dd>
+ </dl>
+ </fieldset>
+ <label for="about">About user:</label>
+ <textarea id="about" rows="5" name="about" cols="60">${data.get('about','')}</textarea>
+ <p class="small" i18n:msg="">You can use <a href="http://daringfireball.net/projects/markdown/syntax">Markdown formatting</a> here.</p>
+
+ <div>
+ <input name="preview" type="submit" value="Preview" />
+ ${h.submit('save', _('Save'))}
+ </div>
+</form>
+
--- a/ckan/tests/functional/api/test_action.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/tests/functional/api/test_action.py Tue Jul 26 13:00:28 2011 +0100
@@ -14,7 +14,8 @@
STATUS_409_CONFLICT = 409
sysadmin_user = None
-
+
+ normal_user = None
@classmethod
def setup_class(self):
@@ -22,6 +23,8 @@
self.sysadmin_user = model.User.get('testsysadmin')
+ self.normal_user = model.User.get('annafan')
+
@classmethod
def teardown_class(self):
model.repo.rebuild_db()
@@ -163,6 +166,7 @@
assert 'display_name' in result
assert 'number_administered_packages' in result
assert 'number_of_edits' in result
+ assert not 'password' in result
def test_10_user_create_parameters_missing(self):
user_dict = {}
@@ -200,3 +204,79 @@
'help': 'Creates a new user',
'success': False
}
+
+ def test_12_user_update(self):
+ normal_user_dict = {'id': self.normal_user.id,
+ 'password': self.normal_user.password,
+ 'fullname': 'Updated normal user full name',
+ 'about':'Updated normal user about'}
+
+ sysadmin_user_dict = {'id': self.sysadmin_user.id,
+ 'password': self.sysadmin_user.password,
+ 'fullname': 'Updated sysadmin user full name',
+ 'about':'Updated sysadmin user about'}
+
+ #Normal users can update themselves
+ postparams = '%s=1' % json.dumps(normal_user_dict)
+ res = self.app.post('/api/action/user_update', params=postparams,
+ extra_environ={'Authorization': str(self.normal_user.apikey)})
+
+ res_obj = json.loads(res.body)
+ assert res_obj['help'] == 'Updates the user\'s details'
+ assert res_obj['success'] == True
+ result = res_obj['result']
+ assert result['id'] == self.normal_user.id
+ assert result['name'] == self.normal_user.name
+ assert result['fullname'] == normal_user_dict['fullname']
+ assert result['about'] == normal_user_dict['about']
+ assert 'apikey' in result
+ assert 'created' in result
+ assert 'display_name' in result
+ assert 'number_administered_packages' in result
+ assert 'number_of_edits' in result
+ assert not 'password' in result
+
+ #Sysadmin users can update themselves
+ postparams = '%s=1' % json.dumps(sysadmin_user_dict)
+ res = self.app.post('/api/action/user_update', params=postparams,
+ extra_environ={'Authorization': str(self.sysadmin_user.apikey)})
+
+ res_obj = json.loads(res.body)
+ assert res_obj['help'] == 'Updates the user\'s details'
+ assert res_obj['success'] == True
+ result = res_obj['result']
+ assert result['id'] == self.sysadmin_user.id
+ assert result['name'] == self.sysadmin_user.name
+ assert result['fullname'] == sysadmin_user_dict['fullname']
+ assert result['about'] == sysadmin_user_dict['about']
+
+ #Sysadmin users can update all users
+ postparams = '%s=1' % json.dumps(normal_user_dict)
+ res = self.app.post('/api/action/user_update', params=postparams,
+ extra_environ={'Authorization': str(self.sysadmin_user.apikey)})
+
+ res_obj = json.loads(res.body)
+ assert res_obj['help'] == 'Updates the user\'s details'
+ assert res_obj['success'] == True
+ result = res_obj['result']
+ assert result['id'] == self.normal_user.id
+ assert result['name'] == self.normal_user.name
+ assert result['fullname'] == normal_user_dict['fullname']
+ assert result['about'] == normal_user_dict['about']
+
+ #Normal users can not update other users
+ postparams = '%s=1' % json.dumps(sysadmin_user_dict)
+ res = self.app.post('/api/action/user_update', params=postparams,
+ extra_environ={'Authorization': str(self.normal_user.apikey)},
+ status=self.STATUS_403_ACCESS_DENIED)
+
+ res_obj = json.loads(res.body)
+ assert res_obj == {
+ 'error': {
+ '__type': 'Authorization Error',
+ 'message': 'Access denied'
+ },
+ 'help': 'Updates the user\'s details',
+ 'success': False
+ }
+
--- a/ckan/tests/functional/test_user.py Mon Jul 25 14:45:56 2011 +0100
+++ b/ckan/tests/functional/test_user.py Tue Jul 26 13:00:28 2011 +0100
@@ -1,6 +1,7 @@
from routes import url_for
from nose.tools import assert_equal
+from pprint import pprint
from ckan.tests import search_related, CreateTestData
from ckan.tests.html_check import HtmlCheckMethods
import ckan.model as model
@@ -185,7 +186,6 @@
res = self.app.get(offset, status=200)
main_res = self.main_div(res)
assert 'Register' in main_res, main_res
- from pprint import pprint
fv = res.forms['user-edit']
fv['name'] = username
fv['fullname'] = fullname
@@ -389,8 +389,6 @@
# preview
main_res = self.main_div(res)
assert 'Edit User: testedit' in main_res, main_res
- before_preview = main_res[:main_res.find('Preview')]
- assert new_about in before_preview, before_preview
in_preview = main_res[main_res.find('Preview'):]
assert new_about in in_preview, in_preview
http://bitbucket.org/okfn/ckan/changeset/3983f71ac7cb/
changeset: 3983f71ac7cb
branch: feature-1229-db-out-of-controllers
user: amercader
date: 2011-07-26 15:36:05
summary: [logic] Move user request_reset and perform_reset
affected #: 2 files (1.1 KB)
--- a/ckan/controllers/user.py Tue Jul 26 13:00:28 2011 +0100
+++ b/ckan/controllers/user.py Tue Jul 26 14:36:05 2011 +0100
@@ -246,32 +246,64 @@
def request_reset(self):
if request.method == 'POST':
id = request.params.get('user')
- user = model.User.get(id)
- if user is None:
+
+ context = {'model': model,
+ 'user': c.user}
+
+ data_dict = {'id':id}
+
+ try:
+ user_dict = get.user_show(context,data_dict)
+ user_obj = context['user_obj']
+
+ if user_dict is None:
+ h.flash_error(_('No such user: %s') % id)
+ try:
+ mailer.send_reset_link(user_obj)
+ h.flash_success(_('Please check your inbox for a reset code.'))
+ redirect('/')
+ except mailer.MailerException, e:
+ h.flash_error(_('Could not send reset link: %s') % unicode(e))
+
+ except NotFound:
h.flash_error(_('No such user: %s') % id)
- try:
- mailer.send_reset_link(user)
- h.flash_success(_('Please check your inbox for a reset code.'))
- redirect('/')
- except mailer.MailerException, e:
- h.flash_error(_('Could not send reset link: %s') % unicode(e))
return render('user/request_reset.html')
def perform_reset(self, id):
- user = model.User.get(id)
- if user is None:
- abort(404)
+ context = {'model': model, 'session': model.Session,
+ 'user': c.user}
+
+ data_dict = {'id':id}
+
+ try:
+ user_dict = get.user_show(context,data_dict)
+ user_obj = context['user_obj']
+ except NotFound, e:
+ abort(404, _('User not found'))
+
c.reset_key = request.params.get('key')
- if not mailer.verify_reset_link(user, c.reset_key):
+ if not mailer.verify_reset_link(user_obj, c.reset_key):
h.flash_error(_('Invalid reset key. Please try again.'))
abort(403)
+
if request.method == 'POST':
try:
- user.password = self._get_form_password()
- model.Session.add(user)
- model.Session.commit()
+ context['reset_password'] = True
+ new_password = self._get_form_password()
+ user_dict['password'] = new_password
+ user_dict['reset_key'] = c.reset_key
+ user = update.user_update(context, user_dict)
+
h.flash_success(_("Your password has been reset."))
redirect('/')
+ except NotAuthorized:
+ h.flash_error(_('Unauthorized to edit user %s') % id)
+ except NotFound, e:
+ h.flash_error(_('User not found'))
+ except DataError:
+ h.flash_error(_(u'Integrity Error'))
+ except ValidationError, e:
+ h.flash_error(u'%r'% e.error_dict)
except ValueError, ve:
h.flash_error(unicode(ve))
return render('user/perform_reset.html')
--- a/ckan/logic/action/update.py Tue Jul 26 13:00:28 2011 +0100
+++ b/ckan/logic/action/update.py Tue Jul 26 14:36:05 2011 +0100
@@ -293,7 +293,8 @@
if user_obj is None:
raise NotFound('User was not found.')
- if not (ckan.authz.Authorizer().is_sysadmin(unicode(user)) or user == user_obj.name):
+ if not (ckan.authz.Authorizer().is_sysadmin(unicode(user)) or user == user_obj.name) and \
+ not ('reset_key' in data_dict and data_dict['reset_key'] == user_obj['reset_key']):
raise NotAuthorized( _('User %s not authorized to edit %s') % (str(user), id))
data, errors = validate(data_dict, schema, context)
http://bitbucket.org/okfn/ckan/changeset/bc14ffe11d16/
changeset: bc14ffe11d16
branch: feature-1229-db-out-of-controllers
user: amercader
date: 2011-07-26 16:03:17
summary: [logic] Make password not mandatory when editing users
affected #: 3 files (264 bytes)
--- a/ckan/logic/schema.py Tue Jul 26 14:36:05 2011 +0100
+++ b/ckan/logic/schema.py Tue Jul 26 15:03:17 2011 +0100
@@ -218,9 +218,10 @@
def user_edit_form_schema():
schema = default_user_schema()
- schema['name'] = [ignore_missing]
- schema['password1'] = [unicode,user_both_passwords_entered,user_password_validator,user_passwords_match]
- schema['password2'] = [unicode]
+ schema['name'] = [ignore_missing]
+ schema['password'] = [ignore_missing]
+ schema['password1'] = [ignore_missing,unicode,user_password_validator,user_passwords_match]
+ schema['password2'] = [ignore_missing,unicode]
return schema
@@ -228,6 +229,6 @@
schema = default_user_schema()
schema['name'] = [ignore_missing]
-
+ schema['password'] = [user_password_validator,ignore_missing, unicode]
return schema
--- a/ckan/logic/validators.py Tue Jul 26 14:36:05 2011 +0100
+++ b/ckan/logic/validators.py Tue Jul 26 15:03:17 2011 +0100
@@ -194,8 +194,8 @@
def user_password_validator(key, data, errors, context):
value = data[key]
-
- if not isinstance(value, Missing) and not len(value) >= 4:
+
+ if not value == '' and not isinstance(value, Missing) and not len(value) >= 4:
errors[('password',)].append(_('Your password must be 4 characters or longer'))
def user_passwords_match(key, data, errors, context):
--- a/ckan/tests/functional/api/test_action.py Tue Jul 26 14:36:05 2011 +0100
+++ b/ckan/tests/functional/api/test_action.py Tue Jul 26 15:03:17 2011 +0100
@@ -207,12 +207,10 @@
def test_12_user_update(self):
normal_user_dict = {'id': self.normal_user.id,
- 'password': self.normal_user.password,
'fullname': 'Updated normal user full name',
'about':'Updated normal user about'}
sysadmin_user_dict = {'id': self.sysadmin_user.id,
- 'password': self.sysadmin_user.password,
'fullname': 'Updated sysadmin user full name',
'about':'Updated sysadmin user about'}
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