Compare commits
No commits in common. "b818e56954b549cc0adab3a713840e158fece34b" and "80caa02d74f4c8e703c9288ef2f9fd9acc166100" have entirely different histories.
b818e56954
...
80caa02d74
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"blocklist",
|
"blocklist",
|
||||||
"displayname",
|
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"gensalt",
|
"gensalt",
|
||||||
"hashpw",
|
"hashpw",
|
||||||
|
@ -60,5 +60,4 @@ def get_image_name(id: int):
|
|||||||
|
|
||||||
@bp_product.route('/create', methods=['POST'])
|
@bp_product.route('/create', methods=['POST'])
|
||||||
def create_product_listing():
|
def create_product_listing():
|
||||||
name = request.json.get('name')
|
return abort(501)
|
||||||
|
|
@ -7,14 +7,13 @@ from app.services.user_service import UserService
|
|||||||
@bp_user.route('/register', methods=['POST'])
|
@bp_user.route('/register', methods=['POST'])
|
||||||
def register():
|
def register():
|
||||||
username = request.json.get('username')
|
username = request.json.get('username')
|
||||||
displayname = request.json.get('displayname')
|
|
||||||
email = request.json.get('email')
|
email = request.json.get('email')
|
||||||
password = request.json.get('password')
|
password = request.json.get('password')
|
||||||
|
|
||||||
if username is None or email is None or password is None or displayname is None:
|
if username is None or email is None or password is None:
|
||||||
return abort(400)
|
return abort(400)
|
||||||
|
|
||||||
result, status_code = UserService.register(username, displayname, email, password)
|
result, status_code = UserService.register(username, email, password)
|
||||||
|
|
||||||
return result, status_code
|
return result, status_code
|
||||||
|
|
||||||
@ -44,32 +43,13 @@ def logout():
|
|||||||
@bp_user.route('/update/username', methods=['PUT'])
|
@bp_user.route('/update/username', methods=['PUT'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def update_username():
|
def update_username():
|
||||||
user_id = get_jwt_identity()
|
username = get_jwt_identity()
|
||||||
new_username = request.json.get('new_username')
|
new_username = request.json.get('new_username')
|
||||||
|
|
||||||
if new_username is None:
|
if new_username is None:
|
||||||
return abort(400)
|
return abort(400)
|
||||||
|
|
||||||
result, status_code = UserService.update_username(user_id, new_username)
|
result, status_code = UserService.update_username(username, new_username)
|
||||||
|
|
||||||
jwt = get_jwt()
|
|
||||||
|
|
||||||
jti = jwt['jti']
|
|
||||||
exp = jwt['exp']
|
|
||||||
UserService.logout(jti, exp)
|
|
||||||
|
|
||||||
return result, status_code
|
|
||||||
|
|
||||||
@bp_user.route('/update/displayname', methods=['PUT'])
|
|
||||||
@jwt_required()
|
|
||||||
def update_displayname():
|
|
||||||
user_id = get_jwt_identity()
|
|
||||||
new_displayname = request.json.get('new_displayname')
|
|
||||||
|
|
||||||
if new_displayname is None:
|
|
||||||
return abort(400)
|
|
||||||
|
|
||||||
result, status_code = UserService.update_username(user_id, new_displayname)
|
|
||||||
|
|
||||||
jwt = get_jwt()
|
jwt = get_jwt()
|
||||||
|
|
||||||
|
@ -45,8 +45,4 @@ class ProductService:
|
|||||||
"price": result['price_pc'],
|
"price": result['price_pc'],
|
||||||
"image_name": result['image_name'],
|
"image_name": result['image_name'],
|
||||||
"image": base64.b64encode(result['image']).decode('utf-8')
|
"image": base64.b64encode(result['image']).decode('utf-8')
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def create_listing():
|
|
||||||
print("asd")
|
|
@ -24,7 +24,7 @@ class UserService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def register(username: str, displayname: str, email: str, password: str) -> Tuple[Union[dict, str], int]:
|
def register(username: str, email: str, password: str) -> Tuple[Union[dict, str], int]:
|
||||||
"""
|
"""
|
||||||
Registers a new user with the provided username, email, and password.
|
Registers a new user with the provided username, email, and password.
|
||||||
|
|
||||||
@ -39,21 +39,18 @@ class UserService:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if not UserService.__verify_username(username):
|
if not UserService.__verify_username(username):
|
||||||
return {"Failed": "Failed to verify username. Try another username"}, 400
|
return {"Failed": "Failed to verify username. Try another username"}, 400
|
||||||
|
|
||||||
if not UserService.__verify_displayname(displayname):
|
|
||||||
return {"Failed": "Failed to verify display name. Try another name"}, 400
|
|
||||||
|
|
||||||
if not UserService.__verify_email(email):
|
if not UserService.__verify_email(email):
|
||||||
return {"Failed": "Failed to verify email. Try another email"}, 400
|
return {"Failed": "Failed to verify email. Try another email"}, 400
|
||||||
|
|
||||||
if not UserService.__verify_password(password):
|
if not UserService.__verify_password(password):
|
||||||
return {"Failed": "Failed to verify password. Try another (stronger) password"}, 400
|
return {"Failed": "Failed to verify password. Try another (stronger) password"}, 400
|
||||||
|
|
||||||
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
|
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
db_cursor.execute("insert into user (username, displayname, email, password) values (%s, %s, %s, %s)", (username, displayname, email, hashed_password))
|
db_cursor.execute("insert into user (username, email, password, role_id) values (%s, %s, %s, 1)", (username, email, hashed_password))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
except Error as e:
|
except Error as e:
|
||||||
print(f"Error: {e}")
|
print(f"Error: {e}")
|
||||||
@ -74,10 +71,10 @@ class UserService:
|
|||||||
:rtype: Tuple[Union[dict, str], int]
|
:rtype: Tuple[Union[dict, str], int]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
db_cursor.execute("select id, password from user where username = %s", (username,))
|
db_cursor.execute("select user_id, password from user where username = %s", (username,))
|
||||||
result = db_cursor.fetchone()
|
result = db_cursor.fetchone()
|
||||||
|
|
||||||
user_id = result['id']
|
user_id = result['user_id']
|
||||||
password_hash = result['password']
|
password_hash = result['password']
|
||||||
|
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
@ -111,7 +108,7 @@ class UserService:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def delete_user(user_id: str) -> Tuple[Union[dict, str], int]:
|
def delete_user(user_id: str) -> Tuple[Union[dict, str], int]:
|
||||||
try:
|
try:
|
||||||
db_cursor.execute("delete from user where id = %s", (user_id,))
|
db_cursor.execute("delete from user where user_id = %s", (user_id,))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
except Error as e:
|
except Error as e:
|
||||||
return {"Failed": f"Failed to delete user. {e}"}, 500
|
return {"Failed": f"Failed to delete user. {e}"}, 500
|
||||||
@ -135,7 +132,7 @@ class UserService:
|
|||||||
return {"Failed": "Failed to verify email. Try another email"}, 400
|
return {"Failed": "Failed to verify email. Try another email"}, 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
db_cursor.execute("update user set email = %s where id = %s", (new_email, user_id))
|
db_cursor.execute("update user set email = %s where user_id = %s", (new_email, user_id))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
except Error as e:
|
except Error as e:
|
||||||
return {"Failed": f"Failed to update email. Email is likely in use already. Error: {e}"}, 500
|
return {"Failed": f"Failed to update email. Email is likely in use already. Error: {e}"}, 500
|
||||||
@ -155,11 +152,11 @@ class UserService:
|
|||||||
:rtype: Tuple[Union[dict, str], int]
|
:rtype: Tuple[Union[dict, str], int]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not UserService.__verify_name(new_username):
|
if not UserService.__verify_username(new_username):
|
||||||
return {"Failed": "Failed to verify username. Try another one"}, 400
|
return {"Failed": "Failed to verify username. Try another one"}, 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
db_cursor.execute("update user set username = %s where id = %s", (new_username, user_id))
|
db_cursor.execute("update user set username = %s where user_id = %s", (new_username, user_id))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
except Error as e:
|
except Error as e:
|
||||||
return {"Failed": f"Failed to update username. Username is likely in use already. Error: {e}"}, 500
|
return {"Failed": f"Failed to update username. Username is likely in use already. Error: {e}"}, 500
|
||||||
@ -185,7 +182,7 @@ class UserService:
|
|||||||
hashed_password = bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt())
|
hashed_password = bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
db_cursor.execute("update user set password = %s where id = %s", (new_username, user_id))
|
db_cursor.execute("update user set password = %s where user_id = %s", (new_username, user_id))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
except Error as e:
|
except Error as e:
|
||||||
return {"Failed": f"Failed to update password. Error: {e}"}, 500
|
return {"Failed": f"Failed to update password. Error: {e}"}, 500
|
||||||
@ -221,19 +218,6 @@ class UserService:
|
|||||||
email_regex = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
|
email_regex = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
|
||||||
return re.match(email_regex, email) and len(email) <= 64
|
return re.match(email_regex, email) and len(email) <= 64
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def __verify_displayname(displayname: str) -> bool:
|
|
||||||
"""
|
|
||||||
Verifies a given display name string against a regular expression.
|
|
||||||
|
|
||||||
:param displayname: Display name string.
|
|
||||||
:type displayname: str
|
|
||||||
:return: Boolean indicating whether the display name successfully passed the check.
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
displayname_regex = r"^[a-zA-Z.-_]{1,64}$"
|
|
||||||
return re.match(username_regex, displayname)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __verify_username(username: str) -> bool:
|
def __verify_username(username: str) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -244,7 +228,7 @@ class UserService:
|
|||||||
:return: Boolean indicating whether the username successfully passed the check.
|
:return: Boolean indicating whether the username successfully passed the check.
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
username_regex = r"^[a-z]{1,64}$"
|
username_regex = r"^[a-zA-Z.-_]{1,64}$"
|
||||||
return re.match(username_regex, username)
|
return re.match(username_regex, username)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
132
shop.sql
132
shop.sql
@ -1,132 +0,0 @@
|
|||||||
create database shop;
|
|
||||||
|
|
||||||
use shop;
|
|
||||||
|
|
||||||
create table user(
|
|
||||||
id int primary key auto_increment,
|
|
||||||
username varchar(64) not null unique,
|
|
||||||
displayname varchar(64) not null,
|
|
||||||
email varchar(64) not null unique,
|
|
||||||
password varchar(60) not null,
|
|
||||||
role_id int not null default 1,
|
|
||||||
creation_date timestamp default current_timestamp,
|
|
||||||
foreign key (role_id) references user_role(id)
|
|
||||||
) auto_increment = 23001;
|
|
||||||
|
|
||||||
create table user_role(
|
|
||||||
id int primary key auto_increment,
|
|
||||||
role varchar(32) not null unique
|
|
||||||
);
|
|
||||||
|
|
||||||
insert into user_role(role) values ('normal')
|
|
||||||
insert into user_role(role) values ('admin')
|
|
||||||
|
|
||||||
create table user_statistics(
|
|
||||||
id int primary key,
|
|
||||||
total_gains decimal(6,2) not null default 0.00,
|
|
||||||
sell_count int not null default 0,
|
|
||||||
total_spent decimal(6,2) not null default 0.00,
|
|
||||||
purchase_count int not null default 0,
|
|
||||||
foreign key (id) references user(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table product(
|
|
||||||
id int primary key auto_increment,
|
|
||||||
seller_id int not null,
|
|
||||||
name varchar(32) not null,
|
|
||||||
price_pc decimal(6,2) not null,
|
|
||||||
image blob not null,
|
|
||||||
image_name varchar(64),
|
|
||||||
foreign key (seller_id) references user(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table cart(
|
|
||||||
id int primary key,
|
|
||||||
price_total decimal(6,2) not null default 0.00,
|
|
||||||
item_count int not null default 0,
|
|
||||||
foreign key (id) references user(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table cart_item(
|
|
||||||
id int primary key auto_increment,
|
|
||||||
cart_id int not null,
|
|
||||||
product_id int not null,
|
|
||||||
count int not null,
|
|
||||||
price_subtotal decimal(6,2) not null,
|
|
||||||
date_added datetime default current_timestamp,
|
|
||||||
foreign key (cart_id) references cart(id),
|
|
||||||
foreign key (product_id) references product(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table purchase(
|
|
||||||
id int primary key auto_increment,
|
|
||||||
user_id int not null,
|
|
||||||
purchase_time datetime default current_timestamp,
|
|
||||||
price_total decimal(6,2) not null,
|
|
||||||
was_successful tinyint(1) not null,
|
|
||||||
foreign key (user_id) references user(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table purchase_item(
|
|
||||||
id int primary key auto_increment,
|
|
||||||
purchase_id int not null,
|
|
||||||
product_id int not null,
|
|
||||||
count int not null,
|
|
||||||
price_subtotal decimal(6,2) not null,
|
|
||||||
foreign key (purchase_id) references purchase(id),
|
|
||||||
foreign key (product_id) references product(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
delimiter //
|
|
||||||
create trigger after_user_insert
|
|
||||||
after insert
|
|
||||||
on user for each row
|
|
||||||
begin
|
|
||||||
insert into user_statistics(id) values (new.id);
|
|
||||||
insert into cart(id) values (new.id);
|
|
||||||
end;
|
|
||||||
//
|
|
||||||
delimiter;
|
|
||||||
|
|
||||||
delimiter //
|
|
||||||
create trigger after_user_delete
|
|
||||||
after delete
|
|
||||||
on user for each row
|
|
||||||
begin
|
|
||||||
delete from user_statistics where id = old.id;
|
|
||||||
delete from cart where id = old.id;
|
|
||||||
end;
|
|
||||||
//
|
|
||||||
delimiter;
|
|
||||||
|
|
||||||
delimiter //
|
|
||||||
create trigger after_cart_insert
|
|
||||||
after insert
|
|
||||||
on cart_item for each row
|
|
||||||
begin
|
|
||||||
update cart
|
|
||||||
set price_total = (
|
|
||||||
select sum(price_subtotal)
|
|
||||||
from cart_item
|
|
||||||
where cart_id = new.cart_id
|
|
||||||
)
|
|
||||||
where id = new.cart_id;
|
|
||||||
end;
|
|
||||||
//
|
|
||||||
delimiter;
|
|
||||||
|
|
||||||
delimiter //
|
|
||||||
create trigger after_cart_delete
|
|
||||||
after delete
|
|
||||||
on cart_item for each row
|
|
||||||
begin
|
|
||||||
update cart
|
|
||||||
set price_total = (
|
|
||||||
select sum(price_subtotal)
|
|
||||||
from cart_item
|
|
||||||
where cart_id = old.cart_id
|
|
||||||
)
|
|
||||||
where id = old.cart_id;
|
|
||||||
end;
|
|
||||||
//
|
|
||||||
delimiter;
|
|
Loading…
x
Reference in New Issue
Block a user