diff options
-rw-r--r-- | API.txt | 24 | ||||
-rw-r--r-- | VERSION | 4 | ||||
-rw-r--r-- | install/ui/src/freeipa/user.js | 10 | ||||
-rw-r--r-- | ipalib/plugins/user.py | 17 | ||||
-rw-r--r-- | ipatests/test_xmlrpc/test_user_plugin.py | 92 |
5 files changed, 136 insertions, 11 deletions
@@ -3791,13 +3791,16 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) output: Output('value', <type 'unicode'>, None) command: user_add -args: 1,39,3 +args: 1,43,3 arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, required=True) option: Str('addattr*', cli_name='addattr', exclude='webui') option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') -option: Str('carlicense', attribute=True, cli_name='carlicense', multivalue=False, required=False) +option: Str('carlicense', attribute=True, cli_name='carlicense', multivalue=True, required=False) option: Str('cn', attribute=True, autofill=True, cli_name='cn', multivalue=False, required=True) +option: Str('departmentnumber', attribute=True, cli_name='departmentnumber', multivalue=True, required=False) option: Str('displayname', attribute=True, autofill=True, cli_name='displayname', multivalue=False, required=False) +option: Str('employeenumber', attribute=True, cli_name='employeenumber', multivalue=False, required=False) +option: Str('employeetype', attribute=True, cli_name='employeetype', multivalue=False, required=False) option: Str('facsimiletelephonenumber', attribute=True, cli_name='fax', multivalue=True, required=False) option: Str('gecos', attribute=True, autofill=True, cli_name='gecos', multivalue=False, required=False) option: Int('gidnumber', attribute=True, cli_name='gidnumber', minvalue=1, multivalue=False, required=False) @@ -3820,6 +3823,7 @@ option: Bool('nsaccountlock', attribute=True, cli_name='nsaccountlock', multival option: Str('ou', attribute=True, cli_name='orgunit', multivalue=False, required=False) option: Str('pager', attribute=True, cli_name='pager', multivalue=True, required=False) option: Str('postalcode', attribute=True, cli_name='postalcode', multivalue=False, required=False) +option: Str('preferredlanguage', attribute=True, cli_name='preferredlanguage', multivalue=False, pattern='^(([a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\\=((0(\\.[0-9]{0,3})?)|(1(\\.0{0,3})?)))?(\\s*,\\s*[a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\\=((0(\\.[0-9]{0,3})?)|(1(\\.0{0,3})?)))?)*)|(\\*))$', required=False) option: Flag('random', attribute=False, autofill=True, cli_name='random', default=False, multivalue=False, required=False) option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') option: Str('setattr*', cli_name='setattr', exclude='webui') @@ -3858,12 +3862,15 @@ output: Output('result', <type 'bool'>, None) output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) output: Output('value', <type 'unicode'>, None) command: user_find -args: 1,49,4 +args: 1,53,4 arg: Str('criteria?', noextrawhitespace=False) option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') -option: Str('carlicense', attribute=True, autofill=False, cli_name='carlicense', multivalue=False, query=True, required=False) +option: Str('carlicense', attribute=True, autofill=False, cli_name='carlicense', multivalue=True, query=True, required=False) option: Str('cn', attribute=True, autofill=False, cli_name='cn', multivalue=False, query=True, required=False) +option: Str('departmentnumber', attribute=True, autofill=False, cli_name='departmentnumber', multivalue=True, query=True, required=False) option: Str('displayname', attribute=True, autofill=False, cli_name='displayname', multivalue=False, query=True, required=False) +option: Str('employeenumber', attribute=True, autofill=False, cli_name='employeenumber', multivalue=False, query=True, required=False) +option: Str('employeetype', attribute=True, autofill=False, cli_name='employeetype', multivalue=False, query=True, required=False) option: Str('facsimiletelephonenumber', attribute=True, autofill=False, cli_name='fax', multivalue=True, query=True, required=False) option: Str('gecos', attribute=True, autofill=False, cli_name='gecos', multivalue=False, query=True, required=False) option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, query=True, required=False) @@ -3895,6 +3902,7 @@ option: Str('ou', attribute=True, autofill=False, cli_name='orgunit', multivalue option: Str('pager', attribute=True, autofill=False, cli_name='pager', multivalue=True, query=True, required=False) option: Flag('pkey_only?', autofill=True, default=False) option: Str('postalcode', attribute=True, autofill=False, cli_name='postalcode', multivalue=False, query=True, required=False) +option: Str('preferredlanguage', attribute=True, autofill=False, cli_name='preferredlanguage', multivalue=False, pattern='^(([a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\\=((0(\\.[0-9]{0,3})?)|(1(\\.0{0,3})?)))?(\\s*,\\s*[a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\\=((0(\\.[0-9]{0,3})?)|(1(\\.0{0,3})?)))?)*)|(\\*))$', query=True, required=False) option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') option: Int('sizelimit?', autofill=False, minvalue=0) option: Str('sn', attribute=True, autofill=False, cli_name='last', multivalue=False, query=True, required=False) @@ -3914,14 +3922,17 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) output: Output('truncated', <type 'bool'>, None) command: user_mod -args: 1,40,3 +args: 1,44,3 arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True) option: Str('addattr*', cli_name='addattr', exclude='webui') option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') -option: Str('carlicense', attribute=True, autofill=False, cli_name='carlicense', multivalue=False, required=False) +option: Str('carlicense', attribute=True, autofill=False, cli_name='carlicense', multivalue=True, required=False) option: Str('cn', attribute=True, autofill=False, cli_name='cn', multivalue=False, required=False) option: Str('delattr*', cli_name='delattr', exclude='webui') +option: Str('departmentnumber', attribute=True, autofill=False, cli_name='departmentnumber', multivalue=True, required=False) option: Str('displayname', attribute=True, autofill=False, cli_name='displayname', multivalue=False, required=False) +option: Str('employeenumber', attribute=True, autofill=False, cli_name='employeenumber', multivalue=False, required=False) +option: Str('employeetype', attribute=True, autofill=False, cli_name='employeetype', multivalue=False, required=False) option: Str('facsimiletelephonenumber', attribute=True, autofill=False, cli_name='fax', multivalue=True, required=False) option: Str('gecos', attribute=True, autofill=False, cli_name='gecos', multivalue=False, required=False) option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, required=False) @@ -3942,6 +3953,7 @@ option: Bool('nsaccountlock', attribute=True, autofill=False, cli_name='nsaccoun option: Str('ou', attribute=True, autofill=False, cli_name='orgunit', multivalue=False, required=False) option: Str('pager', attribute=True, autofill=False, cli_name='pager', multivalue=True, required=False) option: Str('postalcode', attribute=True, autofill=False, cli_name='postalcode', multivalue=False, required=False) +option: Str('preferredlanguage', attribute=True, autofill=False, cli_name='preferredlanguage', multivalue=False, pattern='^(([a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\\=((0(\\.[0-9]{0,3})?)|(1(\\.0{0,3})?)))?(\\s*,\\s*[a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\\=((0(\\.[0-9]{0,3})?)|(1(\\.0{0,3})?)))?)*)|(\\*))$', required=False) option: Flag('random', attribute=False, autofill=True, cli_name='random', default=False, multivalue=False, required=False) option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') option: Str('rename', cli_name='rename', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, required=False) @@ -89,5 +89,5 @@ IPA_DATA_VERSION=20100614120000 # # ######################################################## IPA_API_VERSION_MAJOR=2 -IPA_API_VERSION_MINOR=80 -# Last change: pviktori - ":" in permission names +IPA_API_VERSION_MINOR=81 +# Last change: amisnyov - user plugin extend diff --git a/install/ui/src/freeipa/user.js b/install/ui/src/freeipa/user.js index e6b252649..aee1b694e 100644 --- a/install/ui/src/freeipa/user.js +++ b/install/ui/src/freeipa/user.js @@ -245,12 +245,18 @@ return { name: 'manager', other_entity: 'user', other_field: 'uid' - } + }, + { $type: 'multivalued', name: 'departmentnumber' }, + 'employeenumber', + 'employeetype', + 'preferredlanguage' ] }, { name: 'misc', - fields: [ 'carlicense' ] + fields: [ + { $type: 'multivalued', name: 'carlicense' } + ] } ], actions: [ diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py index edda273b2..4bdfb26a7 100644 --- a/ipalib/plugins/user.py +++ b/ipalib/plugins/user.py @@ -362,7 +362,7 @@ class user(LDAPObject): Str('manager?', label=_('Manager'), ), - Str('carlicense?', + Str('carlicense*', label=_('Car License'), ), Bool('nsaccountlock?', @@ -397,6 +397,21 @@ class user(LDAPObject): cli_name='radius_username', label=_('RADIUS proxy username'), ), + Str('departmentnumber*', + label=_('Department Number'), + ), + Str('employeenumber?', + label=_('Employee Number'), + ), + Str('employeetype?', + label=_('Employee Type'), + ), + Str('preferredlanguage?', + label=_('Preferred Language'), + pattern='^(([a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\=((0(\.[0-9]{0,3})?)|(1(\.0{0,3})?)))?' \ + + '(\s*,\s*[a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?(;q\=((0(\.[0-9]{0,3})?)|(1(\.0{0,3})?)))?)*)|(\*))$', + pattern_errmsg='must match RFC 2068 - 14.4, e.g., "da, en-gb;q=0.8, en;q=0.7"', + ), ) def _normalize_and_validate_email(self, email, config=None): diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py index 9b1777589..b7febe745 100644 --- a/ipatests/test_xmlrpc/test_user_plugin.py +++ b/ipatests/test_xmlrpc/test_user_plugin.py @@ -47,6 +47,15 @@ invaliduser2=u'tuser1234567890123456789012345678901234567890' sshpubkey = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGAX3xAeLeaJggwTqMjxNwa6XHBUAikXPGMzEpVrlLDCZtv00djsFTBi38PkgxBJVkgRWMrcBsr/35lq7P6w8KGIwA8GI48Z0qBS2NBMJ2u9WQ2hjLN6GdMlo77O0uJY3251p12pCVIS/bHRSq8kHO2No8g7KA9fGGcagPfQH+ee3t7HUkpbQkFTmbPPN++r3V8oVUk5LxbryB3UIIVzNmcSIn3JrXynlvui4MixvrtX6zx+O/bBo68o8/eZD26QrahVbA09fivrn/4h3TM019Eu/c2jOdckfU3cHUV/3Tno5d6JicibyaoDDK7S/yjdn5jhaz8MSEayQvFkZkiF0L public key test' sshpubkeyfp = u'13:67:6B:BF:4E:A2:05:8E:AE:25:8B:A1:31:DE:6F:1B public key test (ssh-rsa)' +validlanguage1=u'en-US;q=0.987 , en, abcdfgh-abcdefgh;q=1 , a;q=1.000' +validlanguage2=u'*' + +invalidlanguage1=u'abcdfghji-abcdfghji' +invalidlanguage2=u'en-us;q=0,123' +invalidlanguage3=u'en-us;q=0.1234' +invalidlanguage4=u'en-us;q=1.1' +invalidlanguage5=u'en-us;q=1.0000' + # Date in ISO format (2013-12-10T12:00:00) isodate_re = re.compile('^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$') @@ -1470,4 +1479,87 @@ class test_user(Declarative): ), ), + dict( + desc='Test an invalid preferredlanguage "%s"' % invalidlanguage1, + command=('user_mod', [user1], dict(preferredlanguage=invalidlanguage1)), + expected=errors.ValidationError(name='preferredlanguage', + error=u'must match RFC 2068 - 14.4, e.g., "da, en-gb;q=0.8, en;q=0.7"'), + ), + + dict( + desc='Test an invalid preferredlanguage "%s"' % invalidlanguage2, + command=('user_mod', [user1], dict(preferredlanguage=invalidlanguage2)), + expected=errors.ValidationError(name='preferredlanguage', + error=u'must match RFC 2068 - 14.4, e.g., "da, en-gb;q=0.8, en;q=0.7"'), + ), + + dict( + desc='Test an invalid preferredlanguage "%s"' % invalidlanguage3, + command=('user_mod', [user1], dict(preferredlanguage=invalidlanguage3)), + expected=errors.ValidationError(name='preferredlanguage', + error=u'must match RFC 2068 - 14.4, e.g., "da, en-gb;q=0.8, en;q=0.7"'), + ), + + dict( + desc='Test an invalid preferredlanguage "%s"' % invalidlanguage4, + command=('user_mod', [user1], dict(preferredlanguage=invalidlanguage4)), + expected=errors.ValidationError(name='preferredlanguage', + error=u'must match RFC 2068 - 14.4, e.g., "da, en-gb;q=0.8, en;q=0.7"'), + ), + + dict( + desc='Test an invalid preferredlanguage "%s"' % invalidlanguage5, + command=('user_mod', [user1], dict(preferredlanguage=invalidlanguage5)), + expected=errors.ValidationError(name='preferredlanguage', + error=u'must match RFC 2068 - 14.4, e.g., "da, en-gb;q=0.8, en;q=0.7"'), + ), + + dict( + desc='Set preferredlanguage "%s"' % validlanguage1, + command=('user_mod', [user1], dict(preferredlanguage=validlanguage1)), + expected=dict( + result=dict( + givenname=[u'Test'], + homedirectory=[u'/home/tuser1'], + loginshell=[u'/bin/sh'], + sn=[u'User1'], + uid=[user1], + uidnumber=[fuzzy_digits], + gidnumber=[fuzzy_digits], + mail=[u'%s@%s' % (user1, api.env.domain)], + memberof_group=[u'ipausers'], + nsaccountlock=False, + has_keytab=False, + has_password=False, + preferredlanguage=[validlanguage1], + ), + value=user1, + summary='Modified user "%s"' % user1, + ), + ), + + dict( + desc='Set preferredlanguage "%s"' % validlanguage2, + command=('user_mod', [user1], dict(preferredlanguage=validlanguage2)), + expected=dict( + result=dict( + givenname=[u'Test'], + homedirectory=[u'/home/tuser1'], + loginshell=[u'/bin/sh'], + sn=[u'User1'], + uid=[user1], + uidnumber=[fuzzy_digits], + gidnumber=[fuzzy_digits], + mail=[u'%s@%s' % (user1, api.env.domain)], + memberof_group=[u'ipausers'], + nsaccountlock=False, + has_keytab=False, + has_password=False, + preferredlanguage=[validlanguage2], + ), + value=user1, + summary='Modified user "%s"' % user1, + ), + ), + ] |