From 361cd6cf1689286f239ad684d53c013f7468d042 Mon Sep 17 00:00:00 2001 From: internos Date: Sat, 10 Sep 2022 22:21:24 +0700 Subject: [PATCH 01/30] feat: instatiate db using sqlalch --- starklings-backend/starklings_backend/db.py | 13 ++++++ .../starklings_backend/instantiate_db.py | 6 +++ .../starklings_backend/models.py | 41 +++++++++++++++++++ .../starklings_backend/models/shared.py | 4 -- .../starklings_backend/models/user.py | 8 ---- .../starklings_backend/routes.py | 9 ++-- 6 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 starklings-backend/starklings_backend/db.py create mode 100644 starklings-backend/starklings_backend/instantiate_db.py create mode 100644 starklings-backend/starklings_backend/models.py delete mode 100644 starklings-backend/starklings_backend/models/shared.py delete mode 100644 starklings-backend/starklings_backend/models/user.py diff --git a/starklings-backend/starklings_backend/db.py b/starklings-backend/starklings_backend/db.py new file mode 100644 index 00000000..28db2270 --- /dev/null +++ b/starklings-backend/starklings_backend/db.py @@ -0,0 +1,13 @@ +import os +import pymysql +from sqlalchemy.orm import declarative_base, sessionmaker +from sqlalchemy import create_engine +from dotenv import load_dotenv +load_dotenv() + + +engine = create_engine('mysql+pymysql://root:dazzura1@localhost/wtf', echo=True) + +Base = declarative_base() + +Session = sessionmaker(bind=engine) \ No newline at end of file diff --git a/starklings-backend/starklings_backend/instantiate_db.py b/starklings-backend/starklings_backend/instantiate_db.py new file mode 100644 index 00000000..20946d15 --- /dev/null +++ b/starklings-backend/starklings_backend/instantiate_db.py @@ -0,0 +1,6 @@ +from db import Base,engine +from models import StarklingsUser,Path,Exercise,ValidatedExercise + +print("Creating database ....") + +Base.metadata.create_all(engine) \ No newline at end of file diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py new file mode 100644 index 00000000..3b8d1936 --- /dev/null +++ b/starklings-backend/starklings_backend/models.py @@ -0,0 +1,41 @@ +from sqlalchemy import create_engine, Column, Integer, String, ForeignKey +from sqlalchemy.orm import sessionmaker, relationship +from db import Base + + +class StarklingsUser(Base): + __tablename__ = "starklings_user" + wallet_address = Column(String(42), primary_key=True) + signature = Column(String(255), nullable=False) + github = Column(String(255), nullable=False) + username = Column(String(255), nullable=False) + score = Column(Integer, nullable=False, default=0) + starklings_user = relationship("ValidatedExercise") + + +class Path(Base): + __tablename__ = "path" + path_name = Column(String(255), primary_key=True) + num_exercises = Column(Integer, nullable=False) + path = relationship("Exercise") + + +class Exercise(Base): + __tablename__ = "exercise" + exercise_name = Column(String(255), primary_key=True) + score = Column(Integer, nullable=False, default=0) + path_name = Column(String(255), ForeignKey("path.path_name"), nullable=False) + exercise = relationship("ValidatedExercise") + + +class ValidatedExercise(Base): + __tablename__ = "validated_exercise" + validated_exercise_id = Column(String(64), primary_key=True) + exercise_name = Column( + String(255), + ForeignKey("exercise.exercise_name"), + nullable=False, + ) + wallet_address = Column( + String(42), ForeignKey("starklings_user.wallet_address"), nullable=False + ) \ No newline at end of file diff --git a/starklings-backend/starklings_backend/models/shared.py b/starklings-backend/starklings_backend/models/shared.py deleted file mode 100644 index 1770275b..00000000 --- a/starklings-backend/starklings_backend/models/shared.py +++ /dev/null @@ -1,4 +0,0 @@ -# apps.shared.models -from flask_sqlalchemy import SQLAlchemy - -db = SQLAlchemy() \ No newline at end of file diff --git a/starklings-backend/starklings_backend/models/user.py b/starklings-backend/starklings_backend/models/user.py deleted file mode 100644 index db5b1e9c..00000000 --- a/starklings-backend/starklings_backend/models/user.py +++ /dev/null @@ -1,8 +0,0 @@ -from starklings_backend.models.shared import db - -class Starklingsuser(db.Model): - user_id = db.Column(db.Integer, primary_key=True) - score = db.Column(db.Integer, nullable=False, default=0) - signature = db.Column(db.String(255), nullable=False) - username = db.Column(db.String(255), unique=True, nullable=False) - wallet_address = db.Column(db.String(255), unique=True, nullable=False) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index 768916ec..d59c30c1 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -4,14 +4,17 @@ from sqlalchemy.exc import IntegrityError from flask_sqlalchemy import SQLAlchemy from starklings_backend.utils import verify_email -from starklings_backend.models.shared import db +# from starklings_backend.models.shared import db from starklings_backend.models.user import Starklingsuser from starklings_backend.exercise import verify_exercise from checker import ExerciceFailed import tempfile +from starklings_backend.db import Session app_routes = Blueprint('app_routes', __name__) +db = Session() + @app_routes.route('/', methods=['GET']) def landing(): return 'Starklings API' @@ -34,11 +37,11 @@ def register_user(): #@TODO: Check Signature validity user = Starklingsuser(wallet_address=wallet_address, signature=signature, username=username) - db.session.commit() + session.commit() return f'Welcome! {username}', 200 except IntegrityError as e: - db.session.rollback() + session.rollback() return 'User Already Exists', 400 except AttributeError: return 'Provide an Email and Password in JSON format in the request body', 400 From 968e6ee7bd8fd25fc1639117543095a521d94e12 Mon Sep 17 00:00:00 2001 From: internos Date: Sat, 10 Sep 2022 22:51:34 +0700 Subject: [PATCH 02/30] refactor: use env variable --- starklings-backend/starklings_backend/db.py | 6 +++++- starklings-backend/starklings_backend/instantiate_db.py | 2 -- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/starklings-backend/starklings_backend/db.py b/starklings-backend/starklings_backend/db.py index 28db2270..0886ac71 100644 --- a/starklings-backend/starklings_backend/db.py +++ b/starklings-backend/starklings_backend/db.py @@ -5,8 +5,12 @@ from dotenv import load_dotenv load_dotenv() +host=os.environ.get('DATABASE_HOST', '') +database=os.environ.get('DATABASE_NAME', '') +user=os.environ.get('DATABASE_USER', '') +password=os.environ.get('DATABASE_PWD', '') -engine = create_engine('mysql+pymysql://root:dazzura1@localhost/wtf', echo=True) +engine = create_engine(f'mysql+pymysql://{user}:{password}@{host}/{database}', echo=True) Base = declarative_base() diff --git a/starklings-backend/starklings_backend/instantiate_db.py b/starklings-backend/starklings_backend/instantiate_db.py index 20946d15..368a9220 100644 --- a/starklings-backend/starklings_backend/instantiate_db.py +++ b/starklings-backend/starklings_backend/instantiate_db.py @@ -1,6 +1,4 @@ from db import Base,engine from models import StarklingsUser,Path,Exercise,ValidatedExercise -print("Creating database ....") - Base.metadata.create_all(engine) \ No newline at end of file From 2ab02aee98f5c292af5dc98118dc094ec3490799 Mon Sep 17 00:00:00 2001 From: internos Date: Sat, 10 Sep 2022 23:01:20 +0700 Subject: [PATCH 03/30] feat: remove unecessary file --- starklings-backend/starklings_backend/db.py | 6 +++--- starklings-backend/starklings_backend/instantiate_db.py | 4 ---- starklings-backend/starklings_backend/models.py | 8 +++++--- 3 files changed, 8 insertions(+), 10 deletions(-) delete mode 100644 starklings-backend/starklings_backend/instantiate_db.py diff --git a/starklings-backend/starklings_backend/db.py b/starklings-backend/starklings_backend/db.py index 0886ac71..62cad547 100644 --- a/starklings-backend/starklings_backend/db.py +++ b/starklings-backend/starklings_backend/db.py @@ -1,6 +1,7 @@ import os import pymysql from sqlalchemy.orm import declarative_base, sessionmaker +from models import StarklingsUser,Path,Exercise,ValidatedExercise, Base from sqlalchemy import create_engine from dotenv import load_dotenv load_dotenv() @@ -12,6 +13,5 @@ engine = create_engine(f'mysql+pymysql://{user}:{password}@{host}/{database}', echo=True) -Base = declarative_base() - -Session = sessionmaker(bind=engine) \ No newline at end of file +Session = sessionmaker(bind=engine) +Base.metadata.create_all(engine) \ No newline at end of file diff --git a/starklings-backend/starklings_backend/instantiate_db.py b/starklings-backend/starklings_backend/instantiate_db.py deleted file mode 100644 index 368a9220..00000000 --- a/starklings-backend/starklings_backend/instantiate_db.py +++ /dev/null @@ -1,4 +0,0 @@ -from db import Base,engine -from models import StarklingsUser,Path,Exercise,ValidatedExercise - -Base.metadata.create_all(engine) \ No newline at end of file diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py index 3b8d1936..e75d71ee 100644 --- a/starklings-backend/starklings_backend/models.py +++ b/starklings-backend/starklings_backend/models.py @@ -1,7 +1,8 @@ from sqlalchemy import create_engine, Column, Integer, String, ForeignKey -from sqlalchemy.orm import sessionmaker, relationship -from db import Base +from sqlalchemy.orm import sessionmaker, relationship, declarative_base +# from db import Base +Base = declarative_base() class StarklingsUser(Base): __tablename__ = "starklings_user" @@ -38,4 +39,5 @@ class ValidatedExercise(Base): ) wallet_address = Column( String(42), ForeignKey("starklings_user.wallet_address"), nullable=False - ) \ No newline at end of file + ) + From d468859c36b32f5430ef5491608acdb6ba6ad39b Mon Sep 17 00:00:00 2001 From: internos Date: Sat, 10 Sep 2022 23:18:38 +0700 Subject: [PATCH 04/30] feat(routes): change user model --- starklings-backend/starklings_backend/routes.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index d59c30c1..a383eb2d 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -4,8 +4,7 @@ from sqlalchemy.exc import IntegrityError from flask_sqlalchemy import SQLAlchemy from starklings_backend.utils import verify_email -# from starklings_backend.models.shared import db -from starklings_backend.models.user import Starklingsuser +from starklings_backend.models import StarklingsUser, Path, Exercise, ValidatedExercise, Base from starklings_backend.exercise import verify_exercise from checker import ExerciceFailed import tempfile @@ -36,7 +35,7 @@ def register_user(): return "Wrong form", 400 #@TODO: Check Signature validity - user = Starklingsuser(wallet_address=wallet_address, signature=signature, username=username) + user = StarklingsUser(wallet_address=wallet_address, signature=signature, username=username) session.commit() return f'Welcome! {username}', 200 @@ -57,7 +56,7 @@ def fetch_user_info(): wallet_address = request.json.get('wallet_address', None) if not wallet_address: return 'Missing address', 400 - user = Starklingsuser.query.filter_by(wallet_address=wallet_address).first() + user = StarklingsUser.query.filter_by(wallet_address=wallet_address).first() if not user: return 'User Not Found!', 404 From b682657138e56ff5a4b0ef2369ab61c9d6407158 Mon Sep 17 00:00:00 2001 From: internos Date: Sun, 11 Sep 2022 00:19:46 +0700 Subject: [PATCH 05/30] feat(user): add github field --- starklings-backend/starklings_backend/routes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index a383eb2d..e8fd4109 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -31,11 +31,12 @@ def register_user(): signature = request.json.get('signature', None) wallet_address = request.json.get('wallet_address', None) username = request.json.get('username', wallet_address) - if None in [wallet_address, signature]: + github = request.json.get('github', None) + if None in [wallet_address, signature, github]: return "Wrong form", 400 #@TODO: Check Signature validity - user = StarklingsUser(wallet_address=wallet_address, signature=signature, username=username) + user = StarklingsUser(wallet_address=wallet_address, signature=signature, username=username, github=github) session.commit() return f'Welcome! {username}', 200 From 7da1016a242554d2e979076dc27f0374d313cbfa Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 16 Sep 2022 01:58:46 +0700 Subject: [PATCH 06/30] feat: verify signature --- .../starklings_backend/routes.py | 20 +++++-- .../starklings_backend/utils.py | 58 +++++++++++++++---- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index e8fd4109..90f89454 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -3,12 +3,14 @@ import bcrypt from sqlalchemy.exc import IntegrityError from flask_sqlalchemy import SQLAlchemy -from starklings_backend.utils import verify_email +from starklings_backend.utils import verify_email, VerifySignature from starklings_backend.models import StarklingsUser, Path, Exercise, ValidatedExercise, Base from starklings_backend.exercise import verify_exercise from checker import ExerciceFailed import tempfile from starklings_backend.db import Session + + app_routes = Blueprint('app_routes', __name__) @@ -32,13 +34,19 @@ def register_user(): wallet_address = request.json.get('wallet_address', None) username = request.json.get('username', wallet_address) github = request.json.get('github', None) + message_hash = request.json.get('message_hash', '') + network = request.json.get('network', 'testnet') if None in [wallet_address, signature, github]: return "Wrong form", 400 - #@TODO: Check Signature validity - - user = StarklingsUser(wallet_address=wallet_address, signature=signature, username=username, github=github) - session.commit() - return f'Welcome! {username}', 200 + # verify signature + verify_signature = VerifySignature(abi, network, wallet_address) + is_valid, error = verify_signature.verify_signature(message_hash, signature) + if error is None: + user = StarklingsUser(wallet_address=wallet_address, signature=signature, github=github, username=username) + db.add(user) + db.commit() + return f'Welcome! {username}', 200 + return 'Signature invalid', 400 except IntegrityError as e: session.rollback() diff --git a/starklings-backend/starklings_backend/utils.py b/starklings-backend/starklings_backend/utils.py index 0ffa0266..75c6d223 100644 --- a/starklings-backend/starklings_backend/utils.py +++ b/starklings-backend/starklings_backend/utils.py @@ -2,15 +2,21 @@ import json import os import re +from starknet_py.net.gateway_client import GatewayClient +from starknet_py.net.networks import TESTNET, MAINNET +from starknet_py.contract import Contract +import asyncio -regex = re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+') + +regex = re.compile(r"([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+") def verify_email(email): if re.fullmatch(regex, email): - return True + return True else: - return False + return False + class Requester: def __init__(self, base_url, **kwargs): @@ -22,25 +28,25 @@ def __init__(self, base_url, **kwargs): setattr(self.session, arg, kwargs[arg]) def request(self, method, url, **kwargs): - return self.session.request(method, self.base_url+url, **kwargs) + return self.session.request(method, self.base_url + url, **kwargs) def head(self, url, **kwargs): - return self.session.head(self.base_url+url, **kwargs) + return self.session.head(self.base_url + url, **kwargs) def get(self, url, **kwargs): - return self.session.get(self.base_url+url, **kwargs) + return self.session.get(self.base_url + url, **kwargs) def post(self, url, data, **kwargs): - return self.session.post(self.base_url+url, data=data, **kwargs) + return self.session.post(self.base_url + url, data=data, **kwargs) def put(self, url, **kwargs): - return self.session.put(self.base_url+url, **kwargs) + return self.session.put(self.base_url + url, **kwargs) def patch(self, url, **kwargs): - return self.session.patch(self.base_url+url, **kwargs) + return self.session.patch(self.base_url + url, **kwargs) def delete(self, url, **kwargs): - return self.session.delete(self.base_url+url, **kwargs) + return self.session.delete(self.base_url + url, **kwargs) @staticmethod def __deep_merge(source, destination): @@ -51,3 +57,35 @@ def __deep_merge(source, destination): else: destination[key] = value return destination + + +class VerifySignature: + SUPPORTED_NETWORKS = ["mainnet", "testnet"] + + def __init__(self, abi, network, contract_address): + with open(abi, "r") as reader: + abi = json.load(reader) + assert network in self.SUPPORTED_NETWORKS + network = self.set_network(network) + self.contract = Contract( + contract_address, + abi, + network, + ) + + def set_network(self, network): + if network == "testnet": + return GatewayClient(TESTNET) + elif network == "mainnet": + return GatewayClient(MAINNET) + + def __call__(self, message_hash, signature): + try: + asyncio.run( + self.contract.functions["is_valid_signature"].call( + message_hash, (signature[0], signature[1]) + ) + ) + return "Valid Signature", None + except Exception as e: + return "Invalid Signature", 400 From ed4d5ff2887c7032e09704bc339d1e1cf0250154 Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 16 Sep 2022 02:03:05 +0700 Subject: [PATCH 07/30] feat(register_user): convert signature string to tuple --- starklings-backend/starklings_backend/routes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index 90f89454..9161e6ef 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -31,6 +31,8 @@ def register_user(): """ try: signature = request.json.get('signature', None) + # convert string to tuple + signature = eval(signature) wallet_address = request.json.get('wallet_address', None) username = request.json.get('username', wallet_address) github = request.json.get('github', None) From 2bc22615d56768339ee53a7a9210418ada421413 Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 16 Sep 2022 19:41:25 +0700 Subject: [PATCH 08/30] feat: github is not mandatory --- starklings-backend/starklings_backend/models.py | 2 +- starklings-backend/starklings_backend/routes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py index e75d71ee..6f68729c 100644 --- a/starklings-backend/starklings_backend/models.py +++ b/starklings-backend/starklings_backend/models.py @@ -8,7 +8,7 @@ class StarklingsUser(Base): __tablename__ = "starklings_user" wallet_address = Column(String(42), primary_key=True) signature = Column(String(255), nullable=False) - github = Column(String(255), nullable=False) + github = Column(String(255), nullable=True) username = Column(String(255), nullable=False) score = Column(Integer, nullable=False, default=0) starklings_user = relationship("ValidatedExercise") diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index 9161e6ef..dcc22dff 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -38,7 +38,7 @@ def register_user(): github = request.json.get('github', None) message_hash = request.json.get('message_hash', '') network = request.json.get('network', 'testnet') - if None in [wallet_address, signature, github]: + if None in [wallet_address, signature]: return "Wrong form", 400 # verify signature verify_signature = VerifySignature(abi, network, wallet_address) From ab9d079cce2fc51e14fc1a2027317c32451cd4ad Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 16 Sep 2022 21:02:26 +0700 Subject: [PATCH 09/30] feat: remove unused code --- starklings-backend/starklings_backend/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py index 6f68729c..a75c488a 100644 --- a/starklings-backend/starklings_backend/models.py +++ b/starklings-backend/starklings_backend/models.py @@ -1,6 +1,5 @@ from sqlalchemy import create_engine, Column, Integer, String, ForeignKey from sqlalchemy.orm import sessionmaker, relationship, declarative_base -# from db import Base Base = declarative_base() From 1143eb762f6bbf921263ac4b0ffae91c259e8706 Mon Sep 17 00:00:00 2001 From: internos Date: Mon, 19 Sep 2022 19:02:09 +0700 Subject: [PATCH 10/30] fix: existing user error handling --- starklings-backend/starklings_backend/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index dcc22dff..fc7e723c 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -51,7 +51,7 @@ def register_user(): return 'Signature invalid', 400 except IntegrityError as e: - session.rollback() + db.rollback() return 'User Already Exists', 400 except AttributeError: return 'Provide an Email and Password in JSON format in the request body', 400 From 6687ca635aae7509d3123f76616f68f825c90d97 Mon Sep 17 00:00:00 2001 From: internos Date: Mon, 19 Sep 2022 19:10:43 +0700 Subject: [PATCH 11/30] fix: abi path --- .../starklings_backend/routes.py | 85 ++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index fc7e723c..e8a88ff8 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -4,105 +4,114 @@ from sqlalchemy.exc import IntegrityError from flask_sqlalchemy import SQLAlchemy from starklings_backend.utils import verify_email, VerifySignature -from starklings_backend.models import StarklingsUser, Path, Exercise, ValidatedExercise, Base +from starklings_backend.models import ( + StarklingsUser, + Path, + Exercise, + ValidatedExercise, + Base, +) from starklings_backend.exercise import verify_exercise from checker import ExerciceFailed import tempfile from starklings_backend.db import Session - +from pathlib import Path -app_routes = Blueprint('app_routes', __name__) +app_routes = Blueprint("app_routes", __name__) db = Session() -@app_routes.route('/', methods=['GET']) + +@app_routes.route("/", methods=["GET"]) def landing(): - return 'Starklings API' + return "Starklings API" + ####################### # Users Routes # ####################### -@app_routes.route('/registerUser', methods=['POST']) +@app_routes.route("/registerUser", methods=["POST"]) def register_user(): """ Inserts a new user in the Database @TODO: Starknet ID / Signature and implements model """ try: - signature = request.json.get('signature', None) + signature = request.json.get("signature", None) # convert string to tuple signature = eval(signature) - wallet_address = request.json.get('wallet_address', None) - username = request.json.get('username', wallet_address) - github = request.json.get('github', None) - message_hash = request.json.get('message_hash', '') - network = request.json.get('network', 'testnet') + wallet_address = request.json.get("wallet_address", None) + username = request.json.get("username", wallet_address) + github = request.json.get("github", None) + message_hash = request.json.get("message_hash", "") + network = request.json.get("network", "testnet") if None in [wallet_address, signature]: - return "Wrong form", 400 + return "Wrong form", 400 # verify signature + abi = Path.cwd().parent / "abi" / "account.json" verify_signature = VerifySignature(abi, network, wallet_address) is_valid, error = verify_signature.verify_signature(message_hash, signature) if error is None: - user = StarklingsUser(wallet_address=wallet_address, signature=signature, github=github, username=username) + user = StarklingsUser( + wallet_address=wallet_address, + signature=signature, + github=github, + username=username, + ) db.add(user) db.commit() - return f'Welcome! {username}', 200 - return 'Signature invalid', 400 + return f"Welcome! {username}", 200 + return "Signature invalid", 400 except IntegrityError as e: db.rollback() - return 'User Already Exists', 400 + return "User Already Exists", 400 except AttributeError: - return 'Provide an Email and Password in JSON format in the request body', 400 + return "Provide an Email and Password in JSON format in the request body", 400 -@app_routes.route('/fetchUserInfo', methods=['POST']) +@app_routes.route("/fetchUserInfo", methods=["POST"]) def fetch_user_info(): """ Authenticate a user @TODO Implements Fetch User Information """ try: - wallet_address = request.json.get('wallet_address', None) + wallet_address = request.json.get("wallet_address", None) if not wallet_address: - return 'Missing address', 400 + return "Missing address", 400 user = StarklingsUser.query.filter_by(wallet_address=wallet_address).first() if not user: - return 'User Not Found!', 404 - - return f'Logged in, Welcome {user.username}!', 200 + return "User Not Found!", 404 + + return f"Logged in, Welcome {user.username}!", 200 except AttributeError as e: print(e) - return 'Provide the wallet address in JSON format in the request body', 400 + return "Provide the wallet address in JSON format in the request body", 400 ####################### # Exercises Routes # ####################### -@app_routes.route('/exercise/check', methods=['POST']) +@app_routes.route("/exercise/check", methods=["POST"]) async def starklings_exercise_checker(): """ Check exercise given a body and a user @TODO: Implement User DB for storing results """ try: - address = request.json.get('wallet_address', None) - exercise = request.json.get('exercise', 'storage/storage01') - exercise_data = request.json.get('exercise_data', None) + address = request.json.get("wallet_address", None) + exercise = request.json.get("exercise", "storage/storage01") + exercise_data = request.json.get("exercise_data", None) if not address: - return 'Missing Address', 400 + return "Missing Address", 400 tmp = tempfile.NamedTemporaryFile() - with open(tmp.name, 'w') as temp_exercise: + with open(tmp.name, "w") as temp_exercise: temp_exercise.write(exercise_data) res = await verify_exercise(tmp.name) tmp.close() - return { - "result": "success" - } + return {"result": "success"} except ExerciceFailed as error: print(error) - return { - "result": "failure", - "error": error.message - }, 400 + return {"result": "failure", "error": error.message}, 400 From 7c770e687572ed5c683e8b1b868f158d9bfcdd08 Mon Sep 17 00:00:00 2001 From: internos Date: Tue, 20 Sep 2022 21:53:06 +0700 Subject: [PATCH 12/30] feat(db): move --- starklings-backend/db.py | 39 ++++++--------------- starklings-backend/starklings_backend/db.py | 17 --------- 2 files changed, 10 insertions(+), 46 deletions(-) delete mode 100644 starklings-backend/starklings_backend/db.py diff --git a/starklings-backend/db.py b/starklings-backend/db.py index 2c6cf658..7bb59086 100644 --- a/starklings-backend/db.py +++ b/starklings-backend/db.py @@ -1,36 +1,17 @@ import os import pymysql +from sqlalchemy.orm import declarative_base, sessionmaker +from starklings_backend.models import StarklingsUser,Path,Exercise,ValidatedExercise, Base +from sqlalchemy import create_engine from dotenv import load_dotenv load_dotenv() -connection = pymysql.connect( - host=os.environ.get('DATABASE_HOST', ''), - database=os.environ.get('DATABASE_NAME', ''), - user=os.environ.get('DATABASE_USER', ''), - password=os.environ.get('DATABASE_PWD', ''), - charset="utf8mb4", - cursorclass=pymysql.cursors.DictCursor -) +host=os.environ.get('DATABASE_HOST', '') +database=os.environ.get('DATABASE_NAME', '') +user=os.environ.get('DATABASE_USER', '') +password=os.environ.get('DATABASE_PWD', '') -cursor = connection.cursor() +engine = create_engine(f'mysql+pymysql://{user}:{password}@{host}/{database}', echo=True) -validated_sql_query = """CREATE TABLE validated_exercise ( - exercise_name varchar(255) NOT NULL, - user_id int NOT NULL FOREIGN KEY - ... -) -""" - - -user_sql_query = """CREATE TABLE starklings_user ( - user_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, - wallet_address varchar(255) NOT NULL UNIQUE, - score int NOT NULL DEFAULT 0, - username varchar(255) NOT NULL UNIQUE, - signature varchar(255) NOT NULL -) -""" - -#cursor.execute(validated_sql_query) -cursor.execute(user_sql_query) -connection.close() +Session = sessionmaker(bind=engine) +Base.metadata.create_all(engine) \ No newline at end of file diff --git a/starklings-backend/starklings_backend/db.py b/starklings-backend/starklings_backend/db.py deleted file mode 100644 index 62cad547..00000000 --- a/starklings-backend/starklings_backend/db.py +++ /dev/null @@ -1,17 +0,0 @@ -import os -import pymysql -from sqlalchemy.orm import declarative_base, sessionmaker -from models import StarklingsUser,Path,Exercise,ValidatedExercise, Base -from sqlalchemy import create_engine -from dotenv import load_dotenv -load_dotenv() - -host=os.environ.get('DATABASE_HOST', '') -database=os.environ.get('DATABASE_NAME', '') -user=os.environ.get('DATABASE_USER', '') -password=os.environ.get('DATABASE_PWD', '') - -engine = create_engine(f'mysql+pymysql://{user}:{password}@{host}/{database}', echo=True) - -Session = sessionmaker(bind=engine) -Base.metadata.create_all(engine) \ No newline at end of file From b8a08ed8f24c59a66cd35ce742c924b9b85d8f0c Mon Sep 17 00:00:00 2001 From: internos Date: Tue, 20 Sep 2022 21:53:38 +0700 Subject: [PATCH 13/30] feat: add package --- starklings-backend/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/requirements.txt b/starklings-backend/requirements.txt index d421434f..fd4ccd42 100644 --- a/starklings-backend/requirements.txt +++ b/starklings-backend/requirements.txt @@ -3,7 +3,6 @@ Flask==2.1.3 flask-cors==3.0.10 aioflask==0.4.0 Flask-SQLAlchemy==2.5.1 -mysqlclient==2.1.1 pathspec==0.9.0 PyJWT==2.4.0 PyMySQL==1.0.2 @@ -14,3 +13,4 @@ SQLAlchemy==1.4.39 typing_extensions==4.3.0 urllib3==1.26.11 pytest==7.1.2 +starknet-py==0.5.2a0 \ No newline at end of file From 1f0805ac627ee340f8d1dedd785aa922e3f9505e Mon Sep 17 00:00:00 2001 From: internos Date: Tue, 20 Sep 2022 22:44:02 +0700 Subject: [PATCH 14/30] fix: comment out broken import due to cairo v0.10 --- starklings-backend/starklings_backend/routes.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index e8a88ff8..18455cd7 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -1,3 +1,4 @@ +# import pdb; pdb.set_trace() from flask import request, Blueprint import asyncio import bcrypt @@ -11,10 +12,10 @@ ValidatedExercise, Base, ) -from starklings_backend.exercise import verify_exercise -from checker import ExerciceFailed +# from starklings_backend.exercise import verify_exercise +# from checker import ExerciceFailed import tempfile -from starklings_backend.db import Session +from db import Session from pathlib import Path From c22801ac39f6465abf503e838ce727460957924e Mon Sep 17 00:00:00 2001 From: internos Date: Tue, 20 Sep 2022 22:45:32 +0700 Subject: [PATCH 15/30] docs: add env variables --- starklings-backend/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/starklings-backend/README.md b/starklings-backend/README.md index bbb577f1..c5c81523 100644 --- a/starklings-backend/README.md +++ b/starklings-backend/README.md @@ -29,6 +29,9 @@ pip install -r requirements.txt ## Launch API +### Add ENV variables +create .env file in the same directory as this with the fields defined in .env.DEFAULT + - Development ``` APP_SETTINGS=config.DevConfig python app.py From f47bc6d2823ac1397ec7c6c60c7391049b8e9a64 Mon Sep 17 00:00:00 2001 From: internos Date: Tue, 20 Sep 2022 23:10:26 +0700 Subject: [PATCH 16/30] fix(fetchUserInfo): fix user query --- starklings-backend/starklings_backend/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index 18455cd7..0b5a376a 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -82,7 +82,7 @@ def fetch_user_info(): wallet_address = request.json.get("wallet_address", None) if not wallet_address: return "Missing address", 400 - user = StarklingsUser.query.filter_by(wallet_address=wallet_address).first() + user = db.query(StarklingsUser).filter_by(wallet_address=wallet_address).first() if not user: return "User Not Found!", 404 From 05a5b3426540910af028a3394897fdbd45614b29 Mon Sep 17 00:00:00 2001 From: internos Date: Wed, 21 Sep 2022 02:01:33 +0700 Subject: [PATCH 17/30] fix(registerUser): verify signature --- starklings-backend/starklings_backend/routes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index 0b5a376a..5da75869 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -50,9 +50,9 @@ def register_user(): if None in [wallet_address, signature]: return "Wrong form", 400 # verify signature - abi = Path.cwd().parent / "abi" / "account.json" + abi = Path.cwd() / "abi" / "account.json" verify_signature = VerifySignature(abi, network, wallet_address) - is_valid, error = verify_signature.verify_signature(message_hash, signature) + is_valid, error = verify_signature(message_hash, signature) if error is None: user = StarklingsUser( wallet_address=wallet_address, From 3aa42aa7bfc9a35ac4436070418a807cf45dfc45 Mon Sep 17 00:00:00 2001 From: internos Date: Wed, 21 Sep 2022 02:41:09 +0700 Subject: [PATCH 18/30] fix: signature datatype --- starklings-backend/starklings_backend/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/starklings-backend/starklings_backend/utils.py b/starklings-backend/starklings_backend/utils.py index 75c6d223..0f3df2b4 100644 --- a/starklings-backend/starklings_backend/utils.py +++ b/starklings-backend/starklings_backend/utils.py @@ -81,11 +81,12 @@ def set_network(self, network): def __call__(self, message_hash, signature): try: + asyncio.run( self.contract.functions["is_valid_signature"].call( - message_hash, (signature[0], signature[1]) + message_hash, (eval(signature[0]), eval(signature[1])) ) ) return "Valid Signature", None except Exception as e: - return "Invalid Signature", 400 + return "Invalid Signature", 400 \ No newline at end of file From 89fba895a8e22d562a8260e33948d36cc4616a71 Mon Sep 17 00:00:00 2001 From: internos Date: Wed, 21 Sep 2022 02:49:31 +0700 Subject: [PATCH 19/30] fix(StarklingsUser): change wallet address length --- starklings-backend/starklings_backend/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py index a75c488a..b84778d9 100644 --- a/starklings-backend/starklings_backend/models.py +++ b/starklings-backend/starklings_backend/models.py @@ -5,7 +5,7 @@ class StarklingsUser(Base): __tablename__ = "starklings_user" - wallet_address = Column(String(42), primary_key=True) + wallet_address = Column(String(69), primary_key=True) signature = Column(String(255), nullable=False) github = Column(String(255), nullable=True) username = Column(String(255), nullable=False) From 4a7ea178d4a951d1bfc91f97be0b8c01ee2fcba8 Mon Sep 17 00:00:00 2001 From: internos Date: Wed, 21 Sep 2022 02:50:46 +0700 Subject: [PATCH 20/30] fix(StarklingsUser): signature datatype --- starklings-backend/starklings_backend/routes.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index 5da75869..f6402ca5 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -40,8 +40,6 @@ def register_user(): """ try: signature = request.json.get("signature", None) - # convert string to tuple - signature = eval(signature) wallet_address = request.json.get("wallet_address", None) username = request.json.get("username", wallet_address) github = request.json.get("github", None) @@ -52,7 +50,7 @@ def register_user(): # verify signature abi = Path.cwd() / "abi" / "account.json" verify_signature = VerifySignature(abi, network, wallet_address) - is_valid, error = verify_signature(message_hash, signature) + is_valid, error = verify_signature(message_hash, eval(signature)) if error is None: user = StarklingsUser( wallet_address=wallet_address, From 2abe463c396a8d99a574a3c344eaa8da42ee2e57 Mon Sep 17 00:00:00 2001 From: internos Date: Thu, 22 Sep 2022 17:43:53 +0700 Subject: [PATCH 21/30] feat: add abi --- starklings-backend/abi/account.json | 414 ++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 starklings-backend/abi/account.json diff --git a/starklings-backend/abi/account.json b/starklings-backend/abi/account.json new file mode 100644 index 00000000..f47bc467 --- /dev/null +++ b/starklings-backend/abi/account.json @@ -0,0 +1,414 @@ +[ + { + "members": [ + { + "name": "to", + "offset": 0, + "type": "felt" + }, + { + "name": "selector", + "offset": 1, + "type": "felt" + }, + { + "name": "data_offset", + "offset": 2, + "type": "felt" + }, + { + "name": "data_len", + "offset": 3, + "type": "felt" + } + ], + "name": "CallArray", + "size": 4, + "type": "struct" + }, + { + "data": [ + { + "name": "new_signer", + "type": "felt" + } + ], + "keys": [], + "name": "signer_changed", + "type": "event" + }, + { + "data": [ + { + "name": "new_guardian", + "type": "felt" + } + ], + "keys": [], + "name": "guardian_changed", + "type": "event" + }, + { + "data": [ + { + "name": "new_guardian", + "type": "felt" + } + ], + "keys": [], + "name": "guardian_backup_changed", + "type": "event" + }, + { + "data": [ + { + "name": "active_at", + "type": "felt" + } + ], + "keys": [], + "name": "escape_guardian_triggered", + "type": "event" + }, + { + "data": [ + { + "name": "active_at", + "type": "felt" + } + ], + "keys": [], + "name": "escape_signer_triggered", + "type": "event" + }, + { + "data": [], + "keys": [], + "name": "escape_canceled", + "type": "event" + }, + { + "data": [ + { + "name": "new_guardian", + "type": "felt" + } + ], + "keys": [], + "name": "guardian_escaped", + "type": "event" + }, + { + "data": [ + { + "name": "new_signer", + "type": "felt" + } + ], + "keys": [], + "name": "signer_escaped", + "type": "event" + }, + { + "data": [ + { + "name": "account", + "type": "felt" + }, + { + "name": "key", + "type": "felt" + }, + { + "name": "guardian", + "type": "felt" + } + ], + "keys": [], + "name": "account_created", + "type": "event" + }, + { + "data": [ + { + "name": "new_implementation", + "type": "felt" + } + ], + "keys": [], + "name": "account_upgraded", + "type": "event" + }, + { + "data": [ + { + "name": "hash", + "type": "felt" + }, + { + "name": "response_len", + "type": "felt" + }, + { + "name": "response", + "type": "felt*" + } + ], + "keys": [], + "name": "transaction_executed", + "type": "event" + }, + { + "inputs": [ + { + "name": "signer", + "type": "felt" + }, + { + "name": "guardian", + "type": "felt" + } + ], + "name": "initialize", + "outputs": [], + "type": "function" + }, + { + "inputs": [ + { + "name": "call_array_len", + "type": "felt" + }, + { + "name": "call_array", + "type": "CallArray*" + }, + { + "name": "calldata_len", + "type": "felt" + }, + { + "name": "calldata", + "type": "felt*" + }, + { + "name": "nonce", + "type": "felt" + } + ], + "name": "__execute__", + "outputs": [ + { + "name": "retdata_size", + "type": "felt" + }, + { + "name": "retdata", + "type": "felt*" + } + ], + "type": "function" + }, + { + "inputs": [ + { + "name": "implementation", + "type": "felt" + } + ], + "name": "upgrade", + "outputs": [], + "type": "function" + }, + { + "inputs": [ + { + "name": "new_signer", + "type": "felt" + } + ], + "name": "change_signer", + "outputs": [], + "type": "function" + }, + { + "inputs": [ + { + "name": "new_guardian", + "type": "felt" + } + ], + "name": "change_guardian", + "outputs": [], + "type": "function" + }, + { + "inputs": [ + { + "name": "new_guardian", + "type": "felt" + } + ], + "name": "change_guardian_backup", + "outputs": [], + "type": "function" + }, + { + "inputs": [], + "name": "trigger_escape_guardian", + "outputs": [], + "type": "function" + }, + { + "inputs": [], + "name": "trigger_escape_signer", + "outputs": [], + "type": "function" + }, + { + "inputs": [], + "name": "cancel_escape", + "outputs": [], + "type": "function" + }, + { + "inputs": [ + { + "name": "new_guardian", + "type": "felt" + } + ], + "name": "escape_guardian", + "outputs": [], + "type": "function" + }, + { + "inputs": [ + { + "name": "new_signer", + "type": "felt" + } + ], + "name": "escape_signer", + "outputs": [], + "type": "function" + }, + { + "inputs": [ + { + "name": "hash", + "type": "felt" + }, + { + "name": "sig_len", + "type": "felt" + }, + { + "name": "sig", + "type": "felt*" + } + ], + "name": "is_valid_signature", + "outputs": [ + { + "name": "is_valid", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "interfaceId", + "type": "felt" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "name": "success", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "get_nonce", + "outputs": [ + { + "name": "nonce", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "get_signer", + "outputs": [ + { + "name": "signer", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "get_guardian", + "outputs": [ + { + "name": "guardian", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "get_guardian_backup", + "outputs": [ + { + "name": "guardian_backup", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "get_escape", + "outputs": [ + { + "name": "active_at", + "type": "felt" + }, + { + "name": "type", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "get_version", + "outputs": [ + { + "name": "version", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + } + ] \ No newline at end of file From b4645ea4c2992273cb12f0ffeb0599131e1e0300 Mon Sep 17 00:00:00 2001 From: internos Date: Thu, 22 Sep 2022 18:03:09 +0700 Subject: [PATCH 22/30] fix: instantiate db --- starklings-backend/app.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/starklings-backend/app.py b/starklings-backend/app.py index b628258f..0b0f37fe 100644 --- a/starklings-backend/app.py +++ b/starklings-backend/app.py @@ -4,9 +4,9 @@ import sys sys.path.append('../src/exercises') from starklings_backend.routes import app_routes -from starklings_backend.models.shared import db - +from flask_sqlalchemy import SQLAlchemy +db = SQLAlchemy() app = Flask(__name__) CORS(app) env_config = os.getenv("APP_SETTINGS", "config.DevConfig") @@ -16,6 +16,5 @@ app.register_blueprint(app_routes) - if __name__ == '__main__': app.run(host="0.0.0.0", port=8080) \ No newline at end of file From 4e119b994545fa2e5f9373bdb2dfe9a786e1c47c Mon Sep 17 00:00:00 2001 From: internos Date: Thu, 22 Sep 2022 18:37:49 +0700 Subject: [PATCH 23/30] fix: signature datatype --- starklings-backend/starklings_backend/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/utils.py b/starklings-backend/starklings_backend/utils.py index 0f3df2b4..8e7d05de 100644 --- a/starklings-backend/starklings_backend/utils.py +++ b/starklings-backend/starklings_backend/utils.py @@ -84,7 +84,7 @@ def __call__(self, message_hash, signature): asyncio.run( self.contract.functions["is_valid_signature"].call( - message_hash, (eval(signature[0]), eval(signature[1])) + message_hash, (signature[0], signature[1]) ) ) return "Valid Signature", None From 672bb3e17c3336d160650dace4f655ad3ab1daf0 Mon Sep 17 00:00:00 2001 From: internos Date: Thu, 22 Sep 2022 18:40:39 +0700 Subject: [PATCH 24/30] fix: signature datatype --- starklings-backend/starklings_backend/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index f6402ca5..9f804fe8 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -50,7 +50,7 @@ def register_user(): # verify signature abi = Path.cwd() / "abi" / "account.json" verify_signature = VerifySignature(abi, network, wallet_address) - is_valid, error = verify_signature(message_hash, eval(signature)) + is_valid, error = verify_signature(message_hash, signature) if error is None: user = StarklingsUser( wallet_address=wallet_address, From 77af81050552c2e7e818a2b0b122f637064fa1cb Mon Sep 17 00:00:00 2001 From: internos Date: Thu, 22 Sep 2022 18:43:35 +0700 Subject: [PATCH 25/30] fix: signature datatype --- starklings-backend/starklings_backend/routes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index 9f804fe8..d35cec46 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -17,6 +17,7 @@ import tempfile from db import Session from pathlib import Path +import json app_routes = Blueprint("app_routes", __name__) @@ -54,7 +55,7 @@ def register_user(): if error is None: user = StarklingsUser( wallet_address=wallet_address, - signature=signature, + signature=json.dumps(signature), github=github, username=username, ) From 304d1009861898c2567253166aca66ed56125288 Mon Sep 17 00:00:00 2001 From: internos Date: Thu, 22 Sep 2022 22:40:30 +0700 Subject: [PATCH 26/30] feat(updateUser): add --- .../starklings_backend/routes.py | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index d35cec46..d8491f30 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -37,7 +37,6 @@ def landing(): def register_user(): """ Inserts a new user in the Database - @TODO: Starknet ID / Signature and implements model """ try: signature = request.json.get("signature", None) @@ -52,6 +51,7 @@ def register_user(): abi = Path.cwd() / "abi" / "account.json" verify_signature = VerifySignature(abi, network, wallet_address) is_valid, error = verify_signature(message_hash, signature) + # import pdb; pdb.set_trace() if error is None: user = StarklingsUser( wallet_address=wallet_address, @@ -70,6 +70,33 @@ def register_user(): except AttributeError: return "Provide an Email and Password in JSON format in the request body", 400 +@app_routes.route("/updateUser", methods=["POST"]) +def update_user(): + try: + update_parameter = request.json.get("update_parameter", None) + if update_parameter is None: + return "Missing update parameter", 400 + for k, v in update_parameter.items(): + if k not in ['username', 'github']: + return f"Incorrect payload {k}", 400 + + wallet_address = request.json.get("wallet_address", None) + signature = request.json.get("signature", None) + if not wallet_address: + return "Missing address", 400 + if not signature: + return "Missing signature", 400 + user = db.query(StarklingsUser).filter_by(wallet_address=wallet_address, signature=str(signature)) + if user is None: + return "Invalid wallet and signature pair", 400 + user.update(update_parameter, synchronize_session="fetch") + db.commit() + return f"Update successful", 200 + except AttributeError as e: + print(e) + return "Provide the wallet address in JSON format in the request body", 400 + + @app_routes.route("/fetchUserInfo", methods=["POST"]) def fetch_user_info(): From c7d8ecc4e42eb53fe2edac61cb62b77df8b2bc60 Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 23 Sep 2022 01:02:41 +0700 Subject: [PATCH 27/30] fix(ValidatedExercise): validated_exercise_id length --- starklings-backend/starklings_backend/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py index b84778d9..bb176982 100644 --- a/starklings-backend/starklings_backend/models.py +++ b/starklings-backend/starklings_backend/models.py @@ -30,7 +30,7 @@ class Exercise(Base): class ValidatedExercise(Base): __tablename__ = "validated_exercise" - validated_exercise_id = Column(String(64), primary_key=True) + validated_exercise_id = Column(String(69), primary_key=True) exercise_name = Column( String(255), ForeignKey("exercise.exercise_name"), From 247448bc8106036dab38a33b1a8fc6a88dc49eaa Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 23 Sep 2022 01:12:35 +0700 Subject: [PATCH 28/30] fix(ValidatedExercise): wallet_address length --- starklings-backend/starklings_backend/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py index bb176982..01bf0385 100644 --- a/starklings-backend/starklings_backend/models.py +++ b/starklings-backend/starklings_backend/models.py @@ -30,13 +30,13 @@ class Exercise(Base): class ValidatedExercise(Base): __tablename__ = "validated_exercise" - validated_exercise_id = Column(String(69), primary_key=True) + validated_exercise_id = Column(String(42), primary_key=True) exercise_name = Column( String(255), ForeignKey("exercise.exercise_name"), nullable=False, ) wallet_address = Column( - String(42), ForeignKey("starklings_user.wallet_address"), nullable=False + String(69), ForeignKey("starklings_user.wallet_address"), nullable=False ) From f0bb2e27f159beb201260badb9418714d3ff9e37 Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 23 Sep 2022 01:16:00 +0700 Subject: [PATCH 29/30] fix(ValidatedExercise): validated_exercise_id length --- starklings-backend/starklings_backend/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starklings-backend/starklings_backend/models.py b/starklings-backend/starklings_backend/models.py index 01bf0385..77187ca0 100644 --- a/starklings-backend/starklings_backend/models.py +++ b/starklings-backend/starklings_backend/models.py @@ -30,7 +30,7 @@ class Exercise(Base): class ValidatedExercise(Base): __tablename__ = "validated_exercise" - validated_exercise_id = Column(String(42), primary_key=True) + validated_exercise_id = Column(String(64), primary_key=True) exercise_name = Column( String(255), ForeignKey("exercise.exercise_name"), From 4b4f71d76221e7e13c90689025641d5b18e223d5 Mon Sep 17 00:00:00 2001 From: internos Date: Fri, 23 Sep 2022 01:35:58 +0700 Subject: [PATCH 30/30] feat(updateUser): verify signature --- .../starklings_backend/routes.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/starklings-backend/starklings_backend/routes.py b/starklings-backend/starklings_backend/routes.py index d8491f30..1b09fc84 100644 --- a/starklings-backend/starklings_backend/routes.py +++ b/starklings-backend/starklings_backend/routes.py @@ -86,12 +86,18 @@ def update_user(): return "Missing address", 400 if not signature: return "Missing signature", 400 - user = db.query(StarklingsUser).filter_by(wallet_address=wallet_address, signature=str(signature)) - if user is None: - return "Invalid wallet and signature pair", 400 - user.update(update_parameter, synchronize_session="fetch") - db.commit() - return f"Update successful", 200 + # verify signature + abi = Path.cwd() / "abi" / "account.json" + verify_signature = VerifySignature(abi, network, wallet_address) + is_valid, error = verify_signature(message_hash, signature) + if error is None: + user = db.query(StarklingsUser).filter_by(wallet_address=wallet_address, signature=str(signature)) + if user is None: + return "Invalid wallet and signature pair", 400 + user.update(update_parameter, synchronize_session="fetch") + db.commit() + return f"Update successful", 200 + return "Signature invalid", 400 except AttributeError as e: print(e) return "Provide the wallet address in JSON format in the request body", 400