Kaynağa Gözat

Security hardening

control 3 yıl önce
ebeveyn
işleme
0f2afeddf2

+ 2 - 0
Pipfile

@@ -9,6 +9,8 @@ flask-login = "*"
 sqlalchemy = "*"
 werkzeug = "*"
 flask-sqlalchemy = "*"
+flask-talisman = "*"
+flask-wtf = "*"
 
 [dev-packages]
 

+ 69 - 45
Pipfile.lock

@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "81b692d6e026efab66d5e448fea07558020c0013eb90ce1a63acfdad9aed5ed4"
+            "sha256": "8b2efca72444dec8e703061b7eed77a1d495f44d97a6b90c7d6c909e097f3b3c"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -48,6 +48,22 @@
             "index": "pypi",
             "version": "==2.5.1"
         },
+        "flask-talisman": {
+            "hashes": [
+                "sha256:205d3de7c5ecfad667c84123f5fbe580b1f68cd9a1b058d7353cc0348e15b1bf",
+                "sha256:be2767b6b2bc11b36bf9a0e09ffa10622fbe0d971fd7057a843f82cd795a854b"
+            ],
+            "index": "pypi",
+            "version": "==1.0.0"
+        },
+        "flask-wtf": {
+            "hashes": [
+                "sha256:34fe5c6fee0f69b50e30f81a3b7ea16aa1492a771fe9ad0974d164610c09a6c9",
+                "sha256:9d733658c80be551ce7d5bc13c7a7ac0d80df509be1e23827c847d9520f4359a"
+            ],
+            "index": "pypi",
+            "version": "==1.0.1"
+        },
         "greenlet": {
             "hashes": [
                 "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3",
@@ -106,7 +122,7 @@
                 "sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c",
                 "sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b"
             ],
-            "markers": "python_version >= '3' and (platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32'))))))",
+            "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
             "version": "==1.1.2"
         },
         "importlib-metadata": {
@@ -181,61 +197,69 @@
         },
         "sqlalchemy": {
             "hashes": [
-                "sha256:045d6a26c262929af0b9cb25441aae675ac04db4ea8bd2446b355617cd6b6b7d",
-                "sha256:07f4dab2deb6d34618a2ccfff3971a85923ad7c3a9a45401818870fc51d3f0cc",
-                "sha256:08aaad905aba8940f27aeb9f1f851bf63f18ef97b0062ca41f64afc4b64e0e8c",
-                "sha256:27a42894a2751e438eaed12fc0dcfe741ff2f66c14760d081222c5adc5460064",
-                "sha256:2a3e4dc7c452ba3c0f3175ad5a8e0ba49c2b0570a8d07272cf50844c8d78e74f",
-                "sha256:345306707bb0e51e7cd6e7573adafbce018894ee5e3b9c31134545f704936db0",
-                "sha256:36f08d94670315ca04c8139bd80b3e02b9dd9cc66fc11bcb96fd10ad51a051ab",
-                "sha256:3ebb97ed96f4506e2f212e1fcf0ec07a103bb194938627660a5acb4d9feae49c",
-                "sha256:40b995d7aeeb6f88a1927ce6692c0f626b59d8effd3e1d597f125e141707b37c",
-                "sha256:4414ace6e3a5e39523e55a5d9f3b215699b2ead4ff91fca98f1b659b7ab2d92a",
-                "sha256:50107d8183da3fbe5715957aa3954cd9d82aed555c5b4d3fd37fac861af422fa",
-                "sha256:50174e173d03209c34e07e7b57cca48d0082ac2390edf927aafc706c111da11e",
-                "sha256:5e88912bf192e7b5739c446d2276e1cba74cfa6c1c93eea2b2534404f6be1dbd",
-                "sha256:621d3f6c0ba2407bb97e82b649be5ca7d5b6c201dcfb964ce13f517bf1cb6305",
-                "sha256:623bac2d6bdca3f3e61cf1e1c466c5fb9f5cf08735736ee1111187b7a4108891",
-                "sha256:671f61c3db4595b0e86cc4b30f675a7c0206d9ce99f041b4f6761c7ddd1e0074",
-                "sha256:67c1c27c48875afc950bee5ee24582794f20b545e64e4f9ca94071a9b514d6ed",
-                "sha256:6a6cfd468f54d65324fd3847cfd0148b0610efa6a43e5f5fcc89f455696ae9e7",
-                "sha256:70048a83f0a1ece1fcd7189891c888e20af2c57fbd33eb760d8cece9843b896c",
-                "sha256:7ee14a7f9f76d1ef9d5e5b760c9252617c839b87eee04d1ce8325ac66ae155c4",
-                "sha256:804cf491437f3e4ce31247ab4b309b181f06ecc97d309b746d10f09439b4eb85",
-                "sha256:878c7beaafa365602762c19f638282e1885454fed1aed86f8fae038933c7c671",
-                "sha256:954ea8c527c4322afb6885944904714893af81fe9167e421273770991bf08a4a",
-                "sha256:a47bf6b7ca6c28e4f4e262fabcf5be6b907af81be36de77839c9eeda2cdf3bb3",
-                "sha256:a4fb5c6ee84a6bba4ff6f9f5379f0b3a0ffe9de7ba5a0945659b3da8d519709b",
-                "sha256:b34bbc683789559f1bc9bb685fc162e0956dbbdfbe2fbd6755a9f5982c113610",
-                "sha256:c025d45318b73c0601cca451532556cbab532b2742839ebb8cb58f9ebf06811e",
-                "sha256:c3ad7f5b61ba014f5045912aea15b03c473bb02b1c07fd92c9d2c794fa183276",
-                "sha256:c9218e3519398129e364121e0d89823e6ba2a2b77c28bfc661face0829c41433",
-                "sha256:cd5cffd1dd753828f1069f33062f3896e51c990acd957c264f40e051b3e19887",
-                "sha256:d8efcaa709ea8e7c08c3d3e7639c39b36083f5a995f397f9e6eedf5f5e4e4946",
-                "sha256:e297a5cc625e3f1367a82deedf2d48ee4d2b2bd263b8b8d2efbaaf5608b5229e",
-                "sha256:e67278ceb63270cdac0a7b89fc3c29a56f7dac9616a7ee48e7ad6b52e3b631e5",
-                "sha256:eb6558ba07409dafa18c793c34292b3265be455904966f0724c10198829477e3",
-                "sha256:f197c66663ed0f9e1178d51141d864688fb244a83f6b17f667d521e482537b2e",
-                "sha256:f47996b1810894f766c9ee689607077c6c0e0fd6761e04c12ba13efb56d50c1d"
+                "sha256:093b3109c2747d5dc0fa4314b1caf4c7ca336d5c8c831e3cfbec06a7e861e1e6",
+                "sha256:186cb3bd77abf2ddcf722f755659559bfb157647b3fd3f32ea1c70e8311e8f6b",
+                "sha256:1b4eac3933c335d7f375639885765722534bb4e52e51cdc01a667eea822af9b6",
+                "sha256:1ff9f84b2098ef1b96255a80981ee10f4b5d49b6cfeeccf9632c2078cd86052e",
+                "sha256:28aa2ef06c904729620cc735262192e622db9136c26d8587f71f29ec7715628a",
+                "sha256:28b17ebbaee6587013be2f78dc4f6e95115e1ec8dd7647c4e7be048da749e48b",
+                "sha256:2c6c411d8c59afba95abccd2b418f30ade674186660a2d310d364843049fb2c1",
+                "sha256:2ffc813b01dc6473990f5e575f210ca5ac2f5465ace3908b78ffd6d20058aab5",
+                "sha256:48036698f20080462e981b18d77d574631a3d1fc2c33b416c6df299ec1d10b99",
+                "sha256:48f0eb5bcc87a9b2a95b345ed18d6400daaa86ca414f6840961ed85c342af8f4",
+                "sha256:4ba2c1f368bcf8551cdaa27eac525022471015633d5bdafbc4297e0511f62f51",
+                "sha256:53c7469b86a60fe2babca4f70111357e6e3d5150373bc85eb3b914356983e89a",
+                "sha256:6204d06bfa85f87625e1831ca663f9dba91ac8aec24b8c65d02fb25cbaf4b4d7",
+                "sha256:63c82c9e8ccc2fb4bfd87c24ffbac320f70b7c93b78f206c1f9c441fa3013a5f",
+                "sha256:70e571ae9ee0ff36ed37e2b2765445d54981e4d600eccdf6fe3838bc2538d157",
+                "sha256:95411abc0e36d18f54fa5e24d42960ea3f144fb16caaa5a8c2e492b5424cc82c",
+                "sha256:9837133b89ad017e50a02a3b46419869cf4e9aa02743e911b2a9e25fa6b05403",
+                "sha256:9bec63b1e20ef69484f530fb4b4837e050450637ff9acd6dccc7003c5013abf8",
+                "sha256:9d8edfb09ed2b865485530c13e269833dab62ab2d582fde21026c9039d4d0e62",
+                "sha256:9dac1924611698f8fe5b2e58601156c01da2b6c0758ba519003013a78280cf4d",
+                "sha256:9e1a72197529ea00357640f21d92ffc7024e156ef9ac36edf271c8335facbc1a",
+                "sha256:9e7094cf04e6042c4210a185fa7b9b8b3b789dd6d1de7b4f19452290838e48bd",
+                "sha256:a4efb70a62cbbbc052c67dc66b5448b0053b509732184af3e7859d05fdf6223c",
+                "sha256:a5dbdbb39c1b100df4d182c78949158073ca46ba2850c64fe02ffb1eb5b70903",
+                "sha256:aeea6ace30603ca9a8869853bb4a04c7446856d7789e36694cd887967b7621f6",
+                "sha256:b2489e70bfa2356f2d421106794507daccf6cc8711753c442fc97272437fc606",
+                "sha256:babd63fb7cb6b0440abb6d16aca2be63342a6eea3dc7b613bb7a9357dc36920f",
+                "sha256:c6fb6b9ed1d0be7fa2c90be8ad2442c14cbf84eb0709dd1afeeff1e511550041",
+                "sha256:cfd8e4c64c30a5219032e64404d468c425bdbc13b397da906fc9bee6591fc0dd",
+                "sha256:d17316100fcd0b6371ac9211351cb976fd0c2e12a859c1a57965e3ef7f3ed2bc",
+                "sha256:d38a49aa75a5759d0d118e26701d70c70a37b896379115f8386e91b0444bfa70",
+                "sha256:da25e75ba9f3fabc271673b6b413ca234994e6d3453424bea36bb5549c5bbaec",
+                "sha256:e255a8dd5572b0c66d6ee53597d36157ad6cf3bc1114f61c54a65189f996ab03",
+                "sha256:e8b09e2d90267717d850f2e2323919ea32004f55c40e5d53b41267e382446044",
+                "sha256:ecc81336b46e31ae9c9bdfa220082079914e31a476d088d3337ecf531d861228",
+                "sha256:effadcda9a129cc56408dd5b2ea20ee9edcea24bd58e6a1489fa27672d733182"
             ],
             "index": "pypi",
-            "version": "==1.4.34"
+            "version": "==1.4.35"
         },
         "werkzeug": {
             "hashes": [
-                "sha256:094ecfc981948f228b30ee09dbfe250e474823b69b9b1292658301b5894bbf08",
-                "sha256:9b55466a3e99e13b1f0686a66117d39bda85a992166e0a79aedfcf3586328f7a"
+                "sha256:3c5493ece8268fecdcdc9c0b112211acd006354723b280d643ec732b6d4063d6",
+                "sha256:f8e89a20aeabbe8a893c24a461d3ee5dad2123b05cc6abd73ceed01d39c3ae74"
             ],
             "index": "pypi",
-            "version": "==2.1.0"
+            "version": "==2.1.1"
+        },
+        "wtforms": {
+            "hashes": [
+                "sha256:6b351bbb12dd58af57ffef05bc78425d08d1914e0fd68ee14143b7ade023c5bc",
+                "sha256:837f2f0e0ca79481b92884962b914eba4e72b7a2daaf1f939c890ed0124b834b"
+            ],
+            "markers": "python_version >= '3.7'",
+            "version": "==3.0.1"
         },
         "zipp": {
             "hashes": [
-                "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d",
-                "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"
+                "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad",
+                "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"
             ],
             "markers": "python_version >= '3.7'",
-            "version": "==3.7.0"
+            "version": "==3.8.0"
         }
     },
     "develop": {}

+ 13 - 0
app/__init__.py

@@ -3,6 +3,9 @@ from flask_sqlalchemy import SQLAlchemy
 from flask_login import LoginManager # Flask Login
 from os import path
 
+# Talisman
+from flask_talisman import Talisman
+
 db = SQLAlchemy()
 DB_NAME = "database.db"
 
@@ -30,11 +33,21 @@ def create_app():
     login_manager.login_view =  'accounts.login'
     login_manager.init_app(app)
 
+    # Cookie Protections
+    app.config.update(
+            SESSION_COOKIE_SECURE=True,
+            SESSION_COOKIE_HTTPONLY=True,
+            SESSION_COOKIE_SAMESITE='Lax',
+            )
+
     @login_manager.user_loader
     # tells flask how to load a user from the db
     def load_user(id):
         return User.query.get(int(id)) # by default get() looks for the primary key
 
+    # Talisman
+    Talisman(app)
+
     return app
 
 

+ 17 - 10
app/accounts.py

@@ -6,13 +6,17 @@ from werkzeug.security import generate_password_hash, check_password_hash
 from .models import User
 from . import db
 
+from .forms import LoginForm, RegForm
+
 accounts = Blueprint('accounts', __name__)
 
 @accounts.route('/login', methods=['GET', 'POST'])
 def login():
-    if request.method == 'POST':
-        email = request.form.get('email')
-        challenge_passwd = request.form.get('passwd_login')
+    form = LoginForm()
+    
+    if form.validate_on_submit():
+        email = form.email.data
+        challenge_passwd = form.passwd.data
 
         user = User.query.filter_by(email=email).first()
         if user:
@@ -25,7 +29,7 @@ def login():
         else:
             flash('Unsucessful Login!', category='error')
     
-    return render_template('login.html', user=current_user)
+    return render_template('login.html', user = current_user, form = form)
     
 @accounts.route('/logout')
 @login_required
@@ -36,11 +40,14 @@ def logout():
 @accounts.route('/register', methods=['GET', 'POST'])
 def register():
     pass_list = list()
-    if request.method == 'POST':
-        email = request.form.get('email') 
-        username = request.form.get('username')
-        passwd_1 = request.form.get('passwd_1')
-        passwd_2 = request.form.get('passwd_2')
+
+    form = RegForm()
+    
+    if form.validate_on_submit():
+        email = form.email.data
+        username = form.username.data
+        passwd_1 = form.passwd_1.data
+        passwd_2 = form.passwd_2.data
 
         # Basic User Input Checks
         email_check = User.query.filter_by(email=email).first()
@@ -73,7 +80,7 @@ def register():
                     return redirect(url_for('dashboards.market'))
                 else:
                     flash('Registration Failed', category='error')
-    return render_template("register.html", user=current_user)
+    return render_template("register.html", user=current_user, form = form)
 
 
 

+ 41 - 17
app/dashboards.py

@@ -8,13 +8,13 @@ from . import dispatch
 from app.lib import clean_file as cf
 from app.lib import tools
 
+from .forms import UPForm, PicForm, CAForm
+
 dashboards = Blueprint('dashboards', __name__)
 
 # Main Pages
 @dashboards.route('/', methods=['GET', 'POST'])
 def market():
-
-    
     listings = List.query.all()
     art = Art.query.all()
     return_list = list()
@@ -29,11 +29,25 @@ def market():
 @dashboards.route('/profile', methods=['GET', 'POST'])
 @login_required
 def profile():
-    # fetch post request
-    if request.method == "POST":
-        cpasswd = request.form.get('current_password')
-        passwd = request.form.get('password')
-        passwd_con = request.form.get('password_confirm')
+    form = UPForm()
+    form2 = PicForm()
+
+    if form2.validate_on_submit():
+        print('passsing')
+        f =  form2.upload.data
+        if cf.allowed_file(f.filename):
+            designated_fn = cf.sanitize(f.filename)
+            f.save(f'{cf.PROFILEPIC_FOLDER}/{designated_fn}')
+            dispatch.save_pp(designated_fn)
+            flash('Updated Profile Picture!', category='success')
+        else:
+            print('you dick')    
+        
+
+    if form.validate_on_submit():
+        cpasswd = form.cpasswd.data
+        passwd = form.passwd_1.data
+        passwd_con = form.passwd_2.data
 
         # password check before update
         if passwd and passwd_con and cpasswd:
@@ -48,27 +62,37 @@ def profile():
     my_art = Art.query.filter_by(owner=current_user.id).all()
     my_creation = Art.query.filter_by(creator=current_user.id).all()
 
-    return render_template('profile.html', user = current_user, my_art = my_art, my_creation = my_creation)
+    return render_template(
+            'profile.html',
+            user = current_user,
+            my_art = my_art,
+            my_creation = my_creation,
+            form = form,
+            form2 = form2
+            )
 
 @dashboards.route('/create_art', methods=['GET', 'POST'])
 @login_required
 def create():
-    # check POST req
-    if request.method == "POST":
-        new_art = request.files.get('art_img')
-        art_name = request.form.get('art_name')
-        art_desc = request.form.get('description')
-        min_price = request.form.get('minimum_price')
-        buyout_price = request.form.get('buyout_price')
-        close_date = request.form.get('closing_date')
+    form = CAForm()
+
+   # check POST req
+    if form.validate_on_submit():
+        new_art = form.upload.data
+        art_name = form.art_name.data
+        art_desc = form.art_desc.data
+        min_price = form.min_price.data
+        buyout_price = form.buyout_price.data
+        close_date = form.close_date.data
 
+        # this may be redundant now that we have WTForms ###
         if tools.check_fields([new_art, art_name, min_price, buyout_price, close_date]):
             if new_art and new_art.filename != '' and cf.allowed_file(new_art.filename):
                 designated_fn = cf.sanitize(new_art.filename)
                 new_art.save(f'{cf.UPLOAD_FOLDER}/{designated_fn}')
                 dispatch.mint(designated_fn, art_name, art_desc, min_price, buyout_price, close_date)
 
-    return render_template('create_art.html', user=current_user)
+    return render_template('create_art.html', user = current_user, form = form)
 	
 # Pop Ups
 @dashboards.route('/modal_home')

BIN
app/database.db


+ 6 - 1
app/dispatch.py

@@ -6,7 +6,7 @@ import os
 from datetime import datetime
 from flask_login import current_user
 
-from .models import Hashchain, Art, List, TX 
+from .models import Hashchain, Art, List, TX , User
 from . import db
 
 from app.lib import clean_file as cf
@@ -65,3 +65,8 @@ def mint(designated_fn, art_name, art_desc, min_price, buyout_price, close_date)
 
     db.session.commit() 
 
+
+def save_pp(pp_path):
+    new_pppath =  User.query.filter_by(id=current_user.id).first()
+    new_pppath.profile_image = pp_path
+    db.session.commit()

+ 43 - 0
app/forms.py

@@ -0,0 +1,43 @@
+from flask_wtf import FlaskForm
+from wtforms import StringField, SubmitField, PasswordField, IntegerField, RadioField, TextAreaField, DateField
+from flask_wtf.file import FileField, FileAllowed, FileRequired
+from wtforms.validators import DataRequired
+
+class LoginForm(FlaskForm):
+    email = StringField(validators=[DataRequired()])
+    passwd = PasswordField(validators=[DataRequired()])
+    submit = SubmitField('Login')
+
+class RegForm(FlaskForm):
+    email = StringField(validators=[DataRequired()])
+    username = StringField(validators=[DataRequired()])
+    passwd_1 = PasswordField(validators=[DataRequired()])
+    passwd_2 = PasswordField(validators=[DataRequired()])
+    submit = SubmitField('Register')
+
+class UPForm(FlaskForm):
+    cpasswd = PasswordField(validators=[DataRequired()])
+    passwd_1 = PasswordField(validators=[DataRequired()])
+    passwd_2 = PasswordField(validators=[DataRequired()])
+    submit = SubmitField('Update Password')
+
+class PicForm(FlaskForm):
+    upload = FileField(validators=[
+        FileRequired(),
+        FileAllowed(['jpg', 'jpeg', 'png'], 'Images only!')
+        ])
+    submit = SubmitField('Update Picture')
+
+class CAForm(FlaskForm):
+    art_name = StringField(validators=[DataRequired()])
+    art_desc = TextAreaField(validators=[DataRequired()])
+    min_price = IntegerField(validators=[DataRequired()])
+    buyout_price = IntegerField(validators=[DataRequired()])
+    close_date = DateField(validators=[DataRequired()])
+    upload = FileField(validators=[
+        FileRequired(),
+        FileAllowed(['jpg', 'jpeg', 'png'], 'Images only!')
+        ])
+    submit = SubmitField('Mint Picture')
+
+

+ 1 - 0
app/lib/clean_file.py

@@ -6,6 +6,7 @@ from . import alphagen as ag
 
 UPLOAD_FOLDER = 'app/static/incoming'
 REPO_FOLDER = 'app/static/repository'
+PROFILEPIC_FOLDER = 'app/static/uploads'
 ALLOWED_EXT = {'png', 'jpg', 'jpeg'}
 
 # Checks file for allowed extension

BIN
app/static/repository/7yDTwiUakqiqTpZS.jpeg


BIN
app/static/repository/website_photo/cross_logo.jpg


BIN
app/static/repository/website_photo/defaultprofileimg.png


BIN
app/static/repository/website_photo/market_top.png


BIN
app/static/repository/website_photo/navbar_icon.png


BIN
app/static/repository/website_photo/painting.jpg


BIN
app/static/repository/website_photo/tick_logo.jpg


BIN
app/static/repository/website_photo/web_icon.png


BIN
app/static/uploads/lj7Czu6aeTXytG4z.jpeg


+ 21 - 13
app/templates/create_art.html

@@ -42,49 +42,54 @@ $(function(){
       <img src="static/templates/painting.jpg" alt="IMG">
     </div>
     <form action="" method="POST" enctype="multipart/form-data" class="contact100-form">
+      {{ form.hidden_tag() }}
       <span class="create_art-form-title">
         <b>Create Art Auction</b>
       </span>
       <!--Input Art Name-->
       <div class="create_art-input-box">
-        <input 
+        <!--<input 
         type="art_name" 
         class="form-control create_art-input" 
         id="art_name"
         name="art_name"
         placeholder="Enter Art Name"
-        />
+        />-->
+        {{ form.art_name(placeholder="Enter Art Name") }}
       </div>
       <!--Input Minimum Price-->
       <div class="create_art-input-box">
-        <input 
+        <!--<input 
         type="number" 
         class="form-control create_art-input" 
         id="minimum_price"
         name="minimum_price"
         placeholder="Enter Minimum Price (USD)"
-        />
+        />-->
+        {{ form.min_price(placeholder="Enter Minimum Price (USD)") }}
       </div> 
       <!--Input Buyout Price-->
       <div class="create_art-input-box">
-        <input 
+        <!--<input 
         type="number" 
         class="form-control create_art-input" 
         id="buyout_price"
         name="buyout_price"
         placeholder="Enter Buyout Price (USD)"
-        />
+        />-->
+        {{ form.buyout_price(placeholder="Enter Buyout Price (USD)") }}
       </div>
       <!--Input Description-->
       <div class="create_art-input-box">
-        <textarea type="description" class="form-control create_art-input description_size" id="description" name="description" placeholder="     Enter Description"></textarea>
+          <!--<textarea type="description" class="form-control create_art-input description_size" id="description" name="description" placeholder="     Enter Description"></textarea>-->
+          {{ form.art_desc(placeholder="Enter Description") }}
       </div>
       <!--Upload Art or choose what they bought before-->
       <hr class="hr_size">
       <div class="row">
         <div class="col input-group-prepend">
           <label class="input-group-text">File upload</label>
-            <input
+            <!--<input
               type="file" 
               id="profile_image" 
               name="profile_image" 
@@ -92,9 +97,10 @@ $(function(){
               value="Upload"
               src="http://example.com/path/to/image.png"
               class="upload_Create_art input-group-text"
-            >
+              >-->
+            {{ form.upload() }}
         </div>
-        <p class="upload_Create_art_position">**Accept Only <b>PNG's</b>, <b>JPEG's</b>**</p>
+        <p class="upload_Create_art_position">**<b>PNG's</b>, <b>JPEG's</b> Only**</p>
       </div>
       <p class="body-column-create_art word_OR_location"><b>OR</b></p>
       <!-- Dropdown Menu-->
@@ -112,7 +118,8 @@ $(function(){
       <div class="row">
         <div class="col input-group-prepend">  
           <span class="input-group-text Choose-Time-for-Auction-ends">Auction End Date</span>
-          <input type="date" id="closing_date" name="closing_date" class="body-column-create_art Closing-date-input-size">
+          <!--<input type="date" id="closing_date" name="closing_date" class="body-column-create_art Closing-date-input-size">-->
+          {{ form.close_date() }}
         </div>
       </div>
       <!-- Tips for the date to let user know-->
@@ -127,9 +134,10 @@ $(function(){
       </div>
       <!-- Button for create Auction-->
       <div class="container-create_art-form-btn">
-        <button class="create_art-form-btn">
+          {{ form.submit() }}
+        <!--<button class="create_art-form-btn">
           <b>Create</b>
-        </button>
+        </button>-->
       </div>
     </form>
   </div>

+ 10 - 6
app/templates/login.html

@@ -3,6 +3,7 @@
 {% block content %}
 
 <form method="POST">
+  {{ form.hidden_tag() }}
   <section class="vh-100 gradient-custom">
     <div class="container py-5 h-100">
       <div class="row d-flex justify-content-center align-items-center h-100">
@@ -14,29 +15,32 @@
                 <p class="text-white-50 mb-5">Please enter your login and password!</p>
                 <!--Input Email-->
                 <div class="form-outline form-white mb-4">
-                  <input 
+                  {{ form.email(placeholder="Email") }} 
+                  <!--<input 
                   type="email" 
                   class="form-control" 
                   id="email"
                   name="email"
                   placeholder="Insert Email"
                   />
-                  <label for="email"></label>
+                  <label for="email"></label>-->
                 </div>
                 <!--Input Password-->
                 <div class="form-outline form-white mb-4">
-                  <input 
+                  {{ form.passwd(placeholder="Password") }}
+                  <!--<input 
                   type="password" 
                   class="form-control" 
                   id="passwd_login"
                   name="passwd_login"
                   placeholder="Enter Password"
                   />
-                  <label for="passwd_login"></label>
+                  <label for="passwd_login"></label>-->
                 </div>
                 <p>***(reCAPTCHA): https://python.plainenglish.io/how-to-use-google-recaptcha-with-flask-dbd79d5ea193***</p>
                 <!--Button: Login-->
-                <button class="btn btn-outline-light btn-lg px-5" type="submit">Login</button>
+                <!--<button class="btn btn-outline-light btn-lg px-5" type="submit">Login</button>-->
+                {{ form.submit() }}
               </div>
               <!--Redirect to Sign up Page-->
               <div>
@@ -49,4 +53,4 @@
     </div>
   </section>
 </form>
-{% endblock %}
+{% endblock %}

+ 23 - 6
app/templates/profile.html

@@ -22,7 +22,11 @@
                                 <div class="mt-3">
                                     <p><b>Upload Profile Image</b></p> 
                                     <form action="" method="POST" enctype="multipart/form-data">
-                                    <input
+                                    {{ form2.hidden_tag() }}
+                                    {{ form2.upload() }}
+                                    <br />
+                                    {{ form2.submit() }}
+                                    <!--<input
                                         class="input-UploadProfile-Browse"
                                         type="file" 
                                         id="profile_image" 
@@ -31,22 +35,33 @@
                                         onchange="form.submit()" 
                                         value="Upload"
                                         src="http://example.com/path/to/image.png"
-                                    >
+                                        >-->
                                     <p>**Accept Only <b>PNG's</b>, <b>JPEG's</b>**</p>
                                     </form>
                                 </div>
                             </div>
                             <!------  Change Password ---------->
                             <form method="POST">
+                                {{ form.hidden_tag() }}
                                 <div class="card-body">
                                     <hr class="hr_size">
                                     <p><b>Change Password</b></p><br>
                                         <div class="row">
                                             <div class="col-sm-3" class="change_password_location">
-                                                <h6 class="mb-0"><label for="password">Password</label></h6><br>
+                                                <h6 class="mb-0"><label for="password">Current Password</label></h6><br>
                                             </div>
                                             <div class="col-sm-9 text-secondary">
-                                                <input type="text" id="password" name="password"><br>
+                                                {{ form.cpasswd() }}
+                                                <!--<input type="text" id="password" name="password"><br>-->
+                                            </div>
+                                        </div>
+                                        <div class="row">
+                                            <div class="col-sm-3" class="change_password_location">
+                                                <h6 class="mb-0"><label for="password">New Password</label></h6><br>
+                                            </div>
+                                            <div class="col-sm-9 text-secondary">
+                                                {{ form.passwd_1() }}
+                                                <!--<input type="text" id="password" name="password"><br>-->
                                             </div>
                                         </div>
                                     <div class="row">
@@ -54,12 +69,14 @@
                                             <h6 class="mb-0"><label for="password_confirm">Password<br>(Confirm)</label></h6><br>
                                         </div>
                                         <div class="col-sm-9 text-secondary">
-                                            <input type="text" id="password_confirm" name="password_confirm">
+                                            {{ form.passwd_2() }}
+                                            <!--<input type="text" id="password_confirm" name="password_confirm">-->
                                         </div>
                                     </div>
                                     <div class="row">
                                         <div class="col-sm-12">
-                                            <input type="submit" value="Submit" class="btn btn-grey update_password-form-btn"></a>
+                                            {{ form.submit() }}
+                                            <!--<input type="submit" value="Submit" class="btn btn-grey update_password-form-btn"></a>-->
                                         </div>
                                     </div>
                                     <hr class="hr_size">

+ 20 - 24
app/templates/register.html

@@ -3,6 +3,7 @@
 {% block content %}
 
 <form method="POST">
+  {{ form.hidden_tag() }}
   <section class="vh-100 gradient-custom">
     <div class="container py-5 h-100">
       <div class="row d-flex justify-content-center align-items-center h-100">
@@ -14,63 +15,58 @@
                 <p class="text-white-50 mb-5">Create your Account</p>
                 <!--Input: Email-->
                 <div class="form-outline form-white mb-3">
-                  <label for="email_2"></label>
+                  {{ form.email(placeholder="Email") }}
+                  <!--<label for="email_2"></label>
                   <input 
                     type="email" 
                     class="form-control" 
                     id="email"
                     name="email"
                     placeholder="Insert Email"
-                  />
+                    />-->
                 </div>
+                <!--Input: Username-->
                 <div class="form-outline form-white mb-3">
-                  <label for="email_2"></label>
+                  {{ form.username(placeholder="Username") }}
+                  <!--<label for="Nickname"></label>
                   <input 
-                    type="email" 
+                    type="text" 
                     class="form-control" 
-                    id="email_2"
-                    name="email_2"
-                    placeholder="Confirm Email"
-                  />
+                    id="username"
+                    name="username"
+                    placeholder="Insert User Name"
+                    />-->
                 </div>
                 <!--Input: Password-->
                 <div class="form-outline form-white mb-3">
-                  <label for="passwd_1"></label>
+                  {{ form.passwd_1(placeholder="Password") }}
+                  <!--<label for="passwd_1"></label>
                   <input 
                     type="password" 
                     class="form-control" 
                     id="passwd_1"
                     name="passwd_1"
                     placeholder="Enter Password"
-                  />
+                    />-->
                   <p class="tips_8characters">*Use 8 or more characters</p>
                 </div>
                 <!--Input: Password Confirm-->
                 <div class="form-outline form-white mb-3">
-                  <label for="passwd_2"></label>
+                  {{ form.passwd_2(placeholder="Confirm Password") }}
+                  <!--<label for="passwd_2"></label>
                     <input 
                       type="password" 
                       class="form-control" 
                       id="passwd_2"
                       name="passwd_2"
                       placeholder="Confirm Password"
-                    />
-                </div>
-                <!--Input: Username-->
-                <div class="form-outline form-white mb-3">
-                  <label for="Nickname"></label>
-                  <input 
-                    type="text" 
-                    class="form-control" 
-                    id="username"
-                    name="username"
-                    placeholder="Insert User Name"
-                  />
+                      />-->
                 </div>
                 <p>***(After Register): 1.Required Email Confirmation https://realpython.com/handling-email-confirmation-in-flask/*** </p>
                 <p>2. 2FA (Google Authenticator): https://github.com/GitauHarrison/how-to-implement-time-based-two-factor-auth-in-flask</p>
                 <!--Button: Sign up-->
-                <button class="btn btn-outline-light btn-lg px-5" type="submit">Sign up</button>
+                {{ form.submit() }}
+                <!--<button class="btn btn-outline-light btn-lg px-5" type="submit">Sign up</button>-->
               </div>
               <!--Redirect to Login Page-->
               <div>