created user flow for gohain assignment
This commit is contained in:
parent
fb8a7d5b69
commit
7900493ec5
16
goodchain/readme.md
Normal file
16
goodchain/readme.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# GOODCHAIN
|
||||||
|
This is the final assesment of the blockchain minor of period 1. [EXPLANATION FILE](https://hrnl-my.sharepoint.com/:w:/g/personal/bashb_hr_nl/Ed7VWyB5vbtPmCgeKl1g_S4BbkmE7CPrS1sigEfSAOdmDw?e=0fDOJQ)
|
||||||
|
|
||||||
|
# INSTALL
|
||||||
|
1: Install all the packages
|
||||||
|
```
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
- [ ] 1 Create a gui
|
||||||
|
- [ ] 2 Transfer coins
|
||||||
|
- [ ] 3 Mine new blocks
|
||||||
|
- [ ] 4 explore the blockchain
|
||||||
|
|
||||||
|
|
0
goodchain/requirements.txt
Normal file
0
goodchain/requirements.txt
Normal file
34
goodchain/src/classes/Signature.py
Normal file
34
goodchain/src/classes/Signature.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from cryptography.exceptions import *
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import padding
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
|
||||||
|
class Signature:
|
||||||
|
def generate_keys():
|
||||||
|
private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048)
|
||||||
|
public_key = private_key.public_key()
|
||||||
|
|
||||||
|
return private_key, public_key
|
||||||
|
|
||||||
|
def keys_to_bytes(private_key, public_key):
|
||||||
|
prv_ser = private_key.private_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||||
|
encryption_algorithm=serialization.NoEncryption())
|
||||||
|
|
||||||
|
pbc_ser = public_key.public_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PublicFormat.SubjectPublicKeyInfo)
|
||||||
|
|
||||||
|
return prv_ser, pbc_ser
|
||||||
|
|
||||||
|
def bytes_to_keys(private_ser, public_ser):
|
||||||
|
private_key = serialization.load_pem_private_key(
|
||||||
|
private_ser,
|
||||||
|
password=None
|
||||||
|
)
|
||||||
|
public_key = serialization.load_pem_public_key(
|
||||||
|
public_ser
|
||||||
|
)
|
||||||
|
return private_key, public_key
|
52
goodchain/src/classes/User.py
Normal file
52
goodchain/src/classes/User.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
from getpass import getpass
|
||||||
|
from classes.Signature import Signature
|
||||||
|
|
||||||
|
class User:
|
||||||
|
def __init__(self, db, private_key=None, public_key=None, username=None, password=None):
|
||||||
|
self.db = db
|
||||||
|
self.private_key = private_key
|
||||||
|
self.public_key = public_key
|
||||||
|
self.username = username
|
||||||
|
self.password = password
|
||||||
|
|
||||||
|
def login(self):
|
||||||
|
input_username = input("Username: ")
|
||||||
|
input_password = getpass("Password: ")
|
||||||
|
|
||||||
|
user = self.db.loginUser(input_username, input_password)
|
||||||
|
|
||||||
|
# check if user exists
|
||||||
|
if user:
|
||||||
|
private_key, public_key = Signature.bytes_to_keys(user['private_key'], user['public_key'])
|
||||||
|
self.private_key = private_key
|
||||||
|
self.public_key = public_key
|
||||||
|
self.username = user['username']
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def register(self):
|
||||||
|
input_username = input("Username: ")
|
||||||
|
input_password = getpass("Password: ")
|
||||||
|
|
||||||
|
# check if username is already taken
|
||||||
|
if self.db.fetchUserByUsername(input_username):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# create sig for user
|
||||||
|
private_key, public_key = Signature.generate_keys()
|
||||||
|
private_ser, public_ser = Signature.keys_to_bytes(private_key, public_key)
|
||||||
|
# register user
|
||||||
|
if self.db.createUser( private_ser, public_ser, input_username, input_password):
|
||||||
|
self.private_key = private_key
|
||||||
|
self.public_key = public_key
|
||||||
|
self.username = input_username
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def logout(self):
|
||||||
|
self.db.close()
|
||||||
|
self.private_key = None
|
||||||
|
self.public_key = None
|
||||||
|
self.username = None
|
||||||
|
self.password = None
|
||||||
|
return True
|
BIN
goodchain/src/goodchain.db
Normal file
BIN
goodchain/src/goodchain.db
Normal file
Binary file not shown.
93
goodchain/src/helpers/DatabaseHelper.py
Normal file
93
goodchain/src/helpers/DatabaseHelper.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import sqlite3
|
||||||
|
|
||||||
|
class DatabaseHelper:
|
||||||
|
def __init__(self, db=None):
|
||||||
|
print("Initializing database")
|
||||||
|
self.conn = None
|
||||||
|
self.cursor = None
|
||||||
|
|
||||||
|
if db:
|
||||||
|
self.open(db)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def open(self, db):
|
||||||
|
try:
|
||||||
|
self.conn = sqlite3.connect(db)
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
if self.conn:
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
def query(self, sql, values=None):
|
||||||
|
if values == None:
|
||||||
|
self.cursor.execute(sql)
|
||||||
|
self.commit()
|
||||||
|
else:
|
||||||
|
self.cursor.execute(sql, values)
|
||||||
|
self.commit()
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self.conn:
|
||||||
|
self.conn.commit()
|
||||||
|
self.conn.close()
|
||||||
|
self.cursor.close()
|
||||||
|
|
||||||
|
# Query functions
|
||||||
|
def loginUser(self, username, password):
|
||||||
|
if not self.conn:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
self.cursor.execute("SELECT * FROM `users` WHERE (`username` = ? AND `password` = ?)", (username, password,))
|
||||||
|
return self.cursor.fetchone()
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
print(error)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def createUser(self, private_key, public_key, username, password):
|
||||||
|
if not self.conn:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
self.cursor.execute("INSERT INTO `users` (private_key, public_key, username, password) VALUES (?, ?, ?, ?)", (private_key, public_key, username, password,))
|
||||||
|
self.commit()
|
||||||
|
return True
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
print(error)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def changePasswordUser(self, user_privatekey, password):
|
||||||
|
if not self.conn:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.cursor.execute("UPDATE `users` SET `password` = ? WHERE `private_key` = ?", (password, user_privatekey,))
|
||||||
|
self.commit()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
print(error)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def fetchUserByUsername(self, username):
|
||||||
|
if not self.conn:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.cursor.execute("SELECT * FROM `users` WHERE `username` = ?", (username,))
|
||||||
|
|
||||||
|
return self.cursor.fetchone()
|
||||||
|
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
print(error)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def checkMigrations(self):
|
||||||
|
self.query("CREATE TABLE IF NOT EXISTS `users` ( `private_key` BLOB NOT NULL , `public_key` BLOB NOT NULL , `username` VARCHAR(255) NOT NULL , `password` VARCHAR(255) NOT NULL )")
|
1
goodchain/src/helpers/LoggerHelper.py
Normal file
1
goodchain/src/helpers/LoggerHelper.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Not sure if we're planning to log anything tho
|
122
goodchain/src/helpers/MenuHelper.py
Normal file
122
goodchain/src/helpers/MenuHelper.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from classes.User import User
|
||||||
|
|
||||||
|
class bcolors:
|
||||||
|
HEADER = '\033[95m'
|
||||||
|
OKBLUE = '\033[94m'
|
||||||
|
OKCYAN = '\033[96m'
|
||||||
|
OKGREEN = '\033[92m'
|
||||||
|
WARNING = '\033[93m'
|
||||||
|
FAIL = '\033[91m'
|
||||||
|
ENDC = '\033[0m'
|
||||||
|
BOLD = '\033[1m'
|
||||||
|
UNDERLINE = '\033[4m'
|
||||||
|
|
||||||
|
class MenuHelper:
|
||||||
|
def __init__(self, db):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
self.start_menu = {}
|
||||||
|
self.user_menu = {}
|
||||||
|
|
||||||
|
self.start_menu[0] = "Exit"
|
||||||
|
self.start_menu[1] = "Explore the Blockchain"
|
||||||
|
self.start_menu[2] = "Login"
|
||||||
|
self.start_menu[3] = "Sign up"
|
||||||
|
|
||||||
|
self.user_menu[0] = "Log out"
|
||||||
|
self.user_menu[1] = "Explore the Blockchain"
|
||||||
|
self.user_menu[2] = "Transfer coins"
|
||||||
|
self.user_menu[3] = "Cancel transaction"
|
||||||
|
self.user_menu[4] = "Check balance"
|
||||||
|
self.user_menu[5] = "Check the pool"
|
||||||
|
self.user_menu[6] = "Mine a block"
|
||||||
|
|
||||||
|
self.opened_logs = False
|
||||||
|
|
||||||
|
def printMenu(self, items):
|
||||||
|
for key, value in items.items():
|
||||||
|
print(f'{key} -- {value}')
|
||||||
|
|
||||||
|
def runStartMenu(self):
|
||||||
|
while(True):
|
||||||
|
self.printMenu(self.start_menu)
|
||||||
|
# make input an interger
|
||||||
|
try:
|
||||||
|
choice = int(input())
|
||||||
|
except:
|
||||||
|
self.clearScreen()
|
||||||
|
print("Wrong input, try again")
|
||||||
|
continue
|
||||||
|
self.clearScreen()
|
||||||
|
|
||||||
|
# check if choice is in menu
|
||||||
|
match self.start_menu[choice]:
|
||||||
|
case "Exit":
|
||||||
|
print('Exiting system')
|
||||||
|
exit()
|
||||||
|
|
||||||
|
case "Explore the Blockchain":
|
||||||
|
pass
|
||||||
|
|
||||||
|
case "Login":
|
||||||
|
user = User(self.db)
|
||||||
|
logged_in = user.login()
|
||||||
|
self.clearScreen()
|
||||||
|
if logged_in:
|
||||||
|
print(f'Welcome {user.username}')
|
||||||
|
return user
|
||||||
|
print("Login failed")
|
||||||
|
|
||||||
|
case "Sign up":
|
||||||
|
new_user = User(self.db)
|
||||||
|
registered = new_user.register()
|
||||||
|
if registered:
|
||||||
|
print("Registration successful")
|
||||||
|
return new_user
|
||||||
|
print("Registration failed")
|
||||||
|
|
||||||
|
case _:
|
||||||
|
print("Wrong input, try again")
|
||||||
|
|
||||||
|
def runUserMenu(self, user):
|
||||||
|
while(True):
|
||||||
|
self.printMenu(self.user_menu)
|
||||||
|
# make input an interger
|
||||||
|
try:
|
||||||
|
choice = int(input())
|
||||||
|
except:
|
||||||
|
self.clearScreen()
|
||||||
|
print("Wrong input, try again")
|
||||||
|
continue
|
||||||
|
self.clearScreen()
|
||||||
|
|
||||||
|
# check if choice is in menu
|
||||||
|
match self.user_menu[choice]:
|
||||||
|
case "Log out":
|
||||||
|
user.logout()
|
||||||
|
|
||||||
|
case "Explore the Blockchain":
|
||||||
|
pass
|
||||||
|
|
||||||
|
case "Transfer coins":
|
||||||
|
pass
|
||||||
|
|
||||||
|
case "Cancel transaction":
|
||||||
|
pass
|
||||||
|
|
||||||
|
case "Check balance":
|
||||||
|
pass
|
||||||
|
|
||||||
|
case "Check the pool":
|
||||||
|
pass
|
||||||
|
|
||||||
|
case "Mine a block":
|
||||||
|
pass
|
||||||
|
|
||||||
|
case _:
|
||||||
|
print("Wrong input, try again")
|
||||||
|
|
||||||
|
def clearScreen(self):
|
||||||
|
os.system('cls' if os.name == 'nt' else 'clear')
|
25
goodchain/src/main.py
Normal file
25
goodchain/src/main.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
"""
|
||||||
|
----------------------v1.0.0----------------------
|
||||||
|
____ _ _ _
|
||||||
|
/ ___| ___ ___ __| | ___| |__ __ _(_)_ __
|
||||||
|
| | _ / _ \ / _ \ / _` |/ __| '_ \ / _` | | '_ \
|
||||||
|
| |_| | (_) | (_) | (_| | (__| | | | (_| | | | | |
|
||||||
|
\____|\___/ \___/ \__,_|\___|_| |_|\__,_|_|_| |_|
|
||||||
|
|
||||||
|
------------------Ryan & Teuntje------------------
|
||||||
|
"""
|
||||||
|
from helpers.DatabaseHelper import DatabaseHelper
|
||||||
|
from helpers.MenuHelper import MenuHelper
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# start db connection
|
||||||
|
db = DatabaseHelper("goodchain.db")
|
||||||
|
db.checkMigrations()
|
||||||
|
|
||||||
|
# start menu
|
||||||
|
menu = MenuHelper(db)
|
||||||
|
while(True):
|
||||||
|
user = menu.runStartMenu()
|
||||||
|
|
||||||
|
if user:
|
||||||
|
menu.runUserMenu(user)
|
Loading…
x
Reference in New Issue
Block a user