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.

144 lines
4.5KB

  1. from flask import Flask
  2. from flask import render_template, request
  3. import requests
  4. import json
  5. import redis
  6. import settings
  7. import binascii
  8. from bitstring import BitArray
  9. from hashlib import blake2b
  10. from nano25519 import ed25519_oop as ed25519
  11. r = redis.Redis(host='localhost', port=6379, db=0)
  12. app = Flask(__name__)
  13. def xrb_account(address):
  14. # Given a string containing an XRB address, confirm validity and
  15. # provide resulting hex address
  16. print(address)
  17. if len(address) == 65 and (address[:5] == 'nano_'):
  18. # each index = binary value, account_lookup[0] == '1'
  19. account_map = "13456789abcdefghijkmnopqrstuwxyz"
  20. account_lookup = {}
  21. # populate lookup index with prebuilt bitarrays ready to append
  22. for i in range(32):
  23. account_lookup[account_map[i]] = BitArray(uint=i ,length=5)
  24. # we want everything after 'xrb_' but before the 8-char checksum
  25. acrop_key = address[5:-8]
  26. # extract checksum
  27. acrop_check = address[-8:]
  28. # convert base-32 (5-bit) values to byte string by appending each
  29. # 5-bit value to the bitstring, essentially bitshifting << 5 and
  30. # then adding the 5-bit value.
  31. number_l = BitArray()
  32. for x in range(0, len(acrop_key)):
  33. number_l.append(account_lookup[acrop_key[x]])
  34. # reduce from 260 to 256 bit (upper 4 bits are never used as account
  35. # is a uint256)
  36. number_l = number_l[4:]
  37. check_l = BitArray()
  38. for x in range(0, len(acrop_check)):
  39. check_l.append(account_lookup[acrop_check[x]])
  40. # reverse byte order to match hashing format
  41. check_l.byteswap()
  42. result = number_l.hex.upper()
  43. # verify checksum
  44. h = blake2b(digest_size=5)
  45. h.update(number_l.bytes)
  46. if (h.hexdigest() == check_l.hex):
  47. return True
  48. else:
  49. print('error1')
  50. return False
  51. else:
  52. print('error2')
  53. return False
  54. def sortList(e):
  55. components = e.split(': ')
  56. return int(components[1])
  57. # https://techmonger.github.io/5/python-flask-recaptcha/
  58. def is_human(captcha_response):
  59. """ Validating recaptcha response from google server.
  60. Returns True captcha test passed for the submitted form
  61. else returns False.
  62. """
  63. secret = settings.secret_key
  64. payload = {'response':captcha_response, 'secret':secret}
  65. response = requests.post("https://www.google.com/recaptcha/api/siteverify", payload)
  66. response_text = json.loads(response.text)
  67. return response_text['success']
  68. @app.route('/')
  69. def home_page():
  70. player = r.get('player_count').decode('utf-8')
  71. if int(player) < 0:
  72. player = '0'
  73. top_score = r.keys('score*')
  74. print(top_score)
  75. score_list = list()
  76. for top_players in top_score:
  77. playerScore = r.get(top_players.decode('utf-8'))
  78. # print('{}: {}'.format(top_players.decode('utf-8')[6:], playerScore.decode('utf-8')))
  79. score_list.append('{}: {}'.format(top_players.decode('utf-8')[6:], playerScore.decode('utf-8')))
  80. score_list.sort(key=sortList, reverse=True)
  81. if len(score_list) < 5:
  82. length_list = len(score_list)
  83. else:
  84. length_list = 5
  85. site_key = settings.site_key
  86. return render_template('homepage.html', player=player, score_list=score_list[0:length_list], site_key=site_key)
  87. @app.route('/', methods=['POST'])
  88. def search_form():
  89. captcha_response = request.form['g-recaptcha-response']
  90. if is_human(captcha_response):
  91. # Process request here
  92. status = "Detail submitted successfully."
  93. pass
  94. else:
  95. # Log invalid attempts
  96. status = "Sorry ! Bots are not allowed."
  97. return status
  98. username = request.form['username'].lower()
  99. username.replace(' ', '_')
  100. if 'scores' in username:
  101. return 'Sorry you cannot use a username with scores in the string'
  102. nanoaddress = request.form['nanoaddress'].lower()
  103. player = r.get('player_count').decode('utf-8')
  104. if int(player) < 0:
  105. player = '0'
  106. if xrb_account(nanoaddress):
  107. if r.exists(username):
  108. return render_template('alreadyreg.html', username=username, player=player)
  109. else:
  110. r.set(username, nanoaddress)
  111. return render_template('result.html', username=username, nanoaddress=nanoaddress, player=player)
  112. elif not nanoaddress and r.exists(username):
  113. return render_template('alreadyreg.html', username=username, player=player)
  114. else:
  115. return 'Error - incorrect nano address'