def _add_to_zip(zipf, activity, components_and_submitted, created_at, prefix='', slug=None, multi=False): """ Add this list of (SubmissionComponent, SubmittedComponent) pairs to the zip file. """ for component, subcomp in components_and_submitted: if subcomp: if multi: dt = subcomp.submission.created_at.strftime('%Y-%m-%d-%H-%M-%S') p = os.path.join(prefix, dt) else: p = prefix try: subcomp.add_to_zip(zipf, prefix=p, slug=slug) except OSError as e: if e.errno == errno.ENOENT: # Missing file? How did that come up once in five years? fn = os.path.join(prefix, "MISSING_FILE.txt") zipf.writestr(fn, "A file named '%s' was submitted but can't be found. That's weird.\n" "Please email %s and ask us to help track it down." % (subcomp.get_filename(), help_email(hint='course'))) else: raise # add lateness note if activity.due_date and created_at > activity.due_date: fn = os.path.join(prefix, "LATE.txt") zipf.writestr(fn, "Submission was made at %s.\n\nThat is %s after the due date of %s.\n" % (created_at, created_at - activity.due_date, activity.due_date))
def _add_to_zip(zipf, activity, components_and_submitted, created_at, prefix='', slug=None, multi=False): """ Add this list of (SubmissionComponent, SubmittedComponent) pairs to the zip file. """ for component, subcomp in components_and_submitted: if subcomp: if multi: dt = subcomp.submission.created_at.strftime( '%Y-%m-%d-%H-%M-%S') p = os.path.join(prefix, dt) else: p = prefix try: subcomp.add_to_zip(zipf, prefix=p, slug=slug) except OSError as e: if e.errno == errno.ENOENT: # Missing file? How did that come up once in five years? fn = os.path.join(prefix, "MISSING_FILE.txt") zipf.writestr( fn, "A file named '%s' was submitted but can't be found. That's weird.\n" "Please email %s and ask us to help track it down." % (subcomp.get_filename(), help_email(hint='course'))) else: raise # add lateness note if activity.due_date and created_at > activity.due_date: fn = os.path.join(prefix, "LATE.txt") zipf.writestr( fn, "Submission was made at %s.\n\nThat is %s after the due date of %s.\n" % (created_at, created_at - activity.due_date, activity.due_date))
def media(request): """ Add context things that we need """ # A/B testing: half of instructors and TAs see a different search box instr_ta = is_instr_ta(request.user.username) instr_ta_ab = instr_ta and request.user.is_authenticated and request.user.id % 2 == 0 # GRAD_DATE(TIME?)_FORMAT for the grad/ra/ta apps return { 'GRAD_DATE_FORMAT': settings.GRAD_DATE_FORMAT, 'GRAD_DATETIME_FORMAT': settings.GRAD_DATETIME_FORMAT, 'LOGOUT_URL': settings.LOGOUT_URL, 'LOGIN_URL': settings.LOGIN_URL, 'STATIC_URL': settings.STATIC_URL, 'is_instr_ta': instr_ta, 'instr_ta_ab': instr_ta_ab, 'request_path': request.path, 'CourSys': product_name(request), 'help_email': help_email(request), }
def add_topt(request, next_page=None): next_page, okay_auth, okay_2fa = _setup_view(request, next_page) if not okay_auth: return ForbiddenResponse(request) # This enforces that users have exactly one TOTP. That *seems* like the best practice. devices = TOTPDevice.objects.devices_for_user(request.maybe_stale_user, confirmed=True) if devices: return ForbiddenResponse( request, "You have already configured an authenticator with this account, and cannot add another. Contact %s if you are unable to authenticate with CourSys", (help_email(request), )) device = TOTPDevice(user=request.maybe_stale_user, name='Authenticator, enabled %s' % (datetime.date.today())) device.save() l = LogEntry(userid=request.user.username, description=("Added TOPT from %s") % (ip.get_ip(request), ), related_object=device) l.save() # build QR code uri = totpauth_url(device) qr = qrcode.make(uri, image_factory=qrcode.image.svg.SvgPathImage) qrdata = BytesIO() qr.save(qrdata) # This is the OTP secret (bits) encoded as base32, wrapped in an otpauth URL, encoded as a QR code, encoded as an # SVG, encoded as base64, wrapped in a data URL. I'm strangely proud. dataurl = 'data:image/svg+xml;base64,' + base64.b64encode( qrdata.getvalue()) context = { 'device': device, 'dataurl': dataurl, 'next_page': next_page, } return render(request, 'otp/add_topt.html', context)
def add_topt(request, next_page=None): next_page, okay_auth, okay_2fa = _setup_view(request, next_page) if not okay_auth: return ForbiddenResponse(request) # This enforces that users have exactly one TOTP. That *seems* like the best practice. devices = TOTPDevice.objects.devices_for_user(request.maybe_stale_user, confirmed=True) if devices: return ForbiddenResponse(request, "You have already configured an authenticator with this account, and cannot add another. Contact %s if you are unable to authenticate with CourSys", (help_email(request),)) device = TOTPDevice(user=request.maybe_stale_user, name='Authenticator, enabled %s' % (datetime.date.today())) device.save() l = LogEntry(userid=request.user.username, description=("Added TOPT from %s") % (ip.get_ip(request),), related_object=device) l.save() # build QR code uri = totpauth_url(device) qr = qrcode.make(uri, image_factory=qrcode.image.svg.SvgPathImage) qrdata = BytesIO() qr.save(qrdata) # This is the OTP secret (bits) encoded as base32, wrapped in an otpauth URL, encoded as a QR code, encoded as an # SVG, encoded as base64, wrapped in a data URL. I'm strangely proud. dataurl = (b'data:image/svg+xml;base64,' + base64.b64encode(qrdata.getvalue())).decode("utf-8") context = { 'device': device, 'dataurl': dataurl, 'next_page': next_page, } return render(request, 'otp/add_topt.html', context)