--- /dev/null
+import importlib
+
+class Policy:
+ def get_default_value(self, value):
+ pass
+
+ def is_policy_applied(self, user, value):
+ pass
+
+ def apply_policy(self, user, value):
+ pass
+
+class Plugin:
+ def __init__(self, attribute, module_name, class_name):
+ self.attribute = attribute
+ module = importlib.import_module(module_name)
+ class_object = getattr(module, class_name)
+
+ if Policy not in class_object.__bases__:
+ raise NotImplementedError("Plugin needs to implement 'Policy'")
+
+ self.policy = class_object
+
+ def sync_user(self, user, value):
+ if not self.policy.is_policy_applied(user, value):
+ self.policy.apply_policy(user, value)
+
+ def default_value(self):
+ return self.policy.get_default_value()
--- /dev/null
+import toml
+from pathlib import Path
+
+class Store:
+ def __init__(self, path):
+ self.path = path
+ if not Path(path).is_file():
+ with open(path, "w") as fp:
+ pass
+
+ def add_user(self, user):
+ store = toml.load(self.path)
+ if user not in store:
+ store[user] = {}
+ with open(self.path, "a+") as store_file:
+ toml.dump(store, store_file)
+
+ def get_attribute(self, user, attribute):
+ store = toml.load(self.path)
+ return store.get(user, {}).get(attribute, None)
+
+ def set_attribute(self, user, attribute, value):
+ store = toml.load(self.path)
+ if user in store and attribute in store.get(user):
+ store[user][attribute] = value
+ with open(self.path, "a+") as store_file:
+ toml.dump(store, store_file)
+
+ def get_users(self):
+ return toml.load(self.path).keys
--- /dev/null
+import toml
+from fire import Fire
+
+from plugins import Plugin
+from user_store import Store
+
+CONFIG = toml.load("userd.conf")
+PLUGINS = CONFIG.get("plugins", [])
+
+ATTRIBUTE_POLICIES = {}
+for plugin in PLUGINS:
+ policy = Plugin(**plugin)
+ ATTRIBUTE_POLICIES[policy.attribute] = policy
+
+USER_STORE = Store(CONFIG.get("user_store",{}).get("path", "users.conf"))
+
+def add_user(user):
+ USER_STORE.add_user(user)
+ for attribute, policy in ATTRIBUTE_POLICIES.items():
+ USER_STORE.set_attribute(user, attribute, policy.default_value())
+
+def sync_users(attributes=None):
+ if not attributes:
+ attributes = ATTRIBUTE_POLICIES.keys
+
+ for attribute in attribute:
+ for user in USER_STORE.get_users():
+ ATTRIBUTE_POLICIES[attribute].sync_users(
+ user,
+ USER_STORE.get_attribute(user, attribute)
+ )
+
+if __name__ == '__main__':
+ Fire(
+ {
+ "add": add_user,
+ "sync": sync_users
+ }
+ )