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': ''}
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), )
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'}
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'}
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)
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), } }