[services] don't hardcode 'users' group for register_user
authorJulien Cristau <julien.cristau@logilab.fr>
Tue, 22 Apr 2014 15:18:04 +0200
changeset 9689 9e4a3c8719a7
parent 9688 1f6ecd90df4f
child 9690 2b506822ca54
[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.
sobjects/services.py
sobjects/test/unittest_register_user.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:
--- 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