Esempio n. 1
0
	def test_reset_password(self):
		""" 2 step process:
				POST,PUT /send-reset-code which sets temporary reset_code in cleaner model and sends via SMS to cleaner
				POST,PUT /reset-password with {'phonenumber', 'reset_code', 'password'}
				--> resets password and logs in cleaner
		"""
		NEW_PASSWORD = '******'
		# verify process works with correct reset-code
		self.POST_cleaner()
		self.POST_data('/auth/send-reset-code', data=TEST_CLEANER_DATA)
		c = cleaner.find_one(id=self.cleaner['_id'])
		self.POST_data('/auth/reset-password', data={
				'password': '******',
				'phonenumber': TEST_CLEANER_DATA['phonenumber'],
				'reset_code': c['reset_code'],
				})
		# verify user now logged in
		data = self.GET_data('/auth/user')
		self.assertEqual(data['name'], TEST_CLEANER_DATA['name'])

		# logout user and verify user cannot sign in with old password
		self.logout()
		rv = self.app.post('/auth/login', data=json.dumps({
			'password': TEST_CLEANER_DATA['password'],
			'phonenumber': TEST_CLEANER_DATA['phonenumber']})
		)
		self.assertEqual(rv.status_code, 500)

		# verify user can login with new password
		rv = self.app.post('/auth/login', data=json.dumps({
			'password': NEW_PASSWORD,
			'phonenumber': TEST_CLEANER_DATA['phonenumber']})
		)
		self.assertEqual(rv.status_code, 200)
Esempio n. 2
0
def POST_receipt(list_id):
    """
	Creates receipt + sends receipt to client via SMS

	A receipt is a snapshot of the list at time of POST
	When a receipt is posted, the list/receipt models do the work
	list.create_receipt retrieves a fully populated list and inserts the receipt

	@param 		{list_id} _id of list of which to take snapshot and save as receipt 
	payload:	Request is made with entire list object - have _cleaner as cleaner._id

	Returns _id of newly inserted receipt 
	"""
    try:
        list_data = JSONencoder.load(request.data)

        # verify phonenumber in list_data -- need it to send link to receipt to client
        if not 'phonenumber' in list_data:
            raise APIexception(code=1)
        phonenumber = list_data['phonenumber']

        # need to fetch cleaner for just cleaner's name in SMS message
        cleaner_id = list_data[
            '_cleaner']  # something went wrong with request if _cleaner not in payload
        c = cleaner.find_one(id=cleaner_id)

        # create the receipt that will live forever
        receipt_id = List.create_receipt(list_id)

        # send SMS to client that has link to viewable receipt
        twilio_tools.send_receipt(phonenumber, c['name'], receipt_id)

        return dumpJSON({'_id': receipt_id})
    except Exception as e:
        return respond500(e)
Esempio n. 3
0
def PUT_send_list(id):
    """
	Sends new agreement to client via SMS

	@param 		{id} _id of list to send as agreement to client 
	payload:	Request is made with entire list object - have _cleaner as cleaner._id

	Returns 200 response
	"""
    try:
        list_data = JSONencoder.load(request.data)

        # verify phonenumber in list_data -- need it to send link to receipt to client
        if not 'phonenumber' in list_data:
            raise APIexception(code=1)
        phonenumber = list_data['phonenumber']

        # need to fetch cleaner for just cleaner's name in SMS message
        cleaner_id = list_data[
            '_cleaner']  # something went wrong with request if _cleaner not in payload
        c = cleaner.find_one(id=cleaner_id)

        # send SMS to client that has link to viewable agreement
        twilio_tools.send_agreement(phonenumber, c['name'], id)

        return respond200()
    except Exception as e:
        return respond500(e)
Esempio n. 4
0
def send_reset_code():
    """
	Send reset_code via SMS to the user 
		Each reset_code expires after RESET_CODE_EXPIRATION
		If not yet set, or if expired, reset reset_code and reset_code_expires
	"""
    try:
        data = json.loads(request.data)
        if not 'phonenumber' in data:
            raise APIexception(code=1)

        phonenumber = data['phonenumber']
        c = cleaner.find_one(phonenumber=phonenumber)
        if not c:
            raise APIexception(code=2)

        if ('reset_code' in c and 'reset_code_expires' in c
                and (datetime.now() < c['reset_code_expires'])):
            reset_code = c["reset_code"]
        else:
            (reset_code, reset_code_expires) = cleaner.generate_reset_code()
            cleaner.update(c["_id"], {
                "reset_code": reset_code,
                "reset_code_expires": reset_code_expires
            })

        twilio_tools.send_SMS(
            phonenumber, str("Your password reset code is: " + reset_code))
        return respond200()
    except Exception as e:
        return respond500(e)
Esempio n. 5
0
def get_user():
    """
	Returns JSON encoded user if user in session, otherwise None

	** Potential issue I want to avoid:
		cleaner (user) was deleted (via backstage or direct database interaction) or something else bazaar happened
		yet cleaner is somehow still in session
		If this occurs - take user out of session
	"""
    if not ('user' in session and session['user']):
        return None

    # **see note above
    user = JSONencoder.load(session['user'])
    if not cleaner.find_one(id=user['_id']):
        session['user'] = None

    return session['user']
Esempio n. 6
0
def get_user():
	"""
	Returns JSON encoded user if user in session, otherwise None

	** Potential issue I want to avoid:
		cleaner (user) was deleted (via backstage or direct database interaction) or something else bazaar happened
		yet cleaner is somehow still in session
		If this occurs - take user out of session
	"""
	if not ('user' in session and session['user']):
		return None

	# **see note above
	user = JSONencoder.load(session['user'])
	if not cleaner.find_one(id=user['_id']):
		session['user'] = None

	return session['user']
Esempio n. 7
0
def POST_reset_password():
    try:
        data = json.loads(request.data)
        c = cleaner.find_one(phonenumber=data['phonenumber'])
        if not (c and 'reset_code' in c):
            raise APIexception(code=0)

        if not ((data['reset_code'] == c["reset_code"]) and
                (datetime.now() < c['reset_code_expires'])):
            raise APIexception(code=3)

        # if they made it this far all is good
        cleaner.update_password(c["_id"], data["password"], c["salt"])

        login(cleaner.public(c))
        return respond200()
    except Exception as e:
        return respond500(e)
Esempio n. 8
0
    def test_reset_password(self):
        """ 2 step process:
				POST,PUT /send-reset-code which sets temporary reset_code in cleaner model and sends via SMS to cleaner
				POST,PUT /reset-password with {'phonenumber', 'reset_code', 'password'}
				--> resets password and logs in cleaner
		"""
        NEW_PASSWORD = '******'
        # verify process works with correct reset-code
        self.POST_cleaner()
        self.POST_data('/auth/send-reset-code', data=TEST_CLEANER_DATA)
        c = cleaner.find_one(id=self.cleaner['_id'])
        self.POST_data('/auth/reset-password',
                       data={
                           'password': '******',
                           'phonenumber': TEST_CLEANER_DATA['phonenumber'],
                           'reset_code': c['reset_code'],
                       })
        # verify user now logged in
        data = self.GET_data('/auth/user')
        self.assertEqual(data['name'], TEST_CLEANER_DATA['name'])

        # logout user and verify user cannot sign in with old password
        self.logout()
        rv = self.app.post('/auth/login',
                           data=json.dumps({
                               'password':
                               TEST_CLEANER_DATA['password'],
                               'phonenumber':
                               TEST_CLEANER_DATA['phonenumber']
                           }))
        self.assertEqual(rv.status_code, 500)

        # verify user can login with new password
        rv = self.app.post('/auth/login',
                           data=json.dumps({
                               'password':
                               NEW_PASSWORD,
                               'phonenumber':
                               TEST_CLEANER_DATA['phonenumber']
                           }))
        self.assertEqual(rv.status_code, 200)
Esempio n. 9
0
def POST_feedback(list_id):
    """
	@param 		{list_id} _id of list that is owner of feedback
	payload:	feedback data 

	Sends notification via SMS to cleaner that feedback has been sent with link to list 
	Returns _id of newly inserted feedback
	"""
    try:
        feedback_data = JSONencoder.load(request.data)
        feedback_id = List.add_feedback(list_id, feedback_data)

        # get list and cleaner so that can send SMS
        l = List.find_one(id=list_id)
        c = cleaner.find_one(id=l['_cleaner'])
        twilio_tools.send_feedback_notification(c['phonenumber'], c['name'],
                                                list_id)

        return dumpJSON({'_id': feedback_id})
    except Exception as e:
        return respond500(e)
Esempio n. 10
0
def POST_login():
    try:
        data = json.loads(request.data)
        if not ("phonenumber" in data and "password"
                in data):  # client-side shouldn't have allowed post
            raise APIexception(
                code=0, message="phonenumber and password required to sign in")

        c = cleaner.find_one(phonenumber=data["phonenumber"])
        if not c:
            raise APIexception(code=2)

        if not cleaner.password_valid(data["password"], c["salt"],
                                      c["hashed_pwd"]):
            raise APIexception(code=4)

        profile = cleaner.public(c)
        login(profile)
        return dumpJSON(profile)

    except Exception as e:
        return respond500(e)
Esempio n. 11
0
def GET_cleaner_by_id(id):
    try:
        return dumpJSON(cleaner.find_one(id=id))
    except Exception as e:
        return respond500(e)