def add(request): if "source" not in request.FILES: return problem.views.problem_stats(request, request.POST['year'], request.POST['week'], "Please attach your source code") if "remember" in request.POST: request.session["submitcode"] = request.POST['submitcode'] elif ("remember" not in request.POST) and ("submitcode" in request.session): del request.session["submitcode"] s = get_or_none(Student, submit_code=request.POST['submitcode']) if s is None: return problem.views.problem_stats(request, request.POST['year'], request.POST['week'], "Invalid submission code") extra = "" previous_solution = get_or_none(Solution, student=s, year=request.POST['year'], week=request.POST['week']) if previous_solution is not None and previous_solution.accepted: return problem.views.problem_stats( request, request.POST['year'], request.POST['week'], "You already have an accepted solution to this problem.") if previous_solution is not None and not previous_solution.accepted: previous_solution.delete() extra = "<br />Your previous submission for this problem has been deleted" s.solution_set.create(year=request.POST['year'], week=request.POST['week'], source=request.FILES['source'], public='public' in request.POST) send_mail( 'uWindsor POTW - ' + str(s) + ' Submission Added', 'A submission has been added for the problem of the week! Go check it!', '*****@*****.**', # maybe dont hardcore this? ['*****@*****.**'], fail_silently=False) return problem.views.problem_stats( request, request.POST['year'], request.POST['week'], None, "Your code has been submitted for checking" + extra)
def send_verify(request): if 'uwinid' not in request.POST or len(request.POST['uwinid']) == 0: return sign_up(request, "Please enter your uWindsor ID", {}) uwinid_check = re.compile("(\d|[a-zA-Z])+$") if uwinid_check.match(request.POST['uwinid']) == None: return sign_up(request, "That uWindsor ID is invalid", {}) u = get_or_none(Student, student_id=request.POST['uwinid']) if u is not None: return sign_up(request, "That uWindsor ID is already registered", {}) ''' Generate a verification hash by concatenating a special EMAIL_SECRET string, the users uwindsor ID, and the current hour. This allows for an implicit "time out." Once the hour changes, the hash will be invalided. Now this does mean that if the user submits at 1:59pm and the email comes at 2:00pm the code will be invalid, but thats just something we need to live with, man. ''' now = datetime.datetime.now() verify_hash = hmac.new(settings.EMAIL_SECRET, request.POST['uwinid'] + str(now.hour)).hexdigest() send_mail("uWindsor POTW - Confirm ID", "Click the following link to confirm your uWindsor ID and begin"+\ " submitting your problem of the week solutions.\n"+\ settings.SITE_URL+"/student/verify/" + request.POST['uwinid'] + "/"+\ verify_hash, "*****@*****.**", [request.POST['uwinid'] + "@uwindsor.ca"], fail_silently=False) return sign_up(request, None, "Email Sent")
def verify(request, uwinid, verify_hash): u = get_or_none(Student, student_id=uwinid) if u is not None: return redirect("/") ''' Create the expected hash by concatenating the EMAIL_SECRET, uwind id, and current hour. If the hour has changed since the user was sent the email, the hash will be invalided. ''' now = datetime.datetime.now() check = hmac.new(settings.EMAIL_SECRET, uwinid + str(now.hour)).hexdigest() ''' hmac compare_digest is used here instead of == to defend against timing attacks. It always compares all bytes instead of bailing out on the first differing one. ''' if hmac.compare_digest(str(check), str(verify_hash)): s_code = get_random_string(length=10) Student.objects.create(student_id=uwinid, submit_code=s_code) send_mail("uWindsor POTW - Submission Code", "Your submission code is " + s_code + ", keep it safe.", "*****@*****.**", [uwinid + "@uwindsor.ca"], fail_silently=False) return render(request, "student/verify_success.html", {"code": s_code}) else: return render(request, "student/verify_success.html", {"error": "This link is either expiried or invalid"})
def unsubscribe(request, student_id): s = get_or_none(Student, student_id=student_id) if s is None: return errorpage.views.index(request) s.subscribed = False s.save() return sign_up(request, None, "Successfully unsubscribed!")
def profile(request, uid): student = get_or_none(Student, student_id=uid) if student is None: return errorpage.views.index(request) context = { "student": student, "email_md5": hashlib.md5(student.student_id + "@uwindsor.ca").hexdigest(), "solutions": student.solution_set.order_by("week") } return render(request, "student/student.html", context)
def show(request, solution_id): s = get_or_none(Solution, pk=solution_id) if s is None: return errorpage.views.index(request) recent_year = Problem.objects.filter(published=True).latest('year').year recent_week = Problem.objects.filter(published=True).latest('week').week context = { "solution": s, "most_recent": s.year == recent_year and s.week == recent_week, "public": s.public } return render(request, "solution/index.html", context)
def preview(request, key): problem = get_or_none(Problem, preview_key=key) if problem is None: return errorpage.views.index(request) context = { "solutions": [], "problem": problem, "percent": 0, "error": None, "success": None } return render(request, "problem/index.html", context)
def problem_stats(request, year, week, error=None, success=None): solutions, problem =[ filter_or_none(Solution, year=year, week=week, accepted=True), get_or_none(Problem, year=year, week=week, published=True)] if any_none(solutions, problem): return errorpage.views.index(request) context = { "solutions": solutions, "problem": problem, "percent": round(100 * (solutions.count() / float(Student.objects.count())), 2), "error": error, "success": success, } if "submitcode" in request.session: context["submitcode"] = request.session["submitcode"] return render(request, "problem/index.html", context)