commit d946e91c1a818946d024d8e0dfee21e7bd7590a1
parent f37ec5bf5dec8be69178c924e5dde5c936392dae
Author: Youth Employment Program Production <youthemployment22@gmail.com>
Date: Fri, 3 May 2024 11:47:41 -0600
bugfix: disallow inactive users from signing in. Add user password reset for admin/users/active route
Diffstat:
3 files changed, 73 insertions(+), 22 deletions(-)
diff --git a/TODO.md b/TODO.md
@@ -43,7 +43,7 @@
## OPTIONAL
- [ ] rework admin page flow to show agency for projects?... wanted to sort and display by agency, but is many to one relationship...
-
+- [ ] When users are set to inactive or active (probably just inactive) should remove all current/existing sessions
#TODO TODAY!!!
- [X] Change username to firstname lastname for today
- [X] change all match from feb 1 to today for nolan to tnc management
diff --git a/app/routes.py b/app/routes.py
@@ -26,6 +26,23 @@ mongo = PyMongo(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
+class UserNotFoundError(Exception):
+ pass
+
+def fetch_user(user_id):
+ user = mongo.db.user_collection.find_one({"_id":ObjectId(user_id)})
+ if user == None:
+ raise UserNotFoundError(f"User id {user_id} returned none")
+ else:
+ return user
+
+def fetch_user_from_username(username):
+ user = mongo.db.user_collection.find_one({"username":username})
+ if user == None:
+ raise UserNotFoundError(f"User name {username} returned none")
+ else:
+ return user
+
def get_available_projects(branch=None):
availableProjects = [("","Select Project")]
for project in mongo.db.projects_collection.find():
@@ -125,19 +142,24 @@ def login():
form = LoginForm()
if form.validate_on_submit():
# 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, 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)
- # check next redirect to stop cross-site-redirects, another example here : http://flask.pocoo.org/snippets/62/
- next = request.args.get('next')
- if not next or url_parse(next).netloc != '':
- next = url_for('dashboard')
- return redirect(next)
- else:
+ try:
+ u = fetch_user_from_username(form.username.data)
+ except:
flash("Invalid username or password")
return redirect(url_for('login'))
+ else:
+ if u['is_active'] and User.check_password(u, 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)
+ # check next redirect to stop cross-site-redirects, another example here : http://flask.pocoo.org/snippets/62/
+ next = 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 redirect(url_for('login'))
return render_template('login.html',form=form,ORGNAME = OrganizationName)
#### ####
@@ -164,6 +186,24 @@ def chgpass():
return redirect(url_for('dashboard'))
return render_template('admin/users/newpass.html',form=form,ORGNAME=OrganizationName)
+
+
+@app.route('/newpass/<uid>',methods=['GET','POST'])
+@login_required
+def chgpass_by_uid(uid):
+ try:
+ user = fetch_user(uid)
+ except:
+ return "User not Found"
+ else:
+ form = ChangePasswordForm()
+ if form.validate_on_submit():
+ mongo.db.user_collection.update_one({'username':user['username']},{'$set':{'password_hash':generate_password_hash(form.newpass.data)}})
+ flash("Changed password for {} to {}".format(user['username'],form.newpass.data)) #Will need to sendmail password to form.email.data later
+
+ return redirect(url_for('dashboard'))
+
+ return render_template('admin/users/newpass.html',form=form,ORGNAME=OrganizationName)
#### ####
####### Dashboard Route #######
#### ####
@@ -186,7 +226,7 @@ def dashboard():
clocked_in_users = mongo.db.time_collection.find({'clock_out': {'$exists':False}})
def clock_user_out(time_id,notes='',lunch=False,perdiem=False):
- if notes != '':
+ if notes != '' and notes != None:
if mongo.db.time_collection.find({'_id': time_id}, {'clock_out':{'$exists':False}}):
if lunch==True and perdiem==True:
mongo.db.time_collection.update_one({'_id':time_id},{'$set':{'clock_out':[datetime.datetime.now()],'note':notes,'lunch':True,'per_diem':True}})
@@ -473,15 +513,25 @@ def updateNote(mod_username,timeid):
except:
flash("Issue finding/assigning time_id: {}".format(timeid))
else:
- newNoted = form.note.data
- try:
- mongo.db.time_collection.update_one({'_id':timeid},{'$set':{'note':newNoted},'$push':{'modified_by':mod_username}})
- except:
- flash("{}: Unable to set note to {}".format(mod_username,newNoted))
+ if form.note.data != None and form.note.data != '':
+ newNoted = form.note.data
+ try:
+ mongo.db.time_collection.update_one({'_id':timeid},{'$set':{'note':newNoted},'$push':{'modified_by':mod_username}})
+ except:
+ flash("{}: Unable to set note to {}".format(mod_username,newNoted))
+ else:
+ flash('Updated note')
+ finally:
+ return redirect(url_for('dashboard'))#TODO RETURN LAST PAGE HERE!
else:
- flash('Updated note')
- finally:
- return redirect(url_for('dashboard'))#TODO RETURN LAST PAGE HERE!
+ try:
+ mongo.db.time_collection.update_one({'_id':timeid},{'$unset':{"note":""},'$push':{'modified_by':mod_username}})
+ except:
+ flash("Unable to remove note")
+ else:
+ flash('Removed note')
+ finally:
+ return redirect(url_for('dashboard'))
return render_template('dashboard/punchclock/update/note.html',form=form, ORGNAME=OrganizationName)
@@ -656,7 +706,7 @@ def new_user_time():
entryevent['modified_by'] = [form.userSel.data]
else:
entryevent['modified_by'] = [form.userSel.data,current_user.username]
- if form.note.data != '':
+ if form.note.data != '' and form.note.data != None:
entryevent['note'] = form.note.data
mongo.db.time_collection.insert_one(entryevent)
diff --git a/app/templates/admin/users/active.html b/app/templates/admin/users/active.html
@@ -8,6 +8,7 @@
<div class="usercard">
<h3>{{ user.fname }} {{ user.mname }} {{ user.lname }}</h3>
<table>
+ <button><a href="{{ url_for('chgpass_by_uid',uid=user._id) }}">Reset Password</a></button>
<tr><td>Username</td><td>{{ user.username }}</td></tr>
<tr><td>Birthday</td><td>{{ user.birthday }}</td></tr>
<tr><td>Role</td><td>{{ user.role }}</td></tr>