def create_message(
        self,
        message: EmailMessage,
        fail_silently: bool = False,
        fake_delivery: bool = False,
    ) -> List['SESMailDelivery']:
        assert isinstance(message, EmailMessage)
        assert message.connection is None or isinstance(
            message.connection, SESBackend)

        if settings.DEBUG and getattr(settings,
                                      'SES_SNS_TRACKER_DEBUG_BACKEND', None):
            debug_backend = import_string(
                settings.SES_SNS_TRACKER_DEBUG_BACKEND)
            message.connection = debug_backend()
        elif message.connection is None:
            message.connection = SESBackend()

        if not fake_delivery:
            message.send(fail_silently=fail_silently)

        deliveries = list()
        for recipient in message.recipients():
            deliveries.append(
                self.model(
                    recipient=recipient,
                    message_id=message.extra_headers.get(
                        'message_id', 'NO_MESSAGE_ID'),
                    request_id=message.extra_headers.get(
                        'request_id', 'NO_RESULT_ID'),
                    state=self.model.STATE_DELIVERED
                    if fake_delivery else self.model.STATE_SENT,
                ))
        return self.bulk_create(deliveries)
Beispiel #2
0
    def test_file_sessions(self):
        """Make sure opening a connection creates a new file"""
        msg = EmailMessage(
            "Subject", "Content", "*****@*****.**", ["*****@*****.**"], headers={"From": "*****@*****.**"}
        )
        connection = mail.get_connection()
        connection.send_messages([msg])

        self.assertEqual(len(os.listdir(self.tmp_dir)), 1)
        message = email.message_from_file(open(os.path.join(self.tmp_dir, os.listdir(self.tmp_dir)[0])))
        self.assertEqual(message.get_content_type(), "text/plain")
        self.assertEqual(message.get("subject"), "Subject")
        self.assertEqual(message.get("from"), "*****@*****.**")
        self.assertEqual(message.get("to"), "*****@*****.**")

        connection2 = mail.get_connection()
        connection2.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        connection.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        msg.connection = mail.get_connection()
        self.assertTrue(connection.open())
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)
Beispiel #3
0
    def send_mail(self, connection=None):
        name = self.cleaned_data.get('name', None)
        email = self.cleaned_data.get('email')
        company = self.cleaned_data.get('company')
        phone_number = self.cleaned_data.get('phone_number')
        message = self.cleaned_data.get('message')

        if name and company:
            subject = 'Contact: {0} ({1})'.format(name, company)
        else:
            subject = 'Contact: {0}'.format(name)

        body = '{0}\n\n'.format(message)

        body = '{0}{1}\n{2}\n'.format(body, name, email)

        if phone_number:
            body = '{0}\n{1}'.format(body, phone_number)

        connection = connection or get_connection()

        # headers needs to be specified in the constructor for it to work
        e = EmailMessage(headers={'Reply-To': email})
        
        e.subject = subject
        e.body = body 
        e.to = [settings.CONTACT_EMAIL,]
        e.connection = connection
        
        e.send()
Beispiel #4
0
 def test_file_backend(self):
     tmp_dir = tempfile.mkdtemp()
     connection = filebased.EmailBackend(file_path=tmp_dir)
     email1 = EmailMessage('Subject',
                           'Content',
                           '*****@*****.**', ['*****@*****.**'],
                           headers={'From': '*****@*****.**'})
     connection.send_messages([email1])
     self.assertEqual(len(os.listdir(tmp_dir)), 1)
     message = email.message_from_file(
         open(os.path.join(tmp_dir,
                           os.listdir(tmp_dir)[0])))
     self.assertEqual(message.get_content_type(), 'text/plain')
     self.assertEqual(message.get('subject'), 'Subject')
     self.assertEqual(message.get('from'), '*****@*****.**')
     self.assertEqual(message.get('to'), '*****@*****.**')
     connection2 = filebased.EmailBackend(file_path=tmp_dir)
     connection2.send_messages([email1])
     self.assertEqual(len(os.listdir(tmp_dir)), 2)
     connection.send_messages([email1])
     self.assertEqual(len(os.listdir(tmp_dir)), 2)
     email1.connection = filebased.EmailBackend(file_path=tmp_dir)
     connection_created = connection.open()
     email1.send()
     self.assertEqual(len(os.listdir(tmp_dir)), 3)
     email1.send()
     self.assertEqual(len(os.listdir(tmp_dir)), 3)
     connection.close()
     shutil.rmtree(tmp_dir)
Beispiel #5
0
    def test_file_sessions(self):
        """Make sure opening a connection creates a new file"""
        msg = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], headers={'From': '*****@*****.**'})
        connection = mail.get_connection()
        connection.send_messages([msg])

        self.assertEqual(len(os.listdir(self.tmp_dir)), 1)
        with open(os.path.join(self.tmp_dir, os.listdir(self.tmp_dir)[0])) as fp:
            message = email.message_from_file(fp)
        self.assertEqual(message.get_content_type(), 'text/plain')
        self.assertEqual(message.get('subject'), 'Subject')
        self.assertEqual(message.get('from'), '*****@*****.**')
        self.assertEqual(message.get('to'), '*****@*****.**')

        connection2 = mail.get_connection()
        connection2.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        connection.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        msg.connection = mail.get_connection()
        self.assertTrue(connection.open())
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)

        connection.close()
Beispiel #6
0
def send_enrollment_decision(participation, approved, request=None):
    # type: (Participation, bool, http.HttpRequest) -> None

    with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE):
        course = participation.course
        if request:
            course_uri = request.build_absolute_uri(
                reverse("relate-course_page", args=(course.identifier, )))
        else:
            # This will happen when this method is triggered by
            # a model signal which doesn't contain a request object.
            from six.moves.urllib.parse import urljoin
            course_uri = urljoin(getattr(settings, "RELATE_BASE_URL"),
                                 course.get_absolute_url())

        from django.template.loader import render_to_string
        message = render_to_string(
            "course/enrollment-decision-email.txt", {
                "user": participation.user,
                "approved": approved,
                "course": course,
                "course_uri": course_uri
            })

        from django.core.mail import EmailMessage
        msg = EmailMessage(
            string_concat("[%s] ", _("Your enrollment request")) %
            course.identifier, message, course.get_from_email(),
            [participation.user.email])
        msg.bcc = [course.notify_email]
        if not settings.RELATE_EMAIL_SMTP_ALLOW_NONAUTHORIZED_SENDER:
            from relate.utils import get_outbound_mail_connection
            msg.connection = get_outbound_mail_connection("robot")
        msg.send()
Beispiel #7
0
    def test_file_sessions(self):
        """Make sure opening a connection creates a new file"""
        msg = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], headers={'From': '*****@*****.**'})
        connection = mail.get_connection()
        connection.send_messages([msg])

        self.assertEqual(len(os.listdir(self.tmp_dir)), 1)
        with open(os.path.join(self.tmp_dir, os.listdir(self.tmp_dir)[0]), 'rb') as fp:
            message = message_from_binary_file(fp)
        self.assertEqual(message.get_content_type(), 'text/plain')
        self.assertEqual(message.get('subject'), 'Subject')
        self.assertEqual(message.get('from'), '*****@*****.**')
        self.assertEqual(message.get('to'), '*****@*****.**')

        connection2 = mail.get_connection()
        connection2.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        connection.send_messages([msg])
        self.assertEqual(len(os.listdir(self.tmp_dir)), 2)

        msg.connection = mail.get_connection()
        self.assertTrue(connection.open())
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)
        msg.send()
        self.assertEqual(len(os.listdir(self.tmp_dir)), 3)

        connection.close()
Beispiel #8
0
def sign_in_by_email(request):
    if not settings.RELATE_SIGN_IN_BY_EMAIL_ENABLED:
        messages.add_message(request, messages.ERROR,
                _("Email-based sign-in is not being used"))
        return redirect("relate-sign_in_choice")

    if request.method == 'POST':
        form = SignInByEmailForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data["email"]
            user, created = get_user_model().objects.get_or_create(
                    email__iexact=email,
                    defaults=dict(username=email, email=email))

            if created:
                user.set_unusable_password()

            user.status = user_status.unconfirmed,
            user.sign_in_key = make_sign_in_key(user)
            user.save()

            from relate.utils import render_email_template
            message = render_email_template("course/sign-in-email.txt", {
                "user": user,
                "sign_in_uri": request.build_absolute_uri(
                    reverse(
                        "relate-sign_in_stage2_with_token",
                        args=(user.id, user.sign_in_key,))),
                "home_uri": request.build_absolute_uri(reverse("relate-home"))
                })
            from django.core.mail import EmailMessage
            msg = EmailMessage(
                    _("Your %(relate_site_name)s sign-in link")
                    % {"relate_site_name": _(get_site_name())},
                    message,
                    getattr(settings, "NO_REPLY_EMAIL_FROM",
                            settings.ROBOT_EMAIL_FROM),
                    [email])

            from relate.utils import get_outbound_mail_connection
            msg.connection = (
                get_outbound_mail_connection("no_reply")
                if hasattr(settings, "NO_REPLY_EMAIL_FROM")
                else get_outbound_mail_connection("robot"))
            msg.send()

            messages.add_message(request, messages.INFO,
                    _("Email sent. Please check your email and click the link."))

            return redirect("relate-home")
    else:
        form = SignInByEmailForm()

    return render(request, "course/login-by-email.html", {
        "form_description": "",
        "form": form
        })
Beispiel #9
0
def sign_in_by_email(request):
    if not settings.RELATE_SIGN_IN_BY_EMAIL_ENABLED:
        messages.add_message(request, messages.ERROR,
                _("Email-based sign-in is not being used"))
        return redirect("relate-sign_in_choice")

    if request.method == 'POST':
        form = SignInByEmailForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data["email"]
            user, created = get_user_model().objects.get_or_create(
                    email__iexact=email,
                    defaults=dict(username=email, email=email))

            if created:
                user.set_unusable_password()

            user.status = user_status.unconfirmed,
            user.sign_in_key = make_sign_in_key(user)
            user.save()

            from relate.utils import render_email_template
            message = render_email_template("course/sign-in-email.txt", {
                "user": user,
                "sign_in_uri": request.build_absolute_uri(
                    reverse(
                        "relate-sign_in_stage2_with_token",
                        args=(user.id, user.sign_in_key,))),
                "home_uri": request.build_absolute_uri(reverse("relate-home"))
                })
            from django.core.mail import EmailMessage
            msg = EmailMessage(
                    _("Your %(relate_site_name)s sign-in link")
                    % {"relate_site_name": _(get_site_name())},
                    message,
                    getattr(settings, "NO_REPLY_EMAIL_FROM",
                            settings.ROBOT_EMAIL_FROM),
                    [email])

            from relate.utils import get_outbound_mail_connection
            msg.connection = (
                get_outbound_mail_connection("no_reply")
                if hasattr(settings, "NO_REPLY_EMAIL_FROM")
                else get_outbound_mail_connection("robot"))
            msg.send()

            messages.add_message(request, messages.INFO,
                    _("Email sent. Please check your email and click the link."))

            return redirect("relate-home")
    else:
        form = SignInByEmailForm()

    return render(request, "course/login-by-email.html", {
        "form_description": "",
        "form": form
        })
Beispiel #10
0
    def informStudents(self, request, selectedCompanies):
        print "Informing students about ",selectedCompanies;

        t = loader.get_template('company/informStudents_mail.html');
        conn = get_connection(); #for mailing
        
        for c in selectedCompanies:
            #don't send email intimations about old company arrivals wrongly as done on Sat Mar 17.

            if c.date_of_process < datetime.today(): #company process date has already passed
               print "Not informing because date of process %s has already passed!!" % (c.date_of_process)
               continue
                
            ppltoInform = c.came_for_group.get_query_set()[0].user_set.all() 
            context = Context(
                {
                    'company' : c,
                })

            body = t.render(context)

            to = [];
            for p in ppltoInform:
                to += ["*****@*****.**" % str(p.username)]; #for primary sicsrwala address
       
            #send mail actually.
            email = EmailMessage();
            email.from_email = '"Ashwini Narayan" <*****@*****.**>';
            email.subject = '[Placements] %s coming to campus' % c.name;
            #email.from = '*****@*****.**'; #left for automatic putting
            email.connection = conn;
            email.body = body;
            
            cc = [];
            # Getting the From/ CC from the placement Committee group.
            from django.contrib.auth.models import Group;
            g = Group.objects.get(name = 'placement committee')
            
            for u in g.user_set.all():
               cc.append(u.email)
            
            bcc = []
            for m in MANAGERS:
                bcc.append(list(m)[1])
            
            email.to = to + cc;
            email.bcc = bcc;
            print "to is ",email.to;
            print "bcc is ",email.bcc;
            print "body is ",email.body
            email.content_subtype='html';
            email.send();
            dir(email)
            print "Done with %s" % (c);

        self.message_user(request,"Successfully informd students");    
Beispiel #11
0
def send_social_connection_error_email(context):
    from django.core.mail import get_connection, EmailMessage
    import json
    msg = EmailMessage('social account connection error',
                            json.dumps(context) if context else 'no error message found!',
                           '*****@*****.**',
                           ['*****@*****.**'],
                           ['*****@*****.**'])
    msg.connection = get_connection('django.core.mail.backends.smtp.EmailBackend')
    msg.send()
    msg.connection.close()
Beispiel #12
0
 def contact(self, message):
     from django.core.mail import EmailMessage, get_connection
     email = EmailMessage()
     email.body = message
     email.subject = "[UNIFI]"
     email.connection = get_connection()
     for person in self.persons.all():
         print "{0}({1})".format(person.username(), person.pk)
         address = person.user.email
         if address:
             email.cc.append(person.user.email)
     print message
     email.send()
Beispiel #13
0
 def contact( self, message ):
     from django.core.mail import EmailMessage, get_connection
     email = EmailMessage()
     email.body = message
     email.subject = "[UNIFI]"
     email.connection = get_connection()
     for person in self.persons.all():
         print "{0}({1})".format(person.username(), person.pk)
         address = person.user.email
         if address:
             email.cc.append( person.user.email )
     print message
     email.send()
Beispiel #14
0
    def informStudents(self, request, selectedCompanies):
        print "Informing students about ", selectedCompanies

        t = loader.get_template('company/informStudents_mail.html')
        conn = get_connection()
        #for mailing

        for c in selectedCompanies:
            ppltoInform = c.came_for_group.get_query_set()[0].user_set.all()
            context = Context({
                'company': c,
            })

            body = t.render(context)

            to = []
            for p in ppltoInform:
                to += ["*****@*****.**" % str(p.username)]
                #for primary sicsrwala address

            #send mail actually.
            email = EmailMessage()
            email.from_email = '"Ashwini Narayan" <*****@*****.**>'
            email.subject = '[Placements] %s coming to campus' % c.name
            #email.from = '*****@*****.**'; #left for automatic putting
            email.connection = conn
            email.body = body

            cc = []
            # Getting the From/ CC from the placement Committee group.
            from django.contrib.auth.models import Group
            g = Group.objects.get(name='placement committee')

            for u in g.user_set.all():
                cc.append(u.email)

            bcc = []
            for m in MANAGERS:
                bcc.append(list(m)[1])

            email.to = to + cc
            email.bcc = bcc
            print "to is ", email.to
            print "bcc is ", email.bcc
            print "body is ", email.body
            email.content_subtype = 'html'
            email.send()
            dir(email)
            print "Done with %s" % (c)

        self.message_user(request, "Successfully informd students")
Beispiel #15
0
 def enviar(self):
     toEmails = []
     mail = EmailMessage(subject = self.titulo.__str__(), body = self.texto.__str__(), from_email = "*****@*****.**")
     mail.content_subtype = "html"
     if self.arquivo :
         mail.attach_file(self.arquivo.path)
     for email in self.emailsCadastrados.all() :
             toEmails.append(email.__str__())
     if toEmails.__len__() > 200 :
         connectionSMTP = SMTPConnection()
         mail.connection = connectionSMTP
         loops =  self.emailsCadastrados.all().__len__() / 200
         for loop in range(0, loops) :
             mail.to = toEmails[loop * 200: loop * 200 + 200]
             mail.send()
     else :
         mail.to = toEmails
         mail.send(fail_silently = False)
Beispiel #16
0
    def process(self):

        files_to_delete = []

        from_email = self.from_email or settings.EMAIL_HOST_USER
        email_template = get_template(self.email_template)
        html_content = email_template.render(Context(self.data))

        if settings.EMAIL_DEBUG:
            print "Sending debug mail"
            self.to = ["*****@*****.**"]

        if self.auth_email:
            print "custom mail"
            print self.auth_email
            from_email = self.auth_email
            msg = EmailMessage(self.subject, html_content, from_email, self.to)
            msg.connection = get_connection(username=self.auth_email, password=self.auth_password,
                                            host=self.smtp_host, port=self.smtp_port, use_tls=self.use_tls)

        else:
            msg = EmailMessage(self.subject, html_content, from_email, self.to)

        print "Send to: %s " % self.to

        for filename in self.files:
            # lets make a copy of the file and delete soon after sending
            ext = filename['path'].split('.')[len(filename['path'].split('.'))-1]
            friendly = "%s.%s" % (filename['friendly'], ext)
            src = os.path.join(settings.MEDIA_ROOT, filename['path'])
            dst = os.path.join(settings.MEDIA_ROOT, friendly)
            shutil.copyfile(src, dst)
            msg.attach_file(os.path.join(settings.MEDIA_ROOT, dst))
            files_to_delete.append(dst)

        msg.content_subtype = "html"
        msg.send()

        # let remove the duplicate files
        for filename in files_to_delete:
            print "deleting %s" % filename
            os.path.exists(filename) and os.remove(filename)
Beispiel #17
0
 def test_file_backend(self):
     tmp_dir = tempfile.mkdtemp()
     connection = filebased.EmailBackend(file_path=tmp_dir)
     email1 = EmailMessage('Subject', 'Content', '*****@*****.**', ['*****@*****.**'], headers={'From': '*****@*****.**'})
     connection.send_messages([email1])
     self.assertEqual(len(os.listdir(tmp_dir)), 1)
     message = email.message_from_file(open(os.path.join(tmp_dir, os.listdir(tmp_dir)[0])))
     self.assertEqual(message.get_content_type(), 'text/plain')
     self.assertEqual(message.get('subject'), 'Subject')
     self.assertEqual(message.get('from'), '*****@*****.**')
     self.assertEqual(message.get('to'), '*****@*****.**')
     connection2 = filebased.EmailBackend(file_path=tmp_dir)
     connection2.send_messages([email1])
     self.assertEqual(len(os.listdir(tmp_dir)), 2)
     connection.send_messages([email1])
     self.assertEqual(len(os.listdir(tmp_dir)), 2)
     email1.connection = filebased.EmailBackend(file_path=tmp_dir)
     connection_created = connection.open()
     email1.send()
     self.assertEqual(len(os.listdir(tmp_dir)), 3)
     email1.send()
     self.assertEqual(len(os.listdir(tmp_dir)), 3)
     connection.close()
     shutil.rmtree(tmp_dir)
Beispiel #18
0
def send_enrollment_decision(participation, approved, request=None):
    # type: (Participation, bool, http.HttpRequest) -> None

    with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE):
        course = participation.course
        if request:
            course_uri = request.build_absolute_uri(
                    reverse("relate-course_page",
                        args=(course.identifier,)))
        else:
            # This will happen when this method is triggered by
            # a model signal which doesn't contain a request object.
            from six.moves.urllib.parse import urljoin
            course_uri = urljoin(getattr(settings, "RELATE_BASE_URL"),
                                 course.get_absolute_url())

        from django.template.loader import render_to_string
        message = render_to_string("course/enrollment-decision-email.txt", {
            "user": participation.user,
            "approved": approved,
            "course": course,
            "course_uri": course_uri
            })

        from django.core.mail import EmailMessage
        msg = EmailMessage(
                string_concat("[%s] ", _("Your enrollment request"))
                % course.identifier,
                message,
                course.get_from_email(),
                [participation.user.email])
        msg.bcc = [course.notify_email]
        if not settings.RELATE_EMAIL_SMTP_ALLOW_NONAUTHORIZED_SENDER:
            from relate.utils import get_outbound_mail_connection
            msg.connection = get_outbound_mail_connection("robot")
        msg.send()
Beispiel #19
0
def email_comment(gitlab, forge_id, author, comment, merge_id=None) -> None:
    """Email a comment made on Gitlab"""
    try:
        git_forge = GitForge.objects.get(host=urllib.parse.urlsplit(
            gitlab.url).hostname,
                                         forge_id=forge_id)
    except GitForge.DoesNotExist:
        _log.error(
            "Got comment event for project id %d, which isn't in the database",
            forge_id)
        return

    commit = comment.get("commit_id")
    try:
        bridged_submission = BridgedSubmission.objects.filter(
            git_forge=git_forge).order_by("-series_version")
        if merge_id:
            bridged_submission = bridged_submission.filter(
                merge_request=merge_id)
        if commit:
            bridged_submission = bridged_submission.filter(commit=commit)
        bridged_submission = bridged_submission[0]
    except IndexError:
        _log.info(
            "Unable to find a bridged submission for comment on MR %d, commit %s, forge %r",
            merge_id,
            commit,
            git_forge,
        )
        return

    from_email = settings.PATCHLAB_FROM_EMAIL.format(forge_user=author["name"])
    # From the bridged_submission, find the in-reply-to, create email.
    headers = {
        "Date": email_utils.formatdate(localtime=settings.EMAIL_USE_LOCALTIME),
        "Message-ID": email_utils.make_msgid(domain=DNS_NAME),
        "In-Reply-To": bridged_submission.submission.msgid,
        "X-Patchlab-Comment": comment["url"],
    }
    subject = "Re: " + " ".join(
        message_from_string(
            bridged_submission.submission.headers)["Subject"].splitlines())
    wrapped_description = "\n".join([
        textwrap.fill(line, width=72, replace_whitespace=False)
        for line in comment["note"].splitlines()
    ])
    body = (
        f"From: {author['name']} on {git_forge.host}\n{comment['url']}\n\n{wrapped_description}\n"
        f"")
    comment = EmailMessage(
        subject=subject,
        body=body,
        from_email=from_email,
        to=[git_forge.project.listemail],
        headers=headers,
        reply_to=[git_forge.project.listemail],
    )
    with get_connection(fail_silently=False) as conn:
        patchwork_parser.parse_mail(comment.message(),
                                    list_id=git_forge.project.listid)
        comment.connection = conn
        comment.send(fail_silently=False)
Beispiel #20
0
    def update_grade_data_from_grading_form_v2(self, request, page_context,
                                               page_data, grade_data,
                                               grading_form, files_data):

        if grade_data is None:
            grade_data = {}
        for k in self.grade_data_attrs:
            if k == "grade_percent":
                grade_data[k] = grading_form.cleaned_percent()
            else:
                grade_data[k] = grading_form.cleaned_data[k]

        if grading_form.cleaned_data["notify"] and page_context.flow_session:
            with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE):
                from django.template.loader import render_to_string
                from course.utils import will_use_masked_profile_for_email
                staff_email = [
                    page_context.course.notify_email, request.user.email
                ]
                message = render_to_string(
                    "course/grade-notify.txt", {
                        "page_title":
                        self.title(page_context, page_data),
                        "course":
                        page_context.course,
                        "participation":
                        page_context.flow_session.participation,
                        "feedback_text":
                        grade_data["feedback_text"],
                        "flow_session":
                        page_context.flow_session,
                        "review_uri":
                        page_context.page_uri,
                        "use_masked_profile":
                        will_use_masked_profile_for_email(staff_email)
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                    string_concat("[%(identifier)s:%(flow_id)s] ",
                                  _("New notification")) %
                    {
                        'identifier': page_context.course.identifier,
                        'flow_id': page_context.flow_session.flow_id
                    }, message,
                    getattr(settings, "GRADER_FEEDBACK_EMAIL_FROM",
                            page_context.course.get_from_email()),
                    [page_context.flow_session.participation.user.email])
                msg.bcc = [page_context.course.notify_email]

                if grading_form.cleaned_data["may_reply"]:
                    msg.reply_to = [request.user.email]

                if hasattr(settings, "GRADER_FEEDBACK_EMAIL_FROM"):
                    from relate.utils import get_outbound_mail_connection
                    msg.connection = get_outbound_mail_connection(
                        "grader_feedback")
                msg.send()

        if (grading_form.cleaned_data["notes"]
                and grading_form.cleaned_data["notify_instructor"]
                and page_context.flow_session):
            with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE):
                from django.template.loader import render_to_string
                from course.utils import will_use_masked_profile_for_email
                staff_email = [
                    page_context.course.notify_email, request.user.email
                ]
                message = render_to_string(
                    "course/grade-internal-notes-notify.txt", {
                        "page_title":
                        self.title(page_context, page_data),
                        "course":
                        page_context.course,
                        "participation":
                        page_context.flow_session.participation,
                        "notes_text":
                        grade_data["notes"],
                        "flow_session":
                        page_context.flow_session,
                        "review_uri":
                        page_context.page_uri,
                        "sender":
                        request.user,
                        "use_masked_profile":
                        will_use_masked_profile_for_email(staff_email)
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                    string_concat("[%(identifier)s:%(flow_id)s] ",
                                  _("Grading notes from %(ta)s")) %
                    {
                        'identifier': page_context.course.identifier,
                        'flow_id': page_context.flow_session.flow_id,
                        'ta': request.user.get_full_name()
                    }, message,
                    getattr(settings, "GRADER_FEEDBACK_EMAIL_FROM",
                            page_context.course.get_from_email()),
                    [page_context.course.notify_email])
                msg.bcc = [request.user.email]
                msg.reply_to = [request.user.email]

                if hasattr(settings, "GRADER_FEEDBACK_EMAIL_FROM"):
                    from relate.utils import get_outbound_mail_connection
                    msg.connection = get_outbound_mail_connection(
                        "grader_feedback")
                msg.send()

        return grade_data
Beispiel #21
0
    def grade(self, page_context, page_data, answer_data, grade_data):
        if answer_data is None:
            return AnswerFeedback(correctness=0,
                                  feedback=_("No answer provided."))

        user_code = answer_data["answer"]

        # {{{ request run

        run_req = {"compile_only": False, "user_code": user_code}

        def transfer_attr(name):
            if hasattr(self.page_desc, name):
                run_req[name] = getattr(self.page_desc, name)

        transfer_attr("setup_code")
        transfer_attr("names_for_user")
        transfer_attr("names_from_user")

        run_req["test_code"] = self.get_test_code()

        if hasattr(self.page_desc, "data_files"):
            run_req["data_files"] = {}

            from course.content import get_repo_blob

            for data_file in self.page_desc.data_files:
                from base64 import b64encode
                run_req["data_files"][data_file] = \
                        b64encode(
                                get_repo_blob(
                                    page_context.repo, data_file,
                                    page_context.commit_sha).data).decode()

        try:
            response_dict = request_run_with_retries(
                run_req,
                run_timeout=self.page_desc.timeout,
                image=self.container_image)
        except Exception:
            from traceback import format_exc
            response_dict = {
                "result": "uncaught_error",
                "message": "Error connecting to container",
                "traceback": "".join(format_exc()),
            }

        # }}}

        feedback_bits = []

        correctness = None

        if "points" in response_dict:
            correctness = response_dict["points"]
            try:
                feedback_bits.append("<p><b>%s</b></p>" %
                                     _(get_auto_feedback(correctness)))
            except Exception as e:
                correctness = None
                response_dict["result"] = "setup_error"
                response_dict["message"] = ("%s: %s" %
                                            (type(e).__name__, str(e)))

        # {{{ send email if the grading code broke

        if response_dict["result"] in [
                "uncaught_error", "setup_compile_error", "setup_error",
                "test_compile_error", "test_error"
        ]:
            error_msg_parts = ["RESULT: %s" % response_dict["result"]]
            for key, val in sorted(response_dict.items()):
                if (key not in ["result", "figures"] and val
                        and isinstance(val, str)):
                    error_msg_parts.append(
                        "-------------------------------------")
                    error_msg_parts.append(key)
                    error_msg_parts.append(
                        "-------------------------------------")
                    error_msg_parts.append(val)
            error_msg_parts.append("-------------------------------------")
            error_msg_parts.append("user code")
            error_msg_parts.append("-------------------------------------")
            error_msg_parts.append(user_code)
            error_msg_parts.append("-------------------------------------")

            error_msg = "\n".join(error_msg_parts)

            from relate.utils import local_now, format_datetime_local
            from course.utils import LanguageOverride
            with LanguageOverride(page_context.course):
                from relate.utils import render_email_template
                message = render_email_template(
                    "course/broken-code-question-email.txt", {
                        "site": getattr(settings, "RELATE_BASE_URL"),
                        "page_id": self.page_desc.id,
                        "course": page_context.course,
                        "error_message": error_msg,
                        "review_uri": page_context.page_uri,
                        "time": format_datetime_local(local_now())
                    })

                if (not page_context.in_sandbox
                        and not is_nuisance_failure(response_dict)):
                    try:
                        from django.core.mail import EmailMessage
                        msg = EmailMessage(
                            "".join([
                                "[%s:%s] ",
                                _("code question execution failed")
                            ]) % (page_context.course.identifier,
                                  page_context.flow_session.flow_id
                                  if page_context.flow_session is not None else
                                  _("<unknown flow>")), message,
                            settings.ROBOT_EMAIL_FROM,
                            [page_context.course.notify_email])

                        from relate.utils import get_outbound_mail_connection
                        msg.connection = get_outbound_mail_connection("robot")
                        msg.send()

                    except Exception:
                        from traceback import format_exc
                        feedback_bits.append(
                            str(
                                string_concat(
                                    "<p>",
                                    _("Both the grading code and the attempt to "
                                      "notify course staff about the issue failed. "
                                      "Please contact the course or site staff and "
                                      "inform them of this issue, mentioning this "
                                      "entire error message:"), "</p>", "<p>",
                                    _("Sending an email to the course staff about the "
                                      "following failure failed with "
                                      "the following error message:"), "<pre>",
                                    "".join(format_exc()), "</pre>",
                                    _("The original failure message follows:"),
                                    "</p>")))

        # }}}

        if hasattr(self.page_desc, "correct_code"):

            def normalize_code(s):
                return (s.replace(" ", "").replace("\r", "").replace(
                    "\n", "").replace("\t", ""))

            if (normalize_code(user_code) == normalize_code(
                    self.page_desc.correct_code)):
                feedback_bits.append(
                    "<p><b>%s</b></p>" %
                    _("It looks like you submitted code that is identical to "
                      "the reference solution. This is not allowed."))

        from relate.utils import dict_to_struct
        response = dict_to_struct(response_dict)

        bulk_feedback_bits = []

        if response.result == "success":
            pass
        elif response.result in [
                "uncaught_error", "setup_compile_error", "setup_error",
                "test_compile_error", "test_error"
        ]:
            feedback_bits.append("".join([
                "<p>",
                _("The grading code failed. Sorry about that. "
                  "The staff has been informed, and if this problem is "
                  "due to an issue with the grading code, "
                  "it will be fixed as soon as possible. "
                  "In the meantime, you'll see a traceback "
                  "below that may help you figure out what went wrong."),
                "</p>"
            ]))
        elif response.result == "timeout":
            feedback_bits.append("".join([
                "<p>",
                _("Your code took too long to execute. The problem "
                  "specifies that your code may take at most %s seconds "
                  "to run. "
                  "It took longer than that and was aborted."), "</p>"
            ]) % self.page_desc.timeout)

            correctness = 0
        elif response.result == "user_compile_error":
            feedback_bits.append("".join([
                "<p>",
                _("Your code failed to compile. An error message is "
                  "below."), "</p>"
            ]))

            correctness = 0
        elif response.result == "user_error":
            feedback_bits.append("".join([
                "<p>",
                _("Your code failed with an exception. "
                  "A traceback is below."), "</p>"
            ]))

            correctness = 0
        else:
            raise RuntimeError("invalid run result: %s" % response.result)

        if hasattr(response, "feedback") and response.feedback:

            def sanitize(s):
                import bleach
                return bleach.clean(s, tags=["p", "pre"])

            feedback_bits.append("".join([
                "<p>",
                _("Here is some feedback on your code"), ":"
                "<ul>%s</ul></p>"
            ]) % "".join("<li>%s</li>" % sanitize(fb_item)
                         for fb_item in response.feedback))
        if hasattr(response, "traceback") and response.traceback:
            feedback_bits.append("".join([
                "<p>",
                _("This is the exception traceback"), ":"
                "<pre>%s</pre></p>"
            ]) % escape(response.traceback))
        if hasattr(response,
                   "exec_host") and response.exec_host != "localhost":
            import socket
            try:
                exec_host_name, dummy, dummy = socket.gethostbyaddr(
                    response.exec_host)
            except socket.error:
                exec_host_name = response.exec_host

            feedback_bits.append("".join(
                ["<p>",
                 _("Your code ran on %s.") % exec_host_name, "</p>"]))

        if hasattr(response, "stdout") and response.stdout:
            bulk_feedback_bits.append("".join([
                "<p>",
                _("Your code printed the following output"), ":"
                "<pre>%s</pre></p>"
            ]) % escape(response.stdout))
        if hasattr(response, "stderr") and response.stderr:
            bulk_feedback_bits.append("".join([
                "<p>",
                _("Your code printed the following error messages"), ":"
                "<pre>%s</pre></p>"
            ]) % escape(response.stderr))
        if hasattr(response, "figures") and response.figures:
            fig_lines = [
                "".join([
                    "<p>",
                    _("Your code produced the following plots"), ":</p>"
                ]),
                '<dl class="result-figure-list">',
            ]

            for nr, mime_type, b64data in response.figures:
                if mime_type in ["image/jpeg", "image/png"]:
                    fig_lines.extend([
                        "".join(["<dt>", _("Figure"), "%d<dt>"]) % nr,
                        '<dd><img alt="Figure %d" src="data:%s;base64,%s"></dd>'
                        % (nr, mime_type, b64data)
                    ])

            fig_lines.append("</dl>")
            bulk_feedback_bits.extend(fig_lines)

        # {{{ html output / santization

        if hasattr(response, "html") and response.html:

            def is_allowed_data_uri(allowed_mimetypes, uri):
                import re
                m = re.match(r"^data:([-a-z0-9]+/[-a-z0-9]+);base64,", uri)
                if not m:
                    return False

                mimetype = m.group(1)
                return mimetype in allowed_mimetypes

            def sanitize(s):
                import bleach

                def filter_audio_attributes(tag, name, value):
                    if name in ["controls"]:
                        return True
                    else:
                        return False

                def filter_source_attributes(tag, name, value):
                    if name in ["type"]:
                        return True
                    elif name == "src":
                        if is_allowed_data_uri([
                                "audio/wav",
                        ], value):
                            return bleach.sanitizer.VALUE_SAFE
                        else:
                            return False
                    else:
                        return False

                def filter_img_attributes(tag, name, value):
                    if name in ["alt", "title"]:
                        return True
                    elif name == "src":
                        return is_allowed_data_uri([
                            "image/png",
                            "image/jpeg",
                        ], value)
                    else:
                        return False

                if not isinstance(s, str):
                    return _("(Non-string in 'HTML' output filtered out)")

                return bleach.clean(s,
                                    tags=bleach.ALLOWED_TAGS +
                                    ["audio", "video", "source"],
                                    attributes={
                                        "audio": filter_audio_attributes,
                                        "source": filter_source_attributes,
                                        "img": filter_img_attributes,
                                    })

            bulk_feedback_bits.extend(
                sanitize(snippet) for snippet in response.html)

        # }}}

        return AnswerFeedback(correctness=correctness,
                              feedback="\n".join(feedback_bits),
                              bulk_feedback="\n".join(bulk_feedback_bits))
Beispiel #22
0
def reset_password(request, field="email"):
    if not settings.RELATE_REGISTRATION_ENABLED:
        raise SuspiciousOperation(_("self-registration is not enabled"))

    # return form class by string of class name
    ResetPasswordForm = globals()["ResetPasswordFormBy" +
                                  field.title()]  # noqa
    if request.method == 'POST':
        form = ResetPasswordForm(request.POST)
        if form.is_valid():
            if field == "instid":
                inst_id = form.cleaned_data["instid"]
                try:
                    user = get_user_model().objects.get(
                        institutional_id__iexact=inst_id)
                except ObjectDoesNotExist:
                    user = None

            if field == "email":
                email = form.cleaned_data["email"]
                try:
                    user = get_user_model().objects.get(email__iexact=email)
                except ObjectDoesNotExist:
                    user = None

            if user is None:
                FIELD_DICT = {  # noqa
                    "email": _("email address"),
                    "instid": _("institutional ID")
                }
                messages.add_message(
                    request, messages.ERROR,
                    _("That %(field)s doesn't have an "
                      "associated user account. Are you "
                      "sure you've registered?") %
                    {"field": FIELD_DICT[field]})
            else:
                if not user.email:
                    # happens when a user have an inst_id but have no email.
                    messages.add_message(
                        request, messages.ERROR,
                        _("The account with that institution ID "
                          "doesn't have an associated email."))
                else:
                    email = user.email
                    user.sign_in_key = make_sign_in_key(user)
                    user.save()

                    from django.template.loader import render_to_string
                    message = render_to_string(
                        "course/sign-in-email.txt", {
                            "user":
                            user,
                            "sign_in_uri":
                            request.build_absolute_uri(
                                reverse("relate-reset_password_stage2",
                                        args=(
                                            user.id,
                                            user.sign_in_key,
                                        ))),
                            "home_uri":
                            request.build_absolute_uri(reverse("relate-home"))
                        })
                    from django.core.mail import EmailMessage
                    msg = EmailMessage(
                        string_concat("[", _("RELATE"), "] ",
                                      _("Password reset")), message,
                        getattr(settings, "NO_REPLY_EMAIL_FROM",
                                settings.ROBOT_EMAIL_FROM), [email])

                    from relate.utils import get_outbound_mail_connection
                    msg.connection = (get_outbound_mail_connection("no_reply")
                                      if hasattr(settings,
                                                 "NO_REPLY_EMAIL_FROM") else
                                      get_outbound_mail_connection("robot"))
                    msg.send()

                    if field == "instid":
                        messages.add_message(
                            request, messages.INFO,
                            _("The email address associated with that "
                              "account is %s.") % masked_email(email))

                    messages.add_message(
                        request, messages.INFO,
                        _("Email sent. Please check your email and "
                          "click the link."))

                    return redirect("relate-home")
    else:
        form = ResetPasswordForm()

    return render(
        request, "reset-passwd-form.html", {
            "field": field,
            "form_description": _("Password reset on %(site_name)s") % {
                "site_name": _("RELATE")
            },
            "form": form
        })
Beispiel #23
0
def enroll_view(request, course_identifier):
    # type: (http.HttpRequest, str) -> http.HttpResponse

    course = get_object_or_404(Course, identifier=course_identifier)
    user = request.user
    participations = Participation.objects.filter(course=course, user=user)
    if not participations.count():
        participation = None
    else:
        participation = participations.first()

    if participation is not None:
        if participation.status == participation_status.requested:
            messages.add_message(request, messages.ERROR,
                                 _("You have previously sent the enrollment "
                                   "request. Re-sending the request is not "
                                   "allowed."))
            return redirect("relate-course_page", course_identifier)
        elif participation.status == participation_status.denied:
            messages.add_message(request, messages.ERROR,
                                 _("Your enrollment request had been denied. "
                                   "Enrollment is not allowed."))
            return redirect("relate-course_page", course_identifier)
        elif participation.status == participation_status.dropped:
            messages.add_message(request, messages.ERROR,
                                 _("You had been dropped from the course. "
                                   "Re-enrollment is not allowed."))
            return redirect("relate-course_page", course_identifier)
        else:
            assert participation.status == participation_status.active
            messages.add_message(request, messages.ERROR,
                                 _("Already enrolled. Cannot re-enroll."))
        return redirect("relate-course_page", course_identifier)

    if not course.accepts_enrollment:
        messages.add_message(request, messages.ERROR,
                _("Course is not accepting enrollments."))
        return redirect("relate-course_page", course_identifier)

    if request.method != "POST":
        # This can happen if someone tries to refresh the page, or switches to
        # desktop view on mobile.
        messages.add_message(request, messages.ERROR,
                _("Can only enroll using POST request"))
        return redirect("relate-course_page", course_identifier)

    if user.status != user_status.active:
        messages.add_message(request, messages.ERROR,
                _("Your email address is not yet confirmed. "
                "Confirm your email to continue."))
        return redirect("relate-course_page", course_identifier)

    preapproval = None
    if request.user.email:
        try:
            preapproval = ParticipationPreapproval.objects.get(
                    course=course, email__iexact=request.user.email)
        except ParticipationPreapproval.DoesNotExist:
            pass

    if preapproval is None:
        if user.institutional_id:
            if not (course.preapproval_require_verified_inst_id
                    and not user.institutional_id_verified):
                try:
                    preapproval = ParticipationPreapproval.objects.get(
                            course=course,
                            institutional_id__iexact=user.institutional_id)
                except ParticipationPreapproval.DoesNotExist:
                    pass

    def email_suffix_matches(email, suffix):
        # type: (Text, Text) -> bool
        if suffix.startswith("@"):
            return email.endswith(suffix)
        else:
            return email.endswith("@%s" % suffix) or email.endswith(".%s" % suffix)

    if (preapproval is None
        and course.enrollment_required_email_suffix
        and not email_suffix_matches(
            user.email, course.enrollment_required_email_suffix)):

        messages.add_message(request, messages.ERROR,
                _("Enrollment not allowed. Please use your '%s' email to "
                "enroll.") % course.enrollment_required_email_suffix)
        return redirect("relate-course_page", course_identifier)

    roles = ParticipationRole.objects.filter(
            course=course,
            is_default_for_new_participants=True)

    if preapproval is not None:
        roles = list(preapproval.roles.all())

    try:
        if course.enrollment_approval_required and preapproval is None:
            participation = handle_enrollment_request(
                    course, user, participation_status.requested,
                    roles, request)

            assert participation is not None

            with LanguageOverride(course=course):
                from relate.utils import render_email_template
                message = render_email_template(
                    "course/enrollment-request-email.txt", {
                        "user": user,
                        "course": course,
                        "admin_uri": mark_safe(
                            request.build_absolute_uri(
                                reverse("relate-edit_participation",
                                        args=(course.identifier, participation.id))))
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                    string_concat("[%s] ", _("New enrollment request"))
                    % course_identifier,
                    message,
                    getattr(settings, "ENROLLMENT_EMAIL_FROM",
                            settings.ROBOT_EMAIL_FROM),
                    [course.notify_email])

                from relate.utils import get_outbound_mail_connection
                msg.connection = (
                    get_outbound_mail_connection("enroll")
                    if hasattr(settings, "ENROLLMENT_EMAIL_FROM")
                    else get_outbound_mail_connection("robot"))

                msg.send()

            messages.add_message(request, messages.INFO,
                    _("Enrollment request sent. You will receive notifcation "
                    "by email once your request has been acted upon."))
        else:
            handle_enrollment_request(course, user, participation_status.active,
                                      roles, request)

            messages.add_message(request, messages.SUCCESS,
                    _("Successfully enrolled."))

    except IntegrityError:
        messages.add_message(request, messages.ERROR,
                _("A participation already exists. Enrollment attempt aborted."))

    return redirect("relate-course_page", course_identifier)
Beispiel #24
0
def enroll_view(request, course_identifier):
    # type: (http.HttpRequest, str) -> http.HttpResponse

    course = get_object_or_404(Course, identifier=course_identifier)
    participation = get_participation_for_request(request, course)

    if participation is not None:
        messages.add_message(request, messages.ERROR,
                _("Already enrolled. Cannot re-renroll."))
        return redirect("relate-course_page", course_identifier)

    if not course.accepts_enrollment:
        messages.add_message(request, messages.ERROR,
                _("Course is not accepting enrollments."))
        return redirect("relate-course_page", course_identifier)

    if request.method != "POST":
        # This can happen if someone tries to refresh the page, or switches to
        # desktop view on mobile.
        messages.add_message(request, messages.ERROR,
                _("Can only enroll using POST request"))
        return redirect("relate-course_page", course_identifier)

    user = request.user
    if (course.enrollment_required_email_suffix
            and user.status != user_status.active):
        messages.add_message(request, messages.ERROR,
                _("Your email address is not yet confirmed. "
                "Confirm your email to continue."))
        return redirect("relate-course_page", course_identifier)

    preapproval = None
    if request.user.email:
        try:
            preapproval = ParticipationPreapproval.objects.get(
                    course=course, email__iexact=request.user.email)
        except ParticipationPreapproval.DoesNotExist:
            if user.institutional_id:
                if not (course.preapproval_require_verified_inst_id
                        and not user.institutional_id_verified):
                    try:
                        preapproval = ParticipationPreapproval.objects.get(
                                course=course,
                                institutional_id__iexact=user.institutional_id)
                    except ParticipationPreapproval.DoesNotExist:
                        pass
            pass

    if (
            preapproval is None
            and course.enrollment_required_email_suffix
            and not user.email.endswith(course.enrollment_required_email_suffix)):

        messages.add_message(request, messages.ERROR,
                _("Enrollment not allowed. Please use your '%s' email to "
                "enroll.") % course.enrollment_required_email_suffix)
        return redirect("relate-course_page", course_identifier)

    roles = ParticipationRole.objects.filter(
            course=course,
            is_default_for_new_participants=True)

    if preapproval is not None:
        roles = list(preapproval.roles.all())

    try:
        if course.enrollment_approval_required and preapproval is None:
            participation = handle_enrollment_request(
                    course, user, participation_status.requested,
                    roles, request)

            with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE):
                from django.template.loader import render_to_string
                message = render_to_string("course/enrollment-request-email.txt", {
                    "user": user,
                    "course": course,
                    "admin_uri": mark_safe(
                        request.build_absolute_uri(
                            reverse("relate-edit_participation",
                                args=(course.identifier, participation.id))))
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                        string_concat("[%s] ", _("New enrollment request"))
                        % course_identifier,
                        message,
                        settings.ROBOT_EMAIL_FROM,
                        [course.notify_email])

                from relate.utils import get_outbound_mail_connection
                msg.connection = get_outbound_mail_connection("robot")
                msg.send()

            messages.add_message(request, messages.INFO,
                    _("Enrollment request sent. You will receive notifcation "
                    "by email once your request has been acted upon."))
        else:
            handle_enrollment_request(course, user, participation_status.active,
                                      roles, request)

            messages.add_message(request, messages.SUCCESS,
                    _("Successfully enrolled."))

    except IntegrityError:
        messages.add_message(request, messages.ERROR,
                _("A participation already exists. Enrollment attempt aborted."))

    return redirect("relate-course_page", course_identifier)
Beispiel #25
0
    def form_valid(self, form):
        kindOptions = {"Humans": "H", "ZOMBIES": "Z"}

        sender = "*****@*****.**"
        # sender = "*****@*****.**"

        if form.is_valid():
            # send email using information from the self.cleaned_data dictionary
            subject = form.cleaned_data['subject']
            body = form.cleaned_data['body']
            recipient_title = form.cleaned_data['recipient']
            schoolSelection = form.cleaned_data['school']

            # filter players by team
            kind_recipients = []
            kind_label = "[" + recipient_title + "]"
            # Using a dictionary to have more robust way to select players
            if (recipient_title in kindOptions):
                kind_recipients = [
                    p.user.email for p in Player.current_players()
                    if p.team == kindOptions[recipient_title]
                ]
            else:
                # Default recipients list is all players
                kind_recipients = [
                    p.user.email for p in Player.current_players()
                ]

            # add team tag to subject line
            subject = kind_label + subject

            # filter players by school, add school tag to subject line
            school_recipients = []
            for schools in schoolSelection:
                school_label = "[" + schools + "]"
                subject = school_label + subject
                school_recipients.append([
                    p.user.email for p in Player.current_players()
                    if p.school.name == schools
                ])

            # flatten the list of lists
            school_recipients = [
                item for sublist in school_recipients for item in sublist
            ]

            # combine two lists to get to right list of recipients
            recipients = []
            if (len(school_recipients) == 0):
                recipients = kind_recipients
            else:
                recipients = list(
                    set(kind_recipients).intersection(set(school_recipients)))

            # Create an EmailMessage objwct with our given parameters
            mailBag = EmailMessage(subject, body, sender, [], recipients)
            # Check if the user uploaded an attachment (POST), and attach
            # it to all messages in the mailBag

            attachment = 0
            if self.request.method == 'POST':
                if (self.request.FILES):
                    attachment = self.request.FILES['attachment']
                    mailBag.attach(attachment.name, attachment.read(),
                                   attachment.content_type)

            # Send the email in batches of 100. Each batch is sent from a different email in
            # the list of sender accounts above (EMAIL_LIST)
            recipLen = len(emailList)
            x = 0
            y = 0
            while recipLen > 0:
                if (recipLen > 100):
                    batch = emailList[(y * 100):(y * 100) + 100]
                    mailBag.bcc = batch
                    mailBag.connection = EmailBackend(
                        username=EMAIL_LIST[x], password=EMAIL_PW_LIST[x])

                else:
                    batch = emailList[(y * 100):(y * 100) + recipLen]
                    mailBag.bcc = batch
                    mailBag.connection = EmailBackend(
                        username=EMAIL_LIST[x], password=EMAIL_PW_LIST[x])

                # Send the emails out!
                mailBag.send(fail_silently=False)
                y += 1
                x += 1
                if x > 4:
                    x = 0
                recipLen -= 100

        return super(Mailer, self).form_valid(form)
Beispiel #26
0
    def update_grade_data_from_grading_form_v2(self, request, page_context,
            page_data, grade_data, grading_form, files_data):

        if grade_data is None:
            grade_data = {}
        for k in self.grade_data_attrs:
            if k == "grade_percent":
                grade_data[k] = grading_form.cleaned_percent()
            else:
                grade_data[k] = grading_form.cleaned_data[k]

        if grading_form.cleaned_data["notify"] and page_context.flow_session:
            from course.utils import LanguageOverride
            with LanguageOverride(page_context.course):
                from relate.utils import render_email_template
                from course.utils import will_use_masked_profile_for_email
                staff_email = [page_context.course.notify_email, request.user.email]
                message = render_email_template("course/grade-notify.txt", {
                    "page_title": self.title(page_context, page_data),
                    "course": page_context.course,
                    "participation": page_context.flow_session.participation,
                    "feedback_text": grade_data["feedback_text"],
                    "flow_session": page_context.flow_session,
                    "review_uri": page_context.page_uri,
                    "use_masked_profile":
                        will_use_masked_profile_for_email(staff_email)
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                        string_concat("[%(identifier)s:%(flow_id)s] ",
                            _("New notification"))
                        % {'identifier': page_context.course.identifier,
                            'flow_id': page_context.flow_session.flow_id},
                        message,
                        getattr(settings, "GRADER_FEEDBACK_EMAIL_FROM",
                                page_context.course.get_from_email()),
                        [page_context.flow_session.participation.user.email])
                msg.bcc = [page_context.course.notify_email]

                if grading_form.cleaned_data["may_reply"]:
                    msg.reply_to = [request.user.email]

                if hasattr(settings, "GRADER_FEEDBACK_EMAIL_FROM"):
                    from relate.utils import get_outbound_mail_connection
                    msg.connection = get_outbound_mail_connection("grader_feedback")
                msg.send()

        if (grading_form.cleaned_data["notes"]
                and grading_form.cleaned_data["notify_instructor"]
                and page_context.flow_session):
            from course.utils import LanguageOverride
            with LanguageOverride(page_context.course):
                from relate.utils import render_email_template
                from course.utils import will_use_masked_profile_for_email
                staff_email = [page_context.course.notify_email, request.user.email]
                use_masked_profile = will_use_masked_profile_for_email(staff_email)
                if use_masked_profile:
                    username = (
                        page_context.flow_session.user.get_masked_profile())
                else:
                    username = (
                        page_context.flow_session.user.get_email_appellation())
                message = render_email_template(
                    "course/grade-internal-notes-notify.txt",
                    {
                        "page_title": self.title(page_context, page_data),
                        "username": username,
                        "course": page_context.course,
                        "participation": page_context.flow_session.participation,
                        "notes_text": grade_data["notes"],
                        "flow_session": page_context.flow_session,
                        "review_uri": page_context.page_uri,
                        "sender": request.user,
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                        string_concat("[%(identifier)s:%(flow_id)s] ",
                            _("Grading notes from %(ta)s"))
                        % {'identifier': page_context.course.identifier,
                           'flow_id': page_context.flow_session.flow_id,
                           'ta': request.user.get_full_name()
                           },
                        message,
                        getattr(settings, "GRADER_FEEDBACK_EMAIL_FROM",
                                page_context.course.get_from_email()),
                        [page_context.course.notify_email])
                msg.bcc = [request.user.email]
                msg.reply_to = [request.user.email]

                if hasattr(settings, "GRADER_FEEDBACK_EMAIL_FROM"):
                    from relate.utils import get_outbound_mail_connection
                    msg.connection = get_outbound_mail_connection("grader_feedback")
                msg.send()

        return grade_data
Beispiel #27
0
    def grade(self, page_context, page_data, answer_data, grade_data):
        if answer_data is None:
            return AnswerFeedback(correctness=0,
                    feedback=_("No answer provided."))

        user_code = answer_data["answer"]

        # {{{ request run

        run_req = {"compile_only": False, "user_code": user_code}

        def transfer_attr(name):
            if hasattr(self.page_desc, name):
                run_req[name] = getattr(self.page_desc, name)

        transfer_attr("setup_code")
        transfer_attr("names_for_user")
        transfer_attr("names_from_user")

        if hasattr(self.page_desc, "test_code"):
            run_req["test_code"] = self.get_test_code()

        if hasattr(self.page_desc, "data_files"):
            run_req["data_files"] = {}

            from course.content import get_repo_blob

            for data_file in self.page_desc.data_files:
                from base64 import b64encode
                run_req["data_files"][data_file] = \
                        b64encode(
                                get_repo_blob(
                                    page_context.repo, data_file,
                                    page_context.commit_sha).data).decode()

        try:
            response_dict = request_python_run_with_retries(run_req,
                    run_timeout=self.page_desc.timeout)
        except:
            from traceback import format_exc
            response_dict = {
                    "result": "uncaught_error",
                    "message": "Error connecting to container",
                    "traceback": "".join(format_exc()),
                    }

        # }}}

        feedback_bits = []

        # {{{ send email if the grading code broke

        if response_dict["result"] in [
                "uncaught_error",
                "setup_compile_error",
                "setup_error",
                "test_compile_error",
                "test_error"]:
            error_msg_parts = ["RESULT: %s" % response_dict["result"]]
            for key, val in sorted(response_dict.items()):
                if (key not in ["result", "figures"]
                        and val
                        and isinstance(val, six.string_types)):
                    error_msg_parts.append("-------------------------------------")
                    error_msg_parts.append(key)
                    error_msg_parts.append("-------------------------------------")
                    error_msg_parts.append(val)
            error_msg_parts.append("-------------------------------------")
            error_msg_parts.append("user code")
            error_msg_parts.append("-------------------------------------")
            error_msg_parts.append(user_code)
            error_msg_parts.append("-------------------------------------")

            error_msg = "\n".join(error_msg_parts)

            with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE):
                from django.template.loader import render_to_string
                message = render_to_string("course/broken-code-question-email.txt", {
                    "page_id": self.page_desc.id,
                    "course": page_context.course,
                    "error_message": error_msg,
                    })

                if (
                        not page_context.in_sandbox
                        and
                        not is_nuisance_failure(response_dict)):
                    try:
                        from django.core.mail import EmailMessage
                        msg = EmailMessage("".join(["[%s:%s] ",
                            _("code question execution failed")])
                            % (
                                page_context.course.identifier,
                                page_context.flow_session.flow_id
                                if page_context.flow_session is not None
                                else _("<unknown flow>")),
                            message,
                            settings.ROBOT_EMAIL_FROM,
                            [page_context.course.notify_email])

                        from relate.utils import get_outbound_mail_connection
                        msg.connection = get_outbound_mail_connection("robot")
                        msg.send()

                    except Exception:
                        from traceback import format_exc
                        feedback_bits.append(
                            six.text_type(string_concat(
                                "<p>",
                                _(
                                    "Both the grading code and the attempt to "
                                    "notify course staff about the issue failed. "
                                    "Please contact the course or site staff and "
                                    "inform them of this issue, mentioning this "
                                    "entire error message:"),
                                "</p>",
                                "<p>",
                                _(
                                    "Sending an email to the course staff about the "
                                    "following failure failed with "
                                    "the following error message:"),
                                "<pre>",
                                "".join(format_exc()),
                                "</pre>",
                                _("The original failure message follows:"),
                                "</p>")))

        # }}}

        from relate.utils import dict_to_struct
        response = dict_to_struct(response_dict)

        bulk_feedback_bits = []
        if hasattr(response, "points"):
            correctness = response.points
            feedback_bits.append(
                    "<p><b>%s</b></p>"
                    % get_auto_feedback(correctness))
        else:
            correctness = None

        if response.result == "success":
            pass
        elif response.result in [
                "uncaught_error",
                "setup_compile_error",
                "setup_error",
                "test_compile_error",
                "test_error"]:
            feedback_bits.append("".join([
                "<p>",
                _(
                    "The grading code failed. Sorry about that. "
                    "The staff has been informed, and if this problem is "
                    "due to an issue with the grading code, "
                    "it will be fixed as soon as possible. "
                    "In the meantime, you'll see a traceback "
                    "below that may help you figure out what went wrong."
                    ),
                "</p>"]))
        elif response.result == "timeout":
            feedback_bits.append("".join([
                "<p>",
                _(
                    "Your code took too long to execute. The problem "
                    "specifies that your code may take at most %s seconds "
                    "to run. "
                    "It took longer than that and was aborted."
                    ),
                "</p>"])
                    % self.page_desc.timeout)

            correctness = 0
        elif response.result == "user_compile_error":
            feedback_bits.append("".join([
                "<p>",
                _("Your code failed to compile. An error message is "
                    "below."),
                "</p>"]))

            correctness = 0
        elif response.result == "user_error":
            feedback_bits.append("".join([
                "<p>",
                _("Your code failed with an exception. "
                    "A traceback is below."),
                "</p>"]))

            correctness = 0
        else:
            raise RuntimeError("invalid runpy result: %s" % response.result)

        if hasattr(response, "feedback") and response.feedback:
            feedback_bits.append("".join([
                "<p>",
                _("Here is some feedback on your code"),
                ":"
                "<ul>%s</ul></p>"]) %
                        "".join(
                            "<li>%s</li>" % escape(fb_item)
                            for fb_item in response.feedback))
        if hasattr(response, "traceback") and response.traceback:
            feedback_bits.append("".join([
                "<p>",
                _("This is the exception traceback"),
                ":"
                "<pre>%s</pre></p>"]) % escape(response.traceback))
        if hasattr(response, "exec_host") and response.exec_host != "localhost":
            import socket
            try:
                exec_host_name, dummy, dummy = socket.gethostbyaddr(
                        response.exec_host)
            except socket.error:
                exec_host_name = response.exec_host

            feedback_bits.append("".join([
                "<p>",
                _("Your code ran on %s.") % exec_host_name,
                "</p>"]))

        if hasattr(response, "stdout") and response.stdout:
            bulk_feedback_bits.append("".join([
                "<p>",
                _("Your code printed the following output"),
                ":"
                "<pre>%s</pre></p>"])
                    % escape(response.stdout))
        if hasattr(response, "stderr") and response.stderr:
            bulk_feedback_bits.append("".join([
                "<p>",
                _("Your code printed the following error messages"),
                ":"
                "<pre>%s</pre></p>"]) % escape(response.stderr))
        if hasattr(response, "figures") and response.figures:
            fig_lines = ["".join([
                "<p>",
                _("Your code produced the following plots"),
                ":</p>"]),
                '<dl class="result-figure-list">',
                ]

            for nr, mime_type, b64data in response.figures:
                if mime_type in ["image/jpeg", "image/png"]:
                    fig_lines.extend([
                        "".join([
                            "<dt>",
                            _("Figure"), "%d<dt>"]) % nr,
                        '<dd><img alt="Figure %d" src="data:%s;base64,%s"></dd>'
                        % (nr, mime_type, b64data)])

            fig_lines.append("</dl>")
            bulk_feedback_bits.extend(fig_lines)

        # {{{ html output / santization

        if hasattr(response, "html") and response.html:
            def is_allowed_data_uri(allowed_mimetypes, uri):
                import re
                m = re.match(r"^data:([-a-z0-9]+/[-a-z0-9]+);base64,", uri)
                if not m:
                    return False

                mimetype = m.group(1)
                return mimetype in allowed_mimetypes

            def sanitize(s):
                import bleach

                def filter_audio_attributes(name, value):
                    if name in ["controls"]:
                        return True
                    else:
                        return False

                def filter_source_attributes(name, value):
                    if name in ["type"]:
                        return True
                    elif name == "src":
                        return is_allowed_data_uri([
                            "audio/wav",
                            ], value)
                    else:
                        return False

                def filter_img_attributes(name, value):
                    if name in ["alt", "title"]:
                        return True
                    elif name == "src":
                        return is_allowed_data_uri([
                            "image/png",
                            "image/jpeg",
                            ], value)
                    else:
                        return False

                return bleach.clean(s,
                        tags=bleach.ALLOWED_TAGS + ["audio", "video", "source"],
                        attributes={
                            "audio": filter_audio_attributes,
                            "source": filter_source_attributes,
                            "img": filter_img_attributes,
                            })

            bulk_feedback_bits.extend(
                    sanitize(snippet) for snippet in response.html)

        # }}}

        return AnswerFeedback(
                correctness=correctness,
                feedback="\n".join(feedback_bits),
                bulk_feedback="\n".join(bulk_feedback_bits))
Beispiel #28
0
def registration(request, uuid):
    print('Get FORM')
    event = get_object_or_404(Event, event_uuid=uuid)
    if request.method == 'POST':
        print('Form POST')
        form = RegistrationForm(request.POST, event_uuid=uuid)

        if form.is_valid():
            print('HERE VALID')
            last_name = form.cleaned_data['last_name']
            first_name = form.cleaned_data['first_name']
            school = form.cleaned_data['school']
            shs_track = form.cleaned_data['shs_track']
            # projected_course = form.cleaned_data['projected_course']
            email = form.cleaned_data['email']
            date_of_birth = form.cleaned_data['date_of_birth']
            gender = form.cleaned_data['gender']
            mobile = form.cleaned_data['mobile']
            print(form.cleaned_data['projected_course'])
            print(form.cleaned_data['grade_level'])
            if form.cleaned_data['projected_course'] == 'OTHER':
                print('OTHER')
                projected_course = form.cleaned_data['other']
                print(projected_course)
            else:
                projected_course = form.cleaned_data['projected_course']

            if form.cleaned_data['grade_level'] == 0:
                print('OTHER')
                grade_level = form.cleaned_data['otherGrade']
                print(grade_level)
            else:
                grade_level = form.cleaned_data['grade_level']

            student = Student()
            student.last_name = last_name
            student.first_name = first_name
            student.school = school
            student.shs_track = shs_track
            student.projected_course = projected_course
            student.email = email
            student.date_of_birth = date_of_birth
            student.gender = gender
            student.mobile = mobile
            student.registered_event = event
            student.grade_level = grade_level
            student.save()

            html_message = render_to_string('email_template.html',
                                            context={
                                                'last_name': student.last_name,
                                                'first_name':
                                                student.first_name,
                                                'school': student.school
                                            })

            msg = EmailMessage(subject='Thank You',
                               body=html_message,
                               from_email=settings.DEFAULT_FROM_EMAIL,
                               to=[student.email],
                               cc=[
                                   settings.EMAIL_CC,
                               ])

            msg.attach(student.qr_code.name, student.qr_code.read(),
                       'image/png')
            # change
            msg.content_subtype = 'html'

            try:
                msg.send(fail_silently=False)
            except Exception as e:
                connection = get_connection(
                    host=settings.EMAIL_HOST_BACKUP,
                    port=settings.EMAIL_PORT,
                    username=settings.EMAIL_HOST_USER_BACKUP1,
                    password=settings.EMAIL_HOST_USER_BACKUP_PASSWORD,
                )
                msg.connection = connection
                msg.send(fail_silently=False)

            return render(request,
                          'success.html',
                          context={
                              'student': student,
                              'event_name': event.name,
                              'event_id': event.id,
                              'event_logo': event.logo,
                              'event_uuid': event.event_uuid,
                              'qr': student.qr_code.url
                          })
    else:
        form = RegistrationForm(event_uuid=uuid)

    is_expired = date.today() > event.end_date

    context = {
        'event_uuid': event.event_uuid,
        'event_name': event.name,
        'event_id': event.id,
        'event_logo': event.logo,
        'event_start_date': event.start_date,
        'event_end_date': event.end_date,
        'form': form,
        'is_expired': is_expired,
        'courses': sorted(COURSES),
        'grade_level': GRADE_LEVEL
    }

    return render(request, 'registration.html', context=context)
Beispiel #29
0
def sign_up(request):
    if not settings.RELATE_REGISTRATION_ENABLED:
        raise SuspiciousOperation(
                _("self-registration is not enabled"))

    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            if get_user_model().objects.filter(
                    username=form.cleaned_data["username"]).count():
                messages.add_message(request, messages.ERROR,
                        _("A user with that username already exists."))

            elif get_user_model().objects.filter(
                    email__iexact=form.cleaned_data["email"]).count():
                messages.add_message(request, messages.ERROR,
                        _("That email address is already in use. "
                        "Would you like to "
                        "<a href='%s'>reset your password</a> instead?")
                        % reverse(
                            "relate-reset_password")),
            else:
                email = form.cleaned_data["email"]
                user = get_user_model()(
                        email=email,
                        username=form.cleaned_data["username"])

                user.set_unusable_password()
                user.status = user_status.unconfirmed
                user.sign_in_key = make_sign_in_key(user)
                user.save()

                from django.template.loader import render_to_string
                message = render_to_string("course/sign-in-email.txt", {
                    "user": user,
                    "sign_in_uri": request.build_absolute_uri(
                        reverse(
                            "relate-reset_password_stage2",
                            args=(user.id, user.sign_in_key,))
                        + "?to_profile=1"),
                    "home_uri": request.build_absolute_uri(
                        reverse("relate-home"))
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                        string_concat("[", _("RELATE"), "] ",
                                     _("Verify your email")),
                        message,
                        getattr(settings, "NO_REPLY_EMAIL_FROM",
                                settings.ROBOT_EMAIL_FROM),
                        [email])

                from relate.utils import get_outbound_mail_connection
                msg.connection = (
                        get_outbound_mail_connection("no_reply")
                        if hasattr(settings, "NO_REPLY_EMAIL_FROM")
                        else get_outbound_mail_connection("robot"))
                msg.send()

                messages.add_message(request, messages.INFO,
                        _("Email sent. Please check your email and click "
                        "the link."))

                return redirect("relate-home")

    else:
        form = SignUpForm()

    return render(request, "generic-form.html", {
        "form_description": _("Sign up"),
        "form": form
        })
Beispiel #30
0
def enroll_view(request, course_identifier):
    # type: (http.HttpRequest, str) -> http.HttpResponse

    course = get_object_or_404(Course, identifier=course_identifier)
    user = request.user
    participations = Participation.objects.filter(course=course, user=user)
    if not participations.count():
        participation = None
    else:
        participation = participations.first()

    if participation is not None:
        if participation.status == participation_status.requested:
            messages.add_message(
                request, messages.ERROR,
                _("You have previously sent the enrollment "
                  "request. Re-sending the request is not "
                  "allowed."))
            return redirect("relate-course_page", course_identifier)
        elif participation.status == participation_status.denied:
            messages.add_message(
                request, messages.ERROR,
                _("Your enrollment request had been denied. "
                  "Enrollment is not allowed."))
            return redirect("relate-course_page", course_identifier)
        elif participation.status == participation_status.dropped:
            messages.add_message(
                request, messages.ERROR,
                _("You had been dropped from the course. "
                  "Re-enrollment is not allowed."))
            return redirect("relate-course_page", course_identifier)
        else:
            assert participation.status == participation_status.active
            messages.add_message(request, messages.ERROR,
                                 _("Already enrolled. Cannot re-enroll."))
        return redirect("relate-course_page", course_identifier)

    if not course.accepts_enrollment:
        messages.add_message(request, messages.ERROR,
                             _("Course is not accepting enrollments."))
        return redirect("relate-course_page", course_identifier)

    if request.method != "POST":
        # This can happen if someone tries to refresh the page, or switches to
        # desktop view on mobile.
        messages.add_message(request, messages.ERROR,
                             _("Can only enroll using POST request"))
        return redirect("relate-course_page", course_identifier)

    if user.status != user_status.active:
        messages.add_message(
            request, messages.ERROR,
            _("Your email address is not yet confirmed. "
              "Confirm your email to continue."))
        return redirect("relate-course_page", course_identifier)

    preapproval = None
    if request.user.email:  # pragma: no branch (user email NOT NULL constraint)
        try:
            preapproval = ParticipationPreapproval.objects.get(
                course=course, email__iexact=request.user.email)
        except ParticipationPreapproval.DoesNotExist:
            pass

    if preapproval is None:
        if user.institutional_id:
            if not (course.preapproval_require_verified_inst_id
                    and not user.institutional_id_verified):
                try:
                    preapproval = ParticipationPreapproval.objects.get(
                        course=course,
                        institutional_id__iexact=user.institutional_id)
                except ParticipationPreapproval.DoesNotExist:
                    pass

    def email_suffix_matches(email, suffix):
        # type: (Text, Text) -> bool
        if suffix.startswith("@"):
            return email.endswith(suffix)
        else:
            return email.endswith("@%s" % suffix) or email.endswith(
                ".%s" % suffix)

    if (preapproval is None and course.enrollment_required_email_suffix
            and not email_suffix_matches(
                user.email, course.enrollment_required_email_suffix)):

        messages.add_message(
            request, messages.ERROR,
            _("Enrollment not allowed. Please use your '%s' email to "
              "enroll.") % course.enrollment_required_email_suffix)
        return redirect("relate-course_page", course_identifier)

    roles = ParticipationRole.objects.filter(
        course=course, is_default_for_new_participants=True)

    if preapproval is not None:
        roles = list(preapproval.roles.all())

    try:
        if course.enrollment_approval_required and preapproval is None:
            participation = handle_enrollment_request(
                course, user, participation_status.requested, roles, request)

            assert participation is not None

            with LanguageOverride(course=course):
                from relate.utils import render_email_template
                message = render_email_template(
                    "course/enrollment-request-email.txt", {
                        "user":
                        user,
                        "course":
                        course,
                        "admin_uri":
                        mark_safe(
                            request.build_absolute_uri(
                                reverse("relate-edit_participation",
                                        args=(course.identifier,
                                              participation.id))))
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                    string_concat("[%s] ", _("New enrollment request")) %
                    course_identifier, message,
                    getattr(settings, "ENROLLMENT_EMAIL_FROM",
                            settings.ROBOT_EMAIL_FROM), [course.notify_email])

                from relate.utils import get_outbound_mail_connection
                msg.connection = (get_outbound_mail_connection("enroll")
                                  if hasattr(settings, "ENROLLMENT_EMAIL_FROM")
                                  else get_outbound_mail_connection("robot"))

                msg.send()

            messages.add_message(
                request, messages.INFO,
                _("Enrollment request sent. You will receive notifcation "
                  "by email once your request has been acted upon."))
        else:
            handle_enrollment_request(course, user,
                                      participation_status.active, roles,
                                      request)

            messages.add_message(request, messages.SUCCESS,
                                 _("Successfully enrolled."))

    except IntegrityError:
        messages.add_message(
            request, messages.ERROR,
            _("A participation already exists. Enrollment attempt aborted."))

    return redirect("relate-course_page", course_identifier)
Beispiel #31
0
def enroll_view(request, course_identifier):
    # type: (http.HttpRequest, str) -> http.HttpResponse

    course = get_object_or_404(Course, identifier=course_identifier)
    participation = get_participation_for_request(request, course)

    if participation is not None:
        messages.add_message(request, messages.ERROR,
                             _("Already enrolled. Cannot re-renroll."))
        return redirect("relate-course_page", course_identifier)

    if not course.accepts_enrollment:
        messages.add_message(request, messages.ERROR,
                             _("Course is not accepting enrollments."))
        return redirect("relate-course_page", course_identifier)

    if request.method != "POST":
        # This can happen if someone tries to refresh the page, or switches to
        # desktop view on mobile.
        messages.add_message(request, messages.ERROR,
                             _("Can only enroll using POST request"))
        return redirect("relate-course_page", course_identifier)

    user = request.user
    if (course.enrollment_required_email_suffix
            and user.status != user_status.active):
        messages.add_message(
            request, messages.ERROR,
            _("Your email address is not yet confirmed. "
              "Confirm your email to continue."))
        return redirect("relate-course_page", course_identifier)

    preapproval = None
    if request.user.email:
        try:
            preapproval = ParticipationPreapproval.objects.get(
                course=course, email__iexact=request.user.email)
        except ParticipationPreapproval.DoesNotExist:
            if user.institutional_id:
                if not (course.preapproval_require_verified_inst_id
                        and not user.institutional_id_verified):
                    try:
                        preapproval = ParticipationPreapproval.objects.get(
                            course=course,
                            institutional_id__iexact=user.institutional_id)
                    except ParticipationPreapproval.DoesNotExist:
                        pass
            pass

    if (preapproval is None and course.enrollment_required_email_suffix and
            not user.email.endswith(course.enrollment_required_email_suffix)):

        messages.add_message(
            request, messages.ERROR,
            _("Enrollment not allowed. Please use your '%s' email to "
              "enroll.") % course.enrollment_required_email_suffix)
        return redirect("relate-course_page", course_identifier)

    roles = ParticipationRole.objects.filter(
        course=course, is_default_for_new_participants=True)

    if preapproval is not None:
        roles = list(preapproval.roles.all())

    try:
        if course.enrollment_approval_required and preapproval is None:
            participation = handle_enrollment_request(
                course, user, participation_status.requested, roles, request)

            with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE):
                from django.template.loader import render_to_string
                message = render_to_string(
                    "course/enrollment-request-email.txt", {
                        "user":
                        user,
                        "course":
                        course,
                        "admin_uri":
                        mark_safe(
                            request.build_absolute_uri(
                                reverse("relate-edit_participation",
                                        args=(course.identifier,
                                              participation.id))))
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                    string_concat("[%s] ", _("New enrollment request")) %
                    course_identifier, message, settings.ROBOT_EMAIL_FROM,
                    [course.notify_email])

                from relate.utils import get_outbound_mail_connection
                msg.connection = get_outbound_mail_connection("robot")
                msg.send()

            messages.add_message(
                request, messages.INFO,
                _("Enrollment request sent. You will receive notifcation "
                  "by email once your request has been acted upon."))
        else:
            handle_enrollment_request(course, user,
                                      participation_status.active, roles,
                                      request)

            messages.add_message(request, messages.SUCCESS,
                                 _("Successfully enrolled."))

    except IntegrityError:
        messages.add_message(
            request, messages.ERROR,
            _("A participation already exists. Enrollment attempt aborted."))

    return redirect("relate-course_page", course_identifier)
Beispiel #32
0
def sign_up(request):
    if not settings.RELATE_REGISTRATION_ENABLED:
        raise SuspiciousOperation(_("self-registration is not enabled"))

    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            if get_user_model().objects.filter(
                    username=form.cleaned_data["username"]).count():
                messages.add_message(
                    request, messages.ERROR,
                    _("A user with that username already exists."))

            elif get_user_model().objects.filter(
                    email__iexact=form.cleaned_data["email"]).count():
                messages.add_message(
                    request, messages.ERROR,
                    _("That email address is already in use. "
                      "Would you like to "
                      "<a href='%s'>reset your password</a> instead?") %
                    reverse("relate-reset_password")),
            else:
                email = form.cleaned_data["email"]
                user = get_user_model()(email=email,
                                        username=form.cleaned_data["username"])

                user.set_unusable_password()
                user.status = user_status.unconfirmed
                user.sign_in_key = make_sign_in_key(user)
                user.save()

                from django.template.loader import render_to_string
                message = render_to_string(
                    "course/sign-in-email.txt", {
                        "user":
                        user,
                        "sign_in_uri":
                        request.build_absolute_uri(
                            reverse("relate-reset_password_stage2",
                                    args=(
                                        user.id,
                                        user.sign_in_key,
                                    )) + "?to_profile=1"),
                        "home_uri":
                        request.build_absolute_uri(reverse("relate-home"))
                    })

                from django.core.mail import EmailMessage
                msg = EmailMessage(
                    string_concat("[", _("RELATE"), "] ",
                                  _("Verify your email")), message,
                    getattr(settings, "NO_REPLY_EMAIL_FROM",
                            settings.ROBOT_EMAIL_FROM), [email])

                from relate.utils import get_outbound_mail_connection
                msg.connection = (get_outbound_mail_connection("no_reply")
                                  if hasattr(settings, "NO_REPLY_EMAIL_FROM")
                                  else get_outbound_mail_connection("robot"))
                msg.send()

                messages.add_message(
                    request, messages.INFO,
                    _("Email sent. Please check your email and click "
                      "the link."))

                return redirect("relate-home")

    else:
        form = SignUpForm()

    return render(request, "generic-form.html", {
        "form_description": _("Sign up"),
        "form": form
    })
Beispiel #33
0
def registration_school_official(request, uuid):
    print('GET form')

    event = get_object_or_404(Event, event_uuid=uuid)
    if request.method == 'POST':
        print('Form POST')
        form = SchoolOfficialRegistrationForm(request.POST, event_uuid=uuid)

        if form.is_valid():
            print('VALID')
            last_name = form.cleaned_data['last_name']
            first_name = form.cleaned_data['first_name']
            school = form.cleaned_data['school']
            # projected_course = form.cleaned_data['projected_course']
            email = form.cleaned_data['email']
            date_of_birth = form.cleaned_data['date_of_birth']
            gender = form.cleaned_data['gender']
            mobile = form.cleaned_data['mobile']
            print(form.cleaned_data['course_taken'])
            if form.cleaned_data['course_taken'] == 'OTHER':
                print('OTHER')
                course_taken = form.cleaned_data['other']
            else:
                course_taken = form.cleaned_data['course_taken']

            schoolOfficial = SchoolOfficial()
            schoolOfficial.last_name = last_name
            schoolOfficial.first_name = first_name
            schoolOfficial.school = school
            schoolOfficial.course_taken = course_taken
            schoolOfficial.email = email
            schoolOfficial.date_of_birth = date_of_birth
            schoolOfficial.gender = gender
            schoolOfficial.mobile = mobile
            schoolOfficial.registered_event = event
            schoolOfficial.save()

            html_message = render_to_string('email_template.html',
                                            context={
                                                'last_name':
                                                schoolOfficial.last_name,
                                                'first_name':
                                                schoolOfficial.first_name,
                                                'school': schoolOfficial.school
                                            })

            try:
                msg = EmailMessage(subject='Thank You',
                                   body=html_message,
                                   from_email=settings.EMAIL_HOST_USER,
                                   to=[schoolOfficial.email],
                                   cc=[settings.EMAIL_CC, settings.EMAIL_CC_1])

                msg.attach(schoolOfficial.qr_code.name,
                           schoolOfficial.qr_code.read(), 'image/png')
                msg.content_subtype = 'html'  #this
                msg.send(fail_silently=True)
            except Exception as e:
                try:
                    msg = EmailMessage(
                        subject='Thank You',
                        body=html_message,
                        from_email=settings.EMAIL_HOST_USER_BACKUP1,
                        to=[schoolOfficial.email],
                        cc=[settings.EMAIL_CC, settings.EMAIL_CC_1])

                    msg.attach(schoolOfficial.qr_code.name,
                               schoolOfficial.qr_code.read(), 'image/png')
                    msg.content_subtype = 'html'
                    connection = get_connection(
                        host=settings.EMAIL_HOST,
                        port=settings.EMAIL_PORT,
                        username=settings.EMAIL_HOST_USER_BACKUP1,
                        password=settings.EMAIL_HOST_PASSWORD,
                    )
                    msg.connection = connection
                    msg.send(fail_silently=True)
                except Exception as e:
                    msg = EmailMessage(
                        subject='Thank You',
                        body=html_message,
                        from_email=settings.EMAIL_HOST_USER_BACKUP2,
                        to=[schoolOfficial.email],
                        cc=[settings.EMAIL_CC, settings.EMAIL_CC_1])

                    msg.attach(schoolOfficial.qr_code.name,
                               schoolOfficial.qr_code.read(), 'image/png')
                    msg.content_subtype = 'html'
                    connection = get_connection(
                        host=settings.EMAIL_HOST,
                        port=settings.EMAIL_PORT,
                        username=settings.EMAIL_HOST_USER_BACKUP2,
                        password=settings.EMAIL_HOST_USER_BACKUP_PASSWORD,
                    )
                    msg.connection = connection
                    msg.send(fail_silently=True)

            return render(request,
                          'success.html',
                          context={
                              'official': schoolOfficial,
                              'event_name': event.name,
                              'event_id': event.id,
                              'event_logo': event.logo,
                              'event_uuid': event.event_uuid,
                              'qr': schoolOfficial.qr_code.url
                          })
    else:
        form = SchoolOfficialRegistrationForm(event_uuid=uuid)

    is_expired = date.today() > event.end_date

    context = {
        'event_uuid': event.event_uuid,
        'event_name': event.name,
        'event_id': event.id,
        'event_logo': event.logo,
        'event_start_date': event.start_date,
        'event_end_date': event.end_date,
        'form': form,
        'is_expired': is_expired,
        'courses': sorted(COURSES),
    }
    return render(request,
                  'registration_school_official.html',
                  context=context)
Beispiel #34
0
def reset_password(request, field="email"):
    if not settings.RELATE_REGISTRATION_ENABLED:
        raise SuspiciousOperation(
                _("self-registration is not enabled"))

    # return form class by string of class name
    ResetPasswordForm = globals()["ResetPasswordFormBy" + field.title()]
    if request.method == 'POST':
        form = ResetPasswordForm(request.POST)
        if form.is_valid():
            if field == "instid":
                inst_id = form.cleaned_data["instid"]
                try:
                    user = get_user_model().objects.get(
                            institutional_id__iexact=inst_id)
                except ObjectDoesNotExist:
                    user = None

            if field == "email":
                email = form.cleaned_data["email"]
                try:
                    user = get_user_model().objects.get(email__iexact=email)
                except ObjectDoesNotExist:
                    user = None

            if user is None:
                FIELD_DICT = {
                        "email": _("email address"),
                        "instid": _("institutional ID")
                        }
                messages.add_message(request, messages.ERROR,
                        _("That %(field)s doesn't have an "
                            "associated user account. Are you "
                            "sure you've registered?")
                        % {"field": FIELD_DICT[field]})
            else:
                if not user.email:
                    # happens when a user have an inst_id but have no email.
                    messages.add_message(request, messages.ERROR,
                            _("The account with that institution ID "
                                "doesn't have an associated email."))
                else:
                    email = user.email
                    user.sign_in_key = make_sign_in_key(user)
                    user.save()

                    from django.template.loader import render_to_string
                    message = render_to_string("course/sign-in-email.txt", {
                        "user": user,
                        "sign_in_uri": request.build_absolute_uri(
                            reverse(
                                "relate-reset_password_stage2",
                                args=(user.id, user.sign_in_key,))),
                        "home_uri": request.build_absolute_uri(
                            reverse("relate-home"))
                        })
                    from django.core.mail import EmailMessage
                    msg = EmailMessage(
                            string_concat("[", _("RELATE"), "] ",
                                         _("Password reset")),
                            message,
                            getattr(settings, "NO_REPLY_EMAIL_FROM",
                                    settings.ROBOT_EMAIL_FROM),
                            [email])

                    from relate.utils import get_outbound_mail_connection
                    msg.connection = (
                            get_outbound_mail_connection("no_reply")
                            if hasattr(settings, "NO_REPLY_EMAIL_FROM")
                            else get_outbound_mail_connection("robot"))
                    msg.send()

                    if field == "instid":
                        messages.add_message(request, messages.INFO,
                            _("The email address associated with that "
                                "account is %s.")
                            % masked_email(email))

                    messages.add_message(request, messages.INFO,
                            _("Email sent. Please check your email and "
                            "click the link."))

                    return redirect("relate-home")
    else:
        form = ResetPasswordForm()

    return render(request, "reset-passwd-form.html", {
        "field": field,
        "form_description":
            _("Password reset on %(site_name)s")
            % {"site_name": _("RELATE")},
        "form": form
        })