Exemple #1
0
def change_password(request, format=None):
    data = request.data
    if 'password' not in data or 'new_password' not in data:
        return Response(
            status=404,
            data={"error": "Expects password and new_password fields"})
    if request.user.check_password(data['password']):
        # Verified password
        request.user.set_password(data['new_password'])
        try:
            request.user.save()
            send_mail({
                "user":
                request.user,
                "subject":
                "Reset password",
                "content":
                "Someone has reset your password. If this was not you, please contact us at: [email protected]",
            })
        except:
            return Response({"error": "Could not save password"}, status=404)
    else:
        print(
            "Error, user %s attempted to reset password with incorrect password"
            % (request.user.username))
        return Response({"error": "Incorrect password"})
Exemple #2
0
 def test_mail_util_func(self):
     root_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
     static = 'PDF_Reports'
     full_path = os.path.join(root_dir, static)
     attachment_file_path = str(full_path) + "/test_pdf_report.pdf" 
     print(attachment_file_path)
     result = send_mail({'user': {'email': '*****@*****.**'}, 'subject': 'test', 'content': '<html><body>Testing</body></html>', 'attachment_file_path': attachment_file_path, 'attachment_file_name': 'test_pdf_report.pdf'})
     self.assertTrue(result)
Exemple #3
0
def addMessage(request, format=None):
    log.error(request.data)
    session_key = request.session.get('session_key', None)
    if (session_key is None):
        session_key = str(uuid.uuid1())
        request.session['session_key'] = session_key
        request.session.modified = True
    '''Add a new message to list to be sent to city council'''
    now = datetime.now()
    message_info = request.data
    if 'ag_item' not in message_info or 'committee' not in message_info or 'content' not in message_info or 'pro' not in message_info:
        return Response(
            status=400,
            data={"error": "Missing or incorrect body parameters?"})
    committee = Committee.objects.get(name__contains=message_info['committee'])
    if committee is None:
        return Response(data={
            "error":
            "Could not find committee matching:" + message_info['committee']
        },
                        status=404)
    agenda_item = AgendaItem.objects.get(pk=message_info['ag_item'])
    if agenda_item is None:
        return Response(data={
            "error":
            "Could not find agenda item matching:" + message_info['ag_item']
        },
                        status=404)
    if not settings.TEST and not isCommentAllowed(
            agenda_item.meeting_time, committee.cutoff_offset_days,
            committee.cutoff_hour, committee.cutoff_minute,
            committee.location_tz):
        return Response(
            status=401,
            data={
                "error":
                "Could not add comment about agenda item because past the cutoff time"
            })
    content = message_info['content']
    pro = message_info['pro']
    first_name = None
    last_name = None
    zipcode = 90401
    user = None
    email = None
    user = None
    home_owner = False
    business_owner = False
    resident = False
    works = False
    school = False
    child_school = False
    CODE_LENGTH = 8
    rand_begin = random.randint(0, 32 - CODE_LENGTH)
    authcode_hashed = None
    if (isinstance(request.user, AnonymousUser)):
        if 'first_name' not in message_info or message_info['first_name'] is None or \
            'last_name' not in message_info or message_info['last_name'] is None or \
            'zipcode' not in message_info or message_info['zipcode'] is None or \
            'email' not in message_info or message_info['email'] is None or \
            'home_owner' not in message_info or message_info['home_owner'] is None or \
            'business_owner' not in message_info or message_info['business_owner'] is None or \
            'resident' not in message_info or message_info['resident'] is None or \
            'works' not in message_info or message_info['works'] is None or \
            'school' not in message_info or message_info['school'] is None or \
            'child_school' not in message_info or message_info['child_school'] is None or \
                'token' not in message_info or message_info['token'] is None:
            return Response(
                status=400,
                data={"error": "Missing or incorrect body parameters"})
        messages = Message.objects.filter(session_key=session_key)
        authcode = str(uuid.uuid1()).replace(
            "-", "")[rand_begin:rand_begin + CODE_LENGTH].encode('utf-8')
        if len(messages) == 0:
            verify_token = message_info['token']
            result = verify_recaptcha(verify_token)
            if not result:
                return Response(status=401)
            authcode_hashed = bcrypt.hashpw(authcode,
                                            bcrypt.gensalt()).decode('utf-8')
        else:
            authcode_hashed = messages[0].authcode
        first_name = message_info['first_name']
        last_name = message_info['last_name']
        zipcode = message_info['zipcode']
        email = message_info['email']
        home_owner = message_info['home_owner']
        business_owner = message_info['business_owner']
        resident = message_info['resident']
        works = message_info['works']
        school = message_info['school']
        child_school = message_info['child_school']
        new_message = Message(agenda_item=agenda_item,
                              user=user,
                              first_name=first_name,
                              last_name=last_name,
                              zipcode=zipcode,
                              email=email,
                              committee=committee,
                              content=content,
                              pro=pro,
                              authcode=authcode_hashed,
                              date=now.timestamp(),
                              sent=0,
                              home_owner=home_owner,
                              business_owner=business_owner,
                              resident=resident,
                              works=works,
                              school=school,
                              child_school=child_school,
                              session_key=session_key)
        new_message.save()
        if len(messages) == 0:
            query_parameters = urllib.parse.urlencode({
                "code": authcode,
                "email": email,
                "type": "email",
                "id": str(new_message.id)
            })
            query_string = 'https://sm.engage.town/#/emailConfirmation?' + query_parameters
            content = '<h3>Thanks for voicing your opinion,</h3> Before we process your comments, please click <a href="' + \
                query_string + '">here</a> to authenticate.<br/><br/> Thank you for your interest in your local government!<br/><br/> If you are receiving this in error, please email: <a href="mailto:[email protected]">[email protected]</a>. '
            response = send_mail({
                "user": {
                    "email": email
                },
                "subject":
                "Verify message regarding agenda item: " +
                agenda_item.agenda_item_id,
                "content":
                content
            })
            if (not response):
                new_message.delete()
                return Response(
                    status=500,
                    data={
                        'error':
                        "Something happened sending you your confirmation email, please contact [email protected]"
                    })
    else:
        user = request.user
        profile = EngageUserProfile.objects.get(user_id=request.user.id)
        home_owner = profile.home_owner
        business_owner = profile.business_owner
        resident = profile.resident
        works = profile.works
        school = profile.school
        child_school = profile.child_school
        if profile.authcode != None:
            authcode_hashed = profile.authcode
        new_message = Message(agenda_item=agenda_item,
                              user=user,
                              first_name=first_name,
                              last_name=last_name,
                              zipcode=zipcode,
                              email=email,
                              committee=committee,
                              content=content,
                              pro=pro,
                              authcode=authcode_hashed,
                              date=now.timestamp(),
                              sent=0,
                              home_owner=home_owner,
                              business_owner=business_owner,
                              resident=resident,
                              works=works,
                              school=school,
                              child_school=child_school,
                              session_key=session_key)
        new_message.save()
    # Default to unsent, will send on weekly basis all sent=0
    return Response(status=201,
                    data={
                        "success": True,
                        "message": "Message added"
                    })
Exemple #4
0
def writePdfForAgendaItems(agenda_items, committee, agenda):
    root_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    static = 'PDF_Reports'
    full_path = os.path.join(root_dir, static)
    today = datetime.today()

    if not os.path.exists(full_path):
        os.mkdir(full_path)

    try:
        doc = SimpleDocTemplate(str(full_path) + "/Meeting_" + str(
            datetime.fromtimestamp(
                agenda_items[0].agenda.meeting_time).strftime('%Y%m%d')) +
                                ".pdf",
                                pagesize=letter,
                                rightMargin=72,
                                leftMargin=72,
                                topMargin=72,
                                bottomMargin=18)
        contents = []

        # Paragraph styles
        ps_title = ParagraphStyle("title",
                                  fontSize=14,
                                  spaceAfter=0.2 * inch,
                                  leading=14)
        ps_id = ParagraphStyle("id", fontSize=10)
        ps_pro = ParagraphStyle('pro',
                                fontSize=10,
                                backColor='#27ae60',
                                textColor="#FFFFFF",
                                spaceBefore=7,
                                borderPadding=(5, 5, 5, 5))
        ps_con = ParagraphStyle('con',
                                fontSize=10,
                                backColor='#c0392b',
                                textColor='#FFFFFF',
                                spaceBefore=7,
                                borderPadding=(5, 5, 5, 5))
        ps_need_info = ParagraphStyle('need_info',
                                      fontSize=10,
                                      backColor='#000000',
                                      textColor='#FFFFFF',
                                      spaceBefore=7,
                                      borderPadding=(5, 5, 5, 5))
        ps_need_info = ParagraphStyle('need_info',
                                      fontSize=10,
                                      backColor='#000000',
                                      textColor='#FFFFFF',
                                      spaceBefore=7,
                                      borderPadding=(5, 5, 5, 5))
        ps_no_comments = ParagraphStyle('no_comments',
                                        fontSize=10,
                                        backColor="rgba(100,100,100,0.20)",
                                        textColor="#000000",
                                        spaceBefore=7,
                                        borderPadding=(5, 5, 5, 5),
                                        borderColor="#FFFFFF",
                                        borderWidth=2,
                                        borderRadius=5)
        cover_page_title = ParagraphStyle("cover",
                                          fontSize=21,
                                          alignment=TA_CENTER,
                                          textColor="#000000")
        cover_page_subtitle = ParagraphStyle("cover",
                                             fontSize=16,
                                             spaceBefore=15,
                                             alignment=TA_CENTER,
                                             textColor="#000000")
        cover_page_subtitle_leading = ParagraphStyle("cover",
                                                     fontSize=12,
                                                     spaceBefore=50,
                                                     alignment=TA_CENTER,
                                                     textColor="#000000")

        contents.append(Spacer(0, 3 * inch))
        contents.append(
            Paragraph("Agenda Items - Comment Submissions", cover_page_title))
        contents.append(
            Paragraph(
                f"{datetime.fromtimestamp(agenda_items[0].agenda.meeting_time).strftime('%m/%d/%Y')} {committee.name} - Submissions for {today.strftime('%m/%d/%Y')}",
                cover_page_subtitle))
        contents.append(
            Paragraph(
                "Report generated by <a href='http://engage.town/'><u>Engage.town</u></a>",
                cover_page_subtitle_leading))

        contents.append(PageBreak())

        for upcoming_agenda_item in agenda_items:
            contents.append(Paragraph(upcoming_agenda_item.title, ps_title))
            contents.append(
                Paragraph("ID: " + upcoming_agenda_item.agenda_item_id, ps_id))
            pro_comments_on_agenda_item = Message.objects.filter(
                agenda_item=upcoming_agenda_item, pro=0)
            con_comments_on_agenda_item = Message.objects.filter(
                agenda_item=upcoming_agenda_item, pro=1)
            need_info_comments_on_agenda_item = Message.objects.filter(
                agenda_item=upcoming_agenda_item, pro=2)
            contents.append(
                Paragraph("Comments agreeing with the recommendations:",
                          ps_pro))
            contents.append(Spacer(1, 0.2 * inch))
            if len(pro_comments_on_agenda_item) > 0:
                paragraphize_comments(pro_comments_on_agenda_item, contents)
            else:
                contents.append(
                    Paragraph(
                        "No comments agreeing with recommendations on this item.",
                        ps_no_comments))
            contents.append(Spacer(1, 0.5 * inch))
            contents.append(
                Paragraph("Comments disagreeing with the recommendations:",
                          ps_con))
            contents.append(Spacer(1, 0.2 * inch))
            if len(con_comments_on_agenda_item) > 0:
                paragraphize_comments(con_comments_on_agenda_item, contents)
            else:
                contents.append(
                    Paragraph(
                        "No comments disagreeing with recommendations on this item.",
                        ps_no_comments))
            contents.append(Spacer(1, 0.5 * inch))
            contents.append(
                Paragraph("Need more information comments", ps_need_info))
            contents.append(Spacer(1, 0.2 * inch))
            if len(need_info_comments_on_agenda_item) > 0:
                paragraphize_comments(need_info_comments_on_agenda_item,
                                      contents)
            else:
                contents.append(
                    Paragraph(
                        "No needs more information comments on this item.",
                        ps_no_comments))
            contents.append(Spacer(1, 0.5 * inch))
            contents.append(PageBreak())
        doc.build(contents)
        attachment_file_path = str(full_path) + "/Meeting_" + str(
            datetime.fromtimestamp(agenda_items[0].agenda.meeting_time).
            strftime('%Y%m%d')) + ".pdf"
        attachment_name = "Agenda_Comments_Council_Meeting_" + \
            str(datetime.fromtimestamp(
                agenda_items[0].agenda.meeting_time).strftime('%Y%m%d')) + f".pdf"

        email_body = """<html>
            <head>
                <style>
                    body {
                        font-family: sans-serif;
                        font-size: 12px;
                        color: #000;
                    }
                </style>
            </head>
            <body>
                <p>Greetings from Engage</p>
                <p>Please find attached the latest report for the upcoming Council Meeting.</p>
                <p>Thank you,</p>
                <p>Your Engage team</p>
                <hr>
                <p><i>This is an automated message, for any questions please contact <a hrek=mailto:[email protected]?subject=Feedback%20Agenda%20Comments%20Report>[email protected]</a></i></p>
            </body
        </html>
        """

        subject = f"Council Meeting {datetime.fromtimestamp(agenda_items[0].agenda.meeting_time).strftime('%m/%d/%Y')} - Agenda Recommendations, Comment Submissions for {today.strftime('%m/%d/%Y')}"
        send_mail({
            "user": committee,
            "subject": subject,
            "content": email_body,
            "attachment_file_path": attachment_file_path,
            "attachment_file_name": attachment_name
        })

        agenda.processed = True
        agenda.save()
        return True
    except:
        return False
Exemple #5
0
    def post(self, request):
        '''Add a new message to list to be sent to city council'''
        now = datetime.now().timestamp()
        message_info = request.data
        if 'ag_item' not in message_info or 'committee' not in message_info or 'content' not in message_info or 'token' not in message_info or 'pro' not in message_info:
            return Response(
                status=400,
                data={"error": "Missing or incorrect body parameters"})
        committee = Committee.objects.filter(
            name__contains=message_info['committee'])
        print(committee)
        if committee is None:
            return Response(data={
                "error":
                "Could not find committee matching:" + data['committee']
            },
                            status=404)
        agenda_item = AgendaItem.objects.get(pk=message_info['ag_item'])
        if agenda_item is None:
            return Response(data={
                "error":
                "Could not find agenda item matching:" + data['ag_item']
            },
                            status=404)
        content = message_info['content']
        verify_token = message_info['token']
        pro = message_info['pro']
        result = verify_recaptcha(verify_token)
        if not result:
            return Response(status=401)
        first_name = None
        last_name = None
        zipcode = 90401
        user = None
        ethnicity = None
        email = None
        user = None
        home_owner = False
        business_owner = False
        resident = False
        works = False
        school = False
        child_school = False
        CODE_LENGTH = 8
        rand_begin = random.randint(0, 32 - CODE_LENGTH)
        authcode = str(uuid.uuid1()).replace(
            "-", "")[rand_begin:rand_begin + CODE_LENGTH].encode('utf-8')
        authcode_hashed = bcrypt.hashpw(authcode,
                                        bcrypt.gensalt()).decode('utf-8')
        if (isinstance(request.user, AnonymousUser)):
            if 'first_name' not in message_info or message_info['first_name'] is None or \
                'last_name' not in message_info or message_info['last_name'] is None or \
                'zipcode' not in message_info or message_info['zipcode'] is None or \
                'email' not in message_info or message_info['email'] is None or \
                'home_owner' not in message_info or message_info['home_owner'] is None or \
                'business_owner' not in message_info or message_info['business_owner'] is None or \
                'resident' not in message_info or message_info['resident'] is None or \
                'works' not in message_info or message_info['works'] is None or \
                'school' not in message_info or message_info['school'] is None or \
                'child_school' not in message_info or message_info['child_school'] is None:
                return Response(
                    status=400,
                    data={"error": "Missing or incorrect body parameters"})
            first_name = message_info['first_name']
            last_name = message_info['last_name']
            zipcode = message_info['zipcode']
            email = message_info['email']
            home_owner = message_info['home_owner']
            business_owner = message_info['business_owner']
            resident = message_info['resident']
            works = message_info['works']
            school = message_info['school']
            child_school = message_info['child_school']
        else:
            user = request.user
            profile = EngageUserProfile.objects.get(user_id=request.user.id)
            home_owner = profile.home_owner
            business_owner = profile.business_owner
            resident = profile.resident
            works = profile.works
            school = profile.school
            child_school = profile.child_school
            if profile.authcode == None:
                authcode_hashed = None
        new_message = Message(agenda_item=agenda_item,
                              user=user,
                              first_name=first_name,
                              last_name=last_name,
                              zipcode=zipcode,
                              email=email,
                              ethnicity=ethnicity,
                              committee=committee,
                              content=content,
                              pro=pro,
                              authcode=authcode_hashed,
                              date=now,
                              sent=0,
                              home_owner=home_owner,
                              business_owner=business_owner,
                              resident=resident,
                              works=works,
                              school=school,
                              child_school=child_school)
        new_message.save()
        print(new_message.id)
        if authcode_hashed is not None:
            query_parameters = urllib.parse.urlencode({
                "code": authcode,
                "email": email,
                "type": "email",
                "id": str(new_message.id)
            })
            query_string = 'https://engage-santa-monica.herokuapp.com/#/emailConfirmation?' + query_parameters
            content = '<h3>Thanks for voicing your opinion,</h3> Before we process your comment, please click <a href="' + \
                query_string + '">here</a> to authenticate.<br/><br/>If you create and authenticate an account you will never have to authenticate for messages again.<br/><br/> Thank you for your interest in your local government!<br/><br/> If you are receiving this in error, please email: <a href="mailto:[email protected]">[email protected]</a>. '

            send_mail({
                "user": {
                    "email": email
                },
                "subject":
                "Verify message regarding agenda item: " +
                agenda_item.agenda_item_id,
                "content":
                content
            })
        # Default to unsent, will send on weekly basis all sent=0
        return Response(status=201)
Exemple #6
0
    def post(self, request):
        '''
        Signup new user. Must be unique username and email. Will create authcode and email to user.
        '''
        data = request.data
        if 'first_name' not in data or 'last_name' not in data or 'username' not in data or 'password' not in data or 'email' not in data:
            return Response(data={
                "error":
                "Data object must contain first_name, last_name, username, password, and email"
            },
                            status=400)
        email = data['email']
        password = data['password']
        username = data['username']
        first_name = data['first_name']
        last_name = data['last_name']
        CODE_LENGTH = 8
        rand_begin = random.randint(0, 32 - CODE_LENGTH)
        authcode = str(uuid.uuid1()).replace(
            "-", "")[rand_begin:rand_begin + CODE_LENGTH].encode('utf-8')
        authcode_hashed = bcrypt.hashpw(authcode,
                                        bcrypt.gensalt()).decode('utf-8')

        if 'home_owner' in data and data['home_owner']:
            home_owner = True
        else:
            home_owner = False
        if 'resident' in data and data['resident']:
            resident = True
        else:
            resident = False
        if 'business_owner' in data and data['business_owner']:
            business_owner = True
        else:
            business_owner = False
        if 'works' in data and data['works']:
            works = True
        else:
            works = False
        if 'school' in data and data['school']:
            school = True
        else:
            school = False
        if 'child_school' in data and data['child_school']:
            child_school = True
        else:
            child_school = False
        try:
            user = User.objects.create_user(username, email, password)
            user.first_name = first_name
            user.last_name = last_name
            user.save()
            # Don't need to save any values from it
            EngageUserProfile.objects.create(user=user,
                                             home_owner=home_owner,
                                             resident=resident,
                                             business_owner=business_owner,
                                             works=works,
                                             school=school,
                                             child_school=child_school,
                                             authcode=authcode_hashed)
            query_parameters = urllib.parse.urlencode({
                "code": authcode,
                "email": email,
                "type": "signup",
                "id": ""
            })
            print("ZXY:", query_parameters)
            query_string = 'https://engage-santa-monica.herokuapp.com/#/emailConfirmation?' + query_parameters
            content = '<html><body><h3>Welcome to the Engage platform for Santa Monica,</h3> Please click <a href="' + \
                query_string + '">here</a> to authenticate.<br/><br/>Thank you for your interest in your local government!<br/><br/> If you are receiving this in error, please email: <a href="mailto:[email protected]">[email protected]</a>.</body></html>'
            print(content)
            sent_mail = send_mail({
                "user": user,
                "subject":
                "Please authenticate your email for the Engage platform",
                "content": content
            })
            print("SENT MAIL:", sent_mail)
            token = jwt.encode({"username": user.email}, settings.SECRET_KEY)
            return Response({"token": token}, status=201)
        except:
            print("Unexpected error:", sys.exc_info()[0])
            return Response(status=404)