commit e22804616be78b7f463ad9df7c10e331dbc1b79e
parent f527b58a30c766e70d57473b964fb59ea9e5022e
Author: Brennen T. Mazur <brennen@madis.cool>
Date: Fri, 27 Jan 2023 09:06:35 -0700
fix load_user() and login related functions and methods
Diffstat:
6 files changed, 86 insertions(+), 48 deletions(-)
diff --git a/app/forms.py b/app/forms.py
@@ -10,11 +10,10 @@ from wtforms.validators import DataRequired, optional
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
- remember_me = BooleanField('Remember Me')
login = SubmitField('Login')
class PunchclockWidget(FlaskForm):
- projectsSel = SelectField('Project', validators=[DataRequired()], coerce=str, choices=[])
+ projectsSel = SelectField('Project', validators=[DataRequired()])
#clockin = currenttime
lunchBox = BooleanField('Lunch')
perdiumBox = BooleanField('Perdium')
diff --git a/app/models.py b/app/models.py
@@ -14,19 +14,54 @@ from werkzeug.security import generate_password_hash, check_password_hash
#from app import db
class User:
+
+ def __init__(self, fname, mname, lname, email, phonenumber, branch, address, birthday, role):
+ self.fname = str(fname)
+ self.mname = str(mname)
+ self.lname = str(lname)
+ self.username = self.fname + self.mname + self.lname
+ self.email = email
+ self.phonenumber = int(phonenumber)
+ self.branch = str(branch)
+ self.address = address
+ self.birthday = birthday
+ self.role = role
+
+ def set_password(self, password):
+ self.password_hash = generate_password_hash(password)
+
+ def check_password(self, password):
+ return check_password_hash(self.password_hash, password)
+
+ @staticmethod
+ def is_authenticated():
+ return True
+
+ @staticmethod
+ def is_active():
+ return True
+
+ @staticmethod
+ def is_anonymous():
+ return False
+
+ def get_id(self):
+ return self.username
+
- def start_session(self, user):
- del user['password']
- session['logged_in'] = True
- session['user'] = user
- return jsonify(user), 200
+
+ #def start_session(self, user):
+ # del user['password']
+ # session['logged_in'] = True
+ # session['user'] = user
+ #return jsonify(user), 200
def signup(self):
print(request.form)
user = {
'_id': uuid.uuid4().hex,
- 'username': request.form.get('Username'),
- 'password': request.form.get('Password'),
+ 'username': request.form.get('username'),
+ 'password_hash': request.form.get('password'),
'role': request.form.get('Role'),
'location': request.form.get('Primary Location'),
'phone': request.form.get('Phone Number'),
@@ -41,7 +76,7 @@ class User:
def signout(self):
session.clear()
- return redirect('/loginModel')
+ return redirect('/login')
# def loginModel(self):
# user = db.user.find_one({
@@ -58,24 +93,6 @@ class User:
assert v.isalnum(), 'Username must be alphanumeric'
return v
- @staticmethod
- def is_authenticated():
- return True
-
- @staticmethod
- def is_active():
- return True
-
- @staticmethod
- def is_anonymous():
- return False
-
- def get_id(self):
- return self.username
-
- @staticmethod
- def check_password(password_hash, password):
- return check_password_hash(password_hash, password)
class Time:
diff --git a/app/routes.py b/app/routes.py
@@ -11,7 +11,6 @@ from flask_login import current_user, login_user, logout_user, login_required
from app.models import User, Time, Fleet, Agreement, Projects
OrganizationName = 'Youth Employment Program' # Maybe pass this as a value though the object for relevant pages???
-user_data = {'fname':'Brennen','lname':'Mazur','role':'Crew Lead','clocked_in':True}
# DB Connection & LoginManager init
mongo = PyMongo(app)
@@ -38,36 +37,51 @@ def signout():
def hello():
return render_template('index.html',ORGNAME = OrganizationName) #This implimentation of ORGNAME is messy, maybe abstract to a defPage()?
+@app.route("/logout", methods=['GIT'])
+@login_required
+def logout():
+ logout_user()
+ return redirect(url_for('login'))
+
@app.route("/login", methods=['GET', 'POST'])
def login():
+ if current_user.is_authenticated:
+ return redirect(url_for('dashboard'))
form = LoginForm()
if form.validate_on_submit():
- login_user(user)
- flask.flash('Logged in successfully.')
- next = flask.request.args.get('next')
- # is_safe_url should check url for safe redirects
- # example here : http://flask.pocoo.org/snippets/62/
- if not is_safe_url(next):
- return flask.abort(400)
-
- return flask.redirect(next or flask.url_for('dashboard'))
+ # check form value for identity in db, if found AND form password matches stored hash, create User object
+ u = mongo.db.user_collection.find_one({"username": form.username.data})
+ if u and User.check_password(u['password'], form.password.data):
+ user_obj = User(fname=u['fname'],mname=u['mname'],lname=u['lname'],email=u['email'],branch=u['branch'],address=u['address'],birthday=u['birthday'],role=u['role'],phonenumber=u['phonenumber'])
+ #login with new user object
+ login_user(user_obj)
+ flask.flash('Logged in successfully.')
+ # check next redirect to stop cross-site-redirects, another example here : http://flask.pocoo.org/snippets/62/
+ next = flask.request.args.get('next')
+ if not next or url_parse(next).netloc != '':
+ next = url_for('dashboard')
+ return redirect(next)
+ else:
+ flash("Invalid username or password")
return render_template('login.html',form=form,ORGNAME = OrganizationName)
+#load user_data into User object iff username == stored username
@login_manager.user_loader
def load_user(username):
- u = mongo.db.Users.find_one({"Name": username})
+ u = mongo.db.user_collection.find_one({"username": username})
if not u:
return None
- return User(username=u['name'])
+ return User(fname=u['fname'],mname=u['mname'],lname=u['lname'],email=u['email'],branch=u['branch'],address=u['address'],birthday=u['birthday'],role=u['role'],phonenumber=u['phonenumber'])
@app.route("/dashboard")
+@login_required
def dashboard():
form=PunchclockWidget()
currenttime=datetime.datetime.utcnow()
- available_projects = [('stcapp','STC Webapp'),('yepsite','YEP Website'),('volday','Volunteer Day')]
+ available_projects = {'STC Webapp':'stcapp','YEP Website':'yepsite','Volunteer Day':'volday'}
- return render_template('dashboard/layout.html',currenttime=currenttime,user=user_data,projects=available_projects,form=form,ORGNAME=OrganizationName)
+ return render_template('dashboard/layout.html',currenttime=currenttime,projects=available_projects,form=form,ORGNAME=OrganizationName)
@app.route("/admin")
def admin():
@@ -75,7 +89,7 @@ def admin():
@app.route("/hours")#modify to take userid ex. /hours<userid> for "admin"
def hours():#userid goes into call to db to get user[] -> then returns formatted table (punchclock/index.html
- return render_template ('dashboard/punchclock/index.html',user=user_data,ORGNAME=OrganizationName)
+ return render_template ('dashboard/punchclock/index.html',user=user,ORGNAME=OrganizationName)
@app.route("/fleet")
def fleet():
diff --git a/app/templates/dashboard/punchclock/widget.html b/app/templates/dashboard/punchclock/widget.html
@@ -13,5 +13,5 @@
<p>{ form.perdiumBox() }} {{ form.perdiumBox.label }}</p>
-->
<button><a href="{{ url_for('hours') }}">Change Hours</a></button><!--routes to userhours.html-->
- <h2>{{ user.fname }} {{ user.lname }}</h2><!-- something like currenttime above -->
+ <h2>{{ current_user.fname }} {{ current_user.lname }}</h2><!-- something like currenttime above -->
</section>
diff --git a/app/templates/login.html b/app/templates/login.html
@@ -15,7 +15,6 @@
{{ form.password.label }}<br>
{{ form.password(size=32) }} <!-- is it necessary to limit password lenght? -->
</p>
- <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
<p>{{ form.login() }}</p>
</form>
<!-- old version before structure change -->
diff --git a/seeds.py b/seeds.py
@@ -7,10 +7,18 @@ collection = db.get_collection('user_collection')
x = collection.delete_many({})
# Database collections/documents
+# Example create user via User constructor(all fields required)
+u2 = User(fname='hiccup',mname='',lname='crawford',email='hiccup@example.com',branch='Dillon', address='705 N Railroad Ave, Dillon MT, 59725',birthday='2022-11-17',role='Dog',phonenumber='3074380491')
+#create password
+u2.set_password('hiccupmonster')
+#document/json user_data, will have User.__init__() create userobj (routes.py)
+#pw is 'password'
user1 = {
- 'username': 'Nikolas',
- 'password': 'password',
+ 'fname': 'Nikolas',
+ 'mname': 'M',
+ 'lname': 'Mazur',
+ 'password_hash': 'pbkdf2:sha256:260000$DBIF9Dfq1OcsYwSk$37f5cc231ff2c97cc7a6b60f25c767380574f1c01cc17069da4f3e7e25ba3370',
'role': 'Developer',
'location': 'Lander',
'phone': 3074380460,
@@ -20,9 +28,10 @@ user1 = {
'is_active':False
}
+#pw is 'password2'
user2 = {
'username': 'Brennen',
- 'password': 'password',
+ 'password_hash': 'pbkdf2:sha256:260000$ukazhSEG3m9xH2oL$5cc00ff3411f614720287c18f615d71578face70abc990ea5def89f520b0ac2c',
'role': 'Developer',
'location': 'Dillon',
'phone': 3074380491,