useless crap not working
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fedibbs.py 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. """FediBBS
  2. Usage:
  3. fedibbs.py [--port=<port>]
  4. fedibbs.py (-h | --help)
  5. fedibbs.py --version
  6. Options:
  7. -h --help Show this screen
  8. --version Show version
  9. --port=<port> Set the listening port [default: 6023]
  10. """
  11. import asyncio
  12. import telnetlib3
  13. from mastodon import Mastodon
  14. from docopt import docopt
  15. import colored
  16. from sqlalchemy import create_engine, Column, Integer, String, DateTime
  17. from sqlalchemy.ext.declarative import declarative_base
  18. from sqlalchemy.orm import sessionmaker
  19. from passlib.hash import sha256_crypt
  20. Base = declarative_base()
  21. class User(Base):
  22. __tablename__ = 'users'
  23. id = Column(Integer, primary_key=True)
  24. username = Column(String, nullable=False)
  25. password = Column(String, nullable=False)
  26. engine = create_engine('sqlite:///fedibbs.db', echo=False)
  27. Base.metadata.create_all(engine)
  28. session = sessionmaker(bind=engine)
  29. async def ask(question, reader, writer) -> str:
  30. print(f"asking {question}")
  31. writer.write(question)
  32. response = await reader.readline()
  33. return str(response).strip()
  34. def _handle_new_user(reader, writer) -> str:
  35. username = ask("What is your username? ", reader, writer)
  36. user = session().query(User).filter(User.username==username).one()
  37. if user:
  38. writer.write("Username already used !\r\n")
  39. return _handle_new_user(reader, writer)
  40. password1 = None
  41. password2 = None
  42. while True:
  43. password1 = sha256_crypt.hash(ask("What is your password? ", reader, writer))
  44. password2 = sha256_crypt.hash(("Again? ", reader, writer))
  45. if sha256_crypt.verify(password1, password2):
  46. break
  47. writer.write("Passwords doesn't match.\r\n\r\n")
  48. user = User()
  49. user.username = username
  50. user.password = password2
  51. sess = session()
  52. sess.add(user)
  53. sess.commit()
  54. return username
  55. def _handle_login(reader, writer) -> str:
  56. username = ask("Username? ", reader, writer)
  57. password = ask("Password? ", reader, writer)
  58. password = sha256_crypt.hash(str(password))
  59. user = session().query(User).filter(User.username==username).one()
  60. if not user:
  61. writer.write("Wrong username or password.\r\n")
  62. return _handle_login(reader, writer)
  63. if sha256_crypt.verify(user.password, password):
  64. return True
  65. return False
  66. def _login_or_new_user(reader, writer) -> str:
  67. print("handle login or new user")
  68. new_user = ask("New user? [y/N] ", reader, writer)
  69. if new_user.lower() == 'y':
  70. # New user
  71. _handle_new_user(reader, writer)
  72. else:
  73. # Login
  74. _handle_login(reader, writer)
  75. return False
  76. def _handle_menu(reader, writer) -> None:
  77. # Clear terminal
  78. writer.write("\x1b[2J\x1b[H")
  79. # Display menu
  80. writer.write(f"{colored.stylize('**', colored.fg('red'))} Welcome to FediBBS ! {colored.stylize('**', colored.fg('red'))}\r\n\r\n")
  81. writer.write(f" {colored.stylize('1.', colored.fg('green'))} This help menu\r\n")
  82. writer.write(f" {colored.stylize('2.', colored.fg('green'))} Timeline\r\n")
  83. writer.write(f" {colored.stylize('3.', colored.fg('green'))} Post\r\n")
  84. writer.write(f" {colored.stylize('4.', colored.fg('green'))} Logout / Exit\r\n")
  85. def fedishell(reader, writer):
  86. print("shell called")
  87. writer.write(f"{colored.stylize('**', colored.fg('red'))} Welcome to FediBBS ! {colored.stylize('**', colored.fg('red'))}\r\n\r\n")
  88. username = None
  89. logged = False
  90. while True:
  91. logged = _login_or_new_user(reader, writer)
  92. if logged:
  93. break
  94. username = logged
  95. # User is logged, menu time
  96. while True:
  97. _handle_menu(reader, writer)
  98. print("shell exited")
  99. def oops(writer, e):
  100. print(f"ERROR: {e}")
  101. writer.write("!!! Server error !!!")
  102. writer.close()
  103. @asyncio.coroutine
  104. def cleanhandle(reader, writer):
  105. try:
  106. fedishell(reader, writer)
  107. except Exception as e:
  108. oops(writer, e)
  109. return
  110. if __name__ == '__main__':
  111. arguments = docopt(__doc__, version='FediBBS 0.1')
  112. try:
  113. loop = asyncio.get_event_loop()
  114. coro = telnetlib3.create_server(port=arguments['--port'], shell=cleanhandle)
  115. server = loop.run_until_complete(coro)
  116. print(f"Running FediBBS on port {arguments['--port']}")
  117. loop.run_until_complete(server.wait_closed())
  118. except OSError as e:
  119. print(f"Error: {e}")
  120. exit()
  121. except KeyboardInterrupt:
  122. print("Exiting.")
  123. exit()