def test_update_user(self): """ L{UserChanges.create_diff} should report users modified externally with C{usermod} or similar tools. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] provider = FakeUserProvider(users=users) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() users[0] = ("jdoe", "x", 1000, 1001, "John Doe,Here,789WORK,321HOME", "/home/john", "/bin/zsh") self.assertEqual( changes.create_diff(), { "update-users": [{ "username": "******", "home-phone": u"321HOME", "name": u"John Doe", "enabled": True, "location": "Here", "work-phone": "789WORK", "uid": 1000, "primary-gid": 1001 }] })
def test_add_user(self): """ L{UserChanges.create_diff} should report new users created externally with C{adduser} or similar tools. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] provider = FakeUserProvider(users=users) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() users.append(("bo", "x", 1001, 1001, "Bo,,,,", "/home/bo", "/bin/sh")) self.assertEqual( changes.create_diff(), { "create-users": [{ "username": "******", "home-phone": None, "name": u"Bo", "enabled": True, "location": None, "work-phone": None, "uid": 1001, "primary-gid": 1001 }] })
def test_create_diff_without_changes(self): """ L{UserChanges.create_diff} should return an empty C{dict} if users and groups are unchanged since the last snapshot. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] provider = FakeUserProvider(users=users) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() self.assertEqual(changes.create_diff(), {})
def test_delete_group(self): """ L{UserChanges.create_diff} should report groups removed externally with C{delgroup} or similar tools. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] groups = [("webdev", "x", 50, ["jdoe"]), ("sales", "x", 60, [])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() groups.pop() self.assertEqual(changes.create_diff(), {"delete-groups": ["sales"]})
def test_delete_user(self): """ L{UserChanges.create_diff} should report users removed externally with C{deluser} or similar tools. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh"), ("bo", "x", 1001, 1001, "Bo,,,,", "/home/bo", "/bin/sh")] provider = FakeUserProvider(users=users) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() users.pop() self.assertEqual(changes.create_diff(), {"delete-users": ["bo"]})
def test_clear(self): """ L{UserChanges.clear} removes a snapshot, if present, returning the object to a pristine state. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] groups = [("webdev", "x", 1000, ["jdoe"])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) self.assertTrue(changes.create_diff()) changes.snapshot() self.assertFalse(changes.create_diff()) changes.clear() self.assertTrue(changes.create_diff())
def test_snapshot(self): """ When a snapshot is taken it should persist beyond instance invocations and be used as the baseline in L{UserChanges.create_diff} until another snapshot is taken. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] groups = [("webdev", "x", 1000, ["jdoe"])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes1 = UserChanges(self.persist, provider) self.assertTrue(changes1.create_diff()) changes1.snapshot() changes2 = UserChanges(self.persist, provider) self.assertFalse(changes2.create_diff())
def test_no_existing_snapshot(self): """ The diff created by L{UserChanges.create_diff} contains data for all users and groups if an existing snapshot isn't available. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] groups = [("webdev", "x", 1000, ["jdoe"])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) self.assertEqual( changes.create_diff(), { "create-users": [{ "username": "******", "home-phone": None, "name": u"JD", "enabled": True, "location": None, "work-phone": None, "uid": 1000, "primary-gid": 1000 }], "create-groups": [{ "gid": 1000, "name": "webdev" }], "create-group-members": { "webdev": ["jdoe"] } })
def test_delete_group_members(self): """ L{UserChanges.create_diff} should report members removed from groups externally with C{gpasswd} or similar tools. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] groups = [("webdev", "x", 50, ["jdoe"])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() groups[0] = ("webdev", "x", 50, []) self.assertEqual(changes.create_diff(), {"delete-group-members": { "webdev": ["jdoe"] }})
def test_update_group(self): """ L{UserChanges.create_diff} should report groups modified externally with C{groupmod} or similar tools. """ groups = [("webdev", "x", 1000, [])] provider = FakeUserProvider(groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() groups[0] = ("webdev", "x", 1001, []) self.assertEqual(changes.create_diff(), {"update-groups": [{ "gid": 1001, "name": "webdev" }]})
def test_add_group(self): """ L{UserChanges.create_diff} should report new groups created externally with C{addgroup} or similar tools. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] groups = [("webdev", "x", 50, ["jdoe"])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() groups.append(("bizdev", "x", 60, [])) self.assertEqual(changes.create_diff(), {"create-groups": [{ "gid": 60, "name": "bizdev" }]})
def _detect_changes(self, locked_users, operation_id=None, UserChanges=UserChanges): def update_snapshot(result): changes.snapshot() return result def log_error(result): log_failure( result, "Error occured calling send_message in " "_detect_changes") self._provider.locked_users = locked_users changes = UserChanges(self._persist, self._provider) # Part of bug 1048576 remediation: If the flag file exists, we need to # do a full update of user data. full_refresh = os.path.exists(self.user_update_flag_file_path) if full_refresh: # Clear the record of what changes have been sent to the server in # order to force sending of all user data which will do one of two # things server side: either the server has no user data at all, # in which case it will now have a complete copy, otherwise it # will have at least some user data which this message will # duplicate, provoking the server to note the inconsistency and # request a full resync of the user data. Either way, the result # is the same: the client and server will be in sync with regard # to users. changes.clear() message = changes.create_diff() if message: message["type"] = "users" if operation_id: message["operation-id"] = operation_id result = self.registry.broker.send_message(message, self._session_id, urgent=True) result.addCallback(update_snapshot) # Part of bug 1048576 remediation: if full_refresh: # If we are doing a full refresh, we want to remove the flag # file that triggered the refresh if it completes successfully. result.addCallback(lambda _: self._remove_update_flag_file()) result.addErrback(log_error) return result
def test_snapshot_before_diff(self): """ A valid snapshot should be created if L{UserChanges.snapshot} is called before L{UserChanges.create_diff}. When L{UserChanges.create_diff} is called it shouln't report any changes. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] groups = [("webdev", "x", 1000, ["jdoe"])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.snapshot() self.assertFalse(changes.create_diff())
def test_complex_changes(self): """ L{UserChanges.create_diff} should be able to report multiple kinds of changes at the same time. """ users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh"), ("bo", "x", 1001, 1001, "Bo,,,,", "/home/bo", "/bin/sh")] groups = [("webdev", "x", 50, ["jdoe"]), ("bizdev", "x", 60, ["bo"])] provider = FakeUserProvider(users=users, groups=groups) FakeUserInfo(provider=provider) changes = UserChanges(self.persist, provider) changes.create_diff() changes.snapshot() # We remove the group "webdev", and create a new group # "developers", adding the user "bo" at the same time. groups[0] = ("developers", "x", 50, ["bo"]) # Add a new group "sales" and a new group member, "bo" groups.append(("sales", "x", 70, ["bo"])) # Remove user "jdoe" users.pop(0) self.assertCountEqual( changes.create_diff(), { "create-groups": [{ "gid": 50, "name": "developers" }, { "gid": 70, "name": "sales" }], "delete-users": ["jdoe"], "delete-groups": ["webdev"], "create-group-members": { "developers": ["bo"], "sales": ["bo"] } })