| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- from .user import user
- from .user import user_builder
- from .user_loader import user_loader
- from .application_part import application_part
- from .validators import nick_validator
- from .validators import password_validator
- class application_user(application_part):
- """
- This class is part of the app, which is responsible for user api
- endpoints, like registering users, login to app, change nick and
- others. To full responses and parameters documentation, see api
- documentation.
- """
- def get(self, apikey: str) -> dict:
- """
- This return information about user, like nick or code_key, to use
- in end-to-end encryption.
- Parameters:
- apikey (str): Apikey of the user
- Returns:
- (dict): Information about user
- """
- with self.__loader as loader:
- user = loader.get_by_apikey(apikey)
- if user is None:
- return self._fail_no_apikey()
- return self._success_response(
- nick = user.nick,
- password = user.password,
- apikey = user.apikey,
- code_key = user.code_key
- )
- def register(self, nick: str, password: str) -> dict:
- """
- This register new user, by password and nick. It check that nick is
- not in use, also validate password and nick. ApiKey and code_key
- would be generate by operating system random generator.
- Parameters:
- nick (str): Nick of the new user
- password (str): Password of the new user
- Returns:
- (dict): Response to generate json
- """
- validate = self._validation(
- "nick",
- nick_validator(nick)
- )
- validate = validate or self._validation(
- "password",
- password_validator(password)
- )
- if validate is not None:
- return validate
- builder = user_builder()
- builder.nick = nick
- builder.set_password(password)
- with self.__loader as loader:
- new_user = builder.result
- if loader.nick_in_use(new_user.nick):
- return self._fail_response(cause = "Nick already in use.")
- if loader.register(new_user):
- return self._apikey_response(new_user.apikey)
- return self._fail_response(cause = "Other database error.")
- def login(self, nick: str, password: str) -> dict:
- """
- This function login user. To operate client apps require apikey. This
- endpoint would return apikey, when valid nick and password had been
- provided.
- Parameters:
- nick (str): Nick of the user
- password (str): Passworrd of the user
- Returns:
- (dict): Result with apikey or error on fail
- """
- with self.__loader as loader:
- user = loader.login(nick, password)
- if user is None:
- return self._fail_response(cause = "Bad login or password.")
- return self._apikey_response(user.apikey)
- def unregister(self, apikey: str, password: str) -> dict:
- """
- This function drop user from database. It require password as second
- validation, and of course apikey to identify user.
- Parameters:
- apikey (str): ApiKey of the user to drop
- password (str): Password of the user to drop
- Returns:
- (dict): Result of the operation as to generate json response
- """
- with self.__loader as loader:
- user = loader.get_by_apikey(apikey)
- if user is None:
- return self._fail_no_apikey()
- if not user_builder(user).check_password(password):
- return self._fail_bad_password()
- loader.unregister(user)
- return self._success_response()
- def apikey_refresh(self, apikey: str) -> dict:
- """
- This function refresh apikey. It is useable when want to logout all
- devices which store apikey to stay logged in.
- Parameters:
- apikey (str): ApiKey of the user to refresh apikey
- Returns:
- (dict): Result of the operation, with new apikey when success
- """
- with self.__loader as loader:
- user = loader.get_by_apikey(apikey)
- if user is None:
- return self._fail_no_apikey()
- builder = user_builder(user)
- builder.refresh_apikey()
- new_user = builder.result
- if not loader.save(new_user):
- return self._fail_response(cause = "Database error.")
- return self._apikey_response(new_user.apikey)
- def change_password(
- self,
- apikey: str,
- old_password: str,
- new_password: str
- ) -> dict:
- """
- This function change password of the user. It require also old
- password, to decrypt key, which would be re-encrypt by new password.
- Of course new password would be validated before set.
- Parameters:
- apikey (str): ApiKey of the user to work on
- old_password (str): Old password of the user
- new_password (str): New password which would be set
- Returns:
- (dict): Result of the operation to create response
- """
- validate = self._validation(
- "password",
- password_validator(new_password)
- )
- if validate is not None:
- return validate
- with self.__loader as loader:
- user = loader.get_by_apikey(apikey)
- if user is None:
- return self._fail_no_apikey()
- builder = user_builder(user)
- if not builder.set_password(new_password, old_password):
- return self._fail_bad_password()
- new_user = builder.result
- loader.save(new_user)
- return self._apikey_response(new_user.apikey)
- def change_nick(self, apikey: str, nick: str) -> dict:
- """
- This function would change nick of the user. It also check that nick
- is not in use, and validate that nick is not bad formated.
- Parameters:
- apikey (str): ApiKey of the user to work on
- nick (str): New nick for the user
- Returns:
- (dict): Result of the operation to create response
- """
- validation = self._validation(
- "nick",
- nick_validator(nick)
- )
- if validation is not None:
- return validation
- with self.__loader as loader:
- user = loader.get_by_apikey(apikey)
- if user is None:
- return self._fail_no_apikey()
- if loader.nick_in_use(nick):
- return self._fail_response(cause = "Nick already in use.")
- builder = user_builder(user)
- builder.nick = nick
- new_user = builder.result
- if not loader.save(new_user):
- return self._fail_response(cause = "Other database error.")
- return self._success_response()
- @property
- def __loader(self) -> user_loader:
- """ This return new user_loader with database connector. """
- return user_loader(self._connector)
|