from flask_login import UserMixin from typing import Any, Optional from accounts.utils.login import create_userid class Service(object): id: str name: str url: str def __init__(self, service_id: str, name: str, url: str) -> None: self.id = service_id self.name = name self.url = url #: Wether the user has a separate password for this service. self.changed = False def __repr__(self): return '' % self.id class Account(UserMixin): """ An Account represents a complex ldap tree entry for spline users. For each service a spline user can have a different password. """ _ready = False uid: str services: list[str] password: Optional[str] new_password_services: dict[str, tuple[Optional[str], Optional[str]]] attributes: dict[Any, Any] new_password_root: Optional[tuple[Optional[str], Optional[str]]] def __init__(self, uid: str, mail: str, services=None, password: Optional[str] = None, uidNumber=None): self.uid = uid self.services = list() if services is None else services self.password = password self.new_password_root = None self.new_password_services = {} self.attributes = {} self.uidNumber = uidNumber self._set_attribute('mail', mail) self._ready = True def __repr__(self): return "" % self.uid def reset_password(self, service: str): self.new_password_services[service] = (None, None) def change_password(self, new_password: str, old_password='', service=None): """ Changes a password for a given service. You have to use the UserBackend to make the changes permanent. If no service is given, the root password will be changed. """ if not service: self.new_password_root = (old_password, new_password) else: self.new_password_services[service] = (old_password, new_password) def _set_attribute(self, key: str, value: Any) -> None: self.attributes[key] = value def change_email(self, new_mail: str) -> None: """ Changes the mail address of an account. You have to use the AccountService class to make changes permanent. """ self._set_attribute('mail', new_mail) def __getattr__(self, name): if name in self.attributes: return self.attributes[name] raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name)) def __setattr__(self, name: str, value: Any): if self._ready and name not in self.__dict__: self._set_attribute(name, value) else: super(Account, self).__setattr__(name, value) def get_id(self): """ This is for flask-login. The returned string is saved inside the cookie and used to identify the user. """ return create_userid(self.uid, self.password)