"""Generic backend User and Group, to be implemented by all backends.""" # vim: foldmethod=indent : tw=100 # pylint: disable=invalid-name, superfluous-parens # pylint: disable=logging-fstring-interpolation, logging-not-lazy, logging-format-interpolation # pylint: disable=raise-missing-from, missing-docstring, too-few-public-methods from abc import ABC, abstractmethod from ldf_adapter.backend.hooks import Hooks class User(ABC, Hooks): """Manages the user object on the service.""" def __init__(self, userinfo, **hooks): """ Arguments: userinfo -- (type: UserInfo) """ super().__init__(**hooks) @abstractmethod def exists(self): """Return whether the user exists on the service. If this returns True, calling `create` should have no effect or raise an error. """ return bool() @abstractmethod def name_taken(self, name): """Return whether a given username is already taken by another user on the service. Should return True if the name is not available for this user (even if it is available for other users for some reason) """ return bool() @abstractmethod def create(self): """Create the user on the service. If the user already exists, do nothing or raise an error """ pass @abstractmethod def create_tostring(self): """String representation of commands needed to deploy a new user. Returns: str: backend specific string containing user creation command(s) """ pass # def create_fromstring(self, create_cmd: str): # """Create a new user from string representation of commands needed to deploy a new user. # Optional, only needed if the backend supports it. # # Arguments: # create_cmd str: backend specific string containing user creation command(s) # """ # pass @abstractmethod def update(self): """Update all relevant information about the user on the service. If the user doesn't exists, behaviour is undefined. """ pass @abstractmethod def delete(self): """Delete the user on the service. If the user doesn't exists, do nothing or raise an error. """ pass @abstractmethod def mod(self, supplementary_groups=None): """Modify the user on the service. After this operation, the user will only be part of the provided groups. If the user doesn't exists, behaviour is undefined. Arguments: supplementary_groups -- A list of groups the user must be part of (type: list(Group)) Returns: two lists of groups: the groups the user was added to and the groups the user was removed from """ pass @abstractmethod def mod_tostring(self, supplementary_groups=None): """String representation of commands needed to modify a user to be added and removed from given groups. Arguments: supplementary_groups (list[Group], optional): the list of groups the user must be part of. Defaults to None. Returns: str: backend specific string containing all user modifications """ pass # def mod_fromstring(self, mod_cmd: str): # """Modify a user using string representation of commands needed to add & remove user to groups. # Optional, only needed if the backend supports it. # # Arguments: # mod_cmd str: backend specific string containing all user modification command(s) # """ # pass @abstractmethod def get_groups(self): """Get a list of names of all service groups that the user belongs to. If the user doesn't exist, behaviour is undefined. """ pass @abstractmethod def install_ssh_keys(self): """Install users SSH keys on the service. No other SSH keys should be active after calling this function. If the user doesn't exists, behaviour is undefined. """ pass @abstractmethod def uninstall_ssh_keys(self): """Uninstall the users SSH keys on the service. This must uninstall all SSH keys installed with `install_ssh_keys`. It may uninstall SSH keys installed by other means. If the user doesn't exists, behaviour is undefined. """ pass @abstractmethod def get_username(self): """Return local username on the service. If the user doesn't exists, behaviour is undefined. """ pass @abstractmethod def set_username(self, username): """Set local username on the service.""" pass @abstractmethod def get_primary_group(self): """Check if a user exists based on unique_id and return the primary group name.""" pass def is_suspended(self): """Optional, only if the backend supports it. Return whether the user was suspended (e.g. due to a security incident)""" return False def is_limited(self): """Optional, only if the backend supports it. Return whether the user has limited access""" return False def suspend(self): """Optional, only if the backend supports it. Suspends the user such that no access to the service is possible""" pass def resume(self): """Optional, only if the backend supports it. Restores the suspended user""" pass def limit(self): """Optional, only if the backend supports it. Limits the user's capabilities on the service (e.g. read-only access)""" pass def unlimit(self): """Optional, only if the backend supports it. Restores a user with limited access to full capabilities""" pass class Group(ABC): """Manages the group object on the service.""" def __init__(self, name): """ Arguments: name -- The name of the group """ pass @abstractmethod def exists(self): """Return whether the group already exists.""" pass @abstractmethod def create(self): """Create the group on the service. If the group already exists, behaviour is undefined. """ pass