From 40713e71f96568cbebec44bf034dc72f90f46cd2 Mon Sep 17 00:00:00 2001 From: Thomas Woerner <twoerner@redhat.com> Date: Mon, 21 Oct 2019 12:14:36 +0200 Subject: [PATCH] ipauser: User module extension The ipauser module now supports all user settings and additionally to ensure the presence of several users with the new users setting. The users setting can also be used with other states, but it has to be limited to only contain the name of the users. There updated user management module is placed in the plugins folder: plugins/modules/ipauser.py The user module now additionally allows to handle these user settings: initials principalexpiration random city userstate postalcode mobile pager fax orgunit manager carlicense sshpubkey userauthtype userclass radius radiususer departmentnumber employeenumber employeetype preferredlanguage certificate certmapdata noprivate nomembers Here is the updated documentation for the module: README-user.md New example playbooks have been added: playbooks/user/user_certificate_absent.yml playbooks/user/user_certificate_present.yml playbooks/user/user_present.yml playbooks/user/users_absent.yml playbooks/user/users_certificate_absent.yml playbooks/user/users_certificate_present.yml playbooks/user/users_present.yml plugins/modules/ipauser.py New tests added for ipauser: tests/user/certificate/cert1.der tests/user/certificate/cert1.pem tests/user/certificate/cert2.der tests/user/certificate/cert2.pem tests/user/certificate/cert3.der tests/user/certificate/cert3.pem tests/user/certificate/private1.key tests/user/certificate/private2.key tests/user/certificate/private3.key tests/user/certificate/test_user_certificate.yml tests/user/certificate/test_users_certificate.yml tests/user/certmapdata/test_user_certmapdata.yml tests/user/certmapdata/test_user_certmapdata_issuer_subject.yml tests/user/certmapdata/test_users_certmapdata.yml tests/user/test_user.yml tests/user/test_users.yml tests/user/test_users_absent.yml tests/user/test_users_invalid_cert.yml tests/user/test_users_present.yml tests/user/test_users_present_slice.yml tests/user/users_absent.json tests/user/users_absent.sh tests/user/users_present.json tests/user/users_present.sh --- README-user.md | 180 +- playbooks/user/user_certificate_absent.yml | 16 + playbooks/user/user_certificate_present.yml | 15 + playbooks/user/user_present.yml | 40 + playbooks/user/users_absent.yml | 42 + playbooks/user/users_certificate_absent.yml | 17 + playbooks/user/users_certificate_present.yml | 16 + playbooks/user/users_present.yml | 41 + plugins/modules/ipauser.py | 1114 +++- tests/user/certificate/cert1.der | Bin 0 -> 771 bytes tests/user/certificate/cert1.pem | 19 + tests/user/certificate/cert2.der | Bin 0 -> 771 bytes tests/user/certificate/cert2.pem | 19 + tests/user/certificate/cert3.der | Bin 0 -> 771 bytes tests/user/certificate/cert3.pem | 19 + tests/user/certificate/private1.key | 28 + tests/user/certificate/private2.key | 28 + tests/user/certificate/private3.key | 28 + .../certificate/test_user_certificate.yml | 92 + .../certificate/test_users_certificate.yml | 103 + .../certmapdata/test_user_certmapdata.yml | 160 + .../test_user_certmapdata_issuer_subject.yml | 91 + .../certmapdata/test_users_certmapdata.yml | 171 + tests/user/test_user.yml | 258 + tests/user/test_users.yml | 376 ++ tests/user/test_users_absent.yml | 16 + tests/user/test_users_invalid_cert.yml | 64 + tests/user/test_users_present.yml | 15 + tests/user/test_users_present_slice.yml | 19 + tests/user/users_absent.json | 3004 ++++++++++ tests/user/users_absent.sh | 22 + tests/user/users_present.json | 5004 +++++++++++++++++ tests/user/users_present.sh | 24 + 33 files changed, 10902 insertions(+), 139 deletions(-) create mode 100644 playbooks/user/user_certificate_absent.yml create mode 100644 playbooks/user/user_certificate_present.yml create mode 100644 playbooks/user/user_present.yml create mode 100644 playbooks/user/users_absent.yml create mode 100644 playbooks/user/users_certificate_absent.yml create mode 100644 playbooks/user/users_certificate_present.yml create mode 100644 playbooks/user/users_present.yml create mode 100644 tests/user/certificate/cert1.der create mode 100644 tests/user/certificate/cert1.pem create mode 100644 tests/user/certificate/cert2.der create mode 100644 tests/user/certificate/cert2.pem create mode 100644 tests/user/certificate/cert3.der create mode 100644 tests/user/certificate/cert3.pem create mode 100644 tests/user/certificate/private1.key create mode 100644 tests/user/certificate/private2.key create mode 100644 tests/user/certificate/private3.key create mode 100644 tests/user/certificate/test_user_certificate.yml create mode 100644 tests/user/certificate/test_users_certificate.yml create mode 100644 tests/user/certmapdata/test_user_certmapdata.yml create mode 100644 tests/user/certmapdata/test_user_certmapdata_issuer_subject.yml create mode 100644 tests/user/certmapdata/test_users_certmapdata.yml create mode 100644 tests/user/test_user.yml create mode 100644 tests/user/test_users.yml create mode 100644 tests/user/test_users_absent.yml create mode 100644 tests/user/test_users_invalid_cert.yml create mode 100644 tests/user/test_users_present.yml create mode 100644 tests/user/test_users_present_slice.yml create mode 100644 tests/user/users_absent.json create mode 100644 tests/user/users_absent.sh create mode 100644 tests/user/users_present.json create mode 100644 tests/user/users_present.sh diff --git a/README-user.md b/README-user.md index 064a192f..528f0998 100644 --- a/README-user.md +++ b/README-user.md @@ -41,7 +41,7 @@ ipaserver.test.local ``` -Example playbook to add users: +Example playbook to ensure a user is present: ```yaml --- @@ -50,7 +50,7 @@ Example playbook to add users: become: true tasks: - # Create user pinky + # Ensure user pinky is present - ipauser: ipaadmin_password: MyPassword123 name: pinky @@ -64,7 +64,7 @@ Example playbook to add users: password: "no-brain" update_password: on_create - # Create user brain + # Ensure user brain is present - ipauser: ipaadmin_password: MyPassword123 name: brain @@ -74,6 +74,75 @@ Example playbook to add users: `update_password` controls if a password for a user will be set in present state only on creation or every time (always). +These two `ipauser` module calls can be combined into one with the `users` variable: + +```yaml +--- +- name: Playbook to handle users + hosts: ipaserver + become: true + + tasks: + # Ensure users pinky and brain are present + - ipauser: + ipaadmin_password: MyPassword123 + users: + - name: pinky + first: pinky + last: Acme + uid: 10001 + gid: 100 + phone: "+555123457" + email: pinky@acme.com + passwordexpiration: "2023-01-19 23:59:59" + password: "no-brain" + - name: brain + first: brain + last: Acme + update_password: on_create +``` + +You can also alternatively use a json file containing the users, here `users_present.json`: + +```json +{ + "users": [ + { + "name": "user1", + "first": "First 1", + "last": "Last 1" + }, + { + "name": "user2", + "first": "First 2", + "last": "Last 2" + }, + ... + ] +} +``` + +And ensure the presence of the users with this example playbook: + +```yaml +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Include users_present.json + include_vars: + file: users_present.json + + - name: Users present + ipauser: + ipaadmin_password: SomeADMINpassword + users: "{{ users }}" +``` + + Example playbook to delete a user, but preserve it: ```yaml @@ -91,6 +160,28 @@ Example playbook to delete a user, but preserve it: state: absent ``` +This can also be done with the `users` variable containing only names, this can be combined into one module call: + +Example playbook to delete a user is absent, but preserved: + +```yaml +--- +- name: Playbook to handle users + hosts: ipaserver + become: true + + tasks: + # Remove but preserve user pinky + - ipauser: + ipaadmin_password: MyPassword123 + users: + - name: pinky + preserve: yes + state: absent +``` + +This can also be done as an alternative with the `users` variable containing only names. + Example playbook to undelete a preserved user. @@ -108,6 +199,8 @@ Example playbook to undelete a preserved user. state: undeleted ``` +This can also be done as an alternative with the `users` variable containing only names. + Example playbook to disable a user: @@ -125,6 +218,8 @@ Example playbook to disable a user: state: disabled ``` +This can also be done as an alternative with the `users` variable containing only names. + Example playbook to enable users: @@ -142,6 +237,8 @@ Example playbook to enable users: state: enabled ``` +This can also be done as an alternative with the `users` variable containing only names. + Example playbook to unlock users: @@ -160,7 +257,7 @@ Example playbook to unlock users: ``` -Example playbook to delete users: +Example playbook to ensure users are absent: ```yaml --- @@ -169,13 +266,34 @@ Example playbook to delete users: become: true tasks: - # Remove user pinky and brain + # Ensure users pinky and brain are absent - ipauser: ipaadmin_password: MyPassword123 name: pinky,brain state: absent ``` +This can also be done as an alternative with the `users` variable containing only names. + + +Example playbook to ensure users are absent: + +```yaml +--- +- name: Playbook to handle users + hosts: ipaserver + become: true + + tasks: + # Ensure users pinky and brain are absent + - ipauser: + ipaadmin_password: MyPassword123 + users: + - name: pinky + - name: brain + state: absent +``` + Variables ========= @@ -183,11 +301,28 @@ Variables ipauser ------- +**General Variables:** + Variable | Description | Required -------- | ----------- | -------- `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no `ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no -`name` | The list of user name strings. | no +`name` | The list of user name strings. `name` with *user variables* or `users` containing *user variables* need to be used. | no +**User variables** | Only used with `name` variable in the first level. | no +`users` | The list of user dicts. Each `users` dict entry can contain **user variables**.<br>There is one required option in the `users` dict:| no + | `name` - The user name string of the entry. | yes + | **User variables** | no +`preserve` | Delete a user, keeping the entry available for future use. (bool) | no +`update_password` | Set password for a user in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no +`preserve` | Delete a user, keeping the entry available for future use. (bool) | no +`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `unlocked` or `undeleted`, default: `present`. Only `names` or `users` with only `name` set are allowed if state is not `present`. | yes + + + +**User Variables:** + +Variable | Description | Required +-------- | ----------- | -------- `first` \| `givenname` | The first name string. | no `last` | The last name | no `fullname` \| `cn` | The full name string. | no @@ -195,17 +330,40 @@ Variable | Description | Required `homedir` | The home directory string. | no `shell` \| `loginshell` | The login shell string. | no `email` | List of email address strings. | no -`principalname` \| `krbprincipalname` | The kerberos principal sptring. | no +`principal` \| `principalnam` \| `krbprincipalname` | The kerberos principal sptring. | no +`principalexpiration` \| `krbprincipalexpiration` | The kerberos principal expiration date. Possible formats: `YYYYMMddHHmmssZ`, `YYYY-MM-ddTHH:mm:ssZ`, `YYYY-MM-ddTHH:mmZ`, `YYYY-MM-ddZ`, `YYYY-MM-dd HH:mm:ssZ` or `YYYY-MM-dd HH:mmZ`. The trailing 'Z' can be skipped. | no `passwordexpiration` \| `krbpasswordexpiration` | The kerberos password expiration date. Possible formats: `YYYYMMddHHmmssZ`, `YYYY-MM-ddTHH:mm:ssZ`, `YYYY-MM-ddTHH:mmZ`, `YYYY-MM-ddZ`, `YYYY-MM-dd HH:mm:ssZ` or `YYYY-MM-dd HH:mmZ`. The trailing 'Z' can be skipped. | no `password` | The user password string. | no +`random` | Generate a random user password | no `uid` \| `uidnumber` | The UID integer. | no `gid` \| `gidnumber` | The GID integer. | no +`city` | City | no +`userstate` \| `st` | State/Province | no +`postalcode` \| `zip` | Postalcode/ZIP | no `phone` \| `telephonenumber` | List of telephone number strings, | no +`mobile` | List of mobile telephone number strings. | no +`pager` | List of pager number strings. | no +`fax` \| `facsimiletelephonenumber` | List of fax number strings. | no +`orgunit` | The Organisation unit. | no `title` | The job title string. | no -~~`sshpubkey` \| `ipasshpubkey`~~ | ~~List of SSH public keys.~~ | ~~no~~ -`update_password` | Set password for a user in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no -`preserve` | Delete a user, keeping the entry available for future use. (bool) | no -`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `unlocked` or `undeleted`, default: `present`. | yes +`manager` | List of manager user names. | no +`carlicense` | List of car licenses. | no +`sshpubkey` \| `ipasshpubkey` | List of SSH public keys. | no +`userauthtype` | List of supported user authentication types. Choices: `password`, `radius` and `otp` | no +`userclass` | User category. (semantics placed on this attribute are for local interpretation). | no +`radius` | RADIUS proxy configuration | no +`radiususer` | RADIUS proxy username | no +`departmentnumber` | Department Number | no +`employeenumber` | Employee Number | no +`employeetype` | Employee Type | no +`preferredlanguage` | Preferred Language | no +`certificate` | List of base-64 encoded user certificates. | no +`certmapdata` | List of certificate mappings. Either `certificate` or `issuer` together with `subject` need to be specified. <br>Options: | no + | `certificate` - Base-64 encoded user certificate | no + | `issuer` - Issuer of the certificate | no + | `subject` - Subject of the certificate | no +`noprivate` | Do not create user private group. (bool) | no +`nomembers` | Suppress processing of membership attributes. (bool) | no Authors diff --git a/playbooks/user/user_certificate_absent.yml b/playbooks/user/user_certificate_absent.yml new file mode 100644 index 00000000..d50b40f4 --- /dev/null +++ b/playbooks/user/user_certificate_absent.yml @@ -0,0 +1,16 @@ +--- +- name: Test user certificates + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test cert absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certificate: + - 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 + state: absent diff --git a/playbooks/user/user_certificate_present.yml b/playbooks/user/user_certificate_present.yml new file mode 100644 index 00000000..b3220846 --- /dev/null +++ b/playbooks/user/user_certificate_present.yml @@ -0,0 +1,15 @@ +--- +- name: Test user certificates + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test cert present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certificate: + - 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 diff --git a/playbooks/user/user_present.yml b/playbooks/user/user_present.yml new file mode 100644 index 00000000..9abf26a9 --- /dev/null +++ b/playbooks/user/user_present.yml @@ -0,0 +1,40 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User pinky present + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + uid: 10001 + gid: 100 + phone: "+555123457" + email: pinky@acme.com + principalexpiration: "20220119235959" + passwordexpiration: "2022-01-19 23:59:59" + first: pinky + last: Acme + initials: pa + principal: pa + random: yes + city: PinkyCity + userstate: PinkyState + postalcode: 321 + mobile: "+555123458,+555123459" + pager: "+555123450,+555123451" + fax: "+555123452,+555123453" + orgunit: PinkyOrgUnit + manager: manager1,manager2 + update_password: on_create + carlicense: PinkyCarLicense1,PinkyCarLicense2 + userauthtype: password,radius,otp + userclass: PinkyUserClass + departmentnumber: "1234" + employeenumber: "0815" + employeetype: "PinkyExmployeeType" + preferredlanguage: "en" + noprivate: yes + nomembers: false diff --git a/playbooks/user/users_absent.yml b/playbooks/user/users_absent.yml new file mode 100644 index 00000000..a592a062 --- /dev/null +++ b/playbooks/user/users_absent.yml @@ -0,0 +1,42 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Users user1..10 absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: user1 + givenname: user1 + last: Last + - name: user2 + first: user2 + last: Last + - name: user3 + first: user3 + last: Last + - name: user4 + first: user4 + last: Last + - name: user5 + first: user5 + last: Last + - name: user6 + first: user6 + last: Last + - name: user7 + first: user7 + last: Last + - name: user8 + first: user8 + last: Last + - name: user9 + first: user9 + last: Last + - name: user10 + first: user10 + last: Last + state: absent diff --git a/playbooks/user/users_certificate_absent.yml b/playbooks/user/users_certificate_absent.yml new file mode 100644 index 00000000..0963e4fe --- /dev/null +++ b/playbooks/user/users_certificate_absent.yml @@ -0,0 +1,17 @@ +--- +- name: Test user certificates + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test cert absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - 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 + state: absent diff --git a/playbooks/user/users_certificate_present.yml b/playbooks/user/users_certificate_present.yml new file mode 100644 index 00000000..8d82a877 --- /dev/null +++ b/playbooks/user/users_certificate_present.yml @@ -0,0 +1,16 @@ +--- +- name: Test user certificates + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test cert present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - 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 diff --git a/playbooks/user/users_present.yml b/playbooks/user/users_present.yml new file mode 100644 index 00000000..3b9303b0 --- /dev/null +++ b/playbooks/user/users_present.yml @@ -0,0 +1,41 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Users user1..10 present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: user1 + first: user1 + last: Last + - name: user2 + first: user2 + last: Last + - name: user3 + first: user3 + last: Last + - name: user4 + first: user4 + last: Last + - name: user5 + first: user5 + last: Last + - name: user6 + first: user6 + last: Last + - name: user7 + first: user7 + last: Last + - name: user8 + first: user8 + last: Last + - name: user9 + first: user9 + last: Last + - name: user10 + first: user10 + last: Last diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py index 748eb841..4a25ed7b 100644 --- a/plugins/modules/ipauser.py +++ b/plugins/modules/ipauser.py @@ -41,6 +41,167 @@ options: name: description: The list of users (internally uid). required: false + users: + description: The list of user dicts (internally uid). + options: + name: + description: The ser (internally uid). + required: true + first: + description: The first name + required: false + aliases: ["givenname"] + last: + description: The last name + required: false + fullname: + description: The full name + required: false + aliases: ["cn"] + displayname: + description: The display name + required: false + initials: + description: Initials + required: false + homedir: + description: The home directory + required: false + shell: + description: The login shell + required: false + aliases: ["loginshell"] + email: + description: List of email addresses + required: false + principal: + description: The kerberos principal + required: false + aliases: ["principalname", "krbprincipalname"] + principalexpiration: + description: + - The kerberos principal expiration date + - (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ, + - YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ, + - YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped. + required: false + aliases: ["krbprincipalexpiration"] + passwordexpiration: + description: + - The kerberos password expiration date (FreeIPA-4.7+) + - (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ, + - YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ, + - YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped. + required: false + aliases: ["krbpasswordexpiration"] + password: + description: The user password + required: false + random: + description: Generate a random user password + required: false + type: bool + uid: + description: The UID + required: false + aliases: ["uidnumber"] + gid: + description: The GID + required: false + aliases: ["gidnumber"] + city: + description: City + required: false + userstate: + description: State/Province + required: false + aliases: ["st"] + postalcode: + description: Postalcode/ZIP + required: false + aliases: ["zip"] + phone: + description: List of telephone numbers + required: false + aliases: ["telephonenumber"] + mobile: + description: List of mobile telephone numbers + required: false + pager: + description: List of pager numbers + required: false + fax: + description: List of fax numbers + required: false + aliases: ["facsimiletelephonenumber"] + orgunit: + description: Org. Unit + required: false + title: + description: The job title + required: false + manager: + description: List of managers + required: false + carlicense: + description: List of car licenses + required: false + sshpubkey: + description: List of SSH public keys + required: false + aliases: ["ipasshpubkey"] + userauthtype: + description: List of supported user authentication types + choices=['password', 'radius', 'otp'] + required: false + userclass: + description: + - User category + - (semantics placed on this attribute are for local interpretation) + required: false + radius: + description: RADIUS proxy configuration + required: false + radiususer: + description: RADIUS proxy username + required: false + departmentnumber: + description: Department Number + required: false + employeenumber: + description: Employee Number + required: false + employeetype: + description: Employee Type + required: false + preferredlanguage: + description: Preferred Language + required: false + certificate: + description: List of base-64 encoded user certificates + required: false + certmapdata: + description: List of certificate mappings + options: + certificate: + description: Base-64 encoded user certificate + required: false + issuer: + description: Issuer of the certificate + required: false + subject: + description: Subject of the certificate + required: false + required: false + noprivate: + description: Don't create user private group + required: false + type: bool + nomembers: + description: Suppress processing of membership attributes + required: false + type: bool + required: false first: description: The first name required: false @@ -55,6 +216,9 @@ options: displayname: description: The display name required: false + initials: + description: Initials + required: false homedir: description: The home directory required: false @@ -65,13 +229,21 @@ options: email: description: List of email addresses required: false - principalname: + principal: description: The kerberos principal required: false - aliases: ["krbprincipalname"] + aliases: ["principalname", "krbprincipalname"] + principalexpiration: + description: + - The kerberos principal expiration date + - (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ, + - YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ, + - YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped. + required: false + aliases: ["krbprincipalexpiration"] passwordexpiration: description: - - The kerberos password expiration date + - The kerberos password expiration date (FreeIPA-4.7+) - (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ, - YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ, - YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped. @@ -80,6 +252,10 @@ options: password: description: The user password required: false + random: + description: Generate a random user password + required: false + type: bool uid: description: The UID required: false @@ -88,26 +264,111 @@ options: description: The GID required: false aliases: ["gidnumber"] + city: + description: City + required: false + userstate: + description: State/Province + required: false + aliases: ["st"] + postalcode: + description: ZIP + required: false + aliases: ["zip"] phone: description: List of telephone numbers required: false aliases: ["telephonenumber"] + mobile: + description: List of mobile telephone numbers + required: false + pager: + description: List of pager numbers + required: false + fax: + description: List of fax numbers + required: false + aliases: ["facsimiletelephonenumber"] + orgunit: + description: Org. Unit + required: false title: description: The job title required: false - #sshpubkey: - # description: List of SSH public keys - # required: false - # aliases: ["ipasshpubkey"] - # .. + manager: + description: List of managers + required: false + carlicense: + description: List of car licenses + required: false + sshpubkey: + description: List of SSH public keys + required: false + aliases: ["ipasshpubkey"] + userauthtype: + description: List of supported user authentication types + choices=['password', 'radius', 'otp'] + required: false + userclass: + description: + - User category + - (semantics placed on this attribute are for local interpretation) + required: false + radius: + description: RADIUS proxy configuration + required: false + radiususer: + description: RADIUS proxy username + required: false + departmentnumber: + description: Department Number + required: false + employeenumber: + description: Employee Number + required: false + employeetype: + description: Employee Type + required: false + preferredlanguage: + description: Preferred Language + required: false + certificate: + description: List of base-64 encoded user certificates + required: false + certmapdata: + description: List of certificate mappings + options: + certificate: + description: Base-64 encoded user certificate + required: false + issuer: + description: Issuer of the certificate + required: false + subject: + description: Subject of the certificate + required: false + required: false + noprivate: + description: Don't create user private group + required: false + type: bool + nomembers: + description: Suppress processing of membership attributes + required: false + type: bool + preserve: + description: Delete a user, keeping the entry available for future use + required: false update_password: description: Set password for a user in present state only on creation or always - default: 'always' + default: "always" choices: ["always", "on_create"] - preserve: - description: Delete a user, keeping the entry available for future use required: false + action: + description: Work on user or member level + default: "user" + choices: ["member", "user"] state: description: State to ensure default: present @@ -179,31 +440,48 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_text from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ temp_kdestroy, valid_creds, api_connect, api_command, date_format, \ - compare_args_ipa + compare_args_ipa, module_params_get, api_check_param, api_get_realm +import six + + +if six.PY3: + unicode = str def find_user(module, name, preserved=False): _args = { "all": True, - "uid": to_text(name), + "uid": name, } if preserved: _args["preserved"] = preserved - _result = api_command(module, "user_find", to_text(name), _args) + _result = api_command(module, "user_find", name, _args) if len(_result["result"]) > 1: module.fail_json( msg="There is more than one user '%s'" % (name)) elif len(_result["result"]) == 1: - return _result["result"][0] + # Transform each principal to a string + _result = _result["result"][0] + if "krbprincipalname" in _result \ + and _result["krbprincipalname"] is not None: + _list = [] + for x in _result["krbprincipalname"]: + _list.append(str(x)) + _result["krbprincipalname"] = _list + return _result else: return None -def gen_args(first, last, fullname, displayname, homedir, shell, emails, - principalname, passwordexpiration, password, uid, gid, - phones, title, sshpubkey): +def gen_args(first, last, fullname, displayname, initials, homedir, shell, + email, principalexpiration, passwordexpiration, password, + random, uid, gid, city, userstate, postalcode, phone, mobile, + pager, fax, orgunit, title, carlicense, sshpubkey, userauthtype, + userclass, radius, radiususer, departmentnumber, employeenumber, + employeetype, preferredlanguage, noprivate, nomembers): + # principal, manager, certificate and certmapdata are handled not in here _args = {} if first is not None: _args["givenname"] = first @@ -213,33 +491,222 @@ def gen_args(first, last, fullname, displayname, homedir, shell, emails, _args["cn"] = fullname if displayname is not None: _args["displayname"] = displayname + if initials is not None: + _args["initials"] = initials if homedir is not None: _args["homedirectory"] = homedir if shell is not None: _args["loginshell"] = shell - if emails is not None and len(emails) > 0: - _args["mail"] = emails - if principalname is not None: - _args["krbprincipalname"] = principalname + if email is not None and len(email) > 0: + _args["mail"] = email + if principalexpiration is not None: + _args["krbprincipalexpiration"] = principalexpiration if passwordexpiration is not None: _args["krbpasswordexpiration"] = passwordexpiration if password is not None: _args["userpassword"] = password + if random is not None: + _args["random"] = random if uid is not None: - _args["uidnumber"] = str(uid) + _args["uidnumber"] = to_text(str(uid)) if gid is not None: - _args["gidnumber"] = str(gid) - if phones is not None and len(phones) > 0: - _args["telephonenumber"] = phones + _args["gidnumber"] = to_text(str(gid)) + if city is not None: + _args["l"] = city + if userstate is not None: + _args["st"] = userstate + if postalcode is not None: + _args["postalcode"] = postalcode + if phone is not None and len(phone) > 0: + _args["telephonenumber"] = phone + if mobile is not None and len(mobile) > 0: + _args["mobile"] = mobile + if pager is not None and len(pager) > 0: + _args["pager"] = pager + if fax is not None and len(fax) > 0: + _args["facsimiletelephonenumber"] = fax + if orgunit is not None: + _args["ou"] = orgunit if title is not None: _args["title"] = title - if sshpubkey is not None: + if carlicense is not None and len(carlicense) > 0: + _args["carlicense"] = carlicense + if sshpubkey is not None and len(sshpubkey) > 0: _args["ipasshpubkey"] = sshpubkey + if userauthtype is not None and len(userauthtype) > 0: + _args["ipauserauthtype"] = userauthtype + if userclass is not None: + _args["userclass"] = userclass + if radius is not None: + _args["ipatokenradiusconfiglink"] = radius + if radiususer is not None: + _args["ipatokenradiususername"] = radiususer + if departmentnumber is not None: + _args["departmentnumber"] = departmentnumber + if employeenumber is not None: + _args["employeenumber"] = employeenumber + if employeetype is not None: + _args["employeetype"] = employeetype + if preferredlanguage is not None: + _args["preferredlanguage"] = preferredlanguage + if noprivate is not None: + _args["noprivate"] = noprivate + if nomembers is not None: + _args["no_members"] = nomembers + return _args + + +def check_parameters(module, state, action, + first, last, fullname, displayname, initials, homedir, + shell, email, principal, principalexpiration, + passwordexpiration, password, random, uid, gid, city, + phone, mobile, pager, fax, orgunit, title, manager, + carlicense, sshpubkey, userauthtype, userclass, radius, + radiususer, departmentnumber, employeenumber, + employeetype, preferredlanguage, certificate, + certmapdata, noprivate, nomembers, preserve, + update_password): + + if state == "present": + if action == "member": + invalid = ["first", "last", "fullname", "displayname", "initials", + "homedir", "shell", "email", "principalexpiration", + "passwordexpiration", "password", "random", "uid", + "gid", "city", "phone", "mobile", "pager", "fax", + "orgunit", "title", "carlicense", "sshpubkey", + "userauthtype", "userclass", "radius", "radiususer", + "departmentnumber", "employeenumber", "employeetype", + "preferredlanguage", "noprivate", "nomembers", + "preserve", "update_password"] + for x in invalid: + if vars()[x] is not None: + module.fail_json( + msg="Argument '%s' can not be used with action " + "'%s'" % (x, action)) + + else: + invalid = ["first", "last", "fullname", "displayname", "initials", + "homedir", "shell", "email", "principalexpiration", + "passwordexpiration", "password", "random", "uid", + "gid", "city", "phone", "mobile", "pager", "fax", + "orgunit", "title", "carlicense", "sshpubkey", + "userauthtype", "userclass", "radius", "radiususer", + "departmentnumber", "employeenumber", "employeetype", + "preferredlanguage", "noprivate", "nomembers", + "update_password"] + if action == "user": + invalid.extend(["principal", "manager", + "certificate", "certmapdata", + ]) + for x in invalid: + if vars()[x] is not None: + module.fail_json( + msg="Argument '%s' can not be used with state '%s'" % + (x, state)) + + if state != "absent" and preserve is not None: + module.fail_json( + msg="Preserve is only possible for state=absent") + + if certmapdata is not None: + for x in certmapdata: + certificate = x.get("certificate") + issuer = x.get("issuer") + subject = x.get("subject") + + if certificate is not None \ + and (issuer is not None or subject is not None): + module.fail_json( + msg="certmapdata: certificate can not be used with " + "issuer or subject") + if certificate is None: + if issuer is None: + module.fail_json(msg="certmapdata: issuer is missing") + if subject is None: + module.fail_json(msg="certmapdata: subject is missing") + + +def gen_certmapdata_args(certmapdata): + certificate = certmapdata.get("certificate") + issuer = certmapdata.get("issuer") + subject = certmapdata.get("subject") + _args = {} + if certificate is not None: + _args["certificate"] = certificate + if issuer is not None: + _args["issuer"] = issuer + if subject is not None: + _args["subject"] = subject return _args def main(): + user_spec = dict( + # present + first=dict(type="str", aliases=["givenname"], default=None), + last=dict(type="str", default=None), + fullname=dict(type="str", aliases=["cn"], default=None), + displayname=dict(type="str", default=None), + initials=dict(type="str", default=None), + homedir=dict(type="str", default=None), + shell=dict(type="str", aliases=["loginshell"], default=None), + email=dict(type="list", default=None), + principal=dict(type="list", aliases=["principalname", + "krbprincipalname"], + default=None), + principalexpiration=dict(type="str", + aliases=["krbprincipalexpiration"], + default=None), + passwordexpiration=dict(type="str", + aliases=["krbpasswordexpiration"], + default=None), + password=dict(type="str", default=None, no_log=True), + random=dict(type='bool', default=None), + uid=dict(type="int", aliases=["uidnumber"], default=None), + gid=dict(type="int", aliases=["gidnumber"], default=None), + city=dict(type="str", default=None), + userstate=dict(type="str", aliases=["st"], default=None), + postalcode=dict(type="str", aliases=["zip"], default=None), + phone=dict(type="list", aliases=["telephonenumber"], default=None), + mobile=dict(type="list", default=None), + pager=dict(type="list", default=None), + fax=dict(type="list", aliases=["facsimiletelephonenumber"], + default=None), + orgunit=dict(type="str", aliases=["ou"], default=None), + title=dict(type="str", default=None), + manager=dict(type="list", default=None), + carlicense=dict(type="list", default=None), + sshpubkey=dict(type="list", aliases=["ipasshpubkey"], + default=None), + userauthtype=dict(type='list', aliases=["ipauserauthtype"], + default=None, + choices=['password', 'radius', 'otp']), + userclass=dict(type="list", aliases=["class"], + default=None), + radius=dict(type="str", aliases=["ipatokenradiusconfiglink"], + default=None), + radiususer=dict(type="str", aliases=["radiususername", + "ipatokenradiususername"], + default=None), + departmentnumber=dict(type="list", default=None), + employeenumber=dict(type="str", default=None), + employeetype=dict(type="str", default=None), + preferredlanguage=dict(type="str", default=None), + certificate=dict(type="list", aliases=["usercertificate"], + default=None), + certmapdata=dict(type="list", default=None, + options=dict( + # Here certificate is a simple string + certificate=dict(type="str", default=None), + issuer=dict(type="str", default=None), + subject=dict(type="str", default=None) + ), + elements='dict', required=False), + noprivate=dict(type='bool', default=None), + nomembers=dict(type='bool', default=None), + ) + ansible_module = AnsibleModule( argument_spec=dict( # general @@ -247,36 +714,35 @@ def main(): ipaadmin_password=dict(type="str", required=False, no_log=True), name=dict(type="list", aliases=["login"], default=None, - required=True), - # present - first=dict(type="str", aliases=["givenname"], default=None), - last=dict(type="str", default=None), - fullname=dict(type="str", aliases=["cn"], default=None), - displayname=dict(type="str", default=None), - homedir=dict(type="str", default=None), - shell=dict(type="str", aliases=["loginshell"], default=None), - email=dict(type="list", default=None), - principalname=dict(type="str", aliases=["krbprincipalname"], - default=None), - passwordexpiration=dict(type="str", - aliases=["krbpasswordexpiration"], - default=None), - password=dict(type="str", default=None, no_log=True), - uid=dict(type="int", aliases=["uidnumber"], default=None), - gid=dict(type="int", aliases=["gidnumber"], default=None), - phone=dict(type="list", aliases=["telephonenumber"], default=None), - title=dict(type="str", default=None), - # sshpubkey=dict(type="list", aliases=["ipasshpubkey"], - # default=None), - update_password=dict(type='str', default=None, - choices=['always', 'on_create']), + required=False), + users=dict(type="list", aliases=["login"], default=None, + options=dict( + # Here name is a simple string + name=dict(type="str", required=True), + # Add user specific parameters + **user_spec + ), + elements='dict', required=False), + # deleted preserve=dict(required=False, type='bool', default=None), - # state + + # mod + update_password=dict(type='str', default=None, + choices=['always', 'on_create']), + + # general + action=dict(type="str", default="user", + choices=["member", "user"]), state=dict(type="str", default="present", choices=["present", "absent", "enabled", "disabled", "unlocked", "undeleted"]), + + # Add user specific parameters for simple use case + **user_spec ), + mutually_exclusive=[["name", "users"]], + required_one_of=[["name", "users"]], supports_check_mode=True, ) @@ -285,66 +751,101 @@ def main(): # Get parameters # general - ipaadmin_principal = ansible_module.params.get("ipaadmin_principal") - ipaadmin_password = ansible_module.params.get("ipaadmin_password") - names = ansible_module.params.get("name") + ipaadmin_principal = module_params_get(ansible_module, + "ipaadmin_principal") + ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") + names = module_params_get(ansible_module, "name") + users = module_params_get(ansible_module, "users") # present - first = ansible_module.params.get("first") - last = ansible_module.params.get("last") - fullname = ansible_module.params.get("fullname") - displayname = ansible_module.params.get("displayname") - homedir = ansible_module.params.get("homedir") - shell = ansible_module.params.get("shell") - emails = ansible_module.params.get("email") - principalname = ansible_module.params.get("principalname") - passwordexpiration = ansible_module.params.get("passwordexpiration") + first = module_params_get(ansible_module, "first") + last = module_params_get(ansible_module, "last") + fullname = module_params_get(ansible_module, "fullname") + displayname = module_params_get(ansible_module, "displayname") + initials = module_params_get(ansible_module, "initials") + homedir = module_params_get(ansible_module, "homedir") + shell = module_params_get(ansible_module, "shell") + email = module_params_get(ansible_module, "email") + principal = module_params_get(ansible_module, "principal") + principalexpiration = module_params_get(ansible_module, + "principalexpiration") + if principalexpiration is not None: + if principalexpiration[:-1] != "Z": + principalexpiration = principalexpiration + "Z" + principalexpiration = date_format(principalexpiration) + passwordexpiration = module_params_get(ansible_module, + "passwordexpiration") if passwordexpiration is not None: if passwordexpiration[:-1] != "Z": - passwordexpiration = "%sZ" % passwordexpiration + passwordexpiration = passwordexpiration + "Z" passwordexpiration = date_format(passwordexpiration) - password = ansible_module.params.get("password") - uid = ansible_module.params.get("uid") - gid = ansible_module.params.get("gid") - phones = ansible_module.params.get("phone") - title = ansible_module.params.get("title") - sshpubkey = ansible_module.params.get("sshpubkey") - update_password = ansible_module.params.get("update_password") + password = module_params_get(ansible_module, "password") + random = module_params_get(ansible_module, "random") + uid = module_params_get(ansible_module, "uid") + gid = module_params_get(ansible_module, "gid") + city = module_params_get(ansible_module, "city") + userstate = module_params_get(ansible_module, "userstate") + postalcode = module_params_get(ansible_module, "postalcode") + phone = module_params_get(ansible_module, "phone") + mobile = module_params_get(ansible_module, "mobile") + pager = module_params_get(ansible_module, "pager") + fax = module_params_get(ansible_module, "fax") + orgunit = module_params_get(ansible_module, "orgunit") + title = module_params_get(ansible_module, "title") + manager = module_params_get(ansible_module, "manager") + carlicense = module_params_get(ansible_module, "carlicense") + sshpubkey = module_params_get(ansible_module, "sshpubkey") + userauthtype = module_params_get(ansible_module, "userauthtype") + userclass = module_params_get(ansible_module, "userclass") + radius = module_params_get(ansible_module, "radius") + radiususer = module_params_get(ansible_module, "radiususer") + departmentnumber = module_params_get(ansible_module, "departmentnumber") + employeenumber = module_params_get(ansible_module, "employeenumber") + employeetype = module_params_get(ansible_module, "employeetype") + preferredlanguage = module_params_get(ansible_module, "preferredlanguage") + certificate = module_params_get(ansible_module, "certificate") + certmapdata = module_params_get(ansible_module, "certmapdata") + noprivate = module_params_get(ansible_module, "noprivate") + nomembers = module_params_get(ansible_module, "nomembers") # deleted - preserve = ansible_module.params.get("preserve") - # state - state = ansible_module.params.get("state") + preserve = module_params_get(ansible_module, "preserve") + # mod + update_password = module_params_get(ansible_module, "update_password") + # general + action = module_params_get(ansible_module, "action") + state = module_params_get(ansible_module, "state") # Check parameters + if (names is None or len(names) < 1) and \ + (users is None or len(users) < 1): + ansible_module.fail_json(msg="One of name and users is required") + if state == "present": - if len(names) != 1: - ansible_module.fail_json( - msg="Only one user can be added at a time.") - if first is None: - ansible_module.fail_json(msg="First name is needed") - if last is None: - ansible_module.fail_json(msg="Last name is needed") - - if state == "absent": - if len(names) < 1: + if names is not None and len(names) != 1: ansible_module.fail_json( - msg="No name given.") - for x in ["first", "last", "fullname", "displayname", "homedir", - "shell", "emails", "principalname", "passwordexpiration", - "password", "uid", "gid", "phones", "title", "sshpubkey", - "update_password"]: - if vars()[x] is not None: - ansible_module.fail_json( - msg="Argument '%s' can not be used with state '%s'" % - (x, state)) - else: - if preserve is not None: - ansible_module.fail_json( - msg="Preserve is only possible for state=absent") + msg="Only one user can be added at a time using name.") + if action != "member": + # Only check first and last here if names is set + if names is not None: + if first is None: + ansible_module.fail_json(msg="First name is needed") + if last is None: + ansible_module.fail_json(msg="Last name is needed") - if update_password is None: - update_password = "always" + check_parameters( + ansible_module, state, action, + first, last, fullname, displayname, initials, homedir, shell, email, + principal, principalexpiration, passwordexpiration, password, random, + uid, gid, city, phone, mobile, pager, fax, orgunit, title, manager, + carlicense, sshpubkey, userauthtype, userclass, radius, radiususer, + departmentnumber, employeenumber, employeetype, preferredlanguage, + certificate, certmapdata, noprivate, nomembers, preserve, + update_password) + + # Use users if names is None + if users is not None: + names = users # Init @@ -358,53 +859,380 @@ def main(): ipaadmin_password) api_connect() + # Check version specific settings + + server_realm = api_get_realm() + commands = [] - for name in names: + for user in names: + if isinstance(user, dict): + name = user.get("name") + # present + first = user.get("first") + last = user.get("last") + fullname = user.get("fullname") + displayname = user.get("displayname") + initials = user.get("initials") + homedir = user.get("homedir") + shell = user.get("shell") + email = user.get("email") + principal = user.get("principal") + principalexpiration = user.get("principalexpiration") + if principalexpiration is not None: + if principalexpiration[:-1] != "Z": + principalexpiration = principalexpiration + "Z" + principalexpiration = date_format(principalexpiration) + passwordexpiration = user.get("passwordexpiration") + if passwordexpiration is not None: + if passwordexpiration[:-1] != "Z": + passwordexpiration = passwordexpiration + "Z" + passwordexpiration = date_format(passwordexpiration) + password = user.get("password") + random = user.get("random") + uid = user.get("uid") + gid = user.get("gid") + city = user.get("city") + userstate = user.get("userstate") + postalcode = user.get("postalcode") + phone = user.get("phone") + mobile = user.get("mobile") + pager = user.get("pager") + fax = user.get("fax") + orgunit = user.get("orgunit") + title = user.get("title") + manager = user.get("manager") + carlicense = user.get("carlicense") + sshpubkey = user.get("sshpubkey") + userauthtype = user.get("userauthtype") + userclass = user.get("userclass") + radius = user.get("radius") + radiususer = user.get("radiususer") + departmentnumber = user.get("departmentnumber") + employeenumber = user.get("employeenumber") + employeetype = user.get("employeetype") + preferredlanguage = user.get("preferredlanguage") + certificate = user.get("certificate") + certmapdata = user.get("certmapdata") + noprivate = user.get("noprivate") + nomembers = user.get("nomembers") + + check_parameters( + ansible_module, state, action, + first, last, fullname, displayname, initials, homedir, + shell, email, principal, principalexpiration, + passwordexpiration, password, random, uid, gid, city, + phone, mobile, pager, fax, orgunit, title, manager, + carlicense, sshpubkey, userauthtype, userclass, radius, + radiususer, departmentnumber, employeenumber, + employeetype, preferredlanguage, certificate, + certmapdata, noprivate, nomembers, preserve, + update_password) + + elif isinstance(user, str) or isinstance(user, unicode): + name = user + else: + ansible_module.fail_json(msg="User '%s' is not valid" % + repr(user)) + + # Fix principals: add realm if missing + # We need the connected API for the realm, therefore it can not + # be part of check_parameters as this is used also before the + # connection to the API has been established. + if principal is not None: + principal = [x if "@" in x else x + "@" + server_realm + for x in principal] + + # Check passwordexpiration availability. + # We need the connected API for this test, therefore it can not + # be part of check_parameters as this is used also before the + # connection to the API has been established. + if passwordexpiration is not None and \ + not api_check_param("user_add", "krbpasswordexpiration"): + ansible_module.fail_json( + msg="The use of passwordexpiration is not supported by " + "your IPA version") + # Make sure user exists res_find = find_user(ansible_module, name) - # Also search for preserved user - res_find_preserved = find_user(ansible_module, name, - preserved=True) + # Also search for preserved user if the user could not be found + if res_find is None: + res_find_preserved = find_user(ansible_module, name, + preserved=True) + else: + res_find_preserved = None # Create command if state == "present": # Generate args args = gen_args( - first, last, fullname, displayname, homedir, shell, emails, - principalname, passwordexpiration, password, uid, gid, - phones, title, sshpubkey) + first, last, fullname, displayname, initials, homedir, + shell, email, principalexpiration, passwordexpiration, + password, random, uid, gid, city, userstate, postalcode, + phone, mobile, pager, fax, orgunit, title, carlicense, + sshpubkey, userauthtype, userclass, radius, radiususer, + departmentnumber, employeenumber, employeetype, + preferredlanguage, noprivate, nomembers) # Also check preserved users if res_find is None and res_find_preserved is not None: res_find = res_find_preserved - # Found the user - if res_find is not None: - # Ignore password with update_password == on_create - if update_password == "on_create" and \ - "userpassword" in args: - del args["userpassword"] - - # For all settings is args, check if there are - # different settings in the find result. - # If yes: modify - if not compare_args_ipa(ansible_module, args, res_find): - commands.append([name, "user_mod", args]) - else: - commands.append([name, "user_add", args]) + if action == "user": + # Found the user + if res_find is not None: + # Ignore password and random with + # update_password == on_create + if update_password == "on_create": + if "userpassword" in args: + del args["userpassword"] + if "random" in args: + del args["random"] + if "noprivate" in args: + del args["noprivate"] + + # For all settings is args, check if there are + # different settings in the find result. + # If yes: modify + if not compare_args_ipa(ansible_module, args, + res_find): + commands.append([name, "user_mod", args]) + + else: + commands.append([name, "user_add", args]) + + # Handle members: principal, manager + if res_find is not None: + # Generate addition and removal lists + manager_add = list( + set(manager or []) - + set(res_find.get("manager", []))) + manager_del = list( + set(res_find.get("manager", [])) - + set(manager or [])) + principal_add = list( + set(principal or []) - + set(res_find.get("krbprincipalname", []))) + principal_del = list( + set(res_find.get("krbprincipalname", [])) - + set(principal or [])) + + # Principals are not returned as utf8 for IPA using + # python2 using user_find, therefore we need to + # convert the principals that we should remove. + principal_del = [to_text(x) for x in principal_del] + + certificate_add = list( + set(certificate or []) - + set(res_find.get("certificate", []))) + certificate_del = list( + set(res_find.get("certificate", [])) - + set(certificate or [])) + certmapdata_add = list( + set(certmapdata or []) - + set(res_find.get("ipaCertMapData", []))) + certmapdata_del = list( + set(res_find.get("ipaCertMapData", [])) - + set(certmapdata or [])) + + else: + # Use given managers and principals + manager_add = manager or [] + manager_del = [] + principal_add = principal or [] + principal_del = [] + certificate_add = certificate or [] + certificate_del = [] + certmapdata_add = certmapdata or [] + certmapdata_del = [] + + # Remove canonical principal from principal_del + canonical_principal = name + "@" + server_realm + if canonical_principal in principal_del: + principal_del.remove(canonical_principal) + + # Add managers + if len(manager_add) > 0: + commands.append([name, "user_add_manager", + { + "user": manager_add, + }]) + # Remove managers + if len(manager_del) > 0: + commands.append([name, "user_remove_manager", + { + "user": manager_del, + }]) + + # Principals need to be added and removed one by one, + # because if entry already exists, the processing of + # the remaining enries is stopped. The same applies to + # the removal of non-existing entries. + + # Add principals + if len(principal_add) > 0: + for _principal in principal_add: + commands.append([name, "user_add_principal", + { + "krbprincipalname": + _principal, + }]) + # Remove principals + if len(principal_del) > 0: + for _principal in principal_del: + commands.append([name, "user_remove_principal", + { + "krbprincipalname": + _principal, + }]) + + # Certificates need to be added and removed one by one, + # because if entry already exists, the processing of + # the remaining enries is stopped. The same applies to + # the removal of non-existing entries. + + # Add certificates + if len(certificate_add) > 0: + for _certificate in certificate_add: + commands.append([name, "user_add_cert", + { + "usercertificate": + _certificate, + }]) + # Remove certificates + if len(certificate_del) > 0: + for _certificate in certificate_del: + commands.append([name, "user_remove_cert", + { + "usercertificate": + _certificate, + }]) + + # certmapdata need to be added and removed one by one, + # because issuer and subject can only be done one by + # one reliably (https://pagure.io/freeipa/issue/8097) + + # Add certmapdata + if len(certmapdata_add) > 0: + for _data in certmapdata_add: + commands.append([name, "user_add_certmapdata", + gen_certmapdata_args(_data)]) + # Remove certmapdata + if len(certmapdata_del) > 0: + for _data in certmapdata_del: + commands.append([name, "user_add_certmapdata", + gen_certmapdata_args(_data)]) + + elif action == "member": + if res_find is None: + ansible_module.fail_json( + msg="No user '%s'" % name) + + # Ensure managers are present + if manager is not None and len(manager) > 0: + commands.append([name, "user_add_manager", + { + "user": manager, + }]) + + # Principals need to be added and removed one by one, + # because if entry already exists, the processing of + # the remaining enries is stopped. The same applies to + # the removal of non-existing entries. + + # Ensure principals are present + if principal is not None and len(principal) > 0: + for _principal in principal: + commands.append([name, "user_add_principal", + { + "krbprincipalname": + _principal, + }]) + + # Certificates need to be added and removed one by one, + # because if entry already exists, the processing of + # the remaining enries is stopped. The same applies to + # the removal of non-existing entries. + + # Ensure certificates are present + if certificate is not None and len(certificate) > 0: + for _certificate in certificate: + commands.append([name, "user_add_cert", + { + "usercertificate": + _certificate, + }]) + + # certmapdata need to be added and removed one by one, + # because issuer and subject can only be done one by + # one reliably (https://pagure.io/freeipa/issue/8097) + + # Ensure certmapdata are present + if certmapdata is not None and len(certmapdata) > 0: + for _data in certmapdata: + commands.append([name, "user_add_certmapdata", + gen_certmapdata_args(_data)]) elif state == "absent": # Also check preserved users if res_find is None and res_find_preserved is not None: res_find = res_find_preserved - if res_find is not None: - args = {} - if preserve is not None: - args["preserve"] = preserve - commands.append([name, "user_del", args]) + if action == "user": + if res_find is not None: + args = {} + if preserve is not None: + args["preserve"] = preserve + commands.append([name, "user_del", args]) + elif action == "member": + if res_find is None: + ansible_module.fail_json( + msg="No user '%s'" % name) + + # Ensure managers are absent + if manager is not None and len(manager) > 0: + commands.append([name, "user_remove_manager", + { + "user": manager, + }]) + + # Principals need to be added and removed one by one, + # because if entry already exists, the processing of + # the remaining enries is stopped. The same applies to + # the removal of non-existing entries. + # Ensure principals are absent + if principal is not None and len(principal) > 0: + commands.append([name, "user_remove_principal", + { + "krbprincipalname": principal, + }]) + + # Certificates need to be added and removed one by one, + # because if entry already exists, the processing of + # the remaining enries is stopped. The same applies to + # the removal of non-existing entries. + + # Ensure certificates are absent + if certificate is not None and len(certificate) > 0: + for _certificate in certificate: + commands.append([name, "user_remove_cert", + { + "usercertificate": + _certificate, + }]) + + # certmapdata need to be added and removed one by one, + # because issuer and subject can only be done one by + # one reliably (https://pagure.io/freeipa/issue/8097) + + # Ensure certmapdata are absent + if certmapdata is not None and len(certmapdata) > 0: + # Using issuer and subject can only be done one by + # one reliably (https://pagure.io/freeipa/issue/8097) + for _data in certmapdata: + commands.append([name, "user_remove_certmapdata", + gen_certmapdata_args(_data)]) elif state == "undeleted": if res_find_preserved is not None: commands.append([name, "user_undel", {}]) @@ -434,13 +1262,43 @@ def main(): # Execute commands + errors = [] for name, command, args in commands: try: - api_command(ansible_module, command, to_text(name), args) - changed = True + result = api_command(ansible_module, command, name, + args) + if "completed" in result: + if result["completed"] > 0: + changed = True + else: + changed = True except Exception as e: + msg = str(e) + if "already contains" in msg \ + or "does not contain" in msg: + continue + # The canonical principal name may not be removed + if "equal to the canonical principal name must" in msg: + continue ansible_module.fail_json(msg="%s: %s: %s" % (command, name, - str(e))) + msg)) + + # Get all errors + # All "already a member" and "not a member" failures in the + # result are ignored. All others are reported. + if "failed" in result and len(result["failed"]) > 0: + for item in result["failed"]: + failed_item = result["failed"][item] + for member_type in failed_item: + for member, failure in failed_item[member_type]: + if "already a member" in failure \ + or "not a member" in failure: + continue + errors.append("%s: %s %s: %s" % ( + command, member_type, member, failure)) + + if len(errors) > 0: + ansible_module.fail_json(msg=", ".join(errors)) except Exception as e: ansible_module.fail_json(msg=str(e)) diff --git a/tests/user/certificate/cert1.der b/tests/user/certificate/cert1.der new file mode 100644 index 0000000000000000000000000000000000000000..334511ff52b76c7611d9782e454275b06e93c93b GIT binary patch literal 771 zcmXqLV)}2;#Q1yxGZP~dlSoS9=}a|+YdI@lI9Y_GPU6mcZ?)TimyJ`a&7<u*FC!y2 zD}w>QA+G^98*?ZNGY?BiYH^8yoH(zcrJ;eLiJ_U1g|TUrIIod`p@E?>l#8jMiBSpJ zP)1e;<|amd27@L>E~X|%MusEqKOH}_GR*jL>7cs3$<wpb%`<JDFne=7)To=jX_@PT zRRIgt?B^vcW)e!XjPeWW<GT5AV!BU*{PibN|2C=ooAaiDwP*Xh;*I^XF}x4AW!nc_ zuQgDsOMO@<BF)(;`kQmrhu@nI|KG@bk#pTH**TNXZ}4mRP<bh2V^z}mx`N4^Z>l#~ z^lwPI`(RSG<|eJLTaT;N_mtZF-y}12Zeh*5ZGnMBX*Er!l2<$_>)mgAR7I!#gv<%k zU28t4dfMDbPfRnram0IBBG)nQ`{5UIVkb03%$>4vB~$eAK$m?-G!{hfy|Yiy-!Sz~ z&AU>gy_K#fBz#Xw{N5sYt4wQIh~omwfawdKGchwVFfI-@2sDsoV-A(&V-aH!IWK)b zJXE}J$<s4wy=U9?mzI@(y=x#3l2&GsFc53Nu7Dq;K$wy7KMSh?Gb7`F<Y4Cp2RkE! za-_MsQtYxN*Y3+O*YL=3O@89*mXRaxvv2)BYs1oDgTulL)L+y-j<_>@MceyrQ(Dj1 zvR~d?D$Q%j%aF~c_pf^^qe!ia%PLOO%D&tF7hLNme%%>6Q%s=mn}Nd*Kk52;UdOjR z2)MZYx+dc$;Wd^!{Z!7TdjHjWXxh#!^(Hv^?13M9;=SYMKX0p$mvTE%=pA>WKb`&J zcL$@ChF``EdyOQgpDSk<-y-+QIP1{{i_q>z3!l9Xx3K>4btXgiib*qS=BKfkwmR%K zF8}TN^YN*U8<CuxMXw!e^j<E%p>VT*D#xUFgUMHyZl3v-rA6n*c?R=!zKpkj|FX8} NS<1!rW^wna?*K9mJ(d6f literal 0 HcmV?d00001 diff --git a/tests/user/certificate/cert1.pem b/tests/user/certificate/cert1.pem new file mode 100644 index 00000000..6fb9d2e9 --- /dev/null +++ b/tests/user/certificate/cert1.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQEL +BQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4 +MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJm +OVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQb +CYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmsp +sir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzY +Z2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15 +RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdx +pOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8 +DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsG +Lv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOs +OblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMA +vTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePK +iNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyj +i8r3 +-----END CERTIFICATE----- diff --git a/tests/user/certificate/cert2.der b/tests/user/certificate/cert2.der new file mode 100644 index 0000000000000000000000000000000000000000..a3ba5a575677e12a26c96ab8844724e733878ff7 GIT binary patch literal 771 zcmXqLV)}2;#Q1yxGZP~dlL%v?>D~o)GpCo&XUjU6`0Ih&@x8JJylk9WZ60mkc^MhG zSs4uY4S5Z?*_cCFn0Z)AQj1Fr<ivRmEe#C}O$^P9EKE$J#CeSj3=Is8p<GN2O^iy& zhBC4;FgG#sGZ-{6axpbAGBQj%Gh?>a<(kxgryEz^Rk-20sHXM{)1t>6v(mht8Z6|? z@oUZe&+F@UrD5&Wn#mC})DB$T)*UieB4x&6^)34!^*wz1d{x2Ja5YE8h%1j~rk;)d z#&p*3-d&Yh%SvWgteh)T;xuh$(T4qerxn@WO}qYgL2U>7(ft4G0|KT$J8U2lb>qm3 zWg7GSi$4d7UC+PHTySmIG>zEEvn#~h0(Us^T$E<9SoPfc#QPeb6-)Y)`#ZX;Q}0=| z?wW8cgN^ONl8|Q}?b5s7yzE^QEk5I%cIvFORk9*w%QX+VWb{TJi%ZU`I579+<={Cx zvcGdL3G6Y^Vzhj3&>Xhk<M^xk628D|i91~8PG@3fWMEtzY!GN5%f=ik%f}+dA~JiI z;<qVRvlVPVZ4X%^&h00%c==KTd62X+i-dt#19k=cAO*sVjQ?3!4VW1j|04%GH#pcC z8Jt4X%f8o$o$7F1anMIrz_Iz><(uxNC!c&NIrxKZc3+0pgymg3tLCrMJ$giW{q`9? zYM-X<57@%Qf2Ldamabx^+x-{y4|lOHz0ogvz`4<0Me_X?jW-8B+^!amy^!#F>y5)n z*S$7K?KstXBk#IE+{0fHPXp#{4K=mcv(E3R(as|}V!I=iT_%36sLKocwBT5^lCXM% z`mw;b(R16U&Dr)+bjJeC&+kG^*BI0;X|lBxV6PNnd=k0!j|0Er%#+QUpM&qV`F!$d zbLMPaS0cOm*x5@DFMhc5?{>TN%xlLB>~<asxb`A*#xZ@h=%-aVT+6@BSp8>i#rihZ Rd5hVaEaz@No4fH)C;;sUO0@t0 literal 0 HcmV?d00001 diff --git a/tests/user/certificate/cert2.pem b/tests/user/certificate/cert2.pem new file mode 100644 index 00000000..4a243b25 --- /dev/null +++ b/tests/user/certificate/cert2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUAWE1vaA+mZd3nwZqwWH64EbHvR0wDQYJKoZIhvcNAQEL +BQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NDVaFw0yMDEwMTMxNjI4 +NDVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCWzJibKtN8Zf7LgandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3V +fJNYmCbA1baLVJ0YZJijJ7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSY +OKmdHHRClplysL8OyyEG7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv +1wNw1rqWKF1ZzagWRlG4QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCk +VOZIhxu77OmNrFsXmM4rZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0 +KgE57zCDVr9Ix+p/dA5R1mG4RJ2XAgMBAAGjUzBRMB0GA1UdDgQWBBSbuiH2lNVr +ID3yt1SsFwtOFKOnpTAfBgNVHSMEGDAWgBSbuiH2lNVrID3yt1SsFwtOFKOnpTAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBCVWd293wWyohFqMFM +HRBBg97T2Uc1yeT0dMH4BpuOaCqQp4q5ep+uLcXEI6+3mEwm8pa/ULQCD8yLLdot +IWlG3+h/4boFpdiPFcBDgT8kGe+0KOzB8Nt7E13QYOu12MNi10qwGrjKhdhu1xBe +4fpY5VCetVU1OLyuTsUyucQsFrtZI0SR83h+blbyoMZ7IhMngCfGUe1bnYeWnLbp +FbigKfPuVDWsMH2kgj05EAd5EgHkWbX8QA8hmcmDKfNT3YZM8kiGQwmFrnQdq8bN +0uHR8Nz+24cbmdbHcD65wlDW6GmYxi8mW+V6bAqn9pir/J14r4YFnqMGgjmdt81t +scJV +-----END CERTIFICATE----- diff --git a/tests/user/certificate/cert3.der b/tests/user/certificate/cert3.der new file mode 100644 index 0000000000000000000000000000000000000000..783830ee5d9fb52cc41010a3b60047bd68667cd0 GIT binary patch literal 771 zcmXqLV)}2;#Q1yxGZP~dlZcP*_ed`Zi71YcWP>KNJ5T0q<km9aW#iOp^Jx3d%gD&h z%3#26$ZNpO#vIDR%)?TWT3livC(dhVX=q?*VrXV$VQLg5&TC{~Xkcgz<zi}RVpKvl zl#!KzxrvdV!Jvtei>Zl`k>L>YyZ)Om=EamvRnvYOrT*KiI=Rm&?UMCGO%b<^wjZ{? zIh3}Fx%$kfsRq86vgQ7Ko)&vy-`Nr$?$rOqt)-VdwD+bxH@z4e5PmRdMpCSn)?7FC z^d+}`?i2Ah*tW%CQh?_rZu|6W?Z@Y9HJ`M171(oiqNKpeH_kr<6H*P!zshNS5U|Ki znsE9aSJStD3jcop>fTW&$*9xo6F>7w<l1wm-U%C<{NJ{MUwE(L<TC<iUCpv|INx-u z%}umQI%!?paKm5<>;JjY-3djhiGpS}jmeAtrN)<J>=O}{_xth3R(5r~Y(QXH&ZP;9 z{MO%C_vrMpnHlUC*_dbUlx@k8*!QYLC{dn?nUR5Uaj-$4fh-$ys4O3g7>h_JC%@ui z=a<!<ieVB;MyvIw@p$wb$b+PnStJa^8n7$i2PqI{Wc<&<YQW6M_#ZjgxxvBC$iShq z`FYmcZ|lElSO!du<kFS8GwF2QEU~~_ckMYQYDI0i(69LS%7xHLFHIxZ*-UK2@2*Tp z*`wX*_sYB7xy8Qa&<3-eOD6VdZ+m+3M?>wwTYYO*>|mG_a?|Z~A^#q^?d^>}#2Zh} z6S(`>?q!JnH5++@Cn*P2ZXD4|pH@@%ynkojM^C<z9mPJ2eq0oObIDKj@|_uMX;~|L z3Z;(B-zyMMv`3Zc^o0xlcYH3+K5g8!xn#D**=Yhb^Ii+PY<#ojnz}@h`Qud|Wnbl( z|4g1zF+q=~zFy#EhRE4P=cm5BAEa<M<%?^~zA2|3Nnf0|;g>7h*^SHZ2yhmiRq~3K NSu<mE^$TMKcL0JMHdp`v literal 0 HcmV?d00001 diff --git a/tests/user/certificate/cert3.pem b/tests/user/certificate/cert3.pem new file mode 100644 index 00000000..b2a6a99c --- /dev/null +++ b/tests/user/certificate/cert3.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUTC33WUoYGFoIVGMwgjbc5J6xCyowDQYJKoZIhvcNAQEL +BQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NTJaFw0yMDEwMTMxNjI4 +NTJaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDCA+6P2eieXHaVJivtWif7SntjjkJm0juRKRRGsT3wt+zCZqoDe8zylTBN +0mse/POWXdC+zXRMC2X/c4V10kgrvWbnNdFdUFfBUphiXSoqnUYHZ6Ta+b4UTzC2 +tECSUEnSCz9n1ofHnyqDyT9FELzVkRkQqexD+BFgZTF39R4q8BA4bWKQy94Kgvb+ +IP77+ou4fhkBLI1MX5nkWa3Oyu4TMzT/tqgPE70hk8wQzUU2aiwJ7IsmnWE6Ysk7 +c4DYMJQF/51bi2ByZWERNjyBY6L+ZV90aL4UFR9O+Pw9HatfHVBRdmzSkKJOr9iu +4summWgH0QYDmbkdhGwYvup0EmEfAgMBAAGjUzBRMB0GA1UdDgQWBBSJCQ8ho0Pp +e0khVhgiMqsvlgxIjzAfBgNVHSMEGDAWgBSJCQ8ho0Ppe0khVhgiMqsvlgxIjzAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAILLPnau32r/YoOVCV +WQotGtySy36aFlHa3T8IkSpatNCPIf3U0FWS6TVYBwY0PBfdqWBkvCuJTupLh0OE +P4TCsDa5pJGOK7blyfiAfcHajqyouACSVNlG63EPvB63h4H4F4HJnhDd4z7pVC/W +PB8w5GTBJNjELmeWfH7nj7lu8UkOdLhzTKL40RPs0k4l09yYBmZqqExxGsSfvRBQ +crwlAsvQ0E/cTNGbyzOKs3SbOM2WEHye6xNEsey01icYcjfjqvEd6mw3+WOUeJAu +DH9/EOloFM2iz5Xp31Ig3WT0RVy+lMriG9GesPpFBs2xp9wQCXLNIkpbHKyYs3vo +MyBH +-----END CERTIFICATE----- diff --git a/tests/user/certificate/private1.key b/tests/user/certificate/private1.key new file mode 100644 index 00000000..cb76298b --- /dev/null +++ b/tests/user/certificate/private1.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDER/lB8wUAmPTS +wSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fk +Gv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJ +rrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWd +cXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQ +bF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRB +oDlQl6DnAgMBAAECggEBALtKTj6urHxId3xPEKsQR6Noglgp4Qx/Y687W6hWsLAG +051CV+PmtSF2DaZ7XX9U6PLTydzL68RqHjArzhKgmE+WoAYrot5QWQJNqpQYZ19o +uDQW4YYpn/+BTgUKkUNnGm+BqTt8b5QyJxoNHsy4ppZMDnBtomCfrgYxGPr2YmfZ +Ee7oEEf1xIU2maE5Nxv97lNR2Xvm2R4F8lzRcHmvejLYNiqZ2Ag4ijnKVTpoEMUy +afl5LNSzGJETXsv+LtaJGEr6x8/IesVSCdyX2LZeAyQPLKwb3YQDkQree54vwS7p +cVmQdx6fLTYV1tOSXUEC2ibInO188kGA198HSqSgHJkCgYEA7zhL+6tYZdXoMzTH +hXHLYGHmQsQXxleH5uciz4q+en7do6BFB2DqIgLTpcD/H8XMDlg9WO7756H1zqvb +6IOkqwsrro/fsgb6FrmjXl8zlkwT3pTNJfmBydRf7Qk2woCRPUoLZBRAumNL8RSx +Xm1/DbPbTR3jjVNH9dPb3Efd0qUCgYEA0gyesMgwDzjsXpPUsuWTMBMziy0KRFNT +lCMCI5DVpy/XnptyLdkY93jvmq+VWbily4KlOYbfYJ/16xeNZ7aNOMnC6z4z9p9+ +w3E9q5xKJcAJP5kN/WnjBwErveDK9r1YSj8RJpvapJFqjxA5WVTwADtyBhgNS4Og +mXPPBleMC5sCgYEA0Yw/AvXVOV9nR3O0UvCbdpJLYbDkIpoKMfnGRIcE08jN3cdG +sG/0qFZRj6C/2tUpKmehVYYCo6T77U4eFE88r5fZa9Ab45a4+68hrEk4py99ODyg +d+NYDbQ7Uyf/D+IPV+DEmaYkDSFuJIA73ruL0DT8pVDJQ8LwBibPMObDKQECgYBa +aUYxD6noE3diaj1GV5zYN5ubD2L47+jsvXjhOClOkkA8K+qko2qksrBno6YkfV8X +zv8xWMVzgMbIT1X1S1VUGTxGJ3sUb6iPlYGXCWm9AAC7GDU2W8p1rGJYk5apR+zl +4GmQdctRxKnaNICK3A2F/BBjYRzv4RNSmc+Fik9kewKBgHsCF3uEP7ONvmEjYLQ4 +7+6fZ+m4BXKeU/kKQoEXSjSFn0dBIHo+2yuafSUz04VJCVXUic3c47kHwVtgX5lu +jEUL1jgK4aBbl9cvywupHBf3spAP89aocgFiC9uUJzp3u39U0LpgXY7Z+1lUsCL+ +VG2oGh0KVgazjUzmbTf9ZcLp +-----END PRIVATE KEY----- diff --git a/tests/user/certificate/private2.key b/tests/user/certificate/private2.key new file mode 100644 index 00000000..59d83b9f --- /dev/null +++ b/tests/user/certificate/private2.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWzJibKtN8Zf7L +gandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3VfJNYmCbA1baLVJ0YZJij +J7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSYOKmdHHRClplysL8OyyEG +7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv1wNw1rqWKF1ZzagWRlG4 +QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCkVOZIhxu77OmNrFsXmM4r +ZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0KgE57zCDVr9Ix+p/dA5R +1mG4RJ2XAgMBAAECggEAS5nXCDO4Qy1/R9eBqXLF+mMztpGWoMMhwQZ3ld+DXw+9 +bfVuAOU1FWRNwjHqTQg6pYJ/Oer5tzj3rRRC8dBLgckb078Nn9t125oFYHU3LHVm +KJFm5yxHJaE94vLFVhbl0lxeIbmqj2gW7rq+tRpaU5TXEIzNyr6hKQZv5LLPuMx6 +MiBrSpkCwfPf9psv6k2GIGqE1JuY99dNqdEUi8UQryNMzV4pthUmVybO8NPxUY8M +s/VAbG1Hy9tgInR3wRgTjEc2ejUJrTziiqiZarZtCp+JSZufYakDU9yZbu9v4Oz9 +ityPdApkW8CuZnJcUDAtdgtKMhWyBPnWcrUgkbV0AQKBgQDGY1saiI9M7VlleyDc +QNVXpPCmOpDLso5X3hZrrHDgDIGkvXa026Q5ufkdxkybRYJeOCdYzIM/iXSJlgNe +R2a+aoAsePfEVFAe96ZgzrLrBq7lGvcPXGpT6GTVl0d0CwN/vG1Tzk89Hq3xIBbh +NTlM+j2ot66xgekIsE0v5Pi41wKBgQDCl14mgaui4DqYFYlI/ckI00r/X0/0HIhf +kf/Ck/pkF89IeOAK+O4GOfVoMk3vi1gDYgiz6G7h+sUsFTOYKuP9io/vX0pIFNOA +NPgaVtRKitiepNo4vwc+/PRmxvf2XXFXFRSiYf0jDzruvE3yDzWwX9P1nQFBQoPj +r8g/6+7pQQKBgDXHnVzWBDLQbNmLxV6v3KXDutD1M2dk4h2DwQQzXO3/te1YxyNE +H4LenV+q7/1vnGW6R0BVQIcq1gKuPf+Cz6Fy8Ygcyt3YFVgvvlSj8/CugR7ubmcl +oFVavGsCdYZJrgsko2aCmQxykqi5EDrA2OW7OJfSI3NPSkLmuCXxplNFAoGBALHD +D5pDqOTAzCY0vlY0qNrsEr4ZdvO8wQP1XtyEzB919MDy01CSuPZtKfeGxNWIyN1G +SEb5lZnQuSCdOaXPwLjURMralQQmKlQbj26YVZTHJD5AwK1ILTloYWgmaUzhbfGs +a04wD8xgVGjVEquHI3e9AueEBypztgJgiaGDSZxBAoGADpxUn3L6lJrPyOd3IJrj +ypU/EfvY7Qd5pRTrJd9tObbi8zF1sWi/FcQNgoZP7oz/aklFfq8WWwJbe0fL1Wk/ +MeVHj8JEc/dh1ISgbHYdBgegvS6L30RcNRUJWANYcifEQPlSHTzYXviQ8tEOCq+S +/TPqxnd2CkT6w3bSCJbxKVM= +-----END PRIVATE KEY----- diff --git a/tests/user/certificate/private3.key b/tests/user/certificate/private3.key new file mode 100644 index 00000000..f4261623 --- /dev/null +++ b/tests/user/certificate/private3.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDCA+6P2eieXHaV +JivtWif7SntjjkJm0juRKRRGsT3wt+zCZqoDe8zylTBN0mse/POWXdC+zXRMC2X/ +c4V10kgrvWbnNdFdUFfBUphiXSoqnUYHZ6Ta+b4UTzC2tECSUEnSCz9n1ofHnyqD +yT9FELzVkRkQqexD+BFgZTF39R4q8BA4bWKQy94Kgvb+IP77+ou4fhkBLI1MX5nk +Wa3Oyu4TMzT/tqgPE70hk8wQzUU2aiwJ7IsmnWE6Ysk7c4DYMJQF/51bi2ByZWER +NjyBY6L+ZV90aL4UFR9O+Pw9HatfHVBRdmzSkKJOr9iu4summWgH0QYDmbkdhGwY +vup0EmEfAgMBAAECggEAdEgFAGSbHebPD79sDnq9gcf3QgjuVU/lcbAMPf5W4GJr +3WvItAPMJwwxgkL9/vmeSN37kY/0BuvB+yPStnYM2WJQPX0s+V+A6RZGzJWIAzh1 +01RUIwYR3XxE9wv7s3W5eNFS9DpI8OS9h3TjndJVSy8Gtc0SFP6l839S8dGQfiyN +eMqV16M+TM0LwyEogvGa79l4HjMIcorypCXg8NVcDaxNJYnAcegoRwdhGsb4jKG6 +kB+Z4dfAKLu7OFT6/20Q0QUdA/PrdBRAFt8KPhrrweKaAApVtrU0OHNs9ULFHXnu +kSVKZ+UTCUGWxMd4lJw5XZQ4FqUdb8Sxt8TUuvRioQKBgQDy6zY1EiqsDZE+sJbd +/jnUWn+I4/xR5y4KmbEx76dWL39TooyiHYKABJQ9BgvBIXi95AXaRodwn12DhaW7 +VW0m4RgJH/FNZoxc9xOE2+EPr2pQGn6bvJK9IjsITDoAmDbguzMZ+TCDGZqIYiIE +GTcgeW7NOBYM2Qy8Ufqe9zfV0QKBgQDMdo426TPxdU6Gb8AVOFFuXlL6Py0Sxk0q +pEAhyEzCKV9HM1eX8aDrJ5++lFiMwlhkYRrWVBENPyhPgWo9sMATJM0AIsBKTSyg +rVuqlaU8e+Pqyl8ZMOZ6uMq3zLts/Vp1sX5yU8vw5FqMddMas6SMpIoPEIAiJlse +CujyJ29T7wKBgQCiQnry+C+IvYdHWK1tm2MFdW27Ao6IJuOaMQ8rS+l6qD9kni9S +GmQRHv3lxSQU3UbJkIZYRsQxdkIAmEUb3PQMBE8JyUxlZxpa/q8LD9RFpeZdm1T2 +sf9SVosX/9K+ku4VLvXzY4AEEhYnA2W1VyJ7jqF0cwJHkrPvFtNRW9DwAQKBgCRi +6NYu1DahSLM2Cfn8xskccinkulHABpWTG3KnoblgAXu7UFhTAO84Yv5YihWqtG5Q +taT02v//gF39yvlljhkaEH14sb3HVCzYDRsjfH9yENKE5z2lbS7j2fexsJ0pzUJq +rvULopyhFtguU75Jv/vjgEpEBnmNV+PVzzTg/bfzAoGAGz11E33qpZjVw6becf9w +U8qnPfncIqSCg0fWNnsYwD56vI9L2ExCZG//SOUZ54b8GW+RaTFDHOlIE8dRAhrF +M5QnEjm2S+wVPJz7gKQ3cVART8EPi/Q6BT7YIgNIhemq+AwW5xMhZcBiA3vRI/Eu +vi807exD569efFLa9uspI8o= +-----END PRIVATE KEY----- diff --git a/tests/user/certificate/test_user_certificate.yml b/tests/user/certificate/test_user_certificate.yml new file mode 100644 index 00000000..527c0f31 --- /dev/null +++ b/tests/user/certificate/test_user_certificate.yml @@ -0,0 +1,92 @@ +# +# Generate self-signed certificates using openssl: +# +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private1.key -out cert1.pem -subj '/CN=test' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private2.key -out cert2.pem -subj '/CN=test' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private3.key -out cert3.pem -subj '/CN=test' +# +# Convert the certificate do DER for easier handling through CLI +# +# openssl x509 -outform der -in cert1.pem -out cert1.der +# openssl x509 -outform der -in cert2.pem -out cert2.der +# openssl x509 -outform der -in cert3.pem -out cert3.der +# +# Use base64: +# +# base64 cert1.der -w5000 +# base64 cert2.der -w5000 +# base64 cert3.der -w5000 +# +--- +- name: Test user certificates + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + first: test + last: test + + - name: User test cert members present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certificate: + - 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 + action: member + register: result + failed_when: not result.changed + + - name: User test cert members present again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + first: test + last: test + certificate: + - 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 + action: member + register: result + failed_when: result.changed + + - name: User test cert members absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certificate: + - 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 + state: absent + action: member + register: result + failed_when: not result.changed + + - name: User test cert members absent again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certificate: + - 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 + state: absent + action: member + register: result + failed_when: result.changed + + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + state: absent + register: result + failed_when: not result.changed diff --git a/tests/user/certificate/test_users_certificate.yml b/tests/user/certificate/test_users_certificate.yml new file mode 100644 index 00000000..b5abbde2 --- /dev/null +++ b/tests/user/certificate/test_users_certificate.yml @@ -0,0 +1,103 @@ +# +# Generate self-signed certificates using openssl: +# +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private1.key -out cert1.pem -subj '/CN=test' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private2.key -out cert2.pem -subj '/CN=test' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private3.key -out cert3.pem -subj '/CN=test' +# +# Convert the certificate do DER for easier handling through CLI +# +# openssl x509 -outform der -in cert1.pem -out cert1.der +# openssl x509 -outform der -in cert2.pem -out cert2.der +# openssl x509 -outform der -in cert3.pem -out cert3.der +# +# Use base64: +# +# base64 cert1.der -w5000 +# base64 cert2.der -w5000 +# base64 cert3.der -w5000 +# +--- +- name: Test user certificates + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + state: absent + + - name: User test present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + first: test + last: test + + - name: User test cert members present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - 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 + action: member + register: result + failed_when: not result.changed + + - name: User test cert members present again + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - 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 + action: member + register: result + failed_when: result.changed + + - name: User test cert members absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3 + - MIIC/zCCAeegAwIBAgIUAWE1vaA+mZd3nwZqwWH64EbHvR0wDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NDVaFw0yMDEwMTMxNjI4NDVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWzJibKtN8Zf7LgandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3VfJNYmCbA1baLVJ0YZJijJ7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSYOKmdHHRClplysL8OyyEG7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv1wNw1rqWKF1ZzagWRlG4QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCkVOZIhxu77OmNrFsXmM4rZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0KgE57zCDVr9Ix+p/dA5R1mG4RJ2XAgMBAAGjUzBRMB0GA1UdDgQWBBSbuiH2lNVrID3yt1SsFwtOFKOnpTAfBgNVHSMEGDAWgBSbuiH2lNVrID3yt1SsFwtOFKOnpTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBCVWd293wWyohFqMFMHRBBg97T2Uc1yeT0dMH4BpuOaCqQp4q5ep+uLcXEI6+3mEwm8pa/ULQCD8yLLdotIWlG3+h/4boFpdiPFcBDgT8kGe+0KOzB8Nt7E13QYOu12MNi10qwGrjKhdhu1xBe4fpY5VCetVU1OLyuTsUyucQsFrtZI0SR83h+blbyoMZ7IhMngCfGUe1bnYeWnLbpFbigKfPuVDWsMH2kgj05EAd5EgHkWbX8QA8hmcmDKfNT3YZM8kiGQwmFrnQdq8bN0uHR8Nz+24cbmdbHcD65wlDW6GmYxi8mW+V6bAqn9pir/J14r4YFnqMGgjmdt81tscJV + - MIIC/zCCAeegAwIBAgIUTC33WUoYGFoIVGMwgjbc5J6xCyowDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NTJaFw0yMDEwMTMxNjI4NTJaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCA+6P2eieXHaVJivtWif7SntjjkJm0juRKRRGsT3wt+zCZqoDe8zylTBN0mse/POWXdC+zXRMC2X/c4V10kgrvWbnNdFdUFfBUphiXSoqnUYHZ6Ta+b4UTzC2tECSUEnSCz9n1ofHnyqDyT9FELzVkRkQqexD+BFgZTF39R4q8BA4bWKQy94Kgvb+IP77+ou4fhkBLI1MX5nkWa3Oyu4TMzT/tqgPE70hk8wQzUU2aiwJ7IsmnWE6Ysk7c4DYMJQF/51bi2ByZWERNjyBY6L+ZV90aL4UFR9O+Pw9HatfHVBRdmzSkKJOr9iu4summWgH0QYDmbkdhGwYvup0EmEfAgMBAAGjUzBRMB0GA1UdDgQWBBSJCQ8ho0Ppe0khVhgiMqsvlgxIjzAfBgNVHSMEGDAWgBSJCQ8ho0Ppe0khVhgiMqsvlgxIjzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAILLPnau32r/YoOVCVWQotGtySy36aFlHa3T8IkSpatNCPIf3U0FWS6TVYBwY0PBfdqWBkvCuJTupLh0OEP4TCsDa5pJGOK7blyfiAfcHajqyouACSVNlG63EPvB63h4H4F4HJnhDd4z7pVC/WPB8w5GTBJNjELmeWfH7nj7lu8UkOdLhzTKL40RPs0k4l09yYBmZqqExxGsSfvRBQcrwlAsvQ0E/cTNGbyzOKs3SbOM2WEHye6xNEsey01icYcjfjqvEd6mw3+WOUeJAuDH9/EOloFM2iz5Xp31Ig3WT0RVy+lMriG9GesPpFBs2xp9wQCXLNIkpbHKyYs3voMyBH + state: absent + action: member + #register: result + #failed_when: not result.changed + + - name: User test cert members absent again + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - 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 + state: absent + action: member + register: result + failed_when: result.changed + + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + state: absent + register: result + failed_when: not result.changed diff --git a/tests/user/certmapdata/test_user_certmapdata.yml b/tests/user/certmapdata/test_user_certmapdata.yml new file mode 100644 index 00000000..cf5576ec --- /dev/null +++ b/tests/user/certmapdata/test_user_certmapdata.yml @@ -0,0 +1,160 @@ +# +# Generate self-signed certificates using openssl: +# +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private1.key -out cert1.pem -subj '/CN=test1' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private2.key -out cert2.pem -subj '/CN=test2' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private3.key -out cert3.pem -subj '/CN=test2' +# +# Convert the certificate do DER for easier handling through CLI +# +# openssl x509 -outform der -in cert1.pem -out cert1.der +# openssl x509 -outform der -in cert2.pem -out cert2.der +# openssl x509 -outform der -in cert3.pem -out cert3.der +# +# Use base64: +# +# base64 cert1.der -w5000 +# base64 cert2.der -w5000 +# base64 cert3.der -w5000 +# +--- +- name: Test user certmapdata + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + state: absent + + - name: User test present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + first: test + last: test + register: result + failed_when: not result.changed + + - name: User test certmapdata members present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + register: result + failed_when: not result.changed + + - name: User test certmapdata members present again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + register: result + failed_when: result.changed + + - name: User test certmapdata members absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User test certmapdata members absent again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + state: absent + register: result + failed_when: result.changed + + - name: User test certmapdata members present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + register: result + failed_when: not result.changed + + - name: User test certmapdata members present again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + register: result + failed_when: result.changed + + - name: User test certmapdata members absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User test certmapdata members absent again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + state: absent + register: result + failed_when: not result.changed diff --git a/tests/user/certmapdata/test_user_certmapdata_issuer_subject.yml b/tests/user/certmapdata/test_user_certmapdata_issuer_subject.yml new file mode 100644 index 00000000..0309c6af --- /dev/null +++ b/tests/user/certmapdata/test_user_certmapdata_issuer_subject.yml @@ -0,0 +1,91 @@ +--- +- name: Test user certmapdata + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + state: absent + + - name: User test present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + first: test + last: test + register: result + failed_when: not result.changed + + - name: User test certmapdata members present + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + register: result + failed_when: not result.changed + + - name: User test certmapdata members present again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + register: result + failed_when: result.changed + + - name: User test certmapdata members absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User test certmapdata members absent again + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + name: test + state: absent + register: result + failed_when: not result.changed diff --git a/tests/user/certmapdata/test_users_certmapdata.yml b/tests/user/certmapdata/test_users_certmapdata.yml new file mode 100644 index 00000000..5509fa4c --- /dev/null +++ b/tests/user/certmapdata/test_users_certmapdata.yml @@ -0,0 +1,171 @@ +# +# Generate self-signed certificates using openssl: +# +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private1.key -out cert1.pem -subj '/CN=test1' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private2.key -out cert2.pem -subj '/CN=test2' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private3.key -out cert3.pem -subj '/CN=test2' +# +# Convert the certificate do DER for easier handling through CLI +# +# openssl x509 -outform der -in cert1.pem -out cert1.der +# openssl x509 -outform der -in cert2.pem -out cert2.der +# openssl x509 -outform der -in cert3.pem -out cert3.der +# +# Use base64: +# +# base64 cert1.der -w5000 +# base64 cert2.der -w5000 +# base64 cert3.der -w5000 +# +--- +- name: Test user certmapdata + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + state: absent + + - name: User test present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + first: test + last: test + register: result + failed_when: not result.changed + + - name: User test certmapdata members present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + register: result + failed_when: not result.changed + + - name: User test certmapdata members present again + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + register: result + failed_when: result.changed + + - name: User test certmapdata members absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User test certmapdata members absent again + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - certificate: MIIDATCCAemgAwIBAgIUFDZuUg9kBvN+ubTBaS6d62KafvQwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDEwHhcNMTkxMDE0MTk0ODM4WhcNMjAxMDEzMTk0ODM4WjAQMQ4wDAYDVQQDDAV0ZXN0MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALrwv6KuOIZMxjp9aueRgJWKns7P7Oo8lo4ojBVhyB3K11+1OifLqfo2SL9HPx9XynvouMj+XnqbY+NRLOX9wPYAvA7rXUgN1zQYK5stCCTjW0V4QloHnMUPM0shIuErcTP1UMatzTaFxd+UkvZCMNbE9jXHeCd3uDYoqA8Y4yRuqQ4HcnbB7DyMNZHaSCHxQCvZzllJA9m1b+c2sO3l7008PibG5RSpPnrjMUeH4yzjaB8R7A/WApAA1g5bn+IXD2dDsbdHAVFdzqwkxxLlacD8pbM7jWtCI+qJwE6dXpPb5WRkUz3tZLkEW7EQJAi3TMy//hF/SobEul3WVjiO/HUCAwEAAaNTMFEwHQYDVR0OBBYEFCkUPLMp0M5rgxHNAYuunGM0if/vMB8GA1UdIwQYMBaAFCkUPLMp0M5rgxHNAYuunGM0if/vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI7gj1VllrF0eRqPP9xtSqWla+qGMpHUWur1yIoy3R8I7LV3muQpbgxsfOyH2PHj69v+8yvI5einvOXJVgJxcn/ERxm/prIdo+QlK4O/SDdswJWfjCaDlk03PzjDzHXeEWRwDFV9zpRx/hjLUn8knwBOSbUE8ImUGt37ZBMBsz++y+oCZJVxzwZgcXZ3L4yuhJ0l48Cz+2EEoYN08gJqNk1EzmpBcAYJJ0Ai1psFqu12b32fNIhWSSf5THldqNefdpBlMo5ZtC9wE//NTml+nebA1FJDSppTMfHP/rTb/wfNx5vc5KLYYR9wZUUUDeJhdNPlBZZuuVbn29X6a4teoBk= + - certificate: MIIDATCCAemgAwIBAgIUK2Sa8/xr/4H9BOB0K0SswbVmmMcwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDIwHhcNMTkxMDE0MTk0ODM1WhcNMjAxMDEzMTk0ODM1WjAQMQ4wDAYDVQQDDAV0ZXN0MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANQdGqRUTNCptUsZxVe03YTYyhg6+ovidYP9bPPsCS1FzOTCKV9maFv4GHGEI455lkGowW3okT2DPC5pgtH43vZkDtjXNy1JDyg1y4OmxfiAg4Uc0W9DnakvEokVyt44WRzXjlv2CBO+A7Zon8z3aJwKKCV4EfpuvRw/npqhrnGF/w/n7NXyeRXI6lom9hqIQzJoRjXrMIEbtzM8m2GWlFq8af1KJ+Cmm25c87aeyu7I0+BRCq21pwcyQ6Cx0Lo3szQVlD9ZN6wUfz3IDacLjoMOZkVrclIKO0DU595AVo86TD0C1TC/vCjmDGOfgoQsfS5OFfP+FmN6we9IVIAUcL8CAwEAAaNTMFEwHQYDVR0OBBYEFHTGQuoyDwtbHVLU0SseGvarrJKOMB8GA1UdIwQYMBaAFHTGQuoyDwtbHVLU0SseGvarrJKOMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEGcA6GzCv67GYWoFK9zAjN01M79BDSuac2QV+9PYjQ7tLXQPGdoXJjJzrkJLgzTwqH2iIUqGoAZp30dW89yrJuA8s0gk3SbPOowYmst6pN6SeENxXL/1kn/IBm3+oHf5IWf7vaW4j8tYt7Q3x2K3V9GWRrozGEPIXk8yMeJq72wpfWynDxxYOepGG2+pSkm8soi9Fpt29pb+DtKB2U9GpMBS8vHU+1H4trIvEOMsd4v+X1+Vxlnt8tgy8/PrlKk1wLB9r1XA+W/vXPBe0tRcuntsXiniSKGC5oiR9AFS134HFEWuhxXWihNFzsLmNimvvxQBlXMRPZC1waCSoTKTAI= + - certificate: MIIDATCCAemgAwIBAgIUIa8TtXJ4Nq8VYrlgbSKcVt0FdckwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UEAwwFdGVzdDMwHhcNMTkxMDE0MTk0ODQ1WhcNMjAxMDEzMTk0ODQ1WjAQMQ4wDAYDVQQDDAV0ZXN0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyttsxCiNH8qx83FTkQaUKxQXer6aMa5DpyfnGMh1K3icfEHyiKLkrjiuFbnfYC1s/iYkz9UyBQrneglYROGgr8TSFC5LXiVppI3/LONKuBh0GfmBM8dhYkOg6WmEB15EL7Hj3V6Xi/Sx3WFnvY/wAzds06linDp/I46jRXqMrWFuhXbf4A09OXpQs6KOMWkkitw3lKuKLgiNzXEiAHaS2YqW7UwSy9RLCrIDMwEmVzZ/gh3vGwM2jyfhOZ75U/xOt9U6jMQsp7hFQAoSeVBTuGpjI40g3IbNBRNi2SnERFzQFkJr0tzAX250XGDaRwRuLhilYoQoJl59B2cTzYsLECAwEAAaNTMFEwHQYDVR0OBBYEFD8iZgdSshdfyAMNfQNzS74Dl9UVMB8GA1UdIwQYMBaAFD8iZgdSshdfyAMNfQNzS74Dl9UVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFrip5Hl7dHz3oqXLcoza9rQCiMsXV7Q2gVHJ6W2YZZlQpVOBmNPf0n42OVZrnIkDnuGD+pGuw65Aq/TnfMI2KrW8o//aOXLitR60moMEbj61IlBx3aUGvdhyevrz4tM8SHX05p4K86ZJ9jZuS/sNyDwBKBaBAqjW1Rjuqb2o+C9zvDgPWFX++8OgXljDPHR6XYAKpRBmbBZHxYXazjhj1gGhb9/txqDn4EniPXE4rZ/X5MwXzAPs7ROgvr7fkIQypO+O++FGn8rWQL+5zZY0GavOK6FMBJj8M6RDHwEEsXQqSHicsrL8iMx4jun82wgu+gO5lBPTMd0hjsOYR3eT0A= + action: member + state: absent + register: result + failed_when: result.changed + + - name: User test certmapdata members present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + register: result + failed_when: not result.changed + + - name: User test certmapdata members present again + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + register: result + failed_when: result.changed + + - name: User test certmapdata members absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User test certmapdata members absent again + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certmapdata: + - issuer: CN=issuer1 + subject: CN=subject1 + - issuer: CN=issuer2 + subject: CN=subject2 + - issuer: CN=issuer3 + subject: CN=subject3 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + state: absent + register: result + failed_when: not result.changed diff --git a/tests/user/test_user.yml b/tests/user/test_user.yml new file mode 100644 index 00000000..c172049f --- /dev/null +++ b/tests/user/test_user.yml @@ -0,0 +1,258 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Remove test users + ipauser: + ipaadmin_password: SomeADMINpassword + name: manager1,manager2,manager3,pinky,pinky2 + state: absent + + - name: User manager1 present + ipauser: + ipaadmin_password: SomeADMINpassword + name: manager1 + first: Manager + last: One + register: result + failed_when: not result.changed + + - name: User manager2 present + ipauser: + ipaadmin_password: SomeADMINpassword + name: manager2 + first: Manager + last: One + register: result + failed_when: not result.changed + + - name: User manager3 present + ipauser: + ipaadmin_password: SomeADMINpassword + name: manager3 + first: Manager + last: One + register: result + failed_when: not result.changed + + - name: User pinky present + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + uid: 10001 + gid: 100 + phone: "+555123457" + email: pinky@acme.com + principalexpiration: "20220119235959" + #passwordexpiration: "2022-01-19 23:59:59" + first: pinky + last: Acme + initials: pa + #password: foo2 + principal: pa + random: yes + city: PinkyCity + userstate: PinkyState + postalcode: PinkyZip + mobile: "+555123458,+555123459" + pager: "+555123450,+555123451" + fax: "+555123452,+555123453" + orgunit: PinkyOrgUnit + manager: manager1,manager2 + update_password: on_create + carlicense: PinkyCarLicense1,PinkyCarLicense2 + # sshpubkey + userauthtype: password,radius,otp + userclass: PinkyUserClass + #radius: "http://some.link/" + #radiususer: PinkyRadiusUser + departmentnumber: "1234" + employeenumber: "0815" + employeetype: "PinkyExmployeeType" + preferredlanguage: "en" + # certificate + noprivate: yes + nomembers: false + #issuer: PinkyIssuer + #subject: PinkySubject + register: result + failed_when: not result.changed + + - name: User pinky present with changed settings + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + first: pinky + last: Acme + #manager: manager1,manager2,manager3 + #principal: pa,pa1,pa3 + sshpubkey: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqmVDpEX5gnSjKuv97AyzOhaUMMKz8ahOA3GY77tVC4o68KNgMCmDSEG1/kOIaElngNLaCha3p/2iAcU9Bi1tLKUlm2bbO5NHNwHfRxY/3cJtq+/7D1vxJzqThYwI4F9vr1WxyY2+mMTv3pXbfAJoR8Mu06XaEY5PDetlDKjHLuNWF+/O7ZU8PsULTa1dJZFrtXeFpmUoLoGxQBvlrlcPI1zDciCSU24t27Zan5Py2l5QchyI7yhCyMM77KDtj5+AFVpmkb9+zq50rYJAyFVeyUvwjzErvQrKJzYpA0NyBp7vskWbt36M16/M/LxEK7HA6mkcakO3ESWx5MT1LAjvdlnxbWG3787MxweHXuB8CZU+9bZPFBaJ+VQtOfJ7I8eH0S16moPC4ak8FlcFvOH8ERDPWLFDqfy09yaZ7bVIF0//5ZI7Nf3YDe3S7GrBX5ieYuECyP6UNkTx9BRsAQeVvXEc6otzB7iCSnYBMGUGzCqeigoAWaVQUONsSR3Uatks= pinky@ipaserver.el81.local + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDc8MIjaSrxLYHvu+hduoF4m6NUFSlXZWzYbd3BK4L47/U4eiXoOS6dcfuZJDjmLfOipc7XVp7NADwAgA1yBOAjbeVpXr2tC8w8saZibl75WBOEjDfNroiOh/f/ojrwwHg05QTVSZHs27sU1HBPyCQM/FHVM6EnRfmyiBkEBA/3ca0PJ9UJhWb2XisCaz6y6QcTh4gQnvHzgmEmK31GwiKnmBSEQuj8P5NGCO8RlN3cq3zpRpMDEoBRCjQYicllf/5P43r5OGvS1LhTiAMfyqE37URezNQa7aozBpH1GhIwAmjAtm84jXQjxUgZPYC0aSLuADYErScOP4792r6koH9t/DM5/M+jG2c4PNWynDczUw6Eaxl5E3hU0Ee9UN0Oee7iBnVenS/QMeZNyo5lMA/HXT5lrYiJGTYM0shRjGXXYBbJZhWerguSWDAdUd1gvuGP1nb7/+/Cvb46+HX7zYouS5Ojo0yPzMZ07X142jnKAfx9LnKdMUCwBJzbtoJ91Zc= pinky@ipaserver.el81.local + register: result + failed_when: not result.changed + + - name: User pinky add manager manager1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + register: result + failed_when: not result.changed + + - name: User pinky add manager manager1 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + register: result + failed_when: result.changed + + - name: User pinky add manager manager2, manager3 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager2,manager3 + action: member + register: result + failed_when: not result.changed + + - name: User pinky add manager manager2, manager3 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager2,manager3 + action: member + register: result + failed_when: result.changed + + - name: User pinky remove manager manager1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User pinky remove manager manager1 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User pinky add principal pa + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa + action: member + register: result + failed_when: not result.changed + + - name: User pinky add principal pa again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa + action: member + register: result + failed_when: result.changed + + - name: User pinky add principal pa1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa1 + action: member + register: result + failed_when: not result.changed + + - name: User pinky remove principal pa1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa1 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User pinky remove principal pa1 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa1 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User pinky remove principal pa + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User pinky remove principal non-existing pa2 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa2 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User pinky absent and preserved + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + preserve: yes + state: absent + register: result + failed_when: not result.changed + + - name: User pinky undeleted (preserved before) + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + state: undeleted + register: result + failed_when: not result.changed + + - name: Users pinky disabled + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + state: disabled + register: result + failed_when: not result.changed + + - name: User pinky enabled + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + state: enabled + register: result + failed_when: not result.changed + + - name: Remove test users + ipauser: + ipaadmin_password: SomeADMINpassword + name: manager1,manager2,manager3,pinky,pinky2 + state: absent diff --git a/tests/user/test_users.yml b/tests/user/test_users.yml new file mode 100644 index 00000000..729bb68c --- /dev/null +++ b/tests/user/test_users.yml @@ -0,0 +1,376 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Remove test users + ipauser: + ipaadmin_password: SomeADMINpassword + name: user1,user2,user3,user4,user5,user6,user7,user8,user9,user10 + state: absent + + - name: Users user1..10 present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: user1 + givenname: user1 + last: Last + - name: user2 + first: user2 + last: Last + - name: user3 + first: user3 + last: Last + - name: user4 + first: user4 + last: Last + - name: user5 + first: user5 + last: Last + - name: user6 + first: user6 + last: Last + - name: user7 + first: user7 + last: Last + - name: user8 + first: user8 + last: Last + - name: user9 + first: user9 + last: Last + - name: user10 + first: user10 + last: Last + register: result + failed_when: not result.changed + + - name: Users user1..10 present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: user1 + givenname: user1 + last: Last + - name: user2 + first: user2 + last: Last + - name: user3 + first: user3 + last: Last + - name: user4 + first: user4 + last: Last + - name: user5 + first: user5 + last: Last + - name: user6 + first: user6 + last: Last + - name: user7 + first: user7 + last: Last + - name: user8 + first: user8 + last: Last + - name: user9 + first: user9 + last: Last + - name: user10 + first: user10 + last: Last + register: result + failed_when: result.changed + + - name: Remove test users + ipauser: + ipaadmin_password: SomeADMINpassword + name: user1,user2,user3,user4,user5,user6,user7,user8,user9,user10 + state: absent + + - name: Remove test users + ipauser: + ipaadmin_password: SomeADMINpassword + name: manager1,manager2,manager3,pinky,pinky2 + state: absent + + - name: User manager1 present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: manager1 + first: Manager1 + last: One1 + - name: manager2 + first: Manager2 + last: One2 + - name: manager3 + first: Manager3 + last: One3 + register: result + failed_when: not result.changed + + - name: User pinky present + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + uid: 10001 + gid: 100 + phone: "+555123457" + email: pinky@acme.com + principalexpiration: "20220119235959" + #passwordexpiration: "2022-01-19 23:59:59" + first: pinky + last: Acme + initials: pa + #password: foo2 + principal: pa + random: yes + city: PinkyCity + userstate: PinkyState + postalcode: PinkyZip + mobile: "+555123458,+555123459" + pager: "+555123450,+555123451" + fax: "+555123452,+555123453" + orgunit: PinkyOrgUnit + manager: manager1,manager2 + update_password: on_create + carlicense: PinkyCarLicense1,PinkyCarLicense2 + # sshpubkey + userauthtype: password,radius,otp + userclass: PinkyUserClass + #radius: "http://some.link/" + #radiususer: PinkyRadiusUser + departmentnumber: "1234" + employeenumber: "0815" + employeetype: "PinkyExmployeeType" + preferredlanguage: "en" + # certificate + noprivate: yes + nomembers: false + #issuer: PinkyIssuer + #subject: PinkySubject + register: result + failed_when: not result.changed + + - name: Same user pinky present again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + uid: 10001 + gid: 100 + phone: "+555123457" + email: pinky@acme.com + principalexpiration: "20220119235959" + #passwordexpiration: "2022-01-19 23:59:59" + first: pinky + last: Acme + initials: pa + #password: foo2 + principal: pa + random: yes + city: PinkyCity + userstate: PinkyState + postalcode: PinkyZip + mobile: "+555123458,+555123459" + pager: "+555123450,+555123451" + fax: "+555123452,+555123453" + orgunit: PinkyOrgUnit + manager: manager1,manager2 + update_password: on_create + carlicense: PinkyCarLicense1,PinkyCarLicense2 + # sshpubkey + userauthtype: password,radius,otp + userclass: PinkyUserClass + #radius: "http://some.link/" + #radiususer: PinkyRadiusUser + departmentnumber: "1234" + employeenumber: "0815" + employeetype: "PinkyExmployeeType" + preferredlanguage: "en" + # certificate + noprivate: yes + nomembers: false + #issuer: PinkyIssuer + #subject: PinkySubject + register: result + failed_when: result.changed + + - name: User pinky present with changed settings + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + first: pinky + last: Acme + #manager: manager1,manager2,manager3 + #principal: pa,pa1,pa3 + sshpubkey: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqmVDpEX5gnSjKuv97AyzOhaUMMKz8ahOA3GY77tVC4o68KNgMCmDSEG1/kOIaElngNLaCha3p/2iAcU9Bi1tLKUlm2bbO5NHNwHfRxY/3cJtq+/7D1vxJzqThYwI4F9vr1WxyY2+mMTv3pXbfAJoR8Mu06XaEY5PDetlDKjHLuNWF+/O7ZU8PsULTa1dJZFrtXeFpmUoLoGxQBvlrlcPI1zDciCSU24t27Zan5Py2l5QchyI7yhCyMM77KDtj5+AFVpmkb9+zq50rYJAyFVeyUvwjzErvQrKJzYpA0NyBp7vskWbt36M16/M/LxEK7HA6mkcakO3ESWx5MT1LAjvdlnxbWG3787MxweHXuB8CZU+9bZPFBaJ+VQtOfJ7I8eH0S16moPC4ak8FlcFvOH8ERDPWLFDqfy09yaZ7bVIF0//5ZI7Nf3YDe3S7GrBX5ieYuECyP6UNkTx9BRsAQeVvXEc6otzB7iCSnYBMGUGzCqeigoAWaVQUONsSR3Uatks= pinky@ipaserver.el81.local + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDc8MIjaSrxLYHvu+hduoF4m6NUFSlXZWzYbd3BK4L47/U4eiXoOS6dcfuZJDjmLfOipc7XVp7NADwAgA1yBOAjbeVpXr2tC8w8saZibl75WBOEjDfNroiOh/f/ojrwwHg05QTVSZHs27sU1HBPyCQM/FHVM6EnRfmyiBkEBA/3ca0PJ9UJhWb2XisCaz6y6QcTh4gQnvHzgmEmK31GwiKnmBSEQuj8P5NGCO8RlN3cq3zpRpMDEoBRCjQYicllf/5P43r5OGvS1LhTiAMfyqE37URezNQa7aozBpH1GhIwAmjAtm84jXQjxUgZPYC0aSLuADYErScOP4792r6koH9t/DM5/M+jG2c4PNWynDczUw6Eaxl5E3hU0Ee9UN0Oee7iBnVenS/QMeZNyo5lMA/HXT5lrYiJGTYM0shRjGXXYBbJZhWerguSWDAdUd1gvuGP1nb7/+/Cvb46+HX7zYouS5Ojo0yPzMZ07X142jnKAfx9LnKdMUCwBJzbtoJ91Zc= pinky@ipaserver.el81.local + register: result + failed_when: not result.changed + + - name: User pinky add manager manager1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + register: result + failed_when: not result.changed + + - name: User pinky add manager manager1 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + register: result + failed_when: result.changed + + - name: User pinky add manager manager2, manager3 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager2,manager3 + action: member + register: result + failed_when: not result.changed + + - name: User pinky add manager manager2, manager3 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager2,manager3 + action: member + register: result + failed_when: result.changed + + - name: User pinky remove manager manager1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User pinky remove manager manager1 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + manager: manager1 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User pinky add principal pa + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa + action: member + register: result + failed_when: not result.changed + + - name: User pinky add principal pa again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa + action: member + register: result + failed_when: result.changed + + - name: User pinky add principal pa1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa1 + action: member + register: result + failed_when: not result.changed + + - name: User pinky remove principal pa1 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa1 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User pinky remove principal pa1 again + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa1 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User pinky remove principal pa + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa + action: member + state: absent + register: result + failed_when: not result.changed + + - name: User pinky remove principal non-existing pa2 + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + principal: pa2 + action: member + state: absent + register: result + failed_when: result.changed + + - name: User pinky absent and preserved + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + preserve: yes + state: absent + register: result + failed_when: not result.changed + + - name: User pinky undeleted (preserved before) + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + state: undeleted + register: result + failed_when: not result.changed + + - name: Users pinky disabled + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + state: disabled + register: result + failed_when: not result.changed + + - name: User pinky enabled + ipauser: + ipaadmin_password: SomeADMINpassword + name: pinky + state: enabled + register: result + failed_when: not result.changed + + - name: Remove test users + ipauser: + ipaadmin_password: SomeADMINpassword + name: manager1,manager2,manager3,pinky,pinky2 + state: absent diff --git a/tests/user/test_users_absent.yml b/tests/user/test_users_absent.yml new file mode 100644 index 00000000..eaab27f7 --- /dev/null +++ b/tests/user/test_users_absent.yml @@ -0,0 +1,16 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Include users_absent.json + include_vars: + file: users_absent.json + + - name: Users absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: "{{ users }}" + state: absent diff --git a/tests/user/test_users_invalid_cert.yml b/tests/user/test_users_invalid_cert.yml new file mode 100644 index 00000000..62a8d9e5 --- /dev/null +++ b/tests/user/test_users_invalid_cert.yml @@ -0,0 +1,64 @@ +# +# Generate self-signed certificates using openssl: +# +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private1.key -out cert1.pem -subj '/CN=test' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private2.key -out cert2.pem -subj '/CN=test' +# openssl req -x509 -newkey rsa:2048 -days 365 -nodes -keyout private3.key -out cert3.pem -subj '/CN=test' +# +# Convert the certificate do DER for easier handling through CLI +# +# openssl x509 -outform der -in cert1.pem -out cert1.der +# openssl x509 -outform der -in cert2.pem -out cert2.der +# openssl x509 -outform der -in cert3.pem -out cert3.der +# +# Use base64: +# +# base64 cert1.der -w5000 +# base64 cert2.der -w5000 +# base64 cert3.der -w5000 +# +--- +- name: Test user certificates + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: User test absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + state: absent + + - name: User test present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + first: test + last: test + + - name: User test cert members present + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - MIIC/zCCAeegAwIBAgIUAWE1vaA+mZd3nwZqwWH64EbHvR0wDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NDVaFw0yMDEwMTMxNjI4NDVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWzJibKtN8Zf7LgandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3VfJNYmCbA1baLVJ0YZJijJ7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSYOKmdHHRClplysL8OyyEG7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv1wNw1rqWKF1ZzagWRlG4QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCkVOZIhxu77OmNrFsXmM4rZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0KgE57zCDVr9Ix+p/dA5R1mG4RJ2XAgMBAAGjUzBRMB0GA1UdDgQWBBSbuiH2lNVrID3yt1SsFwtOFKOnpTAfBgNVHSMEGDAWgBSbuiH2lNVrID3yt1SsFwtOFKOnpTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBCVWd293wWyohFqMFMHRBBg97T2Uc1yeT0dMH4BpuOaCqQp4q5ep+uLcXEI6+3mEwm8pa/ULQCD8yLLdotIWlG3+h/4boFpdiPFcBDgT8kGe+0KOzB8Nt7E13QYOu12MNi10qwGrjKhdhu1xBe4fpY5VCetVU1OLyuTsUyucQsFrtZI0SR83h+blbyoMZ7IhMngCfGUe1bnYeWnLbpFbigKfPuVDWsMH2kgj05EAd5EgHkWbX8QA8hmcmDKfNT3YZM8kiGQwmFrnQdq8bN0uHR8Nz+24cbmdbHcD65wlDW6GmYxi8mW+V6bAqn9pir/J14r4YFnqMGgjmdt81tscJV + action: member + register: result + failed_when: not result.changed + + - name: User test cert members absent + ipauser: + ipaadmin_password: SomeADMINpassword + users: + - name: test + certificate: + - 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 + state: absent + action: member + #register: result + #failed_when: not result.changed diff --git a/tests/user/test_users_present.yml b/tests/user/test_users_present.yml new file mode 100644 index 00000000..370b1372 --- /dev/null +++ b/tests/user/test_users_present.yml @@ -0,0 +1,15 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: Include users_present.json + include_vars: + file: users_present.json + + - name: Users present + ipauser: + ipaadmin_password: SomeADMINpassword + users: "{{ users }}" diff --git a/tests/user/test_users_present_slice.yml b/tests/user/test_users_present_slice.yml new file mode 100644 index 00000000..8c6524d8 --- /dev/null +++ b/tests/user/test_users_present_slice.yml @@ -0,0 +1,19 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: false + + vars: + slice_size: 500 + tasks: + - name: Include users_present.json + include_vars: + file: users_present.json + - debug: + msg: "{{ users | length }}" + - name: Users present + ipauser: + ipaadmin_password: SomeADMINpassword + users: "{{ users[item:item+slice_size] }}" + loop: "{{ range(0,users | length, slice_size) | list }}" diff --git a/tests/user/users_absent.json b/tests/user/users_absent.json new file mode 100644 index 00000000..6d29807a --- /dev/null +++ b/tests/user/users_absent.json @@ -0,0 +1,3004 @@ +{ + "users": [ + { + "name": "user1", + }, + { + "name": "user2", + }, + { + "name": "user3", + }, + { + "name": "user4", + }, + { + "name": "user5", + }, + { + "name": "user6", + }, + { + "name": "user7", + }, + { + "name": "user8", + }, + { + "name": "user9", + }, + { + "name": "user10", + }, + { + "name": "user11", + }, + { + "name": "user12", + }, + { + "name": "user13", + }, + { + "name": "user14", + }, + { + "name": "user15", + }, + { + "name": "user16", + }, + { + "name": "user17", + }, + { + "name": "user18", + }, + { + "name": "user19", + }, + { + "name": "user20", + }, + { + "name": "user21", + }, + { + "name": "user22", + }, + { + "name": "user23", + }, + { + "name": "user24", + }, + { + "name": "user25", + }, + { + "name": "user26", + }, + { + "name": "user27", + }, + { + "name": "user28", + }, + { + "name": "user29", + }, + { + "name": "user30", + }, + { + "name": "user31", + }, + { + "name": "user32", + }, + { + "name": "user33", + }, + { + "name": "user34", + }, + { + "name": "user35", + }, + { + "name": "user36", + }, + { + "name": "user37", + }, + { + "name": "user38", + }, + { + "name": "user39", + }, + { + "name": "user40", + }, + { + "name": "user41", + }, + { + "name": "user42", + }, + { + "name": "user43", + }, + { + "name": "user44", + }, + { + "name": "user45", + }, + { + "name": "user46", + }, + { + "name": "user47", + }, + { + "name": "user48", + }, + { + "name": "user49", + }, + { + "name": "user50", + }, + { + "name": "user51", + }, + { + "name": "user52", + }, + { + "name": "user53", + }, + { + "name": "user54", + }, + { + "name": "user55", + }, + { + "name": "user56", + }, + { + "name": "user57", + }, + { + "name": "user58", + }, + { + "name": "user59", + }, + { + "name": "user60", + }, + { + "name": "user61", + }, + { + "name": "user62", + }, + { + "name": "user63", + }, + { + "name": "user64", + }, + { + "name": "user65", + }, + { + "name": "user66", + }, + { + "name": "user67", + }, + { + "name": "user68", + }, + { + "name": "user69", + }, + { + "name": "user70", + }, + { + "name": "user71", + }, + { + "name": "user72", + }, + { + "name": "user73", + }, + { + "name": "user74", + }, + { + "name": "user75", + }, + { + "name": "user76", + }, + { + "name": "user77", + }, + { + "name": "user78", + }, + { + "name": "user79", + }, + { + "name": "user80", + }, + { + "name": "user81", + }, + { + "name": "user82", + }, + { + "name": "user83", + }, + { + "name": "user84", + }, + { + "name": "user85", + }, + { + "name": "user86", + }, + { + "name": "user87", + }, + { + "name": "user88", + }, + { + "name": "user89", + }, + { + "name": "user90", + }, + { + "name": "user91", + }, + { + "name": "user92", + }, + { + "name": "user93", + }, + { + "name": "user94", + }, + { + "name": "user95", + }, + { + "name": "user96", + }, + { + "name": "user97", + }, + { + "name": "user98", + }, + { + "name": "user99", + }, + { + "name": "user100", + }, + { + "name": "user101", + }, + { + "name": "user102", + }, + { + "name": "user103", + }, + { + "name": "user104", + }, + { + "name": "user105", + }, + { + "name": "user106", + }, + { + "name": "user107", + }, + { + "name": "user108", + }, + { + "name": "user109", + }, + { + "name": "user110", + }, + { + "name": "user111", + }, + { + "name": "user112", + }, + { + "name": "user113", + }, + { + "name": "user114", + }, + { + "name": "user115", + }, + { + "name": "user116", + }, + { + "name": "user117", + }, + { + "name": "user118", + }, + { + "name": "user119", + }, + { + "name": "user120", + }, + { + "name": "user121", + }, + { + "name": "user122", + }, + { + "name": "user123", + }, + { + "name": "user124", + }, + { + "name": "user125", + }, + { + "name": "user126", + }, + { + "name": "user127", + }, + { + "name": "user128", + }, + { + "name": "user129", + }, + { + "name": "user130", + }, + { + "name": "user131", + }, + { + "name": "user132", + }, + { + "name": "user133", + }, + { + "name": "user134", + }, + { + "name": "user135", + }, + { + "name": "user136", + }, + { + "name": "user137", + }, + { + "name": "user138", + }, + { + "name": "user139", + }, + { + "name": "user140", + }, + { + "name": "user141", + }, + { + "name": "user142", + }, + { + "name": "user143", + }, + { + "name": "user144", + }, + { + "name": "user145", + }, + { + "name": "user146", + }, + { + "name": "user147", + }, + { + "name": "user148", + }, + { + "name": "user149", + }, + { + "name": "user150", + }, + { + "name": "user151", + }, + { + "name": "user152", + }, + { + "name": "user153", + }, + { + "name": "user154", + }, + { + "name": "user155", + }, + { + "name": "user156", + }, + { + "name": "user157", + }, + { + "name": "user158", + }, + { + "name": "user159", + }, + { + "name": "user160", + }, + { + "name": "user161", + }, + { + "name": "user162", + }, + { + "name": "user163", + }, + { + "name": "user164", + }, + { + "name": "user165", + }, + { + "name": "user166", + }, + { + "name": "user167", + }, + { + "name": "user168", + }, + { + "name": "user169", + }, + { + "name": "user170", + }, + { + "name": "user171", + }, + { + "name": "user172", + }, + { + "name": "user173", + }, + { + "name": "user174", + }, + { + "name": "user175", + }, + { + "name": "user176", + }, + { + "name": "user177", + }, + { + "name": "user178", + }, + { + "name": "user179", + }, + { + "name": "user180", + }, + { + "name": "user181", + }, + { + "name": "user182", + }, + { + "name": "user183", + }, + { + "name": "user184", + }, + { + "name": "user185", + }, + { + "name": "user186", + }, + { + "name": "user187", + }, + { + "name": "user188", + }, + { + "name": "user189", + }, + { + "name": "user190", + }, + { + "name": "user191", + }, + { + "name": "user192", + }, + { + "name": "user193", + }, + { + "name": "user194", + }, + { + "name": "user195", + }, + { + "name": "user196", + }, + { + "name": "user197", + }, + { + "name": "user198", + }, + { + "name": "user199", + }, + { + "name": "user200", + }, + { + "name": "user201", + }, + { + "name": "user202", + }, + { + "name": "user203", + }, + { + "name": "user204", + }, + { + "name": "user205", + }, + { + "name": "user206", + }, + { + "name": "user207", + }, + { + "name": "user208", + }, + { + "name": "user209", + }, + { + "name": "user210", + }, + { + "name": "user211", + }, + { + "name": "user212", + }, + { + "name": "user213", + }, + { + "name": "user214", + }, + { + "name": "user215", + }, + { + "name": "user216", + }, + { + "name": "user217", + }, + { + "name": "user218", + }, + { + "name": "user219", + }, + { + "name": "user220", + }, + { + "name": "user221", + }, + { + "name": "user222", + }, + { + "name": "user223", + }, + { + "name": "user224", + }, + { + "name": "user225", + }, + { + "name": "user226", + }, + { + "name": "user227", + }, + { + "name": "user228", + }, + { + "name": "user229", + }, + { + "name": "user230", + }, + { + "name": "user231", + }, + { + "name": "user232", + }, + { + "name": "user233", + }, + { + "name": "user234", + }, + { + "name": "user235", + }, + { + "name": "user236", + }, + { + "name": "user237", + }, + { + "name": "user238", + }, + { + "name": "user239", + }, + { + "name": "user240", + }, + { + "name": "user241", + }, + { + "name": "user242", + }, + { + "name": "user243", + }, + { + "name": "user244", + }, + { + "name": "user245", + }, + { + "name": "user246", + }, + { + "name": "user247", + }, + { + "name": "user248", + }, + { + "name": "user249", + }, + { + "name": "user250", + }, + { + "name": "user251", + }, + { + "name": "user252", + }, + { + "name": "user253", + }, + { + "name": "user254", + }, + { + "name": "user255", + }, + { + "name": "user256", + }, + { + "name": "user257", + }, + { + "name": "user258", + }, + { + "name": "user259", + }, + { + "name": "user260", + }, + { + "name": "user261", + }, + { + "name": "user262", + }, + { + "name": "user263", + }, + { + "name": "user264", + }, + { + "name": "user265", + }, + { + "name": "user266", + }, + { + "name": "user267", + }, + { + "name": "user268", + }, + { + "name": "user269", + }, + { + "name": "user270", + }, + { + "name": "user271", + }, + { + "name": "user272", + }, + { + "name": "user273", + }, + { + "name": "user274", + }, + { + "name": "user275", + }, + { + "name": "user276", + }, + { + "name": "user277", + }, + { + "name": "user278", + }, + { + "name": "user279", + }, + { + "name": "user280", + }, + { + "name": "user281", + }, + { + "name": "user282", + }, + { + "name": "user283", + }, + { + "name": "user284", + }, + { + "name": "user285", + }, + { + "name": "user286", + }, + { + "name": "user287", + }, + { + "name": "user288", + }, + { + "name": "user289", + }, + { + "name": "user290", + }, + { + "name": "user291", + }, + { + "name": "user292", + }, + { + "name": "user293", + }, + { + "name": "user294", + }, + { + "name": "user295", + }, + { + "name": "user296", + }, + { + "name": "user297", + }, + { + "name": "user298", + }, + { + "name": "user299", + }, + { + "name": "user300", + }, + { + "name": "user301", + }, + { + "name": "user302", + }, + { + "name": "user303", + }, + { + "name": "user304", + }, + { + "name": "user305", + }, + { + "name": "user306", + }, + { + "name": "user307", + }, + { + "name": "user308", + }, + { + "name": "user309", + }, + { + "name": "user310", + }, + { + "name": "user311", + }, + { + "name": "user312", + }, + { + "name": "user313", + }, + { + "name": "user314", + }, + { + "name": "user315", + }, + { + "name": "user316", + }, + { + "name": "user317", + }, + { + "name": "user318", + }, + { + "name": "user319", + }, + { + "name": "user320", + }, + { + "name": "user321", + }, + { + "name": "user322", + }, + { + "name": "user323", + }, + { + "name": "user324", + }, + { + "name": "user325", + }, + { + "name": "user326", + }, + { + "name": "user327", + }, + { + "name": "user328", + }, + { + "name": "user329", + }, + { + "name": "user330", + }, + { + "name": "user331", + }, + { + "name": "user332", + }, + { + "name": "user333", + }, + { + "name": "user334", + }, + { + "name": "user335", + }, + { + "name": "user336", + }, + { + "name": "user337", + }, + { + "name": "user338", + }, + { + "name": "user339", + }, + { + "name": "user340", + }, + { + "name": "user341", + }, + { + "name": "user342", + }, + { + "name": "user343", + }, + { + "name": "user344", + }, + { + "name": "user345", + }, + { + "name": "user346", + }, + { + "name": "user347", + }, + { + "name": "user348", + }, + { + "name": "user349", + }, + { + "name": "user350", + }, + { + "name": "user351", + }, + { + "name": "user352", + }, + { + "name": "user353", + }, + { + "name": "user354", + }, + { + "name": "user355", + }, + { + "name": "user356", + }, + { + "name": "user357", + }, + { + "name": "user358", + }, + { + "name": "user359", + }, + { + "name": "user360", + }, + { + "name": "user361", + }, + { + "name": "user362", + }, + { + "name": "user363", + }, + { + "name": "user364", + }, + { + "name": "user365", + }, + { + "name": "user366", + }, + { + "name": "user367", + }, + { + "name": "user368", + }, + { + "name": "user369", + }, + { + "name": "user370", + }, + { + "name": "user371", + }, + { + "name": "user372", + }, + { + "name": "user373", + }, + { + "name": "user374", + }, + { + "name": "user375", + }, + { + "name": "user376", + }, + { + "name": "user377", + }, + { + "name": "user378", + }, + { + "name": "user379", + }, + { + "name": "user380", + }, + { + "name": "user381", + }, + { + "name": "user382", + }, + { + "name": "user383", + }, + { + "name": "user384", + }, + { + "name": "user385", + }, + { + "name": "user386", + }, + { + "name": "user387", + }, + { + "name": "user388", + }, + { + "name": "user389", + }, + { + "name": "user390", + }, + { + "name": "user391", + }, + { + "name": "user392", + }, + { + "name": "user393", + }, + { + "name": "user394", + }, + { + "name": "user395", + }, + { + "name": "user396", + }, + { + "name": "user397", + }, + { + "name": "user398", + }, + { + "name": "user399", + }, + { + "name": "user400", + }, + { + "name": "user401", + }, + { + "name": "user402", + }, + { + "name": "user403", + }, + { + "name": "user404", + }, + { + "name": "user405", + }, + { + "name": "user406", + }, + { + "name": "user407", + }, + { + "name": "user408", + }, + { + "name": "user409", + }, + { + "name": "user410", + }, + { + "name": "user411", + }, + { + "name": "user412", + }, + { + "name": "user413", + }, + { + "name": "user414", + }, + { + "name": "user415", + }, + { + "name": "user416", + }, + { + "name": "user417", + }, + { + "name": "user418", + }, + { + "name": "user419", + }, + { + "name": "user420", + }, + { + "name": "user421", + }, + { + "name": "user422", + }, + { + "name": "user423", + }, + { + "name": "user424", + }, + { + "name": "user425", + }, + { + "name": "user426", + }, + { + "name": "user427", + }, + { + "name": "user428", + }, + { + "name": "user429", + }, + { + "name": "user430", + }, + { + "name": "user431", + }, + { + "name": "user432", + }, + { + "name": "user433", + }, + { + "name": "user434", + }, + { + "name": "user435", + }, + { + "name": "user436", + }, + { + "name": "user437", + }, + { + "name": "user438", + }, + { + "name": "user439", + }, + { + "name": "user440", + }, + { + "name": "user441", + }, + { + "name": "user442", + }, + { + "name": "user443", + }, + { + "name": "user444", + }, + { + "name": "user445", + }, + { + "name": "user446", + }, + { + "name": "user447", + }, + { + "name": "user448", + }, + { + "name": "user449", + }, + { + "name": "user450", + }, + { + "name": "user451", + }, + { + "name": "user452", + }, + { + "name": "user453", + }, + { + "name": "user454", + }, + { + "name": "user455", + }, + { + "name": "user456", + }, + { + "name": "user457", + }, + { + "name": "user458", + }, + { + "name": "user459", + }, + { + "name": "user460", + }, + { + "name": "user461", + }, + { + "name": "user462", + }, + { + "name": "user463", + }, + { + "name": "user464", + }, + { + "name": "user465", + }, + { + "name": "user466", + }, + { + "name": "user467", + }, + { + "name": "user468", + }, + { + "name": "user469", + }, + { + "name": "user470", + }, + { + "name": "user471", + }, + { + "name": "user472", + }, + { + "name": "user473", + }, + { + "name": "user474", + }, + { + "name": "user475", + }, + { + "name": "user476", + }, + { + "name": "user477", + }, + { + "name": "user478", + }, + { + "name": "user479", + }, + { + "name": "user480", + }, + { + "name": "user481", + }, + { + "name": "user482", + }, + { + "name": "user483", + }, + { + "name": "user484", + }, + { + "name": "user485", + }, + { + "name": "user486", + }, + { + "name": "user487", + }, + { + "name": "user488", + }, + { + "name": "user489", + }, + { + "name": "user490", + }, + { + "name": "user491", + }, + { + "name": "user492", + }, + { + "name": "user493", + }, + { + "name": "user494", + }, + { + "name": "user495", + }, + { + "name": "user496", + }, + { + "name": "user497", + }, + { + "name": "user498", + }, + { + "name": "user499", + }, + { + "name": "user500", + }, + { + "name": "user501", + }, + { + "name": "user502", + }, + { + "name": "user503", + }, + { + "name": "user504", + }, + { + "name": "user505", + }, + { + "name": "user506", + }, + { + "name": "user507", + }, + { + "name": "user508", + }, + { + "name": "user509", + }, + { + "name": "user510", + }, + { + "name": "user511", + }, + { + "name": "user512", + }, + { + "name": "user513", + }, + { + "name": "user514", + }, + { + "name": "user515", + }, + { + "name": "user516", + }, + { + "name": "user517", + }, + { + "name": "user518", + }, + { + "name": "user519", + }, + { + "name": "user520", + }, + { + "name": "user521", + }, + { + "name": "user522", + }, + { + "name": "user523", + }, + { + "name": "user524", + }, + { + "name": "user525", + }, + { + "name": "user526", + }, + { + "name": "user527", + }, + { + "name": "user528", + }, + { + "name": "user529", + }, + { + "name": "user530", + }, + { + "name": "user531", + }, + { + "name": "user532", + }, + { + "name": "user533", + }, + { + "name": "user534", + }, + { + "name": "user535", + }, + { + "name": "user536", + }, + { + "name": "user537", + }, + { + "name": "user538", + }, + { + "name": "user539", + }, + { + "name": "user540", + }, + { + "name": "user541", + }, + { + "name": "user542", + }, + { + "name": "user543", + }, + { + "name": "user544", + }, + { + "name": "user545", + }, + { + "name": "user546", + }, + { + "name": "user547", + }, + { + "name": "user548", + }, + { + "name": "user549", + }, + { + "name": "user550", + }, + { + "name": "user551", + }, + { + "name": "user552", + }, + { + "name": "user553", + }, + { + "name": "user554", + }, + { + "name": "user555", + }, + { + "name": "user556", + }, + { + "name": "user557", + }, + { + "name": "user558", + }, + { + "name": "user559", + }, + { + "name": "user560", + }, + { + "name": "user561", + }, + { + "name": "user562", + }, + { + "name": "user563", + }, + { + "name": "user564", + }, + { + "name": "user565", + }, + { + "name": "user566", + }, + { + "name": "user567", + }, + { + "name": "user568", + }, + { + "name": "user569", + }, + { + "name": "user570", + }, + { + "name": "user571", + }, + { + "name": "user572", + }, + { + "name": "user573", + }, + { + "name": "user574", + }, + { + "name": "user575", + }, + { + "name": "user576", + }, + { + "name": "user577", + }, + { + "name": "user578", + }, + { + "name": "user579", + }, + { + "name": "user580", + }, + { + "name": "user581", + }, + { + "name": "user582", + }, + { + "name": "user583", + }, + { + "name": "user584", + }, + { + "name": "user585", + }, + { + "name": "user586", + }, + { + "name": "user587", + }, + { + "name": "user588", + }, + { + "name": "user589", + }, + { + "name": "user590", + }, + { + "name": "user591", + }, + { + "name": "user592", + }, + { + "name": "user593", + }, + { + "name": "user594", + }, + { + "name": "user595", + }, + { + "name": "user596", + }, + { + "name": "user597", + }, + { + "name": "user598", + }, + { + "name": "user599", + }, + { + "name": "user600", + }, + { + "name": "user601", + }, + { + "name": "user602", + }, + { + "name": "user603", + }, + { + "name": "user604", + }, + { + "name": "user605", + }, + { + "name": "user606", + }, + { + "name": "user607", + }, + { + "name": "user608", + }, + { + "name": "user609", + }, + { + "name": "user610", + }, + { + "name": "user611", + }, + { + "name": "user612", + }, + { + "name": "user613", + }, + { + "name": "user614", + }, + { + "name": "user615", + }, + { + "name": "user616", + }, + { + "name": "user617", + }, + { + "name": "user618", + }, + { + "name": "user619", + }, + { + "name": "user620", + }, + { + "name": "user621", + }, + { + "name": "user622", + }, + { + "name": "user623", + }, + { + "name": "user624", + }, + { + "name": "user625", + }, + { + "name": "user626", + }, + { + "name": "user627", + }, + { + "name": "user628", + }, + { + "name": "user629", + }, + { + "name": "user630", + }, + { + "name": "user631", + }, + { + "name": "user632", + }, + { + "name": "user633", + }, + { + "name": "user634", + }, + { + "name": "user635", + }, + { + "name": "user636", + }, + { + "name": "user637", + }, + { + "name": "user638", + }, + { + "name": "user639", + }, + { + "name": "user640", + }, + { + "name": "user641", + }, + { + "name": "user642", + }, + { + "name": "user643", + }, + { + "name": "user644", + }, + { + "name": "user645", + }, + { + "name": "user646", + }, + { + "name": "user647", + }, + { + "name": "user648", + }, + { + "name": "user649", + }, + { + "name": "user650", + }, + { + "name": "user651", + }, + { + "name": "user652", + }, + { + "name": "user653", + }, + { + "name": "user654", + }, + { + "name": "user655", + }, + { + "name": "user656", + }, + { + "name": "user657", + }, + { + "name": "user658", + }, + { + "name": "user659", + }, + { + "name": "user660", + }, + { + "name": "user661", + }, + { + "name": "user662", + }, + { + "name": "user663", + }, + { + "name": "user664", + }, + { + "name": "user665", + }, + { + "name": "user666", + }, + { + "name": "user667", + }, + { + "name": "user668", + }, + { + "name": "user669", + }, + { + "name": "user670", + }, + { + "name": "user671", + }, + { + "name": "user672", + }, + { + "name": "user673", + }, + { + "name": "user674", + }, + { + "name": "user675", + }, + { + "name": "user676", + }, + { + "name": "user677", + }, + { + "name": "user678", + }, + { + "name": "user679", + }, + { + "name": "user680", + }, + { + "name": "user681", + }, + { + "name": "user682", + }, + { + "name": "user683", + }, + { + "name": "user684", + }, + { + "name": "user685", + }, + { + "name": "user686", + }, + { + "name": "user687", + }, + { + "name": "user688", + }, + { + "name": "user689", + }, + { + "name": "user690", + }, + { + "name": "user691", + }, + { + "name": "user692", + }, + { + "name": "user693", + }, + { + "name": "user694", + }, + { + "name": "user695", + }, + { + "name": "user696", + }, + { + "name": "user697", + }, + { + "name": "user698", + }, + { + "name": "user699", + }, + { + "name": "user700", + }, + { + "name": "user701", + }, + { + "name": "user702", + }, + { + "name": "user703", + }, + { + "name": "user704", + }, + { + "name": "user705", + }, + { + "name": "user706", + }, + { + "name": "user707", + }, + { + "name": "user708", + }, + { + "name": "user709", + }, + { + "name": "user710", + }, + { + "name": "user711", + }, + { + "name": "user712", + }, + { + "name": "user713", + }, + { + "name": "user714", + }, + { + "name": "user715", + }, + { + "name": "user716", + }, + { + "name": "user717", + }, + { + "name": "user718", + }, + { + "name": "user719", + }, + { + "name": "user720", + }, + { + "name": "user721", + }, + { + "name": "user722", + }, + { + "name": "user723", + }, + { + "name": "user724", + }, + { + "name": "user725", + }, + { + "name": "user726", + }, + { + "name": "user727", + }, + { + "name": "user728", + }, + { + "name": "user729", + }, + { + "name": "user730", + }, + { + "name": "user731", + }, + { + "name": "user732", + }, + { + "name": "user733", + }, + { + "name": "user734", + }, + { + "name": "user735", + }, + { + "name": "user736", + }, + { + "name": "user737", + }, + { + "name": "user738", + }, + { + "name": "user739", + }, + { + "name": "user740", + }, + { + "name": "user741", + }, + { + "name": "user742", + }, + { + "name": "user743", + }, + { + "name": "user744", + }, + { + "name": "user745", + }, + { + "name": "user746", + }, + { + "name": "user747", + }, + { + "name": "user748", + }, + { + "name": "user749", + }, + { + "name": "user750", + }, + { + "name": "user751", + }, + { + "name": "user752", + }, + { + "name": "user753", + }, + { + "name": "user754", + }, + { + "name": "user755", + }, + { + "name": "user756", + }, + { + "name": "user757", + }, + { + "name": "user758", + }, + { + "name": "user759", + }, + { + "name": "user760", + }, + { + "name": "user761", + }, + { + "name": "user762", + }, + { + "name": "user763", + }, + { + "name": "user764", + }, + { + "name": "user765", + }, + { + "name": "user766", + }, + { + "name": "user767", + }, + { + "name": "user768", + }, + { + "name": "user769", + }, + { + "name": "user770", + }, + { + "name": "user771", + }, + { + "name": "user772", + }, + { + "name": "user773", + }, + { + "name": "user774", + }, + { + "name": "user775", + }, + { + "name": "user776", + }, + { + "name": "user777", + }, + { + "name": "user778", + }, + { + "name": "user779", + }, + { + "name": "user780", + }, + { + "name": "user781", + }, + { + "name": "user782", + }, + { + "name": "user783", + }, + { + "name": "user784", + }, + { + "name": "user785", + }, + { + "name": "user786", + }, + { + "name": "user787", + }, + { + "name": "user788", + }, + { + "name": "user789", + }, + { + "name": "user790", + }, + { + "name": "user791", + }, + { + "name": "user792", + }, + { + "name": "user793", + }, + { + "name": "user794", + }, + { + "name": "user795", + }, + { + "name": "user796", + }, + { + "name": "user797", + }, + { + "name": "user798", + }, + { + "name": "user799", + }, + { + "name": "user800", + }, + { + "name": "user801", + }, + { + "name": "user802", + }, + { + "name": "user803", + }, + { + "name": "user804", + }, + { + "name": "user805", + }, + { + "name": "user806", + }, + { + "name": "user807", + }, + { + "name": "user808", + }, + { + "name": "user809", + }, + { + "name": "user810", + }, + { + "name": "user811", + }, + { + "name": "user812", + }, + { + "name": "user813", + }, + { + "name": "user814", + }, + { + "name": "user815", + }, + { + "name": "user816", + }, + { + "name": "user817", + }, + { + "name": "user818", + }, + { + "name": "user819", + }, + { + "name": "user820", + }, + { + "name": "user821", + }, + { + "name": "user822", + }, + { + "name": "user823", + }, + { + "name": "user824", + }, + { + "name": "user825", + }, + { + "name": "user826", + }, + { + "name": "user827", + }, + { + "name": "user828", + }, + { + "name": "user829", + }, + { + "name": "user830", + }, + { + "name": "user831", + }, + { + "name": "user832", + }, + { + "name": "user833", + }, + { + "name": "user834", + }, + { + "name": "user835", + }, + { + "name": "user836", + }, + { + "name": "user837", + }, + { + "name": "user838", + }, + { + "name": "user839", + }, + { + "name": "user840", + }, + { + "name": "user841", + }, + { + "name": "user842", + }, + { + "name": "user843", + }, + { + "name": "user844", + }, + { + "name": "user845", + }, + { + "name": "user846", + }, + { + "name": "user847", + }, + { + "name": "user848", + }, + { + "name": "user849", + }, + { + "name": "user850", + }, + { + "name": "user851", + }, + { + "name": "user852", + }, + { + "name": "user853", + }, + { + "name": "user854", + }, + { + "name": "user855", + }, + { + "name": "user856", + }, + { + "name": "user857", + }, + { + "name": "user858", + }, + { + "name": "user859", + }, + { + "name": "user860", + }, + { + "name": "user861", + }, + { + "name": "user862", + }, + { + "name": "user863", + }, + { + "name": "user864", + }, + { + "name": "user865", + }, + { + "name": "user866", + }, + { + "name": "user867", + }, + { + "name": "user868", + }, + { + "name": "user869", + }, + { + "name": "user870", + }, + { + "name": "user871", + }, + { + "name": "user872", + }, + { + "name": "user873", + }, + { + "name": "user874", + }, + { + "name": "user875", + }, + { + "name": "user876", + }, + { + "name": "user877", + }, + { + "name": "user878", + }, + { + "name": "user879", + }, + { + "name": "user880", + }, + { + "name": "user881", + }, + { + "name": "user882", + }, + { + "name": "user883", + }, + { + "name": "user884", + }, + { + "name": "user885", + }, + { + "name": "user886", + }, + { + "name": "user887", + }, + { + "name": "user888", + }, + { + "name": "user889", + }, + { + "name": "user890", + }, + { + "name": "user891", + }, + { + "name": "user892", + }, + { + "name": "user893", + }, + { + "name": "user894", + }, + { + "name": "user895", + }, + { + "name": "user896", + }, + { + "name": "user897", + }, + { + "name": "user898", + }, + { + "name": "user899", + }, + { + "name": "user900", + }, + { + "name": "user901", + }, + { + "name": "user902", + }, + { + "name": "user903", + }, + { + "name": "user904", + }, + { + "name": "user905", + }, + { + "name": "user906", + }, + { + "name": "user907", + }, + { + "name": "user908", + }, + { + "name": "user909", + }, + { + "name": "user910", + }, + { + "name": "user911", + }, + { + "name": "user912", + }, + { + "name": "user913", + }, + { + "name": "user914", + }, + { + "name": "user915", + }, + { + "name": "user916", + }, + { + "name": "user917", + }, + { + "name": "user918", + }, + { + "name": "user919", + }, + { + "name": "user920", + }, + { + "name": "user921", + }, + { + "name": "user922", + }, + { + "name": "user923", + }, + { + "name": "user924", + }, + { + "name": "user925", + }, + { + "name": "user926", + }, + { + "name": "user927", + }, + { + "name": "user928", + }, + { + "name": "user929", + }, + { + "name": "user930", + }, + { + "name": "user931", + }, + { + "name": "user932", + }, + { + "name": "user933", + }, + { + "name": "user934", + }, + { + "name": "user935", + }, + { + "name": "user936", + }, + { + "name": "user937", + }, + { + "name": "user938", + }, + { + "name": "user939", + }, + { + "name": "user940", + }, + { + "name": "user941", + }, + { + "name": "user942", + }, + { + "name": "user943", + }, + { + "name": "user944", + }, + { + "name": "user945", + }, + { + "name": "user946", + }, + { + "name": "user947", + }, + { + "name": "user948", + }, + { + "name": "user949", + }, + { + "name": "user950", + }, + { + "name": "user951", + }, + { + "name": "user952", + }, + { + "name": "user953", + }, + { + "name": "user954", + }, + { + "name": "user955", + }, + { + "name": "user956", + }, + { + "name": "user957", + }, + { + "name": "user958", + }, + { + "name": "user959", + }, + { + "name": "user960", + }, + { + "name": "user961", + }, + { + "name": "user962", + }, + { + "name": "user963", + }, + { + "name": "user964", + }, + { + "name": "user965", + }, + { + "name": "user966", + }, + { + "name": "user967", + }, + { + "name": "user968", + }, + { + "name": "user969", + }, + { + "name": "user970", + }, + { + "name": "user971", + }, + { + "name": "user972", + }, + { + "name": "user973", + }, + { + "name": "user974", + }, + { + "name": "user975", + }, + { + "name": "user976", + }, + { + "name": "user977", + }, + { + "name": "user978", + }, + { + "name": "user979", + }, + { + "name": "user980", + }, + { + "name": "user981", + }, + { + "name": "user982", + }, + { + "name": "user983", + }, + { + "name": "user984", + }, + { + "name": "user985", + }, + { + "name": "user986", + }, + { + "name": "user987", + }, + { + "name": "user988", + }, + { + "name": "user989", + }, + { + "name": "user990", + }, + { + "name": "user991", + }, + { + "name": "user992", + }, + { + "name": "user993", + }, + { + "name": "user994", + }, + { + "name": "user995", + }, + { + "name": "user996", + }, + { + "name": "user997", + }, + { + "name": "user998", + }, + { + "name": "user999", + }, + { + "name": "user1000", + } + ] +} diff --git a/tests/user/users_absent.sh b/tests/user/users_absent.sh new file mode 100644 index 00000000..1ee89ada --- /dev/null +++ b/tests/user/users_absent.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +NUM=1000 +FILE="users_absent.json" + +echo "{" > $FILE + +echo " \"users\": [" >> $FILE + +for i in $(seq 1 $NUM); do + echo " {" >> $FILE + echo " \"name\": \"user$i\"," >> $FILE + if [ $i -lt $NUM ]; then + echo " }," >> $FILE + else + echo " }" >> $FILE + fi +done + +echo " ]" >> $FILE + +echo "}" >> $FILE diff --git a/tests/user/users_present.json b/tests/user/users_present.json new file mode 100644 index 00000000..514edc88 --- /dev/null +++ b/tests/user/users_present.json @@ -0,0 +1,5004 @@ +{ + "users": [ + { + "name": "user1", + "first": "First 1", + "last": "Last 1" + }, + { + "name": "user2", + "first": "First 2", + "last": "Last 2" + }, + { + "name": "user3", + "first": "First 3", + "last": "Last 3" + }, + { + "name": "user4", + "first": "First 4", + "last": "Last 4" + }, + { + "name": "user5", + "first": "First 5", + "last": "Last 5" + }, + { + "name": "user6", + "first": "First 6", + "last": "Last 6" + }, + { + "name": "user7", + "first": "First 7", + "last": "Last 7" + }, + { + "name": "user8", + "first": "First 8", + "last": "Last 8" + }, + { + "name": "user9", + "first": "First 9", + "last": "Last 9" + }, + { + "name": "user10", + "first": "First 10", + "last": "Last 10" + }, + { + "name": "user11", + "first": "First 11", + "last": "Last 11" + }, + { + "name": "user12", + "first": "First 12", + "last": "Last 12" + }, + { + "name": "user13", + "first": "First 13", + "last": "Last 13" + }, + { + "name": "user14", + "first": "First 14", + "last": "Last 14" + }, + { + "name": "user15", + "first": "First 15", + "last": "Last 15" + }, + { + "name": "user16", + "first": "First 16", + "last": "Last 16" + }, + { + "name": "user17", + "first": "First 17", + "last": "Last 17" + }, + { + "name": "user18", + "first": "First 18", + "last": "Last 18" + }, + { + "name": "user19", + "first": "First 19", + "last": "Last 19" + }, + { + "name": "user20", + "first": "First 20", + "last": "Last 20" + }, + { + "name": "user21", + "first": "First 21", + "last": "Last 21" + }, + { + "name": "user22", + "first": "First 22", + "last": "Last 22" + }, + { + "name": "user23", + "first": "First 23", + "last": "Last 23" + }, + { + "name": "user24", + "first": "First 24", + "last": "Last 24" + }, + { + "name": "user25", + "first": "First 25", + "last": "Last 25" + }, + { + "name": "user26", + "first": "First 26", + "last": "Last 26" + }, + { + "name": "user27", + "first": "First 27", + "last": "Last 27" + }, + { + "name": "user28", + "first": "First 28", + "last": "Last 28" + }, + { + "name": "user29", + "first": "First 29", + "last": "Last 29" + }, + { + "name": "user30", + "first": "First 30", + "last": "Last 30" + }, + { + "name": "user31", + "first": "First 31", + "last": "Last 31" + }, + { + "name": "user32", + "first": "First 32", + "last": "Last 32" + }, + { + "name": "user33", + "first": "First 33", + "last": "Last 33" + }, + { + "name": "user34", + "first": "First 34", + "last": "Last 34" + }, + { + "name": "user35", + "first": "First 35", + "last": "Last 35" + }, + { + "name": "user36", + "first": "First 36", + "last": "Last 36" + }, + { + "name": "user37", + "first": "First 37", + "last": "Last 37" + }, + { + "name": "user38", + "first": "First 38", + "last": "Last 38" + }, + { + "name": "user39", + "first": "First 39", + "last": "Last 39" + }, + { + "name": "user40", + "first": "First 40", + "last": "Last 40" + }, + { + "name": "user41", + "first": "First 41", + "last": "Last 41" + }, + { + "name": "user42", + "first": "First 42", + "last": "Last 42" + }, + { + "name": "user43", + "first": "First 43", + "last": "Last 43" + }, + { + "name": "user44", + "first": "First 44", + "last": "Last 44" + }, + { + "name": "user45", + "first": "First 45", + "last": "Last 45" + }, + { + "name": "user46", + "first": "First 46", + "last": "Last 46" + }, + { + "name": "user47", + "first": "First 47", + "last": "Last 47" + }, + { + "name": "user48", + "first": "First 48", + "last": "Last 48" + }, + { + "name": "user49", + "first": "First 49", + "last": "Last 49" + }, + { + "name": "user50", + "first": "First 50", + "last": "Last 50" + }, + { + "name": "user51", + "first": "First 51", + "last": "Last 51" + }, + { + "name": "user52", + "first": "First 52", + "last": "Last 52" + }, + { + "name": "user53", + "first": "First 53", + "last": "Last 53" + }, + { + "name": "user54", + "first": "First 54", + "last": "Last 54" + }, + { + "name": "user55", + "first": "First 55", + "last": "Last 55" + }, + { + "name": "user56", + "first": "First 56", + "last": "Last 56" + }, + { + "name": "user57", + "first": "First 57", + "last": "Last 57" + }, + { + "name": "user58", + "first": "First 58", + "last": "Last 58" + }, + { + "name": "user59", + "first": "First 59", + "last": "Last 59" + }, + { + "name": "user60", + "first": "First 60", + "last": "Last 60" + }, + { + "name": "user61", + "first": "First 61", + "last": "Last 61" + }, + { + "name": "user62", + "first": "First 62", + "last": "Last 62" + }, + { + "name": "user63", + "first": "First 63", + "last": "Last 63" + }, + { + "name": "user64", + "first": "First 64", + "last": "Last 64" + }, + { + "name": "user65", + "first": "First 65", + "last": "Last 65" + }, + { + "name": "user66", + "first": "First 66", + "last": "Last 66" + }, + { + "name": "user67", + "first": "First 67", + "last": "Last 67" + }, + { + "name": "user68", + "first": "First 68", + "last": "Last 68" + }, + { + "name": "user69", + "first": "First 69", + "last": "Last 69" + }, + { + "name": "user70", + "first": "First 70", + "last": "Last 70" + }, + { + "name": "user71", + "first": "First 71", + "last": "Last 71" + }, + { + "name": "user72", + "first": "First 72", + "last": "Last 72" + }, + { + "name": "user73", + "first": "First 73", + "last": "Last 73" + }, + { + "name": "user74", + "first": "First 74", + "last": "Last 74" + }, + { + "name": "user75", + "first": "First 75", + "last": "Last 75" + }, + { + "name": "user76", + "first": "First 76", + "last": "Last 76" + }, + { + "name": "user77", + "first": "First 77", + "last": "Last 77" + }, + { + "name": "user78", + "first": "First 78", + "last": "Last 78" + }, + { + "name": "user79", + "first": "First 79", + "last": "Last 79" + }, + { + "name": "user80", + "first": "First 80", + "last": "Last 80" + }, + { + "name": "user81", + "first": "First 81", + "last": "Last 81" + }, + { + "name": "user82", + "first": "First 82", + "last": "Last 82" + }, + { + "name": "user83", + "first": "First 83", + "last": "Last 83" + }, + { + "name": "user84", + "first": "First 84", + "last": "Last 84" + }, + { + "name": "user85", + "first": "First 85", + "last": "Last 85" + }, + { + "name": "user86", + "first": "First 86", + "last": "Last 86" + }, + { + "name": "user87", + "first": "First 87", + "last": "Last 87" + }, + { + "name": "user88", + "first": "First 88", + "last": "Last 88" + }, + { + "name": "user89", + "first": "First 89", + "last": "Last 89" + }, + { + "name": "user90", + "first": "First 90", + "last": "Last 90" + }, + { + "name": "user91", + "first": "First 91", + "last": "Last 91" + }, + { + "name": "user92", + "first": "First 92", + "last": "Last 92" + }, + { + "name": "user93", + "first": "First 93", + "last": "Last 93" + }, + { + "name": "user94", + "first": "First 94", + "last": "Last 94" + }, + { + "name": "user95", + "first": "First 95", + "last": "Last 95" + }, + { + "name": "user96", + "first": "First 96", + "last": "Last 96" + }, + { + "name": "user97", + "first": "First 97", + "last": "Last 97" + }, + { + "name": "user98", + "first": "First 98", + "last": "Last 98" + }, + { + "name": "user99", + "first": "First 99", + "last": "Last 99" + }, + { + "name": "user100", + "first": "First 100", + "last": "Last 100" + }, + { + "name": "user101", + "first": "First 101", + "last": "Last 101" + }, + { + "name": "user102", + "first": "First 102", + "last": "Last 102" + }, + { + "name": "user103", + "first": "First 103", + "last": "Last 103" + }, + { + "name": "user104", + "first": "First 104", + "last": "Last 104" + }, + { + "name": "user105", + "first": "First 105", + "last": "Last 105" + }, + { + "name": "user106", + "first": "First 106", + "last": "Last 106" + }, + { + "name": "user107", + "first": "First 107", + "last": "Last 107" + }, + { + "name": "user108", + "first": "First 108", + "last": "Last 108" + }, + { + "name": "user109", + "first": "First 109", + "last": "Last 109" + }, + { + "name": "user110", + "first": "First 110", + "last": "Last 110" + }, + { + "name": "user111", + "first": "First 111", + "last": "Last 111" + }, + { + "name": "user112", + "first": "First 112", + "last": "Last 112" + }, + { + "name": "user113", + "first": "First 113", + "last": "Last 113" + }, + { + "name": "user114", + "first": "First 114", + "last": "Last 114" + }, + { + "name": "user115", + "first": "First 115", + "last": "Last 115" + }, + { + "name": "user116", + "first": "First 116", + "last": "Last 116" + }, + { + "name": "user117", + "first": "First 117", + "last": "Last 117" + }, + { + "name": "user118", + "first": "First 118", + "last": "Last 118" + }, + { + "name": "user119", + "first": "First 119", + "last": "Last 119" + }, + { + "name": "user120", + "first": "First 120", + "last": "Last 120" + }, + { + "name": "user121", + "first": "First 121", + "last": "Last 121" + }, + { + "name": "user122", + "first": "First 122", + "last": "Last 122" + }, + { + "name": "user123", + "first": "First 123", + "last": "Last 123" + }, + { + "name": "user124", + "first": "First 124", + "last": "Last 124" + }, + { + "name": "user125", + "first": "First 125", + "last": "Last 125" + }, + { + "name": "user126", + "first": "First 126", + "last": "Last 126" + }, + { + "name": "user127", + "first": "First 127", + "last": "Last 127" + }, + { + "name": "user128", + "first": "First 128", + "last": "Last 128" + }, + { + "name": "user129", + "first": "First 129", + "last": "Last 129" + }, + { + "name": "user130", + "first": "First 130", + "last": "Last 130" + }, + { + "name": "user131", + "first": "First 131", + "last": "Last 131" + }, + { + "name": "user132", + "first": "First 132", + "last": "Last 132" + }, + { + "name": "user133", + "first": "First 133", + "last": "Last 133" + }, + { + "name": "user134", + "first": "First 134", + "last": "Last 134" + }, + { + "name": "user135", + "first": "First 135", + "last": "Last 135" + }, + { + "name": "user136", + "first": "First 136", + "last": "Last 136" + }, + { + "name": "user137", + "first": "First 137", + "last": "Last 137" + }, + { + "name": "user138", + "first": "First 138", + "last": "Last 138" + }, + { + "name": "user139", + "first": "First 139", + "last": "Last 139" + }, + { + "name": "user140", + "first": "First 140", + "last": "Last 140" + }, + { + "name": "user141", + "first": "First 141", + "last": "Last 141" + }, + { + "name": "user142", + "first": "First 142", + "last": "Last 142" + }, + { + "name": "user143", + "first": "First 143", + "last": "Last 143" + }, + { + "name": "user144", + "first": "First 144", + "last": "Last 144" + }, + { + "name": "user145", + "first": "First 145", + "last": "Last 145" + }, + { + "name": "user146", + "first": "First 146", + "last": "Last 146" + }, + { + "name": "user147", + "first": "First 147", + "last": "Last 147" + }, + { + "name": "user148", + "first": "First 148", + "last": "Last 148" + }, + { + "name": "user149", + "first": "First 149", + "last": "Last 149" + }, + { + "name": "user150", + "first": "First 150", + "last": "Last 150" + }, + { + "name": "user151", + "first": "First 151", + "last": "Last 151" + }, + { + "name": "user152", + "first": "First 152", + "last": "Last 152" + }, + { + "name": "user153", + "first": "First 153", + "last": "Last 153" + }, + { + "name": "user154", + "first": "First 154", + "last": "Last 154" + }, + { + "name": "user155", + "first": "First 155", + "last": "Last 155" + }, + { + "name": "user156", + "first": "First 156", + "last": "Last 156" + }, + { + "name": "user157", + "first": "First 157", + "last": "Last 157" + }, + { + "name": "user158", + "first": "First 158", + "last": "Last 158" + }, + { + "name": "user159", + "first": "First 159", + "last": "Last 159" + }, + { + "name": "user160", + "first": "First 160", + "last": "Last 160" + }, + { + "name": "user161", + "first": "First 161", + "last": "Last 161" + }, + { + "name": "user162", + "first": "First 162", + "last": "Last 162" + }, + { + "name": "user163", + "first": "First 163", + "last": "Last 163" + }, + { + "name": "user164", + "first": "First 164", + "last": "Last 164" + }, + { + "name": "user165", + "first": "First 165", + "last": "Last 165" + }, + { + "name": "user166", + "first": "First 166", + "last": "Last 166" + }, + { + "name": "user167", + "first": "First 167", + "last": "Last 167" + }, + { + "name": "user168", + "first": "First 168", + "last": "Last 168" + }, + { + "name": "user169", + "first": "First 169", + "last": "Last 169" + }, + { + "name": "user170", + "first": "First 170", + "last": "Last 170" + }, + { + "name": "user171", + "first": "First 171", + "last": "Last 171" + }, + { + "name": "user172", + "first": "First 172", + "last": "Last 172" + }, + { + "name": "user173", + "first": "First 173", + "last": "Last 173" + }, + { + "name": "user174", + "first": "First 174", + "last": "Last 174" + }, + { + "name": "user175", + "first": "First 175", + "last": "Last 175" + }, + { + "name": "user176", + "first": "First 176", + "last": "Last 176" + }, + { + "name": "user177", + "first": "First 177", + "last": "Last 177" + }, + { + "name": "user178", + "first": "First 178", + "last": "Last 178" + }, + { + "name": "user179", + "first": "First 179", + "last": "Last 179" + }, + { + "name": "user180", + "first": "First 180", + "last": "Last 180" + }, + { + "name": "user181", + "first": "First 181", + "last": "Last 181" + }, + { + "name": "user182", + "first": "First 182", + "last": "Last 182" + }, + { + "name": "user183", + "first": "First 183", + "last": "Last 183" + }, + { + "name": "user184", + "first": "First 184", + "last": "Last 184" + }, + { + "name": "user185", + "first": "First 185", + "last": "Last 185" + }, + { + "name": "user186", + "first": "First 186", + "last": "Last 186" + }, + { + "name": "user187", + "first": "First 187", + "last": "Last 187" + }, + { + "name": "user188", + "first": "First 188", + "last": "Last 188" + }, + { + "name": "user189", + "first": "First 189", + "last": "Last 189" + }, + { + "name": "user190", + "first": "First 190", + "last": "Last 190" + }, + { + "name": "user191", + "first": "First 191", + "last": "Last 191" + }, + { + "name": "user192", + "first": "First 192", + "last": "Last 192" + }, + { + "name": "user193", + "first": "First 193", + "last": "Last 193" + }, + { + "name": "user194", + "first": "First 194", + "last": "Last 194" + }, + { + "name": "user195", + "first": "First 195", + "last": "Last 195" + }, + { + "name": "user196", + "first": "First 196", + "last": "Last 196" + }, + { + "name": "user197", + "first": "First 197", + "last": "Last 197" + }, + { + "name": "user198", + "first": "First 198", + "last": "Last 198" + }, + { + "name": "user199", + "first": "First 199", + "last": "Last 199" + }, + { + "name": "user200", + "first": "First 200", + "last": "Last 200" + }, + { + "name": "user201", + "first": "First 201", + "last": "Last 201" + }, + { + "name": "user202", + "first": "First 202", + "last": "Last 202" + }, + { + "name": "user203", + "first": "First 203", + "last": "Last 203" + }, + { + "name": "user204", + "first": "First 204", + "last": "Last 204" + }, + { + "name": "user205", + "first": "First 205", + "last": "Last 205" + }, + { + "name": "user206", + "first": "First 206", + "last": "Last 206" + }, + { + "name": "user207", + "first": "First 207", + "last": "Last 207" + }, + { + "name": "user208", + "first": "First 208", + "last": "Last 208" + }, + { + "name": "user209", + "first": "First 209", + "last": "Last 209" + }, + { + "name": "user210", + "first": "First 210", + "last": "Last 210" + }, + { + "name": "user211", + "first": "First 211", + "last": "Last 211" + }, + { + "name": "user212", + "first": "First 212", + "last": "Last 212" + }, + { + "name": "user213", + "first": "First 213", + "last": "Last 213" + }, + { + "name": "user214", + "first": "First 214", + "last": "Last 214" + }, + { + "name": "user215", + "first": "First 215", + "last": "Last 215" + }, + { + "name": "user216", + "first": "First 216", + "last": "Last 216" + }, + { + "name": "user217", + "first": "First 217", + "last": "Last 217" + }, + { + "name": "user218", + "first": "First 218", + "last": "Last 218" + }, + { + "name": "user219", + "first": "First 219", + "last": "Last 219" + }, + { + "name": "user220", + "first": "First 220", + "last": "Last 220" + }, + { + "name": "user221", + "first": "First 221", + "last": "Last 221" + }, + { + "name": "user222", + "first": "First 222", + "last": "Last 222" + }, + { + "name": "user223", + "first": "First 223", + "last": "Last 223" + }, + { + "name": "user224", + "first": "First 224", + "last": "Last 224" + }, + { + "name": "user225", + "first": "First 225", + "last": "Last 225" + }, + { + "name": "user226", + "first": "First 226", + "last": "Last 226" + }, + { + "name": "user227", + "first": "First 227", + "last": "Last 227" + }, + { + "name": "user228", + "first": "First 228", + "last": "Last 228" + }, + { + "name": "user229", + "first": "First 229", + "last": "Last 229" + }, + { + "name": "user230", + "first": "First 230", + "last": "Last 230" + }, + { + "name": "user231", + "first": "First 231", + "last": "Last 231" + }, + { + "name": "user232", + "first": "First 232", + "last": "Last 232" + }, + { + "name": "user233", + "first": "First 233", + "last": "Last 233" + }, + { + "name": "user234", + "first": "First 234", + "last": "Last 234" + }, + { + "name": "user235", + "first": "First 235", + "last": "Last 235" + }, + { + "name": "user236", + "first": "First 236", + "last": "Last 236" + }, + { + "name": "user237", + "first": "First 237", + "last": "Last 237" + }, + { + "name": "user238", + "first": "First 238", + "last": "Last 238" + }, + { + "name": "user239", + "first": "First 239", + "last": "Last 239" + }, + { + "name": "user240", + "first": "First 240", + "last": "Last 240" + }, + { + "name": "user241", + "first": "First 241", + "last": "Last 241" + }, + { + "name": "user242", + "first": "First 242", + "last": "Last 242" + }, + { + "name": "user243", + "first": "First 243", + "last": "Last 243" + }, + { + "name": "user244", + "first": "First 244", + "last": "Last 244" + }, + { + "name": "user245", + "first": "First 245", + "last": "Last 245" + }, + { + "name": "user246", + "first": "First 246", + "last": "Last 246" + }, + { + "name": "user247", + "first": "First 247", + "last": "Last 247" + }, + { + "name": "user248", + "first": "First 248", + "last": "Last 248" + }, + { + "name": "user249", + "first": "First 249", + "last": "Last 249" + }, + { + "name": "user250", + "first": "First 250", + "last": "Last 250" + }, + { + "name": "user251", + "first": "First 251", + "last": "Last 251" + }, + { + "name": "user252", + "first": "First 252", + "last": "Last 252" + }, + { + "name": "user253", + "first": "First 253", + "last": "Last 253" + }, + { + "name": "user254", + "first": "First 254", + "last": "Last 254" + }, + { + "name": "user255", + "first": "First 255", + "last": "Last 255" + }, + { + "name": "user256", + "first": "First 256", + "last": "Last 256" + }, + { + "name": "user257", + "first": "First 257", + "last": "Last 257" + }, + { + "name": "user258", + "first": "First 258", + "last": "Last 258" + }, + { + "name": "user259", + "first": "First 259", + "last": "Last 259" + }, + { + "name": "user260", + "first": "First 260", + "last": "Last 260" + }, + { + "name": "user261", + "first": "First 261", + "last": "Last 261" + }, + { + "name": "user262", + "first": "First 262", + "last": "Last 262" + }, + { + "name": "user263", + "first": "First 263", + "last": "Last 263" + }, + { + "name": "user264", + "first": "First 264", + "last": "Last 264" + }, + { + "name": "user265", + "first": "First 265", + "last": "Last 265" + }, + { + "name": "user266", + "first": "First 266", + "last": "Last 266" + }, + { + "name": "user267", + "first": "First 267", + "last": "Last 267" + }, + { + "name": "user268", + "first": "First 268", + "last": "Last 268" + }, + { + "name": "user269", + "first": "First 269", + "last": "Last 269" + }, + { + "name": "user270", + "first": "First 270", + "last": "Last 270" + }, + { + "name": "user271", + "first": "First 271", + "last": "Last 271" + }, + { + "name": "user272", + "first": "First 272", + "last": "Last 272" + }, + { + "name": "user273", + "first": "First 273", + "last": "Last 273" + }, + { + "name": "user274", + "first": "First 274", + "last": "Last 274" + }, + { + "name": "user275", + "first": "First 275", + "last": "Last 275" + }, + { + "name": "user276", + "first": "First 276", + "last": "Last 276" + }, + { + "name": "user277", + "first": "First 277", + "last": "Last 277" + }, + { + "name": "user278", + "first": "First 278", + "last": "Last 278" + }, + { + "name": "user279", + "first": "First 279", + "last": "Last 279" + }, + { + "name": "user280", + "first": "First 280", + "last": "Last 280" + }, + { + "name": "user281", + "first": "First 281", + "last": "Last 281" + }, + { + "name": "user282", + "first": "First 282", + "last": "Last 282" + }, + { + "name": "user283", + "first": "First 283", + "last": "Last 283" + }, + { + "name": "user284", + "first": "First 284", + "last": "Last 284" + }, + { + "name": "user285", + "first": "First 285", + "last": "Last 285" + }, + { + "name": "user286", + "first": "First 286", + "last": "Last 286" + }, + { + "name": "user287", + "first": "First 287", + "last": "Last 287" + }, + { + "name": "user288", + "first": "First 288", + "last": "Last 288" + }, + { + "name": "user289", + "first": "First 289", + "last": "Last 289" + }, + { + "name": "user290", + "first": "First 290", + "last": "Last 290" + }, + { + "name": "user291", + "first": "First 291", + "last": "Last 291" + }, + { + "name": "user292", + "first": "First 292", + "last": "Last 292" + }, + { + "name": "user293", + "first": "First 293", + "last": "Last 293" + }, + { + "name": "user294", + "first": "First 294", + "last": "Last 294" + }, + { + "name": "user295", + "first": "First 295", + "last": "Last 295" + }, + { + "name": "user296", + "first": "First 296", + "last": "Last 296" + }, + { + "name": "user297", + "first": "First 297", + "last": "Last 297" + }, + { + "name": "user298", + "first": "First 298", + "last": "Last 298" + }, + { + "name": "user299", + "first": "First 299", + "last": "Last 299" + }, + { + "name": "user300", + "first": "First 300", + "last": "Last 300" + }, + { + "name": "user301", + "first": "First 301", + "last": "Last 301" + }, + { + "name": "user302", + "first": "First 302", + "last": "Last 302" + }, + { + "name": "user303", + "first": "First 303", + "last": "Last 303" + }, + { + "name": "user304", + "first": "First 304", + "last": "Last 304" + }, + { + "name": "user305", + "first": "First 305", + "last": "Last 305" + }, + { + "name": "user306", + "first": "First 306", + "last": "Last 306" + }, + { + "name": "user307", + "first": "First 307", + "last": "Last 307" + }, + { + "name": "user308", + "first": "First 308", + "last": "Last 308" + }, + { + "name": "user309", + "first": "First 309", + "last": "Last 309" + }, + { + "name": "user310", + "first": "First 310", + "last": "Last 310" + }, + { + "name": "user311", + "first": "First 311", + "last": "Last 311" + }, + { + "name": "user312", + "first": "First 312", + "last": "Last 312" + }, + { + "name": "user313", + "first": "First 313", + "last": "Last 313" + }, + { + "name": "user314", + "first": "First 314", + "last": "Last 314" + }, + { + "name": "user315", + "first": "First 315", + "last": "Last 315" + }, + { + "name": "user316", + "first": "First 316", + "last": "Last 316" + }, + { + "name": "user317", + "first": "First 317", + "last": "Last 317" + }, + { + "name": "user318", + "first": "First 318", + "last": "Last 318" + }, + { + "name": "user319", + "first": "First 319", + "last": "Last 319" + }, + { + "name": "user320", + "first": "First 320", + "last": "Last 320" + }, + { + "name": "user321", + "first": "First 321", + "last": "Last 321" + }, + { + "name": "user322", + "first": "First 322", + "last": "Last 322" + }, + { + "name": "user323", + "first": "First 323", + "last": "Last 323" + }, + { + "name": "user324", + "first": "First 324", + "last": "Last 324" + }, + { + "name": "user325", + "first": "First 325", + "last": "Last 325" + }, + { + "name": "user326", + "first": "First 326", + "last": "Last 326" + }, + { + "name": "user327", + "first": "First 327", + "last": "Last 327" + }, + { + "name": "user328", + "first": "First 328", + "last": "Last 328" + }, + { + "name": "user329", + "first": "First 329", + "last": "Last 329" + }, + { + "name": "user330", + "first": "First 330", + "last": "Last 330" + }, + { + "name": "user331", + "first": "First 331", + "last": "Last 331" + }, + { + "name": "user332", + "first": "First 332", + "last": "Last 332" + }, + { + "name": "user333", + "first": "First 333", + "last": "Last 333" + }, + { + "name": "user334", + "first": "First 334", + "last": "Last 334" + }, + { + "name": "user335", + "first": "First 335", + "last": "Last 335" + }, + { + "name": "user336", + "first": "First 336", + "last": "Last 336" + }, + { + "name": "user337", + "first": "First 337", + "last": "Last 337" + }, + { + "name": "user338", + "first": "First 338", + "last": "Last 338" + }, + { + "name": "user339", + "first": "First 339", + "last": "Last 339" + }, + { + "name": "user340", + "first": "First 340", + "last": "Last 340" + }, + { + "name": "user341", + "first": "First 341", + "last": "Last 341" + }, + { + "name": "user342", + "first": "First 342", + "last": "Last 342" + }, + { + "name": "user343", + "first": "First 343", + "last": "Last 343" + }, + { + "name": "user344", + "first": "First 344", + "last": "Last 344" + }, + { + "name": "user345", + "first": "First 345", + "last": "Last 345" + }, + { + "name": "user346", + "first": "First 346", + "last": "Last 346" + }, + { + "name": "user347", + "first": "First 347", + "last": "Last 347" + }, + { + "name": "user348", + "first": "First 348", + "last": "Last 348" + }, + { + "name": "user349", + "first": "First 349", + "last": "Last 349" + }, + { + "name": "user350", + "first": "First 350", + "last": "Last 350" + }, + { + "name": "user351", + "first": "First 351", + "last": "Last 351" + }, + { + "name": "user352", + "first": "First 352", + "last": "Last 352" + }, + { + "name": "user353", + "first": "First 353", + "last": "Last 353" + }, + { + "name": "user354", + "first": "First 354", + "last": "Last 354" + }, + { + "name": "user355", + "first": "First 355", + "last": "Last 355" + }, + { + "name": "user356", + "first": "First 356", + "last": "Last 356" + }, + { + "name": "user357", + "first": "First 357", + "last": "Last 357" + }, + { + "name": "user358", + "first": "First 358", + "last": "Last 358" + }, + { + "name": "user359", + "first": "First 359", + "last": "Last 359" + }, + { + "name": "user360", + "first": "First 360", + "last": "Last 360" + }, + { + "name": "user361", + "first": "First 361", + "last": "Last 361" + }, + { + "name": "user362", + "first": "First 362", + "last": "Last 362" + }, + { + "name": "user363", + "first": "First 363", + "last": "Last 363" + }, + { + "name": "user364", + "first": "First 364", + "last": "Last 364" + }, + { + "name": "user365", + "first": "First 365", + "last": "Last 365" + }, + { + "name": "user366", + "first": "First 366", + "last": "Last 366" + }, + { + "name": "user367", + "first": "First 367", + "last": "Last 367" + }, + { + "name": "user368", + "first": "First 368", + "last": "Last 368" + }, + { + "name": "user369", + "first": "First 369", + "last": "Last 369" + }, + { + "name": "user370", + "first": "First 370", + "last": "Last 370" + }, + { + "name": "user371", + "first": "First 371", + "last": "Last 371" + }, + { + "name": "user372", + "first": "First 372", + "last": "Last 372" + }, + { + "name": "user373", + "first": "First 373", + "last": "Last 373" + }, + { + "name": "user374", + "first": "First 374", + "last": "Last 374" + }, + { + "name": "user375", + "first": "First 375", + "last": "Last 375" + }, + { + "name": "user376", + "first": "First 376", + "last": "Last 376" + }, + { + "name": "user377", + "first": "First 377", + "last": "Last 377" + }, + { + "name": "user378", + "first": "First 378", + "last": "Last 378" + }, + { + "name": "user379", + "first": "First 379", + "last": "Last 379" + }, + { + "name": "user380", + "first": "First 380", + "last": "Last 380" + }, + { + "name": "user381", + "first": "First 381", + "last": "Last 381" + }, + { + "name": "user382", + "first": "First 382", + "last": "Last 382" + }, + { + "name": "user383", + "first": "First 383", + "last": "Last 383" + }, + { + "name": "user384", + "first": "First 384", + "last": "Last 384" + }, + { + "name": "user385", + "first": "First 385", + "last": "Last 385" + }, + { + "name": "user386", + "first": "First 386", + "last": "Last 386" + }, + { + "name": "user387", + "first": "First 387", + "last": "Last 387" + }, + { + "name": "user388", + "first": "First 388", + "last": "Last 388" + }, + { + "name": "user389", + "first": "First 389", + "last": "Last 389" + }, + { + "name": "user390", + "first": "First 390", + "last": "Last 390" + }, + { + "name": "user391", + "first": "First 391", + "last": "Last 391" + }, + { + "name": "user392", + "first": "First 392", + "last": "Last 392" + }, + { + "name": "user393", + "first": "First 393", + "last": "Last 393" + }, + { + "name": "user394", + "first": "First 394", + "last": "Last 394" + }, + { + "name": "user395", + "first": "First 395", + "last": "Last 395" + }, + { + "name": "user396", + "first": "First 396", + "last": "Last 396" + }, + { + "name": "user397", + "first": "First 397", + "last": "Last 397" + }, + { + "name": "user398", + "first": "First 398", + "last": "Last 398" + }, + { + "name": "user399", + "first": "First 399", + "last": "Last 399" + }, + { + "name": "user400", + "first": "First 400", + "last": "Last 400" + }, + { + "name": "user401", + "first": "First 401", + "last": "Last 401" + }, + { + "name": "user402", + "first": "First 402", + "last": "Last 402" + }, + { + "name": "user403", + "first": "First 403", + "last": "Last 403" + }, + { + "name": "user404", + "first": "First 404", + "last": "Last 404" + }, + { + "name": "user405", + "first": "First 405", + "last": "Last 405" + }, + { + "name": "user406", + "first": "First 406", + "last": "Last 406" + }, + { + "name": "user407", + "first": "First 407", + "last": "Last 407" + }, + { + "name": "user408", + "first": "First 408", + "last": "Last 408" + }, + { + "name": "user409", + "first": "First 409", + "last": "Last 409" + }, + { + "name": "user410", + "first": "First 410", + "last": "Last 410" + }, + { + "name": "user411", + "first": "First 411", + "last": "Last 411" + }, + { + "name": "user412", + "first": "First 412", + "last": "Last 412" + }, + { + "name": "user413", + "first": "First 413", + "last": "Last 413" + }, + { + "name": "user414", + "first": "First 414", + "last": "Last 414" + }, + { + "name": "user415", + "first": "First 415", + "last": "Last 415" + }, + { + "name": "user416", + "first": "First 416", + "last": "Last 416" + }, + { + "name": "user417", + "first": "First 417", + "last": "Last 417" + }, + { + "name": "user418", + "first": "First 418", + "last": "Last 418" + }, + { + "name": "user419", + "first": "First 419", + "last": "Last 419" + }, + { + "name": "user420", + "first": "First 420", + "last": "Last 420" + }, + { + "name": "user421", + "first": "First 421", + "last": "Last 421" + }, + { + "name": "user422", + "first": "First 422", + "last": "Last 422" + }, + { + "name": "user423", + "first": "First 423", + "last": "Last 423" + }, + { + "name": "user424", + "first": "First 424", + "last": "Last 424" + }, + { + "name": "user425", + "first": "First 425", + "last": "Last 425" + }, + { + "name": "user426", + "first": "First 426", + "last": "Last 426" + }, + { + "name": "user427", + "first": "First 427", + "last": "Last 427" + }, + { + "name": "user428", + "first": "First 428", + "last": "Last 428" + }, + { + "name": "user429", + "first": "First 429", + "last": "Last 429" + }, + { + "name": "user430", + "first": "First 430", + "last": "Last 430" + }, + { + "name": "user431", + "first": "First 431", + "last": "Last 431" + }, + { + "name": "user432", + "first": "First 432", + "last": "Last 432" + }, + { + "name": "user433", + "first": "First 433", + "last": "Last 433" + }, + { + "name": "user434", + "first": "First 434", + "last": "Last 434" + }, + { + "name": "user435", + "first": "First 435", + "last": "Last 435" + }, + { + "name": "user436", + "first": "First 436", + "last": "Last 436" + }, + { + "name": "user437", + "first": "First 437", + "last": "Last 437" + }, + { + "name": "user438", + "first": "First 438", + "last": "Last 438" + }, + { + "name": "user439", + "first": "First 439", + "last": "Last 439" + }, + { + "name": "user440", + "first": "First 440", + "last": "Last 440" + }, + { + "name": "user441", + "first": "First 441", + "last": "Last 441" + }, + { + "name": "user442", + "first": "First 442", + "last": "Last 442" + }, + { + "name": "user443", + "first": "First 443", + "last": "Last 443" + }, + { + "name": "user444", + "first": "First 444", + "last": "Last 444" + }, + { + "name": "user445", + "first": "First 445", + "last": "Last 445" + }, + { + "name": "user446", + "first": "First 446", + "last": "Last 446" + }, + { + "name": "user447", + "first": "First 447", + "last": "Last 447" + }, + { + "name": "user448", + "first": "First 448", + "last": "Last 448" + }, + { + "name": "user449", + "first": "First 449", + "last": "Last 449" + }, + { + "name": "user450", + "first": "First 450", + "last": "Last 450" + }, + { + "name": "user451", + "first": "First 451", + "last": "Last 451" + }, + { + "name": "user452", + "first": "First 452", + "last": "Last 452" + }, + { + "name": "user453", + "first": "First 453", + "last": "Last 453" + }, + { + "name": "user454", + "first": "First 454", + "last": "Last 454" + }, + { + "name": "user455", + "first": "First 455", + "last": "Last 455" + }, + { + "name": "user456", + "first": "First 456", + "last": "Last 456" + }, + { + "name": "user457", + "first": "First 457", + "last": "Last 457" + }, + { + "name": "user458", + "first": "First 458", + "last": "Last 458" + }, + { + "name": "user459", + "first": "First 459", + "last": "Last 459" + }, + { + "name": "user460", + "first": "First 460", + "last": "Last 460" + }, + { + "name": "user461", + "first": "First 461", + "last": "Last 461" + }, + { + "name": "user462", + "first": "First 462", + "last": "Last 462" + }, + { + "name": "user463", + "first": "First 463", + "last": "Last 463" + }, + { + "name": "user464", + "first": "First 464", + "last": "Last 464" + }, + { + "name": "user465", + "first": "First 465", + "last": "Last 465" + }, + { + "name": "user466", + "first": "First 466", + "last": "Last 466" + }, + { + "name": "user467", + "first": "First 467", + "last": "Last 467" + }, + { + "name": "user468", + "first": "First 468", + "last": "Last 468" + }, + { + "name": "user469", + "first": "First 469", + "last": "Last 469" + }, + { + "name": "user470", + "first": "First 470", + "last": "Last 470" + }, + { + "name": "user471", + "first": "First 471", + "last": "Last 471" + }, + { + "name": "user472", + "first": "First 472", + "last": "Last 472" + }, + { + "name": "user473", + "first": "First 473", + "last": "Last 473" + }, + { + "name": "user474", + "first": "First 474", + "last": "Last 474" + }, + { + "name": "user475", + "first": "First 475", + "last": "Last 475" + }, + { + "name": "user476", + "first": "First 476", + "last": "Last 476" + }, + { + "name": "user477", + "first": "First 477", + "last": "Last 477" + }, + { + "name": "user478", + "first": "First 478", + "last": "Last 478" + }, + { + "name": "user479", + "first": "First 479", + "last": "Last 479" + }, + { + "name": "user480", + "first": "First 480", + "last": "Last 480" + }, + { + "name": "user481", + "first": "First 481", + "last": "Last 481" + }, + { + "name": "user482", + "first": "First 482", + "last": "Last 482" + }, + { + "name": "user483", + "first": "First 483", + "last": "Last 483" + }, + { + "name": "user484", + "first": "First 484", + "last": "Last 484" + }, + { + "name": "user485", + "first": "First 485", + "last": "Last 485" + }, + { + "name": "user486", + "first": "First 486", + "last": "Last 486" + }, + { + "name": "user487", + "first": "First 487", + "last": "Last 487" + }, + { + "name": "user488", + "first": "First 488", + "last": "Last 488" + }, + { + "name": "user489", + "first": "First 489", + "last": "Last 489" + }, + { + "name": "user490", + "first": "First 490", + "last": "Last 490" + }, + { + "name": "user491", + "first": "First 491", + "last": "Last 491" + }, + { + "name": "user492", + "first": "First 492", + "last": "Last 492" + }, + { + "name": "user493", + "first": "First 493", + "last": "Last 493" + }, + { + "name": "user494", + "first": "First 494", + "last": "Last 494" + }, + { + "name": "user495", + "first": "First 495", + "last": "Last 495" + }, + { + "name": "user496", + "first": "First 496", + "last": "Last 496" + }, + { + "name": "user497", + "first": "First 497", + "last": "Last 497" + }, + { + "name": "user498", + "first": "First 498", + "last": "Last 498" + }, + { + "name": "user499", + "first": "First 499", + "last": "Last 499" + }, + { + "name": "user500", + "first": "First 500", + "last": "Last 500" + }, + { + "name": "user501", + "first": "First 501", + "last": "Last 501" + }, + { + "name": "user502", + "first": "First 502", + "last": "Last 502" + }, + { + "name": "user503", + "first": "First 503", + "last": "Last 503" + }, + { + "name": "user504", + "first": "First 504", + "last": "Last 504" + }, + { + "name": "user505", + "first": "First 505", + "last": "Last 505" + }, + { + "name": "user506", + "first": "First 506", + "last": "Last 506" + }, + { + "name": "user507", + "first": "First 507", + "last": "Last 507" + }, + { + "name": "user508", + "first": "First 508", + "last": "Last 508" + }, + { + "name": "user509", + "first": "First 509", + "last": "Last 509" + }, + { + "name": "user510", + "first": "First 510", + "last": "Last 510" + }, + { + "name": "user511", + "first": "First 511", + "last": "Last 511" + }, + { + "name": "user512", + "first": "First 512", + "last": "Last 512" + }, + { + "name": "user513", + "first": "First 513", + "last": "Last 513" + }, + { + "name": "user514", + "first": "First 514", + "last": "Last 514" + }, + { + "name": "user515", + "first": "First 515", + "last": "Last 515" + }, + { + "name": "user516", + "first": "First 516", + "last": "Last 516" + }, + { + "name": "user517", + "first": "First 517", + "last": "Last 517" + }, + { + "name": "user518", + "first": "First 518", + "last": "Last 518" + }, + { + "name": "user519", + "first": "First 519", + "last": "Last 519" + }, + { + "name": "user520", + "first": "First 520", + "last": "Last 520" + }, + { + "name": "user521", + "first": "First 521", + "last": "Last 521" + }, + { + "name": "user522", + "first": "First 522", + "last": "Last 522" + }, + { + "name": "user523", + "first": "First 523", + "last": "Last 523" + }, + { + "name": "user524", + "first": "First 524", + "last": "Last 524" + }, + { + "name": "user525", + "first": "First 525", + "last": "Last 525" + }, + { + "name": "user526", + "first": "First 526", + "last": "Last 526" + }, + { + "name": "user527", + "first": "First 527", + "last": "Last 527" + }, + { + "name": "user528", + "first": "First 528", + "last": "Last 528" + }, + { + "name": "user529", + "first": "First 529", + "last": "Last 529" + }, + { + "name": "user530", + "first": "First 530", + "last": "Last 530" + }, + { + "name": "user531", + "first": "First 531", + "last": "Last 531" + }, + { + "name": "user532", + "first": "First 532", + "last": "Last 532" + }, + { + "name": "user533", + "first": "First 533", + "last": "Last 533" + }, + { + "name": "user534", + "first": "First 534", + "last": "Last 534" + }, + { + "name": "user535", + "first": "First 535", + "last": "Last 535" + }, + { + "name": "user536", + "first": "First 536", + "last": "Last 536" + }, + { + "name": "user537", + "first": "First 537", + "last": "Last 537" + }, + { + "name": "user538", + "first": "First 538", + "last": "Last 538" + }, + { + "name": "user539", + "first": "First 539", + "last": "Last 539" + }, + { + "name": "user540", + "first": "First 540", + "last": "Last 540" + }, + { + "name": "user541", + "first": "First 541", + "last": "Last 541" + }, + { + "name": "user542", + "first": "First 542", + "last": "Last 542" + }, + { + "name": "user543", + "first": "First 543", + "last": "Last 543" + }, + { + "name": "user544", + "first": "First 544", + "last": "Last 544" + }, + { + "name": "user545", + "first": "First 545", + "last": "Last 545" + }, + { + "name": "user546", + "first": "First 546", + "last": "Last 546" + }, + { + "name": "user547", + "first": "First 547", + "last": "Last 547" + }, + { + "name": "user548", + "first": "First 548", + "last": "Last 548" + }, + { + "name": "user549", + "first": "First 549", + "last": "Last 549" + }, + { + "name": "user550", + "first": "First 550", + "last": "Last 550" + }, + { + "name": "user551", + "first": "First 551", + "last": "Last 551" + }, + { + "name": "user552", + "first": "First 552", + "last": "Last 552" + }, + { + "name": "user553", + "first": "First 553", + "last": "Last 553" + }, + { + "name": "user554", + "first": "First 554", + "last": "Last 554" + }, + { + "name": "user555", + "first": "First 555", + "last": "Last 555" + }, + { + "name": "user556", + "first": "First 556", + "last": "Last 556" + }, + { + "name": "user557", + "first": "First 557", + "last": "Last 557" + }, + { + "name": "user558", + "first": "First 558", + "last": "Last 558" + }, + { + "name": "user559", + "first": "First 559", + "last": "Last 559" + }, + { + "name": "user560", + "first": "First 560", + "last": "Last 560" + }, + { + "name": "user561", + "first": "First 561", + "last": "Last 561" + }, + { + "name": "user562", + "first": "First 562", + "last": "Last 562" + }, + { + "name": "user563", + "first": "First 563", + "last": "Last 563" + }, + { + "name": "user564", + "first": "First 564", + "last": "Last 564" + }, + { + "name": "user565", + "first": "First 565", + "last": "Last 565" + }, + { + "name": "user566", + "first": "First 566", + "last": "Last 566" + }, + { + "name": "user567", + "first": "First 567", + "last": "Last 567" + }, + { + "name": "user568", + "first": "First 568", + "last": "Last 568" + }, + { + "name": "user569", + "first": "First 569", + "last": "Last 569" + }, + { + "name": "user570", + "first": "First 570", + "last": "Last 570" + }, + { + "name": "user571", + "first": "First 571", + "last": "Last 571" + }, + { + "name": "user572", + "first": "First 572", + "last": "Last 572" + }, + { + "name": "user573", + "first": "First 573", + "last": "Last 573" + }, + { + "name": "user574", + "first": "First 574", + "last": "Last 574" + }, + { + "name": "user575", + "first": "First 575", + "last": "Last 575" + }, + { + "name": "user576", + "first": "First 576", + "last": "Last 576" + }, + { + "name": "user577", + "first": "First 577", + "last": "Last 577" + }, + { + "name": "user578", + "first": "First 578", + "last": "Last 578" + }, + { + "name": "user579", + "first": "First 579", + "last": "Last 579" + }, + { + "name": "user580", + "first": "First 580", + "last": "Last 580" + }, + { + "name": "user581", + "first": "First 581", + "last": "Last 581" + }, + { + "name": "user582", + "first": "First 582", + "last": "Last 582" + }, + { + "name": "user583", + "first": "First 583", + "last": "Last 583" + }, + { + "name": "user584", + "first": "First 584", + "last": "Last 584" + }, + { + "name": "user585", + "first": "First 585", + "last": "Last 585" + }, + { + "name": "user586", + "first": "First 586", + "last": "Last 586" + }, + { + "name": "user587", + "first": "First 587", + "last": "Last 587" + }, + { + "name": "user588", + "first": "First 588", + "last": "Last 588" + }, + { + "name": "user589", + "first": "First 589", + "last": "Last 589" + }, + { + "name": "user590", + "first": "First 590", + "last": "Last 590" + }, + { + "name": "user591", + "first": "First 591", + "last": "Last 591" + }, + { + "name": "user592", + "first": "First 592", + "last": "Last 592" + }, + { + "name": "user593", + "first": "First 593", + "last": "Last 593" + }, + { + "name": "user594", + "first": "First 594", + "last": "Last 594" + }, + { + "name": "user595", + "first": "First 595", + "last": "Last 595" + }, + { + "name": "user596", + "first": "First 596", + "last": "Last 596" + }, + { + "name": "user597", + "first": "First 597", + "last": "Last 597" + }, + { + "name": "user598", + "first": "First 598", + "last": "Last 598" + }, + { + "name": "user599", + "first": "First 599", + "last": "Last 599" + }, + { + "name": "user600", + "first": "First 600", + "last": "Last 600" + }, + { + "name": "user601", + "first": "First 601", + "last": "Last 601" + }, + { + "name": "user602", + "first": "First 602", + "last": "Last 602" + }, + { + "name": "user603", + "first": "First 603", + "last": "Last 603" + }, + { + "name": "user604", + "first": "First 604", + "last": "Last 604" + }, + { + "name": "user605", + "first": "First 605", + "last": "Last 605" + }, + { + "name": "user606", + "first": "First 606", + "last": "Last 606" + }, + { + "name": "user607", + "first": "First 607", + "last": "Last 607" + }, + { + "name": "user608", + "first": "First 608", + "last": "Last 608" + }, + { + "name": "user609", + "first": "First 609", + "last": "Last 609" + }, + { + "name": "user610", + "first": "First 610", + "last": "Last 610" + }, + { + "name": "user611", + "first": "First 611", + "last": "Last 611" + }, + { + "name": "user612", + "first": "First 612", + "last": "Last 612" + }, + { + "name": "user613", + "first": "First 613", + "last": "Last 613" + }, + { + "name": "user614", + "first": "First 614", + "last": "Last 614" + }, + { + "name": "user615", + "first": "First 615", + "last": "Last 615" + }, + { + "name": "user616", + "first": "First 616", + "last": "Last 616" + }, + { + "name": "user617", + "first": "First 617", + "last": "Last 617" + }, + { + "name": "user618", + "first": "First 618", + "last": "Last 618" + }, + { + "name": "user619", + "first": "First 619", + "last": "Last 619" + }, + { + "name": "user620", + "first": "First 620", + "last": "Last 620" + }, + { + "name": "user621", + "first": "First 621", + "last": "Last 621" + }, + { + "name": "user622", + "first": "First 622", + "last": "Last 622" + }, + { + "name": "user623", + "first": "First 623", + "last": "Last 623" + }, + { + "name": "user624", + "first": "First 624", + "last": "Last 624" + }, + { + "name": "user625", + "first": "First 625", + "last": "Last 625" + }, + { + "name": "user626", + "first": "First 626", + "last": "Last 626" + }, + { + "name": "user627", + "first": "First 627", + "last": "Last 627" + }, + { + "name": "user628", + "first": "First 628", + "last": "Last 628" + }, + { + "name": "user629", + "first": "First 629", + "last": "Last 629" + }, + { + "name": "user630", + "first": "First 630", + "last": "Last 630" + }, + { + "name": "user631", + "first": "First 631", + "last": "Last 631" + }, + { + "name": "user632", + "first": "First 632", + "last": "Last 632" + }, + { + "name": "user633", + "first": "First 633", + "last": "Last 633" + }, + { + "name": "user634", + "first": "First 634", + "last": "Last 634" + }, + { + "name": "user635", + "first": "First 635", + "last": "Last 635" + }, + { + "name": "user636", + "first": "First 636", + "last": "Last 636" + }, + { + "name": "user637", + "first": "First 637", + "last": "Last 637" + }, + { + "name": "user638", + "first": "First 638", + "last": "Last 638" + }, + { + "name": "user639", + "first": "First 639", + "last": "Last 639" + }, + { + "name": "user640", + "first": "First 640", + "last": "Last 640" + }, + { + "name": "user641", + "first": "First 641", + "last": "Last 641" + }, + { + "name": "user642", + "first": "First 642", + "last": "Last 642" + }, + { + "name": "user643", + "first": "First 643", + "last": "Last 643" + }, + { + "name": "user644", + "first": "First 644", + "last": "Last 644" + }, + { + "name": "user645", + "first": "First 645", + "last": "Last 645" + }, + { + "name": "user646", + "first": "First 646", + "last": "Last 646" + }, + { + "name": "user647", + "first": "First 647", + "last": "Last 647" + }, + { + "name": "user648", + "first": "First 648", + "last": "Last 648" + }, + { + "name": "user649", + "first": "First 649", + "last": "Last 649" + }, + { + "name": "user650", + "first": "First 650", + "last": "Last 650" + }, + { + "name": "user651", + "first": "First 651", + "last": "Last 651" + }, + { + "name": "user652", + "first": "First 652", + "last": "Last 652" + }, + { + "name": "user653", + "first": "First 653", + "last": "Last 653" + }, + { + "name": "user654", + "first": "First 654", + "last": "Last 654" + }, + { + "name": "user655", + "first": "First 655", + "last": "Last 655" + }, + { + "name": "user656", + "first": "First 656", + "last": "Last 656" + }, + { + "name": "user657", + "first": "First 657", + "last": "Last 657" + }, + { + "name": "user658", + "first": "First 658", + "last": "Last 658" + }, + { + "name": "user659", + "first": "First 659", + "last": "Last 659" + }, + { + "name": "user660", + "first": "First 660", + "last": "Last 660" + }, + { + "name": "user661", + "first": "First 661", + "last": "Last 661" + }, + { + "name": "user662", + "first": "First 662", + "last": "Last 662" + }, + { + "name": "user663", + "first": "First 663", + "last": "Last 663" + }, + { + "name": "user664", + "first": "First 664", + "last": "Last 664" + }, + { + "name": "user665", + "first": "First 665", + "last": "Last 665" + }, + { + "name": "user666", + "first": "First 666", + "last": "Last 666" + }, + { + "name": "user667", + "first": "First 667", + "last": "Last 667" + }, + { + "name": "user668", + "first": "First 668", + "last": "Last 668" + }, + { + "name": "user669", + "first": "First 669", + "last": "Last 669" + }, + { + "name": "user670", + "first": "First 670", + "last": "Last 670" + }, + { + "name": "user671", + "first": "First 671", + "last": "Last 671" + }, + { + "name": "user672", + "first": "First 672", + "last": "Last 672" + }, + { + "name": "user673", + "first": "First 673", + "last": "Last 673" + }, + { + "name": "user674", + "first": "First 674", + "last": "Last 674" + }, + { + "name": "user675", + "first": "First 675", + "last": "Last 675" + }, + { + "name": "user676", + "first": "First 676", + "last": "Last 676" + }, + { + "name": "user677", + "first": "First 677", + "last": "Last 677" + }, + { + "name": "user678", + "first": "First 678", + "last": "Last 678" + }, + { + "name": "user679", + "first": "First 679", + "last": "Last 679" + }, + { + "name": "user680", + "first": "First 680", + "last": "Last 680" + }, + { + "name": "user681", + "first": "First 681", + "last": "Last 681" + }, + { + "name": "user682", + "first": "First 682", + "last": "Last 682" + }, + { + "name": "user683", + "first": "First 683", + "last": "Last 683" + }, + { + "name": "user684", + "first": "First 684", + "last": "Last 684" + }, + { + "name": "user685", + "first": "First 685", + "last": "Last 685" + }, + { + "name": "user686", + "first": "First 686", + "last": "Last 686" + }, + { + "name": "user687", + "first": "First 687", + "last": "Last 687" + }, + { + "name": "user688", + "first": "First 688", + "last": "Last 688" + }, + { + "name": "user689", + "first": "First 689", + "last": "Last 689" + }, + { + "name": "user690", + "first": "First 690", + "last": "Last 690" + }, + { + "name": "user691", + "first": "First 691", + "last": "Last 691" + }, + { + "name": "user692", + "first": "First 692", + "last": "Last 692" + }, + { + "name": "user693", + "first": "First 693", + "last": "Last 693" + }, + { + "name": "user694", + "first": "First 694", + "last": "Last 694" + }, + { + "name": "user695", + "first": "First 695", + "last": "Last 695" + }, + { + "name": "user696", + "first": "First 696", + "last": "Last 696" + }, + { + "name": "user697", + "first": "First 697", + "last": "Last 697" + }, + { + "name": "user698", + "first": "First 698", + "last": "Last 698" + }, + { + "name": "user699", + "first": "First 699", + "last": "Last 699" + }, + { + "name": "user700", + "first": "First 700", + "last": "Last 700" + }, + { + "name": "user701", + "first": "First 701", + "last": "Last 701" + }, + { + "name": "user702", + "first": "First 702", + "last": "Last 702" + }, + { + "name": "user703", + "first": "First 703", + "last": "Last 703" + }, + { + "name": "user704", + "first": "First 704", + "last": "Last 704" + }, + { + "name": "user705", + "first": "First 705", + "last": "Last 705" + }, + { + "name": "user706", + "first": "First 706", + "last": "Last 706" + }, + { + "name": "user707", + "first": "First 707", + "last": "Last 707" + }, + { + "name": "user708", + "first": "First 708", + "last": "Last 708" + }, + { + "name": "user709", + "first": "First 709", + "last": "Last 709" + }, + { + "name": "user710", + "first": "First 710", + "last": "Last 710" + }, + { + "name": "user711", + "first": "First 711", + "last": "Last 711" + }, + { + "name": "user712", + "first": "First 712", + "last": "Last 712" + }, + { + "name": "user713", + "first": "First 713", + "last": "Last 713" + }, + { + "name": "user714", + "first": "First 714", + "last": "Last 714" + }, + { + "name": "user715", + "first": "First 715", + "last": "Last 715" + }, + { + "name": "user716", + "first": "First 716", + "last": "Last 716" + }, + { + "name": "user717", + "first": "First 717", + "last": "Last 717" + }, + { + "name": "user718", + "first": "First 718", + "last": "Last 718" + }, + { + "name": "user719", + "first": "First 719", + "last": "Last 719" + }, + { + "name": "user720", + "first": "First 720", + "last": "Last 720" + }, + { + "name": "user721", + "first": "First 721", + "last": "Last 721" + }, + { + "name": "user722", + "first": "First 722", + "last": "Last 722" + }, + { + "name": "user723", + "first": "First 723", + "last": "Last 723" + }, + { + "name": "user724", + "first": "First 724", + "last": "Last 724" + }, + { + "name": "user725", + "first": "First 725", + "last": "Last 725" + }, + { + "name": "user726", + "first": "First 726", + "last": "Last 726" + }, + { + "name": "user727", + "first": "First 727", + "last": "Last 727" + }, + { + "name": "user728", + "first": "First 728", + "last": "Last 728" + }, + { + "name": "user729", + "first": "First 729", + "last": "Last 729" + }, + { + "name": "user730", + "first": "First 730", + "last": "Last 730" + }, + { + "name": "user731", + "first": "First 731", + "last": "Last 731" + }, + { + "name": "user732", + "first": "First 732", + "last": "Last 732" + }, + { + "name": "user733", + "first": "First 733", + "last": "Last 733" + }, + { + "name": "user734", + "first": "First 734", + "last": "Last 734" + }, + { + "name": "user735", + "first": "First 735", + "last": "Last 735" + }, + { + "name": "user736", + "first": "First 736", + "last": "Last 736" + }, + { + "name": "user737", + "first": "First 737", + "last": "Last 737" + }, + { + "name": "user738", + "first": "First 738", + "last": "Last 738" + }, + { + "name": "user739", + "first": "First 739", + "last": "Last 739" + }, + { + "name": "user740", + "first": "First 740", + "last": "Last 740" + }, + { + "name": "user741", + "first": "First 741", + "last": "Last 741" + }, + { + "name": "user742", + "first": "First 742", + "last": "Last 742" + }, + { + "name": "user743", + "first": "First 743", + "last": "Last 743" + }, + { + "name": "user744", + "first": "First 744", + "last": "Last 744" + }, + { + "name": "user745", + "first": "First 745", + "last": "Last 745" + }, + { + "name": "user746", + "first": "First 746", + "last": "Last 746" + }, + { + "name": "user747", + "first": "First 747", + "last": "Last 747" + }, + { + "name": "user748", + "first": "First 748", + "last": "Last 748" + }, + { + "name": "user749", + "first": "First 749", + "last": "Last 749" + }, + { + "name": "user750", + "first": "First 750", + "last": "Last 750" + }, + { + "name": "user751", + "first": "First 751", + "last": "Last 751" + }, + { + "name": "user752", + "first": "First 752", + "last": "Last 752" + }, + { + "name": "user753", + "first": "First 753", + "last": "Last 753" + }, + { + "name": "user754", + "first": "First 754", + "last": "Last 754" + }, + { + "name": "user755", + "first": "First 755", + "last": "Last 755" + }, + { + "name": "user756", + "first": "First 756", + "last": "Last 756" + }, + { + "name": "user757", + "first": "First 757", + "last": "Last 757" + }, + { + "name": "user758", + "first": "First 758", + "last": "Last 758" + }, + { + "name": "user759", + "first": "First 759", + "last": "Last 759" + }, + { + "name": "user760", + "first": "First 760", + "last": "Last 760" + }, + { + "name": "user761", + "first": "First 761", + "last": "Last 761" + }, + { + "name": "user762", + "first": "First 762", + "last": "Last 762" + }, + { + "name": "user763", + "first": "First 763", + "last": "Last 763" + }, + { + "name": "user764", + "first": "First 764", + "last": "Last 764" + }, + { + "name": "user765", + "first": "First 765", + "last": "Last 765" + }, + { + "name": "user766", + "first": "First 766", + "last": "Last 766" + }, + { + "name": "user767", + "first": "First 767", + "last": "Last 767" + }, + { + "name": "user768", + "first": "First 768", + "last": "Last 768" + }, + { + "name": "user769", + "first": "First 769", + "last": "Last 769" + }, + { + "name": "user770", + "first": "First 770", + "last": "Last 770" + }, + { + "name": "user771", + "first": "First 771", + "last": "Last 771" + }, + { + "name": "user772", + "first": "First 772", + "last": "Last 772" + }, + { + "name": "user773", + "first": "First 773", + "last": "Last 773" + }, + { + "name": "user774", + "first": "First 774", + "last": "Last 774" + }, + { + "name": "user775", + "first": "First 775", + "last": "Last 775" + }, + { + "name": "user776", + "first": "First 776", + "last": "Last 776" + }, + { + "name": "user777", + "first": "First 777", + "last": "Last 777" + }, + { + "name": "user778", + "first": "First 778", + "last": "Last 778" + }, + { + "name": "user779", + "first": "First 779", + "last": "Last 779" + }, + { + "name": "user780", + "first": "First 780", + "last": "Last 780" + }, + { + "name": "user781", + "first": "First 781", + "last": "Last 781" + }, + { + "name": "user782", + "first": "First 782", + "last": "Last 782" + }, + { + "name": "user783", + "first": "First 783", + "last": "Last 783" + }, + { + "name": "user784", + "first": "First 784", + "last": "Last 784" + }, + { + "name": "user785", + "first": "First 785", + "last": "Last 785" + }, + { + "name": "user786", + "first": "First 786", + "last": "Last 786" + }, + { + "name": "user787", + "first": "First 787", + "last": "Last 787" + }, + { + "name": "user788", + "first": "First 788", + "last": "Last 788" + }, + { + "name": "user789", + "first": "First 789", + "last": "Last 789" + }, + { + "name": "user790", + "first": "First 790", + "last": "Last 790" + }, + { + "name": "user791", + "first": "First 791", + "last": "Last 791" + }, + { + "name": "user792", + "first": "First 792", + "last": "Last 792" + }, + { + "name": "user793", + "first": "First 793", + "last": "Last 793" + }, + { + "name": "user794", + "first": "First 794", + "last": "Last 794" + }, + { + "name": "user795", + "first": "First 795", + "last": "Last 795" + }, + { + "name": "user796", + "first": "First 796", + "last": "Last 796" + }, + { + "name": "user797", + "first": "First 797", + "last": "Last 797" + }, + { + "name": "user798", + "first": "First 798", + "last": "Last 798" + }, + { + "name": "user799", + "first": "First 799", + "last": "Last 799" + }, + { + "name": "user800", + "first": "First 800", + "last": "Last 800" + }, + { + "name": "user801", + "first": "First 801", + "last": "Last 801" + }, + { + "name": "user802", + "first": "First 802", + "last": "Last 802" + }, + { + "name": "user803", + "first": "First 803", + "last": "Last 803" + }, + { + "name": "user804", + "first": "First 804", + "last": "Last 804" + }, + { + "name": "user805", + "first": "First 805", + "last": "Last 805" + }, + { + "name": "user806", + "first": "First 806", + "last": "Last 806" + }, + { + "name": "user807", + "first": "First 807", + "last": "Last 807" + }, + { + "name": "user808", + "first": "First 808", + "last": "Last 808" + }, + { + "name": "user809", + "first": "First 809", + "last": "Last 809" + }, + { + "name": "user810", + "first": "First 810", + "last": "Last 810" + }, + { + "name": "user811", + "first": "First 811", + "last": "Last 811" + }, + { + "name": "user812", + "first": "First 812", + "last": "Last 812" + }, + { + "name": "user813", + "first": "First 813", + "last": "Last 813" + }, + { + "name": "user814", + "first": "First 814", + "last": "Last 814" + }, + { + "name": "user815", + "first": "First 815", + "last": "Last 815" + }, + { + "name": "user816", + "first": "First 816", + "last": "Last 816" + }, + { + "name": "user817", + "first": "First 817", + "last": "Last 817" + }, + { + "name": "user818", + "first": "First 818", + "last": "Last 818" + }, + { + "name": "user819", + "first": "First 819", + "last": "Last 819" + }, + { + "name": "user820", + "first": "First 820", + "last": "Last 820" + }, + { + "name": "user821", + "first": "First 821", + "last": "Last 821" + }, + { + "name": "user822", + "first": "First 822", + "last": "Last 822" + }, + { + "name": "user823", + "first": "First 823", + "last": "Last 823" + }, + { + "name": "user824", + "first": "First 824", + "last": "Last 824" + }, + { + "name": "user825", + "first": "First 825", + "last": "Last 825" + }, + { + "name": "user826", + "first": "First 826", + "last": "Last 826" + }, + { + "name": "user827", + "first": "First 827", + "last": "Last 827" + }, + { + "name": "user828", + "first": "First 828", + "last": "Last 828" + }, + { + "name": "user829", + "first": "First 829", + "last": "Last 829" + }, + { + "name": "user830", + "first": "First 830", + "last": "Last 830" + }, + { + "name": "user831", + "first": "First 831", + "last": "Last 831" + }, + { + "name": "user832", + "first": "First 832", + "last": "Last 832" + }, + { + "name": "user833", + "first": "First 833", + "last": "Last 833" + }, + { + "name": "user834", + "first": "First 834", + "last": "Last 834" + }, + { + "name": "user835", + "first": "First 835", + "last": "Last 835" + }, + { + "name": "user836", + "first": "First 836", + "last": "Last 836" + }, + { + "name": "user837", + "first": "First 837", + "last": "Last 837" + }, + { + "name": "user838", + "first": "First 838", + "last": "Last 838" + }, + { + "name": "user839", + "first": "First 839", + "last": "Last 839" + }, + { + "name": "user840", + "first": "First 840", + "last": "Last 840" + }, + { + "name": "user841", + "first": "First 841", + "last": "Last 841" + }, + { + "name": "user842", + "first": "First 842", + "last": "Last 842" + }, + { + "name": "user843", + "first": "First 843", + "last": "Last 843" + }, + { + "name": "user844", + "first": "First 844", + "last": "Last 844" + }, + { + "name": "user845", + "first": "First 845", + "last": "Last 845" + }, + { + "name": "user846", + "first": "First 846", + "last": "Last 846" + }, + { + "name": "user847", + "first": "First 847", + "last": "Last 847" + }, + { + "name": "user848", + "first": "First 848", + "last": "Last 848" + }, + { + "name": "user849", + "first": "First 849", + "last": "Last 849" + }, + { + "name": "user850", + "first": "First 850", + "last": "Last 850" + }, + { + "name": "user851", + "first": "First 851", + "last": "Last 851" + }, + { + "name": "user852", + "first": "First 852", + "last": "Last 852" + }, + { + "name": "user853", + "first": "First 853", + "last": "Last 853" + }, + { + "name": "user854", + "first": "First 854", + "last": "Last 854" + }, + { + "name": "user855", + "first": "First 855", + "last": "Last 855" + }, + { + "name": "user856", + "first": "First 856", + "last": "Last 856" + }, + { + "name": "user857", + "first": "First 857", + "last": "Last 857" + }, + { + "name": "user858", + "first": "First 858", + "last": "Last 858" + }, + { + "name": "user859", + "first": "First 859", + "last": "Last 859" + }, + { + "name": "user860", + "first": "First 860", + "last": "Last 860" + }, + { + "name": "user861", + "first": "First 861", + "last": "Last 861" + }, + { + "name": "user862", + "first": "First 862", + "last": "Last 862" + }, + { + "name": "user863", + "first": "First 863", + "last": "Last 863" + }, + { + "name": "user864", + "first": "First 864", + "last": "Last 864" + }, + { + "name": "user865", + "first": "First 865", + "last": "Last 865" + }, + { + "name": "user866", + "first": "First 866", + "last": "Last 866" + }, + { + "name": "user867", + "first": "First 867", + "last": "Last 867" + }, + { + "name": "user868", + "first": "First 868", + "last": "Last 868" + }, + { + "name": "user869", + "first": "First 869", + "last": "Last 869" + }, + { + "name": "user870", + "first": "First 870", + "last": "Last 870" + }, + { + "name": "user871", + "first": "First 871", + "last": "Last 871" + }, + { + "name": "user872", + "first": "First 872", + "last": "Last 872" + }, + { + "name": "user873", + "first": "First 873", + "last": "Last 873" + }, + { + "name": "user874", + "first": "First 874", + "last": "Last 874" + }, + { + "name": "user875", + "first": "First 875", + "last": "Last 875" + }, + { + "name": "user876", + "first": "First 876", + "last": "Last 876" + }, + { + "name": "user877", + "first": "First 877", + "last": "Last 877" + }, + { + "name": "user878", + "first": "First 878", + "last": "Last 878" + }, + { + "name": "user879", + "first": "First 879", + "last": "Last 879" + }, + { + "name": "user880", + "first": "First 880", + "last": "Last 880" + }, + { + "name": "user881", + "first": "First 881", + "last": "Last 881" + }, + { + "name": "user882", + "first": "First 882", + "last": "Last 882" + }, + { + "name": "user883", + "first": "First 883", + "last": "Last 883" + }, + { + "name": "user884", + "first": "First 884", + "last": "Last 884" + }, + { + "name": "user885", + "first": "First 885", + "last": "Last 885" + }, + { + "name": "user886", + "first": "First 886", + "last": "Last 886" + }, + { + "name": "user887", + "first": "First 887", + "last": "Last 887" + }, + { + "name": "user888", + "first": "First 888", + "last": "Last 888" + }, + { + "name": "user889", + "first": "First 889", + "last": "Last 889" + }, + { + "name": "user890", + "first": "First 890", + "last": "Last 890" + }, + { + "name": "user891", + "first": "First 891", + "last": "Last 891" + }, + { + "name": "user892", + "first": "First 892", + "last": "Last 892" + }, + { + "name": "user893", + "first": "First 893", + "last": "Last 893" + }, + { + "name": "user894", + "first": "First 894", + "last": "Last 894" + }, + { + "name": "user895", + "first": "First 895", + "last": "Last 895" + }, + { + "name": "user896", + "first": "First 896", + "last": "Last 896" + }, + { + "name": "user897", + "first": "First 897", + "last": "Last 897" + }, + { + "name": "user898", + "first": "First 898", + "last": "Last 898" + }, + { + "name": "user899", + "first": "First 899", + "last": "Last 899" + }, + { + "name": "user900", + "first": "First 900", + "last": "Last 900" + }, + { + "name": "user901", + "first": "First 901", + "last": "Last 901" + }, + { + "name": "user902", + "first": "First 902", + "last": "Last 902" + }, + { + "name": "user903", + "first": "First 903", + "last": "Last 903" + }, + { + "name": "user904", + "first": "First 904", + "last": "Last 904" + }, + { + "name": "user905", + "first": "First 905", + "last": "Last 905" + }, + { + "name": "user906", + "first": "First 906", + "last": "Last 906" + }, + { + "name": "user907", + "first": "First 907", + "last": "Last 907" + }, + { + "name": "user908", + "first": "First 908", + "last": "Last 908" + }, + { + "name": "user909", + "first": "First 909", + "last": "Last 909" + }, + { + "name": "user910", + "first": "First 910", + "last": "Last 910" + }, + { + "name": "user911", + "first": "First 911", + "last": "Last 911" + }, + { + "name": "user912", + "first": "First 912", + "last": "Last 912" + }, + { + "name": "user913", + "first": "First 913", + "last": "Last 913" + }, + { + "name": "user914", + "first": "First 914", + "last": "Last 914" + }, + { + "name": "user915", + "first": "First 915", + "last": "Last 915" + }, + { + "name": "user916", + "first": "First 916", + "last": "Last 916" + }, + { + "name": "user917", + "first": "First 917", + "last": "Last 917" + }, + { + "name": "user918", + "first": "First 918", + "last": "Last 918" + }, + { + "name": "user919", + "first": "First 919", + "last": "Last 919" + }, + { + "name": "user920", + "first": "First 920", + "last": "Last 920" + }, + { + "name": "user921", + "first": "First 921", + "last": "Last 921" + }, + { + "name": "user922", + "first": "First 922", + "last": "Last 922" + }, + { + "name": "user923", + "first": "First 923", + "last": "Last 923" + }, + { + "name": "user924", + "first": "First 924", + "last": "Last 924" + }, + { + "name": "user925", + "first": "First 925", + "last": "Last 925" + }, + { + "name": "user926", + "first": "First 926", + "last": "Last 926" + }, + { + "name": "user927", + "first": "First 927", + "last": "Last 927" + }, + { + "name": "user928", + "first": "First 928", + "last": "Last 928" + }, + { + "name": "user929", + "first": "First 929", + "last": "Last 929" + }, + { + "name": "user930", + "first": "First 930", + "last": "Last 930" + }, + { + "name": "user931", + "first": "First 931", + "last": "Last 931" + }, + { + "name": "user932", + "first": "First 932", + "last": "Last 932" + }, + { + "name": "user933", + "first": "First 933", + "last": "Last 933" + }, + { + "name": "user934", + "first": "First 934", + "last": "Last 934" + }, + { + "name": "user935", + "first": "First 935", + "last": "Last 935" + }, + { + "name": "user936", + "first": "First 936", + "last": "Last 936" + }, + { + "name": "user937", + "first": "First 937", + "last": "Last 937" + }, + { + "name": "user938", + "first": "First 938", + "last": "Last 938" + }, + { + "name": "user939", + "first": "First 939", + "last": "Last 939" + }, + { + "name": "user940", + "first": "First 940", + "last": "Last 940" + }, + { + "name": "user941", + "first": "First 941", + "last": "Last 941" + }, + { + "name": "user942", + "first": "First 942", + "last": "Last 942" + }, + { + "name": "user943", + "first": "First 943", + "last": "Last 943" + }, + { + "name": "user944", + "first": "First 944", + "last": "Last 944" + }, + { + "name": "user945", + "first": "First 945", + "last": "Last 945" + }, + { + "name": "user946", + "first": "First 946", + "last": "Last 946" + }, + { + "name": "user947", + "first": "First 947", + "last": "Last 947" + }, + { + "name": "user948", + "first": "First 948", + "last": "Last 948" + }, + { + "name": "user949", + "first": "First 949", + "last": "Last 949" + }, + { + "name": "user950", + "first": "First 950", + "last": "Last 950" + }, + { + "name": "user951", + "first": "First 951", + "last": "Last 951" + }, + { + "name": "user952", + "first": "First 952", + "last": "Last 952" + }, + { + "name": "user953", + "first": "First 953", + "last": "Last 953" + }, + { + "name": "user954", + "first": "First 954", + "last": "Last 954" + }, + { + "name": "user955", + "first": "First 955", + "last": "Last 955" + }, + { + "name": "user956", + "first": "First 956", + "last": "Last 956" + }, + { + "name": "user957", + "first": "First 957", + "last": "Last 957" + }, + { + "name": "user958", + "first": "First 958", + "last": "Last 958" + }, + { + "name": "user959", + "first": "First 959", + "last": "Last 959" + }, + { + "name": "user960", + "first": "First 960", + "last": "Last 960" + }, + { + "name": "user961", + "first": "First 961", + "last": "Last 961" + }, + { + "name": "user962", + "first": "First 962", + "last": "Last 962" + }, + { + "name": "user963", + "first": "First 963", + "last": "Last 963" + }, + { + "name": "user964", + "first": "First 964", + "last": "Last 964" + }, + { + "name": "user965", + "first": "First 965", + "last": "Last 965" + }, + { + "name": "user966", + "first": "First 966", + "last": "Last 966" + }, + { + "name": "user967", + "first": "First 967", + "last": "Last 967" + }, + { + "name": "user968", + "first": "First 968", + "last": "Last 968" + }, + { + "name": "user969", + "first": "First 969", + "last": "Last 969" + }, + { + "name": "user970", + "first": "First 970", + "last": "Last 970" + }, + { + "name": "user971", + "first": "First 971", + "last": "Last 971" + }, + { + "name": "user972", + "first": "First 972", + "last": "Last 972" + }, + { + "name": "user973", + "first": "First 973", + "last": "Last 973" + }, + { + "name": "user974", + "first": "First 974", + "last": "Last 974" + }, + { + "name": "user975", + "first": "First 975", + "last": "Last 975" + }, + { + "name": "user976", + "first": "First 976", + "last": "Last 976" + }, + { + "name": "user977", + "first": "First 977", + "last": "Last 977" + }, + { + "name": "user978", + "first": "First 978", + "last": "Last 978" + }, + { + "name": "user979", + "first": "First 979", + "last": "Last 979" + }, + { + "name": "user980", + "first": "First 980", + "last": "Last 980" + }, + { + "name": "user981", + "first": "First 981", + "last": "Last 981" + }, + { + "name": "user982", + "first": "First 982", + "last": "Last 982" + }, + { + "name": "user983", + "first": "First 983", + "last": "Last 983" + }, + { + "name": "user984", + "first": "First 984", + "last": "Last 984" + }, + { + "name": "user985", + "first": "First 985", + "last": "Last 985" + }, + { + "name": "user986", + "first": "First 986", + "last": "Last 986" + }, + { + "name": "user987", + "first": "First 987", + "last": "Last 987" + }, + { + "name": "user988", + "first": "First 988", + "last": "Last 988" + }, + { + "name": "user989", + "first": "First 989", + "last": "Last 989" + }, + { + "name": "user990", + "first": "First 990", + "last": "Last 990" + }, + { + "name": "user991", + "first": "First 991", + "last": "Last 991" + }, + { + "name": "user992", + "first": "First 992", + "last": "Last 992" + }, + { + "name": "user993", + "first": "First 993", + "last": "Last 993" + }, + { + "name": "user994", + "first": "First 994", + "last": "Last 994" + }, + { + "name": "user995", + "first": "First 995", + "last": "Last 995" + }, + { + "name": "user996", + "first": "First 996", + "last": "Last 996" + }, + { + "name": "user997", + "first": "First 997", + "last": "Last 997" + }, + { + "name": "user998", + "first": "First 998", + "last": "Last 998" + }, + { + "name": "user999", + "first": "First 999", + "last": "Last 999" + }, + { + "name": "user1000", + "first": "First 1000", + "last": "Last 1000" + } + ] +} diff --git a/tests/user/users_present.sh b/tests/user/users_present.sh new file mode 100644 index 00000000..c23f8d1f --- /dev/null +++ b/tests/user/users_present.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +NUM=1000 +FILE="users_present.json" + +echo "{" > $FILE + +echo " \"users\": [" >> $FILE + +for i in $(seq 1 $NUM); do + echo " {" >> $FILE + echo " \"name\": \"user$i\"," >> $FILE + echo " \"first\": \"First $i\"," >> $FILE + echo " \"last\": \"Last $i\"" >> $FILE + if [ $i -lt $NUM ]; then + echo " }," >> $FILE + else + echo " }" >> $FILE + fi +done + +echo " ]" >> $FILE + +echo "}" >> $FILE -- GitLab