# HG changeset patch # User Julien Cristau # Date 1398172684 -7200 # Node ID 9e4a3c8719a7541bf14cd613452a464ef256b2bb # Parent 1f6ecd90df4ff7a01d0401362e9d00687611b75b [services] don't hardcode 'users' group for register_user Let the caller choose which group the user should be in. Related to #3020639 Caveat: this is a possible security hole if untrusted values are allowed. diff -r 1f6ecd90df4f -r 9e4a3c8719a7 sobjects/services.py --- a/sobjects/services.py Tue Apr 22 15:03:24 2014 +0200 +++ b/sobjects/services.py Tue Apr 22 15:18:04 2014 +0200 @@ -118,8 +118,9 @@ """ __regid__ = 'register_user' __select__ = Service.__select__ & match_kwargs('login', 'password') + default_groups = ('users',) - def call(self, login, password, email=None, **kwargs): + def call(self, login, password, email=None, groups=None, **kwargs): cnx = self._cw errmsg = cnx._('the value "%s" is already used, use another one') @@ -137,7 +138,10 @@ kwargs['upassword'] = password # we have to create the user user = cnx.create_entity('CWUser', **kwargs) - cnx.execute('SET X in_group G WHERE X eid %(x)s, G name "users"', + if groups is None: + groups = self.default_groups + group_names = ', '.join('%r' % group for group in groups) + cnx.execute('SET X in_group G WHERE X eid %%(x)s, G name IN (%s)' % group_names, {'x': user.eid}) if email or '@' in login: diff -r 1f6ecd90df4f -r 9e4a3c8719a7 sobjects/test/unittest_register_user.py --- a/sobjects/test/unittest_register_user.py Tue Apr 22 15:03:24 2014 +0200 +++ b/sobjects/test/unittest_register_user.py Tue Apr 22 15:18:04 2014 +0200 @@ -58,6 +58,37 @@ self.assertEqual(user.firstname, u'Foo3') self.assertEqual(user.use_email[0].address, u'foo3@bar3.com') + def test_register_user_groups(self): + with self.repo.internal_cnx() as cnx: + # default + cnx.call_service('register_user', login=u'foo_user', + password=u'bar_user', email=u'foo_user@bar_user.com', + firstname=u'Foo_user', surname=u'Bar_user') + + # group kwarg + cnx.call_service('register_user', login=u'foo_admin', + password=u'bar_admin', email=u'foo_admin@bar_admin.com', + firstname=u'Foo_admin', surname=u'Bar_admin', + groups=('managers', 'users')) + + # class attribute + from cubicweb.sobjects import services + services.RegisterUserService.default_groups = ('guests',) + cnx.call_service('register_user', login=u'foo_guest', + password=u'bar_guest', email=u'foo_guest@bar_guest.com', + firstname=u'Foo_guest', surname=u'Bar_guest') + cnx.commit() + + with self.admin_access.client_cnx() as cnx: + user = cnx.find('CWUser', login=u'foo_user').one() + self.assertEqual([g.name for g in user.in_group], ['users']) + + admin = cnx.find('CWUser', login=u'foo_admin').one() + self.assertEqual(sorted(g.name for g in admin.in_group), ['managers', 'users']) + + guest = cnx.find('CWUser', login=u'foo_guest').one() + self.assertEqual([g.name for g in guest.in_group], ['guests']) + if __name__ == '__main__': from logilab.common.testlib import unittest_main