def before_request() -> None: """ Runs before each request. """ try: vote = cube.load_file("vote") except: #sometimes fails, not sure why app.logger.warning("Error in parsing JSON file") else: if time.time() > cube.short_date(vote["ends_at"]): vote["vote_active"] = False cube.dump_file(vote, "vote") # record number of times each page has been visted path = flask.request.path if path.split("/")[1] != "static" and path.split("/")[1] != "_uploads": vists = cube.load_file("vists") date = cube.unix_to_date(time.time()) vists[path] = vists.get(path, {}) vists[path][date] = vists[path].get(date, 0) + 1 # more than one day if time.time() - vists["time"] > 60 * 60 * 24: cube.graph_vists() vists["time"] = time.time() cube.dump_file(vists, "vists")
def email() -> Response: """ After requesting to be added to the email list, see if nonce matches. """ emails = cube.load_file("emails") requests = emails["requests"] nonce = flask.request.args.get("nonce", None) # subscribing if nonce in requests: email = requests[nonce] # Remove previous attempts emails["requests"] = { nonce: value for nonce, value in requests.items() if value != email } cube.dump_file(emails, "emails") cube.register_email(email) return alert("You have been added to the email list.", "success") requests = emails["unsubscribe-requests"] # unsubscribing if nonce in requests: email = requests[nonce] # Remove previous attempts emails["unsubscribe-requests"] = { nonce: value for nonce, value in requests.items() if value != email } cube.dump_file(emails, "emails") cube.remove_email(email) return alert("You have been removed from the email list.", "success") return alert("Wrong nonce. Try registering again?", "danger")
def records() -> dict: """ Displays TJ's all time bests. """ records = cube.load_file("records") times, people = records["records"], records["people"] refresh = False if "wca_token" in flask.session and "ion_token" in flask.session: me = cube.api_call("wca", "me")["me"] year = cube.api_call("ion", "profile")["graduation_year"] if [me["url"], me["name"], year] not in people: records["people"].append([me["url"], me["name"], year]) # New person added refresh = True cube.dump_file(records, "records") if refresh or time.time() - records["time"] > cube.CONFIG["time"]: cube.update_records() (sing_rank, avg_rank), kinch_rank = cube.get_ranks() cube.dump_file( { "sor_single": sing_rank, "sor_average": avg_rank, "kinch": kinch_rank }, "wca/ranks") return { "times": times, "events": cube.EVENTS, "icons": cube.ICONS, "DNF": statistics.DNF, "ranks": cube.RANKS }
def delete_photo() -> None: """ Deletes a photo from the server. """ users = cube.load_file("users") user = users[flask.session["account"]] try: del user["pfp"] except KeyError: pass try: os.remove(forms.photos.path(user["pfpfilename"])) del user["pfpfilename"] except (KeyError, FileNotFoundError): pass cube.dump_file(users, "users")
def register_complete(): data = cbor.decode(flask.request.get_data()) client_data = ClientData(data["clientDataJSON"]) att_obj = AttestationObject(data["attestationObject"]) # print("clientData", client_data) # print("AttestationObject:", att_obj) auth_data = server.register_complete(flask.session["state"], client_data, att_obj) flask.session["credentials"].append(auth_data.credential_data) encoded = websafe_encode(auth_data.credential_data) users = cube.load_file("users") users[flask.session["account"]]["yubi"] = encoded cube.dump_file(users, "users") # print("REGISTERED CREDENTIAL:", auth_data.credential_data) return cbor.encode({"status": "OK"})
def check(club_id): """ Checks the signups for a user on ION. """ # may be subject to change, check: https://ion.tjhsst.edu/api/activities # 152 - Rubik's cube club, 198 - Computer vision, 204 - SCT if not cube.test_token("ion"): flask.session["action"] = flask.request.path return flask.redirect(flask.url_for("ion_login")) club_name = cube.api_call("ion", f"activities/{club_id}")["name"] fname = f"signups_{club_id}" record = cube.load_file(fname) username = cube.api_call("ion", "profile")["ion_username"] signups = cube.get_signups(club_id) number = cube.count_meetings(signups) record[username] = number cube.dump_file(record, fname) return alert( f"Recorded for {username} {number} attendances at {club_name}")
def settings() -> dict: """ Adjusts a user's profile. """ if "account" not in flask.session: return flask.redirect("profile") users = cube.load_file("users") user = users[flask.session["account"]] gpgForm = forms.GPGForm() photoForm = forms.PhotoForm() if gpgForm.validate_on_submit(): key = cube.gpg.import_keys(gpgForm.gpgkey.data) user["keys"] += cube.gpg.list_keys(keys=[key.fingerprints[0]]) curr = user["keys"][-1] curr["fuids"] = ", ".join( [uid.split()[-1][1:-1] for uid in curr["uids"]]) cube.dump_file(users, "users") return alert("GPG key added.", "success", "meta") elif photoForm.validate_on_submit(): users = cube.load_file("users") delete_photo() #old profile picture not necessary anymore filename = forms.photos.save(photoForm.photo.data) users[flask.session["account"]]["pfp"] = forms.photos.url(filename) users[flask.session["account"]]["pfpfilename"] = filename cube.dump_file(users, "users") return alert("Profile photo changed.", "success", "profile") if flask.request.method == "POST": if "remove" in flask.request.form: delete_photo() return alert("Profile picture removed.", "success", "profile") if "delete" in flask.request.form: del user["keys"][int(flask.request.form["delete"])] cube.dump_file(users, "users") return {"gpgForm": gpgForm, "photoForm": photoForm}
import time, os from flask_frozen import Freezer import cube OUT = "rendered_templates" #Change URL format to end with a tailing slash site = cube.load_file("site") site["tailing_slash"] = True cube.dump_file(site, "site") from app import app app.config['FREEZER_IGNORE_MIMETYPE_WARNINGS'] = True app.config['FREEZER_REDIRECT_POLICY'] = 'ignore' freezer = Freezer(app) # if __name__ == '__main__': # freezer.freeze() #Undo changes site["tailing_slash"] = False cube.dump_file(site, "site") try: os.mkdir(OUT) except FileExistsError: pass
def profile() -> dict: """ Allows the user to login as well as register a new account. """ loginForm = forms.LoginForm() codeForm = forms.TFAForm() signupForm = forms.SignupForm() mailForm = forms.MailForm() httpForm = forms.HTTPForm() ionForm, wcaForm = forms.APIForm(prefix="ion"), forms.APIForm(prefix="wca") rtn = { "loginForm": loginForm, "codeForm": codeForm, "signupForm": signupForm, "mailForm": mailForm, "httpForm": httpForm, "ionForm": ionForm, "wcaForm": wcaForm } users = cube.load_file("users") if "account" in flask.session: tabs = [["overview", "API"], ["email", "refresh", "develop"], ["edit"]] scopes = {"default": 0, "privileged": 1, "admin": 2} tab = flask.request.args.get('tab', 'overview') scope = scopes[flask.session["scope"]] i = None for j, group in enumerate(tabs): if tab in group: i = j if i is None: return alert("Invalid tab!", "info", "self") if i > scope: return alert( "User does not have the valid scope. This incident will be logged.", "danger", "self") rtn = cube.add_dict( { "tabs": tabs, "scopes": scopes, "clubmailpassword": cube.load_file("secrets")["clubmailpassword"], "emails": cube.load_file("emails")["emails"], }, rtn) else: scope = 0 if scope >= 0: if "confirm" in flask.request.form and signupForm.validate_on_submit(): username, password = signupForm.username.data, signupForm.password.data if username in cube.load_file("users"): return alert("Username is taken.", "info", "meta") if password != signupForm.confirm.data: return alert("Passwords do not match.", "info", "meta") cube.register(username, password) return alert("Account registered!", "success", "self") elif "login" in flask.request.form and loginForm.validate_on_submit(): username, password = loginForm.username.data, loginForm.password.data if not cube.check(username, password): return alert("Username or password is incorrect.", "info", "self") # Save login to cookies if 2fa is not enabled, otherwise don't if "2fa" not in users[username] and "yubi" not in users[username]: flask.session["account"] = username flask.session["scope"] = users[username]["scope"] else: if "2fa" in users[username]: flask.session["2fa"] = True flask.session["username"] = username # load U2F challenge if it exists if "yubi" in users[username]: flask.session["yubi"] = websafe_decode(users[username]["yubi"]) return flask.redirect(flask.url_for("profile")) elif "yubi_check" in flask.session or ( "login_2fa" in flask.request.form and codeForm.validate_on_submit()): username = flask.session["username"] if "yubi_check" not in flask.session and not cube.check_2fa( username, str(codeForm.code.data)): return alert("2FA code is incorrect.", "info", "self") if "yubi_check" in flask.session: del flask.session["yubi_check"] # actually login flask.session["account"] = username flask.session["scope"] = users[username]["scope"] return flask.redirect(flask.url_for("profile")) elif "cancel_2fa" in flask.request.form and "2fa" in flask.session: del flask.session["2fa"] elif "cancel_yubi" in flask.request.form and "yubi" in flask.session: del flask.session["yubi"] elif ionForm.validate_on_submit(): rtn = cube.add_dict( {"data": cube.api_call("ion", ionForm.call.data)}, rtn) elif wcaForm.validate_on_submit(): rtn = cube.add_dict( {"data": cube.api_call("wca", wcaForm.call.data)}, rtn) if scope >= 1: if mailForm.validate_on_submit(): recipients = mailForm.recipients.data.split( ", ") if mailForm.recipients.data != "" else cube.load_file( "emails")["emails"] # add footer with unsubscribe information body = mailForm.email.data.replace("\n", "") + \ f""" -- If you're tired of seeing these emails, unsubscribe [here]({cube.TJ}). """ body = cube.markdown2.markdown(body) cube.send_email(recipients, mailForm.subject.data, body) if mailForm.log.data: cube.save_email(mailForm.subject.data, mailForm.email.data) return alert("Mail sent.", "success", "meta") elif httpForm.validate_on_submit(): flask.abort(int(httpForm.http.data)) if scope >= 2: pass if flask.request.method == "POST": if "logout" in flask.request.form: del flask.session["account"] if "2fa" in flask.session: del flask.session["2fa"] if "yubi" in flask.session: del flask.session["yubi"] if "delete" in flask.request.form: del users[flask.session["account"]] del flask.session["account"] cube.dump_file(users, "users") return alert("Account deleted!", "success", "self") if "clear" in flask.request.form: # Save CSRF token csrf = flask.session["csrf_token"] flask.session.clear() flask.session["csrf_token"] = csrf if "fb" in flask.request.form: cube.get_pfps(cube.CONFIG["officers"]) alert("Updated the profile pictures!") if "comps" in flask.request.form: cube.get_comps() alert("Updated the competitions!") if "records" in flask.request.form: cube.update_records() alert("Updated the records!") if "history" in flask.request.form: cube.save_club_history() cube.graph_capacity() cube.graph_blocks("by_x") cube.graph_blocks("by_y") alert("Updated the club history!") if "heatmap" in flask.request.form: cube.graph_vists() alert("Updated the heatmap!") return rtn
def profile() -> dict: """ Allows the user to login as well as register a new account. """ loginForm = forms.LoginForm() signupForm = forms.SignupForm() mailForm = forms.MailForm() httpForm = forms.HTTPForm() ionForm, wcaForm = forms.APIForm(prefix="ion"), forms.APIForm(prefix="wca") rtn = { "loginForm": loginForm, "signupForm": signupForm, "mailForm": mailForm, "httpForm": httpForm, "ionForm": ionForm, "wcaForm": wcaForm } users = cube.load_file("users") if "account" in flask.session: tabs = [["overview", "API"], ["email", "refresh", "develop"], ["edit"]] scopes = {"default": 0, "privileged": 1, "admin": 2} tab = flask.request.args.get('tab', 'overview') scope = scopes[flask.session["scope"]] i = None for j, group in enumerate(tabs): if tab in group: i = j if i is None: return alert("Invalid tab!", "info", "self") if i > scope: return alert( "User does not have the valid scope. This incident will be logged.", "danger", "self") rtn = cube.add_dict( { "tabs": tabs, "scopes": scopes, "clubmailpassword": cube.load_file("secrets")["clubmailpassword"], "emails": cube.load_file("emails")["emails"], }, rtn) else: scope = 0 if scope >= 0: if "confirm" in flask.request.form and signupForm.validate_on_submit(): username, password = signupForm.username.data, signupForm.password.data if username in cube.load_file("users"): return alert("Username is taken.", "info", "meta") if password != signupForm.confirm.data: return alert("Passwords do not match.", "info", "meta") cube.register(username, password) return alert("Account registered!", "success", "self") elif "login" in flask.request.form and loginForm.validate_on_submit(): username, password = loginForm.username.data, loginForm.password.data if not cube.check(username, password): return alert("Username or password is incorrect.", "info", "self") # Save login to cookies flask.session["account"] = username flask.session["scope"] = users[username]["scope"] return flask.redirect(flask.url_for("profile")) elif ionForm.validate_on_submit(): rtn = cube.add_dict( {"data": cube.api_call("ion", ionForm.call.data)}, rtn) elif wcaForm.validate_on_submit(): rtn = cube.add_dict( {"data": cube.api_call("wca", wcaForm.call.data)}, rtn) if scope >= 1: if mailForm.validate_on_submit(): recipients = mailForm.recipients.data.split( ", ") if mailForm.recipients.data != "" else cube.load_file( "emails")["emails"] body = cube.markdown2.markdown(mailForm.email.data).replace( "\n", "") cube.send_email(recipients, mailForm.subject.data, body) if mailForm.log.data: cube.save_email(mailForm.subject.data, mailForm.email.data) return alert("Mail sent.", "success", "meta") elif httpForm.validate_on_submit(): flask.abort(int(httpForm.http.data)) if scope >= 2: pass if flask.request.method == "POST": if "logout" in flask.request.form: del flask.session["account"] if "delete" in flask.request.form: del users[flask.session["account"]] del flask.session["account"] cube.dump_file(users, "users") return alert("Account deleted!", "success", "self") if "clear" in flask.request.form: # Save CSRF token csrf = flask.session["csrf_token"] flask.session.clear() flask.session["csrf_token"] = csrf if "fb" in flask.request.form: cube.get_pfps(cube.CONFIG["officers"]) if "comps" in flask.request.form: cube.get_comps() if "records" in flask.request.form: cube.update_records() return rtn