Ejemplo n.º 1
0
    def post(self):
        body = json.loads(self.request.body)

        if 'organization' in body:
            organization = body['organization']
        else:
            organization = 'N/A'

        message = u"""
Message from {} <{}>:

Organization: {}

Message:

{}

____

-- Sent via Contact Form --
""".format(body['name'], body['email'], organization, body['message'])

        # Send a message to the PERTS staff via @contact.
        mandrill.send(
            to_address='',
            subject='Inquiry from PERTS.net',
            body=mandrill.render_markdown(message),
        )

        logging.info('api_handlers.SendContactEmailHandler')
        logging.info('sending an email to: ')

        return {'success': True, 'data': ''}
Ejemplo n.º 2
0
    def _send_reminder_summary(self, reminders):
        # send summary to perts team
        body = """

To whom it may concern,

Lots of reminders today (or not)! The full list of emails is below.

Recreationally Yours,<br />
Yellowstone

----

{}
""".format(''.join([self._reminder_summary(r) for r in reminders]))

        mandrill.send(
            to_address=config.reminder_summary_recipients,
            subject="{} Reminder Emails sent today".format(len(reminders)),
            body=mandrill.render_markdown(body),
        )
Ejemplo n.º 3
0
    def do(self):
        new_password = self.request.get('new_password') or None
        auth_response = self.authenticate(
            auth_type='direct',
            username=self.request.get('username'),
            password=self.request.get('current_password'))
        if auth_response is False or auth_response is None:
            return {'success': True, 'data': 'invalid_credentials'}
        user = auth_response
        user.hashed_password = util.hash_password(new_password)
        user.put()

        # Alert the user that their password has been changed.
        mandrill.send(to_address=user.login_email,
                      subject=config.change_password_subject,
                      body=mandrill.render_markdown(
                          config.change_password_body))

        logging.info('api_handlers.ChangePasswordHandler')
        logging.info('sending an email to: {}'.format(user.login_email))

        return {'success': True, 'data': 'changed'}
Ejemplo n.º 4
0
    def do(self):
        # ensure this email address belongs to a known user
        email = self.request.get('email').lower()

        # Look up users by auth_id because that's how they log in;
        # there are other kinds of auth type ('google', 'public') that we
        # wouldn't want returned.
        result = self.internal_api.get('user', {'auth_id': 'direct_' + email})

        if len(result) is 1 and result[0].is_test is False:
            # then this email address is valid; proceed with send
            user = result[0]

            # deactivate any existing reset tokens
            self.api.clear_reset_password_tokens(user.id)

            # create a new token for them
            new_token = ResetPasswordToken.create(user=user.id)
            new_token.put()

            # and email them about it
            link = '/reset_password/' + new_token.token()
            mandrill.send(
                to_address=email,
                subject=config.forgot_password_subject,
                body=mandrill.render_markdown(
                    config.forgot_password_body.format(link)),
            )

            logging.info(
                'ForgotPasswordHandler sending an email to: {}'.format(email))

            return {'success': True, 'data': 'sent'}
        else:
            logging.info(
                'ForgotPasswordHandler invalid email: {}'.format(email))
            return {'success': True, 'data': 'not_sent'}
Ejemplo n.º 5
0
    def register(self, program_id, auth_type, username=None, password=None, cohort_id=None):
        """Logs in users and registers them if they're new.

        Raises exceptions when the system appears to be broken (e.g. redundant
        users).

        Returns tuple(
            user - mixed, False when given non-sensical data by users (e.g.
                registering an existing email under a new auth type) or
                matching user entity,
            user_is_new - bool, True if user was newly registered
        )

        """
        user_is_new = False

        if auth_type not in config.allowed_auth_types:
            raise Exception("Bad auth_type: {}.".format(auth_type))
        if auth_type == 'direct':
            if None in [username, password]:
                raise Exception("Credentials incomplete.")
            creation_kwargs = {
                'login_email': username,
                'auth_id': 'direct_' + username,
                'plaintext_password': password,  # it WILL be hashed later
            }

        # These are the third party identity providers we currently know
        # how to handle. See util_handlers.BaseHandler.get_third_party_auth().
        elif auth_type in ['google']:
            # may raise CredentialsMissing
            creation_kwargs = self.get_third_party_auth(auth_type)

        # Check that the user hasn't already registered in two ways.

        # 1) If the email matches but the auth type is different, we reject
        #    the request to register so the UI can warn the user.
        email_match_params = {'login_email': creation_kwargs['login_email']}
        email_matches = self.internal_api.get('user', email_match_params)
        for user in email_matches:
            if user.auth_type() != auth_type:
                user = False
                return (user, user_is_new)

        # 2) If the auth_id matches, they tried to register when they should
        #    have logged in. Just log them in.
        auth_match_params = {'auth_id': creation_kwargs['auth_id']}
        auth_matches = self.internal_api.get('user', auth_match_params)
        if len(auth_matches) == 1:
            # they already have an account
            user = auth_matches[0]

        # This user hasn't already registered. Register them.
        elif len(auth_matches) == 0:
            user_is_new = True

            # Having collected the user's information, build a user object.
            creation_kwargs['user_type'] = 'teacher'
            # Include the program id as an initial relationship (see
            # config.optional_associations).
            creation_kwargs['program'] = program_id
            user = self.api.create('user', creation_kwargs)

            # Refresh the api with the user's new privileges.
            self.api = Api(user)
            # Send them an email to confirm that they have registered.
            # The email text is hard coded in the program app.
            program = self.api.get_from_path('program', program_id)
            program_conf = Program.get_app_configuration(program.abbreviation)
            mandrill.send(
                to_address=creation_kwargs['login_email'],
                subject=program_conf.registration_email_subject,
                body=mandrill.render_markdown(
                    program_conf.registration_email_body),
                template_data={'email': creation_kwargs['login_email'],
                               'cohort_id': cohort_id}
            )

            logging.info('url_handlers.BaseHandler.register()')
            logging.info('sending an email to: {}'
                         .format(creation_kwargs['login_email']))

        # There's a big problem.
        else:
            logging.error("Two matching users! {}".format(auth_match_params))
            # Sort the users by modified time, so we take the most recently
            # modified one.
            auth_matches = sorted(
                auth_matches, key=lambda u: u.modified, reverse=True)
            user = auth_matches[0]

        # Sign in the user.
        self.session['user'] = user.id

        return (user, user_is_new)
Ejemplo n.º 6
0
    def do(self):
        params = util.get_request_dictionary(self.request)

        # Check that the requested program allows public registration.
        program = self.internal_api.get_from_path('program', params['program'])
        program_config = Program.get_app_configuration(program.abbreviation)
        if not getattr(program_config, 'public_registration', False):
            user = self.get_current_user()
            logging.error("User {} attempted public registration on program "
                          "{}, but it isn't allowed.".format(
                              user, program.abbreviation))

        # Create a school admin based on the user's information.
        # They get the special auth_type 'public', preventing them from
        # appearing in sign-in queries or reset-password queries.
        # However, the user entity will still hold data and be associated with
        # the created schools.
        params['user']['user_type'] = 'school_admin'
        params['user']['auth_id'] = 'public_' + params['user']['login_email']
        school_admin = self.internal_api.create('user', params['user'])

        # If the school already exists, use the id to find the right cohort.
        if 'existing_school_id' in params:
            s_id = params['existing_school_id']
            cohort_list = self.internal_api.get('cohort',
                                                {'assc_school_list': s_id})
            if len(cohort_list) is not 1:
                raise Exception("Problem with public registration: found {} "
                                "cohorts for school {}".format(
                                    len(cohort_list), s_id))
            cohort = cohort_list[0]
            school = None
            classroom = None
            activities = None

        # Otherwise, create a school, cohort, and classroom based on the
        # provided data.
        else:
            school = self.internal_api.create('school', params['new_school'])
            cohort = self.internal_api.create(
                'cohort', {
                    'name': params['new_school']['name'],
                    'school': school.id,
                    'program': program.id,
                    'promised_students': params['promised_students'],
                })
            classroom = self.internal_api.create(
                'classroom', {
                    'name': 'All Students',
                    'program': program.id,
                    'cohort': cohort.id,
                    'user': school_admin.id,
                })
            activities = self.internal_api.init_activities(
                'student',
                school_admin.id,
                program.id,
                cohort_id=cohort.id,
                classroom_id=classroom.id)

        # Whether the cohort is new or exisiting, make the new user owner of it
        self.internal_api.associate('set_owner', school_admin, cohort)

        # Send an email to the user with all the information they need to
        # participate.
        mandrill.send(to_address=school_admin.login_email,
                      subject=program_config.registration_email_subject,
                      body=mandrill.render_markdown(
                          program_config.registration_email_body),
                      template_data={
                          'email': school_admin.login_email,
                          'cohort_id': cohort.id
                      })

        logging.info('api_handlers.CreatePublicSchoolHandler')
        logging.info('sending an email to: {}'.format(
            school_admin.login_email))

        return {
            'success': True,
            'data': {
                'user':
                school_admin.to_dict(),
                'program':
                program.to_dict(),
                'school':
                school.to_dict() if school else None,
                'cohort':
                cohort.to_dict(),
                'classroom':
                classroom.to_dict() if classroom else None,
                'activities':
                ([a.to_dict() for a in activities] if activities else None),
            }
        }