Esempio n. 1
0
    def get(self):
        email = request.args.get('email')

        LOGGER.debug("Resending verification email to: {}".format(email))

        user = user_repository.get_by_email(email, g.organisation.id)

        if not user:
            LOGGER.debug(
                "User not found for email: {} in organisation: {}".format(
                    email, g.organisation.name))
            return USER_NOT_FOUND

        if user.verify_token is None:
            user.verify_token = make_code()

        try:
            db.session.commit()
        except IntegrityError:
            LOGGER.error("Adding verify token for {} failed. ".format(email))
            return ADD_VERIFY_TOKEN_FAILED

        email_user('verify-email',
                   template_parameters=dict(system=g.organisation.system_name,
                                            organisation=g.organisation.name,
                                            host=misc.get_baobab_host(),
                                            token=user.verify_token),
                   user=user,
                   subject_parameters=dict(system=g.organisation.system_name))

        LOGGER.debug("Resent email verification to: {}".format(email))

        return {}, 201
Esempio n. 2
0
    def post(self):

        req_parser = reqparse.RequestParser()
        req_parser.add_argument('email', type=str, required=True)
        args = req_parser.parse_args()

        LOGGER.debug(
            "Requesting password reset for email {} and organisation {}".
            format(args['email'], g.organisation.name))

        user = user_repository.get_by_email(args['email'], g.organisation.id)

        if not user:
            LOGGER.debug(
                "No user found for email {} and organisation {}".format(
                    args['email'], g.organisation.name))
            return USER_NOT_FOUND

        password_reset = PasswordReset(user=user)
        db.session.add(password_reset)
        db.session.commit()

        email_user(
            'password-reset',
            template_parameters=dict(system=g.organisation.system_name,
                                     organisation=g.organisation.name,
                                     host=misc.get_baobab_host(),
                                     token=password_reset.code),
            subject_parameters=dict(system_name=g.organisation.system_name),
            user=user)

        return {}, 201
Esempio n. 3
0
    def post(self):
        args = self.req_parser.parse_args()
        event_id = args['event_id']
        user_id = g.current_user['id']

        event = db.session.query(Event).get(event_id)
        if not event:
            return EVENT_NOT_FOUND

        current_user = user_repository.get_by_id(user_id)
        if not current_user.is_event_admin(event_id):
            return FORBIDDEN

        users = user_repository.get_all_without_responses()
        for user in users:
            event_name = event.get_name('en')
            organisation_name = event.organisation.name
            system_name = event.organisation.system_name
            deadline = event.application_close.strftime('%A %-d %B %Y')

            email_user('application-not-started',
                       template_parameters=dict(
                           event=event_name,
                           organisation_name=organisation_name,
                           system_name=system_name,
                           deadline=deadline),
                       event=event,
                       user=user)

        return {'not_started_responses': len(users)}, 201
Esempio n. 4
0
    def send_confirmation(self, user, questions, answers, confirmed, event):
        if answers is None:
            LOGGER.warn(
                'Found no answers associated with response with id {response_id}'
                .format(response_id=user.id))
        if questions is None:
            LOGGER.warn(
                'Found no questions associated with application form with id {form_id}'
                .format(form_id=user.id))
        try:
            # Building the summary, where the summary is a dictionary whose key is the question headline, and the value
            # is the relevant answer
            summary = ""
            for answer in answers:
                for question in questions:
                    if answer.registration_question_id == question.id:
                        summary += "Question:" + question.headline + "\nAnswer:" + _get_answer_value(
                            answer, question) + "\n"

            emailer.email_user('registration-with-confirmation' if confirmed
                               else 'registration-pending-confirmation',
                               template_parameters=dict(summary=summary),
                               event=event,
                               user=user)

        except Exception as e:
            LOGGER.error(
                'Could not send confirmation email for response with id : {response_id}'
                .format(response_id=user.id))
Esempio n. 5
0
    def delete(self):
        args = self.del_req_parser.parse_args()
        current_user_id = g.current_user['id']

        response = response_repository.get_by_id(args['id'])
        if not response:
            return errors.RESPONSE_NOT_FOUND

        if response.user_id != current_user_id:
            return errors.UNAUTHORIZED

        response.withdraw()
        response_repository.save(response)      

        try:
            user = user_repository.get_by_id(current_user_id)
            event = response.application_form.event
            organisation = event.organisation

            emailer.email_user(
                'withdrawal',
                template_parameters=dict(
                    organisation_name=organisation.name
                ),
                event=event,
                user=user
            )

        except:                
            LOGGER.error('Failed to send withdrawal confirmation email for response with ID : {id}, but the response was withdrawn succesfully'.format(id=args['id']))

        return {}, 204
Esempio n. 6
0
    def post(self, invitedGuest=False):
        args = self.req_parser.parse_args()
        email = args['email']
        firstname = args['firstname']
        lastname = args['lastname']
        user_title = args['user_title']
        policy_agreed = args['policy_agreed']
        user_primaryLanguage = args['language']

        if (invitedGuest):
            password = self.randomPassword()
        else:
            password = args['password']

        if (password is None):
            return MISSING_PASSWORD

        if not policy_agreed:
            return POLICY_NOT_AGREED

        LOGGER.info("Registering email: {}".format(email))

        user = AppUser(email=email,
                       firstname=firstname,
                       lastname=lastname,
                       user_title=user_title,
                       password=password,
                       organisation_id=g.organisation.id)
        user.user_primaryLanguage = user_primaryLanguage

        db.session.add(user)

        try:
            db.session.commit()
        except IntegrityError:
            LOGGER.error("email: {} already in use".format(email))
            return EMAIL_IN_USE

        if (not invitedGuest):
            email_user(
                'verify-email',
                template_parameters=dict(system=g.organisation.system_name,
                                         organisation=g.organisation.name,
                                         host=misc.get_baobab_host(),
                                         token=user.verify_token),
                user=user,
                subject_parameters=dict(system=g.organisation.system_name))

            LOGGER.debug("Sent verification email to {}".format(user.email))
        else:
            user.verified_email = True
            try:
                db.session.commit()
            except IntegrityError:
                LOGGER.error("Unable to verify email: {}".format(email))
                return VERIFY_EMAIL_INVITED_GUEST

        return user_info(user, []), 201
Esempio n. 7
0
    def post(self):
        args = self.req_parser.parse_args()
        user_id = args['user_id']
        event_id = args['event_id']
        email_template = args['email_template']
        offer_date = datetime.strptime((args['offer_date']), '%Y-%m-%dT%H:%M:%S.%fZ')
        expiry_date = datetime.strptime((args['expiry_date']), '%Y-%m-%dT%H:%M:%S.%fZ')
        payment_required = args['payment_required']
        travel_award = args['travel_award']
        accommodation_award = args['accommodation_award']
        user = db.session.query(AppUser).filter(AppUser.id == user_id).first()
        event = db.session.query(Event).filter(Event.id == event_id).first()
        event_name = event.get_name('en')
        event_email_from = event.email_from

        existing_offer = db.session.query(Offer).filter(Offer.user_id == user_id, Offer.event_id == event_id).first()
        if existing_offer:
            return errors.DUPLICATE_OFFER

        existing_outcome = outcome_repository.get_latest_by_user_for_event(user_id, event_id)
        if existing_outcome:
            if existing_outcome.status == Status.REJECTED:
                return errors.CANDIDATE_REJECTED
            existing_outcome.reset_latest()

        new_outcome = Outcome(
            event_id,
            user_id,
            Status.ACCEPTED,
            g.current_user['id']
        )
        outcome_repository.add(new_outcome)

        offer_entity = Offer(
            user_id=user_id,
            event_id=event_id,
            offer_date=offer_date,
            expiry_date=expiry_date,
            payment_required=payment_required,
            travel_award=travel_award,
            accommodation_award=accommodation_award
        )

        db.session.add(offer_entity)
        db.session.commit()

        email_user(
            'offer',
            template_parameters=dict(
                host=misc.get_baobab_host(),
                expiry_date=offer_entity.expiry_date.strftime("%Y-%m-%d"),
                event_email_from=event_email_from
            ),
            event=event,
            user=user)

        return offer_info(offer_entity), 201
Esempio n. 8
0
def _send_registration_confirmation_mail(user, event):
    try:
        emailer.email_user('registration-confirmed', event=event, user=user)

        return True
    except Exception as e:
        LOGGER.error('Error occured while sending email to {}: {}'.format(
            user.email, e))
        return False
Esempio n. 9
0
    def post(self, send_email=True):
        args = self.req_parser.parse_args()
        event_id = args['event_id']
        email = args['email']
        role = args['role']

        user = user_repository.get_by_email(email, g.organisation.id)

        if not user:
            return USER_NOT_FOUND

        event = event_repository.get_by_id(event_id)
        if not event:
            return EVENT_NOT_FOUND

        existingInvitedGuest = db.session.query(InvitedGuest).filter(
            InvitedGuest.event_id == event_id).filter(InvitedGuest.user_id == user.id).first()

        if existingInvitedGuest:
            return INVITED_GUEST_FOR_EVENT_EXISTS

        invitedGuest = InvitedGuest(
            event_id=event_id,
            user_id=user.id,
            role=role
        )

        db.session.add(invitedGuest)

        try:
            db.session.commit()
        except IntegrityError:
            LOGGER.error(
                "Failed to add invited guest: {}".format(email))
            return ADD_INVITED_GUEST_FAILED

        if send_email:
            try:
                email_user(
                    'guest-invitation-with-registration' if event.is_registration_open else 'guest-invitation',
                    template_parameters=dict(
                        role=role,
                        system_name=g.organisation.system_name,
                        host=misc.get_baobab_host(),
                        event_key=event.key
                    ),
                    event=event,
                    user=user)

            except Exception as e:
                LOGGER.error('Failed to send email to invited guest with user Id {}, due to {}'.format(user.id, e))
                return INVITED_GUEST_EMAIL_FAILED

        return invitedGuest_info(invitedGuest, user), 201
Esempio n. 10
0
    def post(self):
        args = self.post_req_parser.parse_args()
        response_id = args['response_id']
        title = args['title']
        firstname = args['firstname']
        lastname = args['lastname']
        relation = args['relation']
        email = args['email']
        user = user_repository.get_by_id(g.current_user['id'])

        if not user:
            return USER_NOT_FOUND

        event = event_repository.get_event_by_response_id(response_id)
        if not event:
            return EVENT_NOT_FOUND

        response = response_repository.get_by_id(response_id)
        if not response:
            return RESPONSE_NOT_FOUND

        reference_request = ReferenceRequest(response_id=response_id,
                                             title=title,
                                             firstname=firstname,
                                             lastname=lastname,
                                             relation=relation,
                                             email=email)
        reference_request_repository.create(reference_request)

        link = "{host}/reference/{token}".format(host=misc.get_baobab_host(),
                                                 token=reference_request.token)

        try:
            candidate, candidate_firstname, nominator = _get_candidate_nominator(
                response)
        except ValueError as e:
            LOGGER.error(e)
            return BAD_CONFIGURATION

        email_user('reference-request-self-nomination'
                   if nominator is None else 'reference-request',
                   template_parameters=dict(
                       candidate=candidate,
                       candidate_firstname=candidate_firstname,
                       nominator=nominator,
                       event_url=event.url,
                       application_close_date=event.application_close,
                       link=link),
                   event=event,
                   user=user)

        reference_request.set_email_sent(datetime.now())
        reference_request_repository.add(reference_request)
        return reference_request, 201
Esempio n. 11
0
    def post(self, event_id):
        req_parser = reqparse.RequestParser()
        req_parser.add_argument('user_id', type=int, required=True)
        req_parser.add_argument('outcome', type=str, required=True)
        args = req_parser.parse_args()

        event = event_repository.get_by_id(event_id)
        if not event:
            return errors.EVENT_NOT_FOUND

        user = user_repository.get_by_id(args['user_id'])
        if not user:
            return errors.USER_NOT_FOUND

        try:
            status = Status[args['outcome']]
        except KeyError:
            return errors.OUTCOME_STATUS_NOT_VALID

        try:
            # Set existing outcomes to no longer be the latest outcome
            existing_outcomes = outcome_repository.get_all_by_user_for_event(args['user_id'], event_id)
            for existing_outcome in existing_outcomes:
                existing_outcome.reset_latest()

            # Add new outcome
            outcome = Outcome(
                    event_id,
                    args['user_id'],
                    status,
                    g.current_user['id'])

            outcome_repository.add(outcome)
            db.session.commit()

            if status != Status.ACCEPTED:  # Email will be sent with offer for accepted candidates  
                email_user(
                    'outcome-rejected' if status == Status.REJECTED else 'outcome-waitlist',
                    template_parameters=dict(
                        host=misc.get_baobab_host()
                    ),
                    event=event,
                    user=user,
                )

            return outcome, 201

        except SQLAlchemyError as e:
            LOGGER.error("Database error encountered: {}".format(e))            
            return errors.DB_NOT_AVAILABLE
        except: 
            LOGGER.error("Encountered unknown error: {}".format(traceback.format_exc()))
            return errors.DB_NOT_AVAILABLE
Esempio n. 12
0
    def test_email_no_event_english(self, send_mail_fn):
        """Check email to an English user with no event."""
        self.seed_static_data()

        email_user('template1',
                   template_parameters={'param': 'Blah'},
                   user=self.english_user)

        send_mail_fn.assert_called_with(
            recipient=self.english_user.email,
            subject='English subject no event',
            body_text='English template no event Blah',
            file_name='',
            file_path='')
Esempio n. 13
0
    def test_email_no_event_french(self, send_mail_fn):
        """Check email to an French user with no event."""
        self.seed_static_data()

        email_user('template1',
                   template_parameters={'param': 'bleu'},
                   user=self.french_user)

        send_mail_fn.assert_called_with(
            recipient=self.french_user.email,
            subject='Sujet français sans événement',
            body_text='Modèle français sans événement bleu',
            file_name='',
            file_path='')
Esempio n. 14
0
    def test_email_english_default(self, send_mail_fn):
        """Check email to use with unsupported language defaults to English."""
        self.seed_static_data()

        email_user('template1',
                   template_parameters={'param': 'Blah'},
                   user=self.zulu_user)

        send_mail_fn.assert_called_with(
            recipient=self.zulu_user.email,
            subject='English subject no event',
            body_text='English template no event Blah',
            file_name='',
            file_path='')
Esempio n. 15
0
    def post(self, event_id):
        parser = reqparse.RequestParser()
        parser.add_argument('response_ids',
                            type=int,
                            required=True,
                            action='append')
        parser.add_argument('reviewer_email', type=str, required=True)
        args = parser.parse_args()

        response_ids = args['response_ids']
        reviewer_email = args['reviewer_email']

        filtered_response_ids = response_repository.filter_ids_to_event(
            response_ids, event_id)

        print('response_ids:', response_ids)
        print('filtered_response_ids:', filtered_response_ids)

        if set(filtered_response_ids) != set(response_ids):
            return FORBIDDEN

        event = event_repository.get_by_id(event_id)

        reviewer_user = user_repository.get_by_email(reviewer_email,
                                                     g.organisation.id)
        if reviewer_user is None:
            return USER_NOT_FOUND

        if not reviewer_user.is_reviewer(event_id):
            _add_reviewer_role(reviewer_user.id, event_id)

        response_reviewers = [
            ResponseReviewer(response_id, reviewer_user.id)
            for response_id in response_ids
        ]
        db.session.add_all(response_reviewers)
        db.session.commit()

        if len(response_ids) > 0:
            email_user('reviews-assigned',
                       template_parameters=dict(
                           num_reviews=len(response_ids),
                           baobab_host=misc.get_baobab_host(),
                           system_name=g.organisation.system_name,
                           event_key=event.key),
                       event=event,
                       user=reviewer_user)
        return {}, 201
Esempio n. 16
0
    def test_files(self, send_mail_fn):
        """Check that file parameters are correctly passed to send_mail function."""
        self.seed_static_data()

        email_user('template1',
                   template_parameters={'param': 'Blah'},
                   user=self.english_user,
                   file_name='myfile.pdf',
                   file_path='/long/way/home')

        send_mail_fn.assert_called_with(
            recipient=self.english_user.email,
            subject='English subject no event',
            body_text='English template no event Blah',
            file_name='myfile.pdf',
            file_path='/long/way/home')
Esempio n. 17
0
    def send_confirmation(self, user, response):
        try:
            answers = response.answers
            if not answers:
                LOGGER.warn(
                    'Found no answers associated with response with id {response_id}'
                    .format(response_id=response.id))

            application_form = response.application_form
            if application_form is None:
                LOGGER.warn(
                    'Found no application form with id {form_id}'.format(
                        form_id=response.application_form_id))

            event = application_form.event
            if event is None:
                LOGGER.warn('Found no event id {event_id}'.format(
                    form_id=application_form.event_id))
        except:
            LOGGER.error(
                'Could not connect to the database to retrieve response confirmation email data on response with ID : {response_id}'
                .format(response_id=response.id))

        try:
            question_answer_summary = strings.build_response_email_body(
                answers, user.user_primaryLanguage, application_form)

            if event.has_specific_translation(user.user_primaryLanguage):
                event_description = event.get_description(
                    user.user_primaryLanguage)
            else:
                event_description = event.get_description('en')

            emailer.email_user(
                'confirmation-response-call' if event.event_type
                == EventType.CALL else 'confirmation-response',
                template_parameters=dict(
                    event_description=event_description,
                    question_answer_summary=question_answer_summary,
                ),
                event=event,
                user=user)

        except Exception as e:
            LOGGER.error(
                'Could not send confirmation email for response with id : {response_id} due to: {e}'
                .format(response_id=response.id, e=e))
Esempio n. 18
0
    def post(self):
        args = self.post_req_parser.parse_args()
        user_id = g.current_user['id']
        event_id = args['event_id']
        reviewer_user_email = args['reviewer_user_email']
        num_reviews = args['num_reviews']

        event = event_repository.get_by_id(event_id)
        if not event:
            return EVENT_NOT_FOUND

        current_user = user_repository.get_by_id(user_id)
        if not current_user.is_event_admin(event_id):
            return FORBIDDEN

        reviewer_user = user_repository.get_by_email(reviewer_user_email,
                                                     g.organisation.id)
        if reviewer_user is None:
            return USER_NOT_FOUND

        if not reviewer_user.is_reviewer(event_id):
            _add_reviewer_role(reviewer_user.id, event_id)

        config = review_configuration_repository.get_configuration_for_event(
            event_id)

        response_ids = self.get_eligible_response_ids(
            event_id, reviewer_user.id, num_reviews,
            config.num_reviews_required)
        response_reviewers = [
            ResponseReviewer(response_id, reviewer_user.id)
            for response_id in response_ids
        ]
        db.session.add_all(response_reviewers)
        db.session.commit()

        if len(response_ids) > 0:
            email_user('reviews-assigned',
                       template_parameters=dict(
                           num_reviews=len(response_ids),
                           baobab_host=misc.get_baobab_host(),
                           system_name=g.organisation.system_name,
                           event_key=event.key),
                       event=event,
                       user=reviewer_user)
        return {}, 201
Esempio n. 19
0
    def put(self):
        args = self.put_req_parser.parse_args()

        firstname = args['firstname']
        lastname = args['lastname']
        user_title = args['user_title']
        email = args['email']
        user_primaryLanguage = args['language']

        user = db.session.query(AppUser).filter(
            AppUser.id == g.current_user['id']).first()

        if user.email != email:
            user.update_email(email)

        user.firstname = firstname
        user.lastname = lastname
        user.user_title = user_title
        user.user_primaryLanguage = user_primaryLanguage

        try:
            db.session.commit()
        except Exception as e:
            LOGGER.error("Exception updating user profile - {}".format(e))
            return ERROR_UPDATING_USER_PROFILE

        if not user.verified_email:
            email_user(
                'verify-email',
                template_parameters=dict(
                    system=g.organisation.system_name,
                    organisation=g.organisation.name,
                    host=misc.get_baobab_host(),
                    token=user.verify_token
                ),
                user=user,
                subject_parameters=dict(system=g.organisation.system_name))

            LOGGER.debug("Sent re-verification email to {}".format(user.email))

        roles = db.session.query(EventRole).filter(
            EventRole.user_id == user.id).all()

        return user_info(user, roles), 200
Esempio n. 20
0
    def post(self):
        args = self.req_parser.parse_args()

        user_api = UserAPI.UserAPI()
        user, status = user_api.post(invitedGuest=True)
        if status != 201:
            return user, status

        invited_guest_api = InvitedGuestAPI()
        invited_guest_info, status = invited_guest_api.post(send_email=False)

        if status == 201:
            event_id = invited_guest_info['event_id']
            role = invited_guest_info['role']
            user = user_repository.get_by_id(user['id'])
            event = event_repository.get_by_id(event_id)
            
            reset_code = misc.make_code()
            password_reset=PasswordReset(user=user)
            db.session.add(password_reset)
            db.session.commit()

            try:

                email_user(
                    'new-guest-registration' if event.is_registration_open else 'new-guest-no-registration',
                    template_parameters=dict(
                        event_key=event.key,
                        system_name=g.organisation.system_name,
                        host=misc.get_baobab_host(),
                        role=role,
                        reset_code=password_reset.code,
                    ),
                    event=event,
                    user=user
                )
            except Exception as e:
                LOGGER.error('Failed to send email for invited guest with user Id {} due to: {}'.format(user.id, e))
                return INVITED_GUEST_EMAIL_FAILED

        return invited_guest_info, status
Esempio n. 21
0
def generate(template_path, event_id, work_address, addressed_to, residential_address, passport_name,
             passport_no, passport_issued_by, invitation_letter_sent_at, to_date, from_date, country_of_residence,
             nationality, date_of_birth, email, user_title, firstname, lastname, bringing_poster, expiry_date, user):

    check_values(template_path, event_id, work_address, addressed_to, residential_address, passport_name,
        passport_no, passport_issued_by, invitation_letter_sent_at, to_date, from_date, country_of_residence,
        nationality, date_of_birth, email, user_title, firstname, lastname, bringing_poster, expiry_date)
    
    # Path to store the template locally of merged and unmerged
    template = 'app/invitationletter/template/tmp.docx'
    template_merged = 'app/invitationletter/template/template.docx'

    download_blob(bucket_name=GCP_BUCKET_NAME, source_blob_name=template_path,
                  destination_file_name=template)

    if not os.path.exists(template):
        return errors.TEMPLATE_NOT_FOUND

    document = MailMerge(template)
    LOGGER.debug("merge-fields.... {} .".format(document.get_merge_fields()))
    document.merge(
        TITLE=user_title,
        FIRSTNAME=firstname,
        LASTNAME=lastname,
        WORK_ADDRESS=work_address.decode('utf-8'),
        ADDRESSED_TO=addressed_to.decode('utf-8'),
        RESIDENTIAL_ADDRESS=residential_address.decode('utf-8'),
        PASSPORT_NAME=passport_name.decode('utf-8'),
        PASSPORT_NO=passport_no.decode('utf-8'),
        ISSUED_BY=passport_issued_by.decode('utf-8'),
        EXPIRY_DATE=expiry_date,
        ACCOMODATION_END_DATE=to_date,
        ACCOMODATION_START_DATE=from_date,
        COUNTRY_OF_RESIDENCE=country_of_residence.decode('utf-8'),
        NATIONALITY=nationality,
        DATE_OF_BIRTH=date_of_birth,
        INVITATION_LETTER_SENT_AT=invitation_letter_sent_at,
        BRINGING_POSTER=bringing_poster
    )

    document.write(template_merged)

    # Conversion
    template_pdf = 'app/invitationletter/letter/template.pdf'
    if os.path.exists(template_pdf):
        os.remove(template_pdf)
    success = pdfconvertor.convert_to(folder='app/invitationletter/letter', source=template_merged, output=template_pdf)
    if not success:
        return errors.CREATING_INVITATION_FAILED

    event = db.session.query(Event).get(event_id)
    if not event:
        return errors.EVENT_NOT_FOUND

    try:
        emailer.email_user(
            'invitation-letter',
            event=event,
            user=user,
            file_name="InvitationLetter.pdf",
            file_path=template_pdf
        )

        LOGGER.debug('successfully sent email...')
        return True
    except ValueError:
        LOGGER.debug('Did not send email...')
        return False

    return False