def set_new_password(user): """updates a user password from the reset page""" try: data = request.get_json() email = user["email"] new_password = data["password"] check_for_whitespace(data, ["email", "password"]) isValidEmail(email) isValidPassword(new_password) User.query.filter_by(email=user["email"]).update( dict(password=f"{generate_password_hash(str(new_password))}")) db.session.commit() subject = """Password updated successfully.""" content = f""" {password_reset_success_content()} <a href="/forgot" style="{button_style()}" >Forgot Password</a> {email_signature()} """ send_mail(email, subject, content) return custom_make_response( "data", "Your password has been updated successfully", 200) except Exception as e: abort( custom_make_response("error", f"The following error ocurred: {e}", 400))
def reactivate_system_user(user): """ reactivate a suspended user account check if account is suspended if not then notify the user no need proceeding if account if already active. """ try: data = request.get_json() email = data["email"] check_for_whitespace(data, ["email"]) isValidEmail(email) employee = employee_schema.dump( Employees.query.filter_by(companyId=user['companyId']).filter_by( email=email).first()) if not employee: abort(403) user = user_schema.dump( User.query.filter_by(email=email).filter_by( companyId=user['companyId']).first()) if employee and not user: abort(404) if user['isActive'] == 'true': abort(400) User.query.filter_by(email=email).update(dict(isActive="true")) db.session.commit() return custom_make_response("data", "User account activated successfully", 200) except Exception as e: if (e.code == 400): return custom_make_response("error", "The user account is already active.", 400) elif (e.code == 403): return custom_make_response( "error", "The user whose account you are trying to activate \ is not a member of your company", 403) elif (e.code == 404): return custom_make_response( "error", "You are trying to activate an account\ that does not exist, Please create one.", 404)
def suspend_system_user(user): """ suspend a system user """ try: data = request.get_json() email = data["email"] check_for_whitespace(data, ["email"]) isValidEmail(email) employee = employee_schema.dump( Employees.query.filter_by(companyId=user['companyId']).filter_by( email=email).first()) if not employee: abort(400) user = user_schema.dump( User.query.filter_by(email=email).filter_by( companyId=user['companyId']).first()) if employee and not user: abort(404) if user['isActive'] == 'false': abort(403) User.query.filter_by(email=email).update(dict(isActive="false")) db.session.commit() return custom_make_response("data", "User account suspended successfully", 200) except Exception as e: if (e.code == 400): return custom_make_response( "error", "The user you are trying to suspend \ is not a member of your company", 400) elif (e.code == 404): return custom_make_response( "error", "The employee you are trying to\ suspend is not a system user.", 404) elif (e.code == 403): return custom_make_response( "error", "The user account is already suspended.", 403) else: return custom_make_response( "error", "An internal server error occured,\ the site admin has been notified, \ please give it a moment and try again.", 500)
def company_signup_intent(): """ send a sign up link on the email to would be customers """ try: data = request.get_json() email = data["email"] company = data["company"] id = generate_db_ids() check_for_whitespace(data, ["email", "company"]) if not (email and company): abort(400) isValidEmail(email) if Company.query.filter_by(company=data["company"]).first(): abort(409) token = jwt.encode( { "email": email, "company": company, "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30), }, KEY, algorithm="HS256", ) # send signup intent email subject = f"""Thank you for requesting to register {company}.""" content = f""" Welcome , <br/> <br/> We are grateful to have you.<br/> Please click on register below to register your personal information to start using the system.<br/>Kindly note this link will only be active for thirty minutes. <br/> <br/> <a href="{signup_url}?in={token.decode('utf-8')}" style="{button_style()}">Register</a> <br/> <br/> Regards Antony,<br/> RMS Admin. """ new_company = Company(id=id, company=company, joined_at=datetime.datetime.utcnow()) db.session.add(new_company) db.session.commit() send_mail(email, subject, content) resp = custom_make_response( "data", { "message": f"Link to register {company} sent \ successfully,head over to {email} inbox for instructions", "admin_token": token.decode('utf-8'), "company": { "company": company, "email": email } }, 201) return resp except Exception as e: error = "" if (e.code == 409): error = custom_make_response( "error", "Your company is already registered, please\ contact the company admin.", 409, ) elif (e.code == 404): error = custom_make_response( "error", "Please enter a valid email address.", 404) elif (e.code == 400): error = custom_make_response( "error", "One or more mandatory fields has not been filled.", 400) return error
def insert_admin_employee(company): """ insert admin details to the employee table. """ try: user_data = request.get_json() id = generate_db_ids() this_company = Company.query.filter_by( company=user_data["company"]).first() _company = company_schema.dump(this_company) companyId = _company["id"] fullname = user_data["fullname"] # mobile = user_data["mobile"] email = user_data["email"] password = user_data["password"] role = user_data["role"] isActive = user_data["isActive"] # check data for sanity incase it bypass js on the frontend check_for_whitespace( user_data, [ "companyId", "fullname", "email", # "mobile", "password", "role", "isActive", ], ) if (company['id'] != companyId): abort( custom_make_response( "error", "There is a mismatch in your token info,\ we could not complete the request,\ Please reopen this page and try again.", 401 ) ) isValidEmail(email) new_employee = Employees( id=id, companyId=companyId, fullname=fullname, # mobile=mobile, email=email, ) db.session.add(new_employee) db.session.commit() # once you have created an admin as an employee # let create them as user in the system. isValidPassword(password) new_user = User( id=id, username=user_data["fullname"].split(" ")[0] + "." + id, email=email, password=password, role=role, companyId=companyId, isActive=isActive, ) db.session.add(new_user) db.session.commit() return custom_make_response( "data", "Registration completed Successfully,\ you can now signin & start using the system.", 201, ) except Exception as e: message = str(e) if "UniqueViolation" and "Employees_mobile_key" in message: abort( custom_make_response( "error", "The mobile number you have entered seems\ to have been registered to another user,\ please change and try again. ", 409, ) ) elif "Employees_email_key" and "UniqueViolation" in message: abort( custom_make_response( "error", "The email address you have entered seems\ to have been registered to another user,\ please change and try again. ", 409, ) ) else: abort( custom_make_response( "error", message, 500, ) )
def signup_system_users(): """ signup system users """ try: user_data = request.get_json() role = user_data["role"] if role == "Admin": this_company = Company.query.filter_by( company=user_data["company"]).first() _company = company_schema.dump(this_company) companyId = _company["id"] password = user_data["password"] else: companyId = user_data["companyId"] password = generate_random_password() email = user_data["email"] isActive = user_data["isActive"] this_employee = (Employees.query.filter_by( email=user_data["email"]).filter_by( companyId=user_data["companyId"]).first()) employee = employee_schema.dump(this_employee) id = employee["id"] username = employee["fullname"].split(" ")[0] + "." + id # check data for sanity incase it bypass js on the frontend check_for_whitespace( user_data, ["companyId", "username", "email", "password", "role", "status"]) isValidEmail(email) # check if user is already registered if User.query.filter_by(email=user_data["email"]).first(): abort(409) isValidPassword(password) new_user = User( id=id, username=username, email=email, password=password, companyId=companyId, role=role, isActive=isActive, ) db.session.add(new_user) db.session.commit() if role != "Admin": token = jwt.encode( { "id": id, "email": user_data["email"], "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30) }, KEY, algorithm="HS256", ) subject = """Activate your account.""" content = f""" Hey {username.split('.', 1)[0]}, {non_admin_user_registration_content()} <a href="{password_reset_url}?u={token.decode('utf-8')}" style="{button_style()}">Activate account</a> {email_signature()} """ send_mail(email, subject, content) return custom_make_response( "data", f"User registered successfully, email sent to {email}\ for further instructions.", 201, ) except Exception as e: message = str(e) if "id" in message: return custom_make_response( "error", "The user you are creating an account for\ is not on your company masterfile,\ Please add them and try again.", 400, ) elif (e.code == 409): return custom_make_response( "error", "A user account with that email already exists,\ please use another one and try again.", 409, ) else: return custom_make_response( "error", "Bummer an internal server error occured\ site admin has been notified, please give\ it a moment and try again.", 500)
def forgot_password(): """send reset password email""" try: user_data = request.get_json() email = user_data["email"] check_for_whitespace(user_data, ["email"]) isValidEmail(email) user = User.query.filter_by(email=user_data["email"]).first() if not user: # well this is interesting we are aborting with a code # 200 normally this is not the case but for this one we # have to make an exception reason being we don't # want to allow enumeration attacks on our system so we # we want to make it like we sending the email even though # that will not always be the case. abort(200) this_user = user_schema.dump(user) token = jwt.encode( { "id": this_user["id"], "email": this_user["email"], "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30), }, KEY, algorithm="HS256", ) subject = """Password reset request""" content = f""" Hey {this_user['username'].split('.', 1)[0]}, {password_reset_request_content()} <a href="{password_reset_url}?u={token.decode('utf-8')}" style="{button_style()}" >Reset Password</a> {email_signature()} """ send_mail(email, subject, content) resp = custom_make_response( "data", { "message": "An email has been sent to the address on record,\ If you don't receive one shortly, please contact\ the site admin.", }, 202) return resp except Exception as e: # exceptions go to site administrator and email # the user gets a friendly error notification if (e.code == 200): return custom_make_response( "data", { "message": "An email has been sent to the address on record,\ If you don't receive one shortly, please contact\ the site admin.", }, 200) elif (e.code == 400): return custom_make_response( "error", "Please enter an email and try again.", 400) else: return custom_make_response( "error", "Bummer an internal server error has occured\ the site admin has been notified, Please\ give it some moment and try again.", 500)
def signin_all_users(): """ this signs in all users """ try: user_data = request.get_json() email = user_data["email"] password = user_data["password"] # check data for sanity incase it bypass js on the frontend check_for_whitespace(user_data, ["email", "password"]) isValidEmail(email) user = User.query.filter_by(email=user_data["email"]).first() if not user: abort(401) _user = user_schema.dump(user) _password_hash = _user["password"] if not User.compare_password(_password_hash, password): abort(401) _curr_user = user_schema.dump(user) if _curr_user["isActive"] != "true": abort(403) token = jwt.encode( { "id": _curr_user["id"], "role": _curr_user["role"], "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=480), }, KEY, algorithm="HS256", ) resp = custom_make_response( "data", { "message": "Signed in successfully, \ preparing your dashboard...", "auth_token": token.decode('utf-8'), "username": _curr_user["username"], "role": _curr_user["role"], "companyId": _curr_user["companyId"] }, 200) return resp except Exception as e: if (e.code == 401): return custom_make_response( "error", "Incorrect email and or password, check & try again !", 401) elif (e.code == 403): return custom_make_response( "error", "Your account is not in active\ status, contact company admin.", 403, ) elif (e.code == 400): return custom_make_response( "error", "One or more mandatory fields has not been filled.", 400) else: return custom_make_response( "error", "Bummer an internal server error has occured,\ the site admin has been notified, Please give it a \ moment and try again.", 500)