def web_request_selected(): """ Process a session request unless the session is already expired. """ if SESSION_USERID in session: userid = session[SESSION_USERID] email = session[SESSION_EMAIL] else: # Session Timeout app.logger.error("web_request_selected: session expired") rendered = render_template("login_form.html", frm_uname=UNAME, frm_userid="", frm_password="", frm_status="* PREVIOUS SESSION EXPIRED *") return ensure_no_caching(rendered), 200 function = request.form["function"] if app.debug: app.logger.debug( "web_request_selected: form with function {%s} received", function) if function == "csr": rendered = render_template("csr_form.html", frm_uname=UNAME, frm_userid=userid, frm_email=email, frm_status="") return ensure_no_caching(rendered) if function == "chgpswd": rendered = render_template("chgpswd_form.html", frm_uname=UNAME, frm_userid=userid, frm_email=email, frm_status="") return ensure_no_caching(rendered) if function == "logout": wtext = util.sprintf("User {%s} logged out", userid) rendered = render_template("login_form.html", frm_uname=UNAME, frm_userid="", frm_password="", frm_status=wtext) app.logger.info("web_request_selected: " + wtext) response = ensure_no_caching(rendered) response.set_cookie(SESSION_COOKIE_NAME, "", expires=0) session.clear() return response, 200 # Unrecognizable function - impossible! wtext = util.sprintf( "web_request_selected: *** function {%s} is unsupported; logged out ***", function) app.logger.error(wtext) response = build_logout_response("<h3>*** " + wtext + "</h3>") return response, 400
def delete_user(): """ Delete a user """ userid = get_user_id() if userid == "": return ptext = util.sprintf("delete_user: Are you REALLY REALLY REALLY sure that you want to delete user {%s}? (y/Y=yes; anything else=no): ", userid) yesorno = prompt(ptext) if yesorno in ("y", "Y"): with app.app_context(): # Open database dbpath = app.config["DBPATH"] util.dbopen(dbpath) # User exists? row = util.dbuser_get(userid) if row is None: app.logger.error("delete_user: User {%s} does not exist", userid) util.dbclose() return # Remove user if util.dbuser_remove(userid): app.logger.info("delete_user: User {%s} deleted", userid) # Close database util.dbclose() else: print("delete_user: Cancelled")
def web_request_initial_contact(): """ Main entry point (/) if in session, stay in session --> main_form Else, present login form """ if SESSION_USERID in session: userid = session[SESSION_USERID] email = session[SESSION_EMAIL] if app.debug: app.logger.debug( "web_request_initial_contact: Already in session with user {%s}", userid) hello = util.sprintf("Hello, %s", userid) rendered = main_form_renderer(userid, email, hello) return ensure_no_caching(rendered), 200 # Not currently in session if app.debug: app.logger.debug( "web_request_initial_contact: Not currently in session") rendered = render_template("login_form.html", frm_uname=UNAME, frm_userid="", frm_password="", frm_status="") return ensure_no_caching(rendered), 200
def web_request_change_password(): """ Change password request. """ if SESSION_USERID in session: userid = session[SESSION_USERID] email = session[SESSION_EMAIL] else: # Session Timeout app.logger.error("web_request_change_password: session expired") rendered = render_template("login_form.html", frm_uname=UNAME, frm_userid="", frm_password="", frm_status="* PREVIOUS SESSION EXPIRED *") return ensure_no_caching(rendered), 200 # Hash the current password password = util.hash_a_secret(request.form["password"]) # Get database row for this userid row = util.dbuser_get(userid) if row is None: # User not found - impossible! wtext = util.sprintf( "web_request_change_password: user {%s} NOT FOUND; logged out", userid) app.logger.error(wtext) response = build_logout_response("<h3>*** " + wtext + "</h3>") return response, 400 # Extract row columns for userid (dummy, email, db_password, stamp) = row # Valid password entered? if password != db_password: #Invalid password app.logger.error( "web_request_change_password: user {%s} provided an INVALID PASSWORD", userid) rendered = render_template("chgpswd_form.html", frm_uname=UNAME, frm_userid=userid, frm_password=email, frm_status="* INVALID PASSWORD *") return ensure_no_caching(rendered), 200 # Hash the new password field ok_password = util.hash_a_secret(request.form["password1"]) # Update user with new password if util.dbuser_update_password(userid, ok_password): # Success rendered = main_form_renderer(userid, email, "Password changed") app.logger.info( "web_request_change_password: userid {%s / %s} successfully changed password", userid, email) return ensure_no_caching(rendered), 200 # Report database update error app.logger.error( "web_request_change_password: Could not update password for user {%s}", userid) rendered = main_form_renderer(userid, email, "*** Password change FAILED ***") return ensure_no_caching(rendered), 204
def web_request_register(): """ Process a web register form """ userid = request.form["userid"] email = request.form["email"] # Validate email address if not util.verify_email_recipient(email): rendered = render_template("register_form.html", frm_uname=UNAME, frm_userid=userid, frm_email=email, frm_password1="", frm_password2="", frm_status="* INVALID EMAIL ADDRESS *") app.logger.error( "web_request_register: userid {%s / %s} provided an INVALID EMAIL ADDRESS", userid, email) return ensure_no_caching(rendered), 200 # Hash the first password field (Javascript in the register_form ensured that they are equal) ok_password = util.hash_a_secret(request.form["password1"]) # Add user to database if util.dbuser_add(userid, ok_password, email): # Success session[SESSION_USERID] = userid session[SESSION_EMAIL] = email hello = util.sprintf("Hello, %s", userid) rendered = main_form_renderer(userid, email, hello) app.logger.info( "web_request_register: userid {%s / %s} successfully registered", userid, email) return ensure_no_caching(rendered), 200 # Failed, user already exists app.logger.error("web_request_register: user {%s} already exists", userid) rendered = render_template("register_form.html", frm_uname=UNAME, frm_userid=userid, frm_email=email, frm_password1="", frm_password2="", frm_status="* USER ALREADY EXISTS *") return ensure_no_caching(rendered), 200
def web_request_login(): """ Process a web login form (userid, password) """ userid = request.form["userid"] if app.debug: app.logger.debug("web_request_login: userid is {%s}", userid) # Hash the password password = util.hash_a_secret(request.form["password"]) # Get database row for this userid row = util.dbuser_get(userid) if row is None: # User not found app.logger.error("web_request_login: user {%s} NOT FOUND", userid) rendered = render_template("login_form.html", frm_uname=UNAME, frm_userid=userid, frm_password="", frm_status="* NO SUCH USER ID *") return ensure_no_caching(rendered), 200 # Extract row columns for userid (dummy, email, db_password, stamp) = row # Valid password entered? if password != db_password: #Invalid password app.logger.error( "web_request_login: user {%s} provided an INVALID PASSWORD", userid) rendered = render_template("login_form.html", frm_uname=UNAME, frm_userid=userid, frm_password=email, frm_status="* INVALID PASSWORD *") return ensure_no_caching(rendered), 200 # Password valid session[SESSION_USERID] = userid session[SESSION_EMAIL] = email hello = util.sprintf("Hello, %s", userid) rendered = main_form_renderer(userid, email, hello) app.logger.info("web_request_login: user {%s} successfully logged in", userid) return ensure_no_caching(rendered), 200
def reset_password(): """ Reset a user's password to RESET_PASSWORD """ userid = get_user_id() if userid == "": return ptext = util.sprintf("reset_password: Are you REALLY REALLY REALLY sure that you want to reset the password of user {%s}? (y/Y=yes; anything else=no): ", userid) yesorno = prompt(ptext) if yesorno in ("y", "Y"): with app.app_context(): # Open database dbpath = app.config["DBPATH"] util.dbopen(dbpath) # Reset password hashed_password = util.hash_a_secret(RESET_PASSWORD) # Update the user's password if util.dbuser_update_password(userid, hashed_password): app.logger.info("reset_password: User {%s} password set to {%s}", userid, RESET_PASSWORD) # Close database util.dbclose() else: print("reset_password: Cancelled")
return # Remove user if util.dbuser_remove(userid): app.logger.info("delete_user: User {%s} deleted", userid) # Close database util.dbclose() else: print("delete_user: Cancelled") #------------ Begin Launched Program ------------------------------------ if __name__ == "__main__": nargs = len(sys.argv) # Ensure that there are no arguments after python program name if nargs != 1: text = util.sprintf("Command line error, nargs=%s, should be 1", nargs) print(text) sys.exit(86) # Catch termination signals signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) # Connect to application configuration app.config.from_pyfile(CFGFILE) # Initialize logging logfile = app.config["LOGFILE"] logformat = app.config["LOGFORMAT"] handler = TimedRotatingFileHandler(logfile, when='midnight', interval=1, backupCount=10) handler.setLevel(logging.DEBUG)
def web_request_sign_csr(): """ Sign an uploaded CSR file, yielding a CRT file """ if SESSION_USERID in session: userid = session[SESSION_USERID] email = session[SESSION_EMAIL] else: # Session Timeout app.logger.error("web_request_sign_csr: session expired") rendered = render_template("login_form.html", frm_uname=UNAME, frm_userid="", frm_password="", frm_status="* PREVIOUS SESSION EXPIRED *") return ensure_no_caching(rendered), 200 # Check for the impossible if "file" not in request.files: wtext = util.sprintf( "web_request_sign_csr from user {%s}: 'file' missing from request.files", userid) app.logger.error(wtext) return wtext, 400 csr_file_obj = request.files["file"] if csr_file_obj.filename == "": wtext = util.sprintf( "web_request_sign_csr from user {%s}: csr_file_obj.filename is empty", userid) app.logger.error(wtext) return wtext, 400 if not allowed_file(csr_file_obj.filename): app.logger.error( "web_request_sign_csr from user {%s}: csr_file_obj.filename {%s} is not an allowed type", userid, csr_file_obj.filename) wstr = util.sprintf( "*** File extension of {%s} is invalid. Only 'csr' extensions are permitted. ***", csr_file_obj.filename) rendered = render_template("csr_form.html", frm_uname=UNAME, frm_userid=userid, frm_email=email, frm_status=wstr) return ensure_no_caching(rendered), 200 # Save it csr_filename = secure_filename(csr_file_obj.filename) csr_filepath = os.path.join(SIGNER_FOLDER, csr_filename) csr_file_obj.save(csr_filepath) app.logger.info("File {%s} successfully uploaded for user {%s}", csr_filepath, userid) # Sign file crt_filename = csr_filename.rsplit(".", 1)[0] + ".crt" crt_filepath = os.path.join(SIGNER_FOLDER, crt_filename) if not signer.sign_csr(userid, csr_filepath, crt_filepath): app.logger.error( "web_request_sign_csr {%s} from user {%s}: invalid contents (CA sign failed)", csr_file_obj.filename, userid) wtext = util.sprintf("*** Invalid CSR File Contents (%s) ***", csr_filename) rendered = render_template("csr_form.html", frm_uname=UNAME, frm_userid=userid, frm_email=email, frm_status=wtext) return ensure_no_caching(rendered), 200 if app.debug: app.logger.debug( "web_request_sign_csr CRT {%s} from user {%s}: CA sign successful", crt_filename, userid) # Successful: CRT = signed(CSR) # Remove the uploaded CSR file try: os.remove(csr_filepath) except Exception as exc: app.logger.error( "Failed to remove CSR {%s} for user {%s}, reason: {%s}", csr_filepath, userid, repr(exc)) # Do not alarm the user # Download CRT file to user return send_file(crt_filepath, mimetype='application/pkix-cert', attachment_filename=crt_filename, as_attachment=True)
csr_filepath, userid, repr(exc)) # Do not alarm the user # Download CRT file to user return send_file(crt_filepath, mimetype='application/pkix-cert', attachment_filename=crt_filename, as_attachment=True) #------------ Begin Launched Program ------------------------------------ if __name__ == "__main__": nargs = len(sys.argv) # Ensure that there are no arguments after python program name if nargs != 1: text = util.sprintf("%s: Command line error, nargs=%s, should be 1", __name__, nargs) print(text) sys.exit(86) # Connect to application configuration app.config.from_pyfile(CFGFILE) # Initialize logging logfile = app.config["LOGFILE"] logformat = app.config["LOGFORMAT"] handler = TimedRotatingFileHandler(logfile, when='midnight', interval=1, backupCount=10) handler.setLevel(logging.DEBUG) formatter = logging.Formatter(logformat) handler.setFormatter(formatter) app.logger.addHandler(handler)