core.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import typer
  2. import enum
  3. import pathlib
  4. import getpass
  5. import json
  6. from assets import *
  7. default_config = pathlib.Path("config.json")
  8. default_users_db = pathlib.Path("users.json")
  9. default_db = pathlib.Path("database.db")
  10. config_help = "This is configuration file of the app to use."
  11. users_db_help = "This is location of the users json database."
  12. db_help = "This is location of SQLite3 database file."
  13. description = "This is core reservationer package. It could be used to host "
  14. description = description + "app, or manage configuration or database."
  15. app = typer.Typer(help = description)
  16. class user_command(str, enum.Enum):
  17. """
  18. That commands could be used in the user subcommand.
  19. """
  20. add = "register"
  21. delete = "delete"
  22. password = "password-change"
  23. logout = "full-logout"
  24. def password_prompt() -> str:
  25. while True:
  26. first = getpass.getpass("Password: ")
  27. second = getpass.getpass("Repeat password: ")
  28. if first == second:
  29. return first
  30. print("Passwords do not match.")
  31. @app.command()
  32. def server(
  33. port: int = typer.Option(8080, help = "Port to listen on."),
  34. address: str = typer.Option("0.0.0.0", help = "Address to listen on."),
  35. config: pathlib.Path = typer.Option(default_config, help = config_help)
  36. ) -> None:
  37. """
  38. Start app on selected port and interfaces.
  39. """
  40. print(port)
  41. print(address)
  42. @app.command()
  43. def user(
  44. command: user_command = typer.Argument(help = "Command to run on users."),
  45. nick: str = typer.Argument(help = "Nick of the user to work on."),
  46. config: pathlib.Path = typer.Option(default_config, help = config_help)
  47. ) -> None:
  48. """
  49. Modify user database.
  50. """
  51. try:
  52. loader = config_loader(app_config).load(config)
  53. collection = loader.resources.users
  54. # User adding
  55. if command == user_command.add:
  56. # Check that user exists
  57. if collection.exists(nick):
  58. raise Exception("User with that nick already exists.")
  59. # Create new user
  60. creator = user_factory()
  61. creator.nick = nick
  62. creator.password = password_prompt()
  63. # Add it
  64. collection.add(creator.result)
  65. print("Adding \"" + nick + "\" to the database.")
  66. # User remove
  67. elif command == user_command.delete:
  68. # Load from database
  69. target = collection.get_by_nick(nick)
  70. # Check that user exists
  71. if target is None:
  72. raise Exception("User with given nick not exists.")
  73. # When exists remove it
  74. collection.remove(target)
  75. # Change user password
  76. elif command == user_command.password:
  77. # Load user by nick
  78. target = collection.get_by_nick(nick)
  79. # Check that user exists
  80. if target is None:
  81. raise Exception("User not exists, can not change password.")
  82. # Change password
  83. handler = user_factory(target)
  84. handler.password = password_prompt()
  85. modified = handler.result
  86. # Store it in collection
  87. collection.remove(target).add(modified)
  88. # Logout user from all devices
  89. elif command == user_command.logout:
  90. # Load user from database
  91. target = collection.get_by_nick(nick)
  92. # Check that exists
  93. if target is None:
  94. raise Exception("User not exists, can not logout.")
  95. # Refresh apikey
  96. modified = user_factory(target) \
  97. .refresh_apikey() \
  98. .result
  99. # Store result
  100. collection.remove(target).add(modified)
  101. # Save collection to file
  102. users_saver(collection) \
  103. .drop(loader.result.users_path) \
  104. .save()
  105. print("Users database saved success.")
  106. except validator_exception as error:
  107. print("Password is not correct, too easy to break.")
  108. except json.JSONDecodeError as error:
  109. print("User JSON has syntax exception.")
  110. print(str(error))
  111. except Exception as error:
  112. print("Can not done work.")
  113. print(str(error))
  114. @app.command()
  115. def initialize(
  116. config: pathlib.Path = typer.Option(default_config, help = config_help),
  117. users: pathlib.Path = typer.Option(default_users_db, help = users_db_help),
  118. database: pathlib.Path = typer.Option(default_db, help = db_help)
  119. ) -> None:
  120. """
  121. Initialize app configuration.
  122. """
  123. try:
  124. # Generating config file
  125. config_generator(app_config) \
  126. .modify("users_file", str(users)) \
  127. .modify("database_uri", "sqlite:///" + str(database)) \
  128. .save(config)
  129. # Generating new blank users database
  130. users_saver(users_collection()).save(users)
  131. print("Config file is being created.")
  132. except Exception as error:
  133. print("Config initialization failed.")
  134. print(str(error))
  135. if __name__ == "__main__":
  136. app()