From fba0d9c580ebce9f29fcfacd2f054e86e28c0a73 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 3 Oct 2020 20:51:40 +0900 Subject: [PATCH 01/15] fix: removed '-pkg-resources' because of an unknown package resource error (non-existent?) --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 31f4507..3ddabfb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,7 +24,6 @@ MarkupSafe==1.1.1 marshmallow==3.7.1 marshmallow-sqlalchemy==0.23.1 oauthlib==2.1.0 -pkg-resources==0.0.0 pycparser==2.20 PyJWT==1.6.4 python-dateutil==2.8.1 From c0c30764ed0238823e9f7f2d85229289093ef468 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 3 Oct 2020 20:51:53 +0900 Subject: [PATCH 02/15] feature: Added Dockerfile --- Dockerfile | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..98a825b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.8 + +ENV FLASK_APP=app.py + +ENV FLASK_RUN_HOST=0.0.0.0 + +WORKDIR /app + +COPY . . + +# Install packages +RUN pip3 install -r requirements.txt + +COPY .env.example .env + +RUN rm site.db + +EXPOSE 5000 + +CMD ["python3", "app.py"] \ No newline at end of file From a5b2667c9dca43b967a42d27c3016e54fa1eab09 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 3 Oct 2020 20:52:19 +0900 Subject: [PATCH 03/15] feature: Added docker-compose.yml file for container orchestration --- docker-compose.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docker-compose.yaml diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..6de6783 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,16 @@ +version: '3.8' +services: + app: + build: + context: . + dockerfile: Dockerfile + env_file: + - .env + volumes: + - ./:/app + environment: + FLASK_ENV: development + FLASK_APP: ./app.py + ports: + - "5000:5000" + restart: always From 390b58561a13b6c7e598fcc12c7c2ce07b95d5fa Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 3 Oct 2020 21:26:18 +0900 Subject: [PATCH 04/15] fix: database.conf --- database.conf | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 database.conf diff --git a/database.conf b/database.conf new file mode 100644 index 0000000..ca9734d --- /dev/null +++ b/database.conf @@ -0,0 +1,5 @@ +POSTGRES_USER=test +POSTGRES_PASSWORD=password +POSTGRES_HOST=db +POSTGRES_PORT=5432 +POSTGRES_DB=flask_online_store \ No newline at end of file From 82fc0b0ff925e1dd90ced15467258268d7904ba7 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 3 Oct 2020 21:26:29 +0900 Subject: [PATCH 05/15] fix: Added image for postgres --- docker-compose.yaml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 6de6783..5a20247 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,12 @@ version: '3.8' services: + db: + image: postgres:latest + env_file: database.conf + ports: + - 5432:5432 + volumes: + - ./db_volume:/var/lib/db app: build: context: . @@ -12,5 +19,9 @@ services: FLASK_ENV: development FLASK_APP: ./app.py ports: - - "5000:5000" + - 5000:5000 restart: always + depends_on: + - db +volumes: + data-volume: \ No newline at end of file From 3cfa5418da144915b811768b6b7011def3d6672a Mon Sep 17 00:00:00 2001 From: gabrielhicks Date: Sat, 3 Oct 2020 12:36:11 -0400 Subject: [PATCH 06/15] Add nullable to User modeel --- model/users.py | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/model/users.py b/model/users.py index 6f26301..305c850 100644 --- a/model/users.py +++ b/model/users.py @@ -19,7 +19,7 @@ class UserModel(db.Model): __tablename__="users" id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),nullable=False,unique=True) - password = db.Column(db.String(20)) + password = db.Column(db.String(20),nullable=True) email = db.Column(db.String(40),nullable=False,unique=True) activated = db.Column(db.Boolean,default=False) #set default as False diff --git a/requirements.txt b/requirements.txt index 31f4507..0a95e5a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,7 +24,7 @@ MarkupSafe==1.1.1 marshmallow==3.7.1 marshmallow-sqlalchemy==0.23.1 oauthlib==2.1.0 -pkg-resources==0.0.0 +# pkg-resources==0.0.0 pycparser==2.20 PyJWT==1.6.4 python-dateutil==2.8.1 From 3ff4bf2c5aa7071e686b0802c5a6b0a1f82aa5df Mon Sep 17 00:00:00 2001 From: gabrielhicks Date: Sat, 3 Oct 2020 18:13:37 -0400 Subject: [PATCH 07/15] Attempt 2 --- model/users.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/model/users.py b/model/users.py index 305c850..947a663 100644 --- a/model/users.py +++ b/model/users.py @@ -6,6 +6,10 @@ from itsdangerous import URLSafeTimedSerializer,SignatureExpired from mail import mail from flask_mail import Message +import secrets +import string +alpha = string.ascii_letters + string.digits +random = ''.join(secrets.choice(alphabet) for i in range(20)) MAILGUN_DOMAIN = "mailgun domain" MAILGUN_API_KEY = "api key" @@ -19,7 +23,7 @@ class UserModel(db.Model): __tablename__="users" id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),nullable=False,unique=True) - password = db.Column(db.String(20),nullable=True) + password = db.Column(db.String(20),default=random) email = db.Column(db.String(40),nullable=False,unique=True) activated = db.Column(db.Boolean,default=False) #set default as False From 9322928c9d42f73965aa9c1b5049c9eb3598789f Mon Sep 17 00:00:00 2001 From: gabrielhicks Date: Sat, 3 Oct 2020 19:42:51 -0400 Subject: [PATCH 08/15] Fixed variable mismatch --- model/users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/users.py b/model/users.py index 947a663..b15bb92 100644 --- a/model/users.py +++ b/model/users.py @@ -9,7 +9,7 @@ import secrets import string alpha = string.ascii_letters + string.digits -random = ''.join(secrets.choice(alphabet) for i in range(20)) +random = ''.join(secrets.choice(alpha) for i in range(20)) MAILGUN_DOMAIN = "mailgun domain" MAILGUN_API_KEY = "api key" From 9605efc97541840e4094f87cd845f2508b42edb1 Mon Sep 17 00:00:00 2001 From: gabrielhicks Date: Sat, 3 Oct 2020 19:56:58 -0400 Subject: [PATCH 09/15] add class method for password --- model/users.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/model/users.py b/model/users.py index b15bb92..27d352f 100644 --- a/model/users.py +++ b/model/users.py @@ -8,8 +8,6 @@ from flask_mail import Message import secrets import string -alpha = string.ascii_letters + string.digits -random = ''.join(secrets.choice(alpha) for i in range(20)) MAILGUN_DOMAIN = "mailgun domain" MAILGUN_API_KEY = "api key" @@ -23,7 +21,7 @@ class UserModel(db.Model): __tablename__="users" id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),nullable=False,unique=True) - password = db.Column(db.String(20),default=random) + password = db.Column(db.String(20),default=UserModel.generate_sample_password()) email = db.Column(db.String(40),nullable=False,unique=True) activated = db.Column(db.Boolean,default=False) #set default as False @@ -41,7 +39,6 @@ def delete_from_db(self): db.session.delete(self) db.session.commit() - def generate_mail(self): serializer = URLSafeTimedSerializer("secrettoken",1800) token = serializer.dumps({"email":self.email},salt="flask-email-confirmation") @@ -68,6 +65,12 @@ def find_by_username(cls,username): def find_by_email(cls,email): return cls.query.filter_by(email=email).first() + @classmethod + def generate_sample_password(cls): + alpha = string.ascii_letters + string.digits + random = ''.join(secrets.choice(alpha) for i in range(20)) + return random + @classmethod def check_password(cls,username,password): user=cls.query.filter_by(username=username).first() From e960eba72e788cf2f6948032ad1e12fa17610943 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 4 Oct 2020 09:14:39 +0900 Subject: [PATCH 10/15] fix: removed copying .env file during build --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 98a825b..995db1f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,6 @@ COPY . . # Install packages RUN pip3 install -r requirements.txt -COPY .env.example .env - RUN rm site.db EXPOSE 5000 From 4d1d4e431d93d67dbc24cca76eba0aeff7fc738d Mon Sep 17 00:00:00 2001 From: gabrielhicks Date: Sat, 3 Oct 2020 22:35:24 -0400 Subject: [PATCH 11/15] Moved logic to github_login, set nullable to True --- model/users.py | 10 +--------- resource/github_login.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/model/users.py b/model/users.py index 27d352f..eaa70f0 100644 --- a/model/users.py +++ b/model/users.py @@ -6,8 +6,6 @@ from itsdangerous import URLSafeTimedSerializer,SignatureExpired from mail import mail from flask_mail import Message -import secrets -import string MAILGUN_DOMAIN = "mailgun domain" MAILGUN_API_KEY = "api key" @@ -21,7 +19,7 @@ class UserModel(db.Model): __tablename__="users" id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),nullable=False,unique=True) - password = db.Column(db.String(20),default=UserModel.generate_sample_password()) + password = db.Column(db.String(20),nullable=True) email = db.Column(db.String(40),nullable=False,unique=True) activated = db.Column(db.Boolean,default=False) #set default as False @@ -64,12 +62,6 @@ def find_by_username(cls,username): @classmethod def find_by_email(cls,email): return cls.query.filter_by(email=email).first() - - @classmethod - def generate_sample_password(cls): - alpha = string.ascii_letters + string.digits - random = ''.join(secrets.choice(alpha) for i in range(20)) - return random @classmethod def check_password(cls,username,password): diff --git a/resource/github_login.py b/resource/github_login.py index 3e76ae4..ca390eb 100644 --- a/resource/github_login.py +++ b/resource/github_login.py @@ -3,6 +3,8 @@ from outh import github from model.users import UserModel from flask_jwt_extended import create_access_token,create_refresh_token +import secrets +import string class Github(Resource): @classmethod @@ -28,9 +30,16 @@ def get(cls): #if UserModel.find_by_username(github_username): # return {"msg": "User with username exists"} - + + #generate a sample password for github oauth users + @classmethod + def generate_sample_password(cls): + alpha = string.ascii_letters + string.digits + random = ''.join(secrets.choice(alpha) for i in range(20)) + return random + #add user to database - user = UserModel(username=github_username,password=None,activated=True,email=github_email) + user = UserModel(username=github_username,password=GithubAuthorize.generate_sample_password(),activated=True,email=github_email) user.save_to_db() #create jwt tokens From d698a95e44c5ef59423f2cbe9a8bbd3b18ece57d Mon Sep 17 00:00:00 2001 From: rpdswtk Date: Sun, 4 Oct 2020 12:02:02 +0200 Subject: [PATCH 12/15] Add seller parameters --- model/users.py | 4 +++- resource/stores.py | 16 ++++++++++++++-- resource/users.py | 3 ++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/model/users.py b/model/users.py index 6f26301..cd6c232 100644 --- a/model/users.py +++ b/model/users.py @@ -22,12 +22,14 @@ class UserModel(db.Model): password = db.Column(db.String(20)) email = db.Column(db.String(40),nullable=False,unique=True) activated = db.Column(db.Boolean,default=False) #set default as False + seller = db.Column(db.Boolean, default=False) - def __init__(self,username,password,email,activated=True): + def __init__(self,username,password,email,activated=True,seller=False): self.username=username self.password=password self.email = email self.activated = activated + self.seller = seller def save_to_db(self): db.session.add(self) diff --git a/resource/stores.py b/resource/stores.py index 1c4f274..7e7d257 100644 --- a/resource/stores.py +++ b/resource/stores.py @@ -1,8 +1,9 @@ from flask_restful import Resource from model.store import StoreModel +from model.users import UserModel from flask import request from schemas.stores import StoreSchema -from flask_jwt_extended import jwt_required,fresh_jwt_required +from flask_jwt_extended import jwt_required,fresh_jwt_required, get_jwt_identity store_schema = StoreSchema() store_list_schema = StoreSchema(many=True) @@ -19,10 +20,16 @@ def get(self): @jwt_required def post(self): + user = UserModel.find_by_id(get_jwt_identity()) + + if not user.seller: + return {"msg": "User is not a seller"}, 403 + data=request.get_json() name=data["name"] - + store = StoreModel.find_by_name(name) + if store: return {"msg": "Store exists already"},400 @@ -36,6 +43,11 @@ def post(self): @fresh_jwt_required def delete(self): + user = UserModel.find_by_id(get_jwt_identity()) + + if not user.seller: + return {"msg": "User is not a seller"}, 403 + data=request.get_json() name=data["name"] diff --git a/resource/users.py b/resource/users.py index c7f8c66..6d9096a 100644 --- a/resource/users.py +++ b/resource/users.py @@ -22,6 +22,7 @@ def post(self): username = data.username passwd = data.password email = data.email + seller = data.seller print(username,passwd,email) hashed = bcrypt.hashpw(passwd.encode('utf-8'),bcrypt.gensalt()) @@ -32,7 +33,7 @@ def post(self): if UserModel.find_by_email(email): return {"msg": "user with email id exists"} - user = UserModel(username,hashed,email) + user = UserModel(username,hashed,email,seller=seller) user.save_to_db() user.generate_mail() #send emails to new users From 03a84ff3ad1d13352f245ece209e9f76aeebc91a Mon Sep 17 00:00:00 2001 From: pulkit Date: Sun, 4 Oct 2020 19:51:45 +0900 Subject: [PATCH 13/15] Fixed order input to accept quantity along with item name --- resource/order.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/resource/order.py b/resource/order.py index ac6809e..331670c 100644 --- a/resource/order.py +++ b/resource/order.py @@ -15,16 +15,17 @@ class Order(Resource): def post(cls): data= request.get_json() items=[] - item_quantity = Counter(data["items"]) + ordered_list = data['items'] # list of dictionaries - for name,count in item_quantity.most_common(): + for ordered_item in data['items']: + name = ordered_item['name'] + count = ordered_item['qty'] res = ItemModel.find_by_name(name) if not res: return {"msg": "Item not present {}".format(name)},404 items.append(ItemsInOrder(item_id=ItemModel.find_id(name),quantity=count)) print(items) - - + order = OrderModel(items=items,status="pending") order.save_to_db() #save orders to database From f0a936b4225630a91f82e40167a5ba19fc064511 Mon Sep 17 00:00:00 2001 From: DiptoChakrabarty Date: Mon, 5 Oct 2020 20:28:36 +0530 Subject: [PATCH 14/15] minor changes in readme and files --- README.md | 19 +++++++++++++++++++ model/__pycache__/users.cpython-36.pyc | Bin 2987 -> 2987 bytes model/users.py | 4 ++-- resource/github_login.py | 17 ++++++++++------- site.db | Bin 40960 -> 40960 bytes 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 00092ce..84f6053 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ### How to run the project :horse_racing: + + ##### To run locally ```sh * Clone the repository git clone https://github.com/DiptoChakrabarty/flask-online-store.git @@ -46,6 +48,23 @@ (it is preferable if you use something as postman as most are post requests) +``` + +##### To run in docker +```sh + * Set environment variables + cp .env.example .env + +* Fill the required parameters + +* If you have removed site.db remove teh following line in Dockerfile + RUN rm site.db + +* Run using + docker-compose up -d to start as background process + +* Head over to http://localhost:5000 + ``` ## Repository Structure :deciduous_tree: diff --git a/model/__pycache__/users.cpython-36.pyc b/model/__pycache__/users.cpython-36.pyc index bfcd4060f75032d3bade1694800a4ba54b9f99a3..724ce5911df0218d0667817df9542d95ea8f8d12 100644 GIT binary patch delta 15 WcmZ22zFM5kn3tDpp2|kHrQ84^4+IMU delta 15 WcmZ22zFM5kn3tC;T6iPdQf>erCTJ{3P{S+ zOEWSrFDwo!F)GNcs!B}C&vZ!7P0Y;E%P&fwJWW0iXyJ1P{^$IkHw!A<=2zurmS%+7 v#l*ub&zYQ2nw$-?nTvsefr$NUom n*u;65x8c From b6a89d4949f24ca6c2afe4bd44b5f9f78954400d Mon Sep 17 00:00:00 2001 From: Dipto Chakrabarty <45638240+DiptoChakrabarty@users.noreply.github.com> Date: Mon, 5 Oct 2020 20:29:48 +0530 Subject: [PATCH 15/15] typo error --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 84f6053..a527338 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * Fill the required parameters -* If you have removed site.db remove teh following line in Dockerfile +* If you have removed site.db then remove the following line in Dockerfile RUN rm site.db * Run using