def test_location_update(self): with self.app.test_client() as c: user = self.create_user(c) headers = [('Content-Type', 'application/json')] json_data = self.create_location(c) # anonymous cannot update patch = c.patch('/api/locations/%d' % json_data['id'], headers=headers, data=json.dumps(json_data)) self.assertEqual(patch.status_code, 401) # registered users cannot update user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] patch = c.patch('/api/locations/%d' % json_data['id'], headers=user_headers, data=json.dumps(json_data)) self.assertEqual(patch.status_code, 401) # partner can update user = User.from_email(user.email) user.change_role('partner') user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] patch = c.patch('/api/locations/%d' % json_data['id'], headers=user_headers, data=json.dumps(json_data)) self.assertEqual(patch.status_code, 401) # team member can update user = User.from_email(user.email) user.change_role('mapping') user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] patch = c.patch('/api/locations/%d' % json_data['id'], headers=user_headers, data=json.dumps(json_data)) self.assertEqual(patch.status_code, 200) # admin can update user = User.from_email(user.email) user.change_role('admin') user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] patch = c.patch('/api/locations/%d' % json_data['id'], headers=user_headers, data=json.dumps(json_data)) self.assertEqual(patch.status_code, 200)
def test_who_can_edit_users(self): with self.app.test_client() as c: me = { 'first': 'Justin', 'last': 'Poehnelt', 'organization': 'USGS', 'password': '******', 'email': '*****@*****.**' } other = { 'first': 'Justin', 'last': 'Poehnelt', 'organization': 'USGS', 'password': '******', 'email': '*****@*****.**' } headers = [('Content-Type', 'application/json')] c.post('/auth/register', headers=headers, data=json.dumps(me)) c.post('/auth/register', headers=headers, data=json.dumps(other)) user = User.from_email(me['email']) other = User.from_email(other['email']) # attempt to edit a user from anyone response = c.patch('/api/users/%d' % user.id, headers=headers, data=json.dumps(me)) self.assertEqual(response.status_code, 401) self.assertEqual(json.loads(response.data)['status_code'], 401) # attempt to edit user from user headers = [('Content-Type', 'application/json'), ('authorization', 'bearer ' + make_jwt(user))] c.patch('/api/users/%d' % user.id, headers=headers, data=json.dumps(me)) # attempt to edit user from different user without roles headers = [('Content-Type', 'application/json'), ('authorization', 'bearer ' + make_jwt(other))] response = c.patch('/api/users/%d' % user.id, headers=headers, data=json.dumps(me)) self.assertEqual(response.status_code, 401) self.assertEqual(json.loads(response.data)['status_code'], 401) # attempt to edit different user with admin user.role = 'admin' headers = [('Content-Type', 'application/json'), ('authorization', 'bearer ' + make_jwt(user))] c.patch('/api/users/%d' % other.id, headers=headers, data=json.dumps(me))
def test_record_update_rating(self): with self.app.test_client() as c: user = self.create_user(c) user = User.from_email(user.email) headers = [('Content-Type', 'application/json')] user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] location = self.create_location(c) data_record = { 'year': 2014, 'month': 1, 'location_id': location['id'] } post = c.post('/api/records', headers=user_headers, data=json.dumps(data_record)) record = json.loads(post.data) data_rating = {'rating': 1, 'record_id': record['id']} post = c.post('/api/ratings', headers=user_headers, data=json.dumps(data_rating)) rating = json.loads(post.data) other = { 'first': 'Justin', 'last': 'Poehnelt', 'organization': 'USGS', 'password': '******', 'email': '*****@*****.**' } c.post('/auth/register', headers=headers, data=json.dumps(other)) other = User.from_email(other['email']) other_headers = headers + [ ('authorization', 'bearer ' + make_jwt(other)) ] patch = c.patch('/api/ratings/%d' % rating['id'], headers=other_headers, data=json.dumps(data_rating)) self.assertEqual(patch.status_code, 401) # cannot edit someone elses rating patch = c.patch('/api/ratings/%d' % rating['id'], headers=user_headers, data=json.dumps(data_rating)) self.assertEqual(patch.status_code, 200) # can edit own rating
def test_record_rating_stale_after_update(self): with self.app.test_client() as c: user = self.create_user(c) user = User.from_email(user.email) user.change_role('partner') headers = [('Content-Type', 'application/json')] user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] location = self.create_location(c) data_record = { 'year': 2014, 'month': 1, 'location_id': location['id'] } post = c.post('/api/records', headers=user_headers, data=json.dumps(data_record)) record = json.loads(post.data) data_rating = {'rating': 1, 'record_id': record['id']} c.post('/api/ratings', headers=user_headers, data=json.dumps(data_rating)) patch = c.patch('/api/records/%d' % record['id'], headers=user_headers, data=json.dumps(record)) record = json.loads(patch.data) for rating in record['ratings']: self.assertTrue(rating['stale'])
def test_record_update(self): with self.app.test_client() as c: headers = [('Content-Type', 'application/json')] user = self.create_user(c) user = User.from_email(user.email) user.change_role('partner') user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] data = {'lat': 0, 'lon': 0} post = c.post('/api/locations', headers=user_headers, data=json.dumps(data)) location = json.loads(post.data) data_record = { 'year': 2014, 'month': 1, 'location_id': location['id'] } post = c.post('/api/records', headers=user_headers, data=json.dumps(data_record)) record = json.loads(post.data) c.patch('/api/records/%d' % record['id'], headers=user_headers, data=json.dumps(record))
def test_record_create_rating(self): with self.app.test_client() as c: user = self.create_user(c) user = User.from_email(user.email) headers = [('Content-Type', 'application/json')] user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] location = self.create_location(c) data_record = { 'year': 2014, 'month': 1, 'location_id': location['id'] } post = c.post('/api/records', headers=user_headers, data=json.dumps(data_record)) record = json.loads(post.data) data_rating = {'rating': 1, 'record_id': record['id']} c.post('/api/ratings', headers=user_headers, data=json.dumps(data_rating)) # try a duplicate, should replace old post = c.post('/api/ratings', headers=user_headers, data=json.dumps(data_rating)) self.assertEqual(post.status_code, 201)
def reset_password(): token = request.json['token'] email = decode_token(token, current_app.config['SECRET_KEY'], current_app.config['AUTH_RESET_TOKEN_EXPIRATION']) user = User.from_email(email) user.change_password(request.json['password']) return JSONResponse(status_code=200, description='Password was changed', data={'token': make_jwt(user)})
def forgot_password(): user = User.from_email(request.json['email']) if user is not None: # send email token = generate_token(user.email, current_app.config['SECRET_KEY']) # Send Email # link = 'https://croplands.org/app/a/reset?token=' + token send_reset_email(link, user.email) return jsonify({'status_code': 200, 'description': 'Email sent'}), 200
def test_classification_user(self): with self.app.test_client() as c: me = {'first': 'Justin', 'last': 'Poehnelt', 'affiliation': 'USGS', 'password': '******', 'email': '*****@*****.**'} headers = [('Content-Type', 'application/json')] c.post('/auth/register', headers=headers, data=json.dumps(me)) # verify user User.from_email(me['email']) # login response = c.post('/auth/login', headers=headers, data=json.dumps({'email': me['email'], 'password': me['password']})) response.json = json.loads(response.data) self.assertIn('data', response.json) self.assertIn('token', response.json['data']) token = response.json['data']['token'] headers = [('Content-Type', 'application/json'), ('authorization', 'bearer ' + token)] data = {'lat': 35.312, 'lon': -111.112} post = c.post('/api/locations', headers=headers, data=json.dumps(data)) response = json.loads(post.data) image_data = {'date_acquired': '2015-01-01', 'lat': 0, 'lon': 0, 'location_id': response['id'], 'bearing': 0, 'url': 'asdf'} c.post('/api/images', headers=headers, data=json.dumps(image_data)) response = c.get('/api/images', headers=headers) image_id = json.loads(response.data)['objects'][0]['id'] data = { "image": image_id, "classification": 3 } response = c.post('/api/image_classifications', headers=headers, data=json.dumps(data)) classification = json.loads(response.data) self.assertIsNotNone(classification['user_id']) self.assertEqual(classification['user_id'], 1)
def send_confirm(): user = User.from_email(request.json['email']) if user is not None: # send email token = generate_token( (user.email, user.custom_data['email_verification_token']), current_app.config['SECRET_KEY']) # Send Email # link = 'http://www.croplands.org/account/confirm?t=' + token send_confirmation_email(link, user.email) return JSONResponse(status_code=200, description='Confirmation email sent')
def create_user(self, c): me = { 'first': 'Justin', 'last': 'Poehnelt', 'organization': 'USGS', 'password': '******', 'email': '*****@*****.**' } headers = [('Content-Type', 'application/json')] c.post('/auth/register', headers=headers, data=json.dumps(me)) return User.from_email(me['email'])
def test_location_delete(self): with self.app.test_client() as c: user = self.create_user(c) user = User.from_email(user.email) headers = [('Content-Type', 'application/json')] json_data = self.create_location(c) delete = c.delete('/api/locations/%d' % json_data['id'], headers=headers) self.assertEqual(delete.status_code, 401) # admin can delete user = User.from_email(user.email) user.change_role('admin') user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] delete = c.delete('/api/locations/%d' % json_data['id'], headers=user_headers) self.assertEqual(delete.status_code, 204)
def user(db_init, app, request): if request is None: u = None else: u = User.create(email=str(uuid.uuid4()) + '@test.com', password='******', first='first', last='last', role=str(request), organization="USGS") def tearDown(): if u is not None: db.session.delete(u) db.session.commit() return u
def test_api_role(self): with self.app.test_request_context() as request_ctx: from croplands_api.views.api.processors import api_roles def api_roles_wrapper(role): """ Help for roles in test :param role: :return: """ api_roles(role)() # should not be authorized for any of these since current user is none self.assertRaises(Unauthorized, api_roles_wrapper, 'registered') self.assertRaises(Unauthorized, api_roles_wrapper, 'partner') self.assertRaises(Unauthorized, api_roles_wrapper, 'team') self.assertRaises(Unauthorized, api_roles_wrapper, 'admin') self.assertRaises(Unauthorized, api_roles_wrapper, ['registered', 'partner', 'team', 'admin']) request_ctx.current_user = user = User( **{ 'first': 'Justin', 'last': 'Poehnelt', 'organization': 'USGS', 'password': '******', 'email': '*****@*****.**' }) user.role = 'registered' self.assertEqual(api_roles_wrapper('registered'), None) self.assertRaises(Unauthorized, api_roles_wrapper, ['partner', 'team', 'admin']) user.role = 'partner' self.assertEqual(api_roles_wrapper('partner'), None) self.assertRaises(Unauthorized, api_roles_wrapper, ['registered', 'team', 'admin']) user.role = 'team' self.assertEqual(api_roles_wrapper('team'), None) self.assertRaises(Unauthorized, api_roles_wrapper, ['partner', 'registered', 'admin']) user.role = 'admin' self.assertEqual(api_roles_wrapper('admin'), None) self.assertRaises(Unauthorized, api_roles_wrapper, ['partner', 'team', 'registered'])
def test_user_email_case_insensitivity(self): """ Emails are by nature case insensitive. This test checks that the user model correctly handles this specification. :return: """ with self.app.app_context(): data = { 'email': '*****@*****.**', 'password': '******', 'first': 'First', 'last': 'Last' } user = User(**data) assert (user.email.islower()) user = User.create(**data) assert (user.email.islower()) user = User.from_email(data['email']) self.assertIsNotNone(user) user = User.from_login(data['email'], data['password']) self.assertIsNotNone(user)
def test_record_create_has_history(self): with self.app.test_client() as c: headers = [('Content-Type', 'application/json')] user = self.create_user(c) user = User.from_email(user.email) user.change_role('partner') user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] data = {'lat': 0, 'lon': 0} post = c.post('/api/locations', headers=user_headers, data=json.dumps(data)) location = json.loads(post.data) data_record = { 'year': 2014, 'month': 1, 'location_id': location['id'] } post = c.post('/api/records', headers=user_headers, data=json.dumps(data_record)) record = json.loads(post.data) self.assertEqual(len(record['history']), 1) self.assertAlmostEqual(datetime.datetime.strptime( record['history'][0]['date_edited'], "%Y-%m-%dT%H:%M:%S.%f"), datetime.datetime.now(), delta=datetime.timedelta(seconds=5)) patch = c.patch('/api/records/%d' % record['id'], headers=user_headers, data=json.dumps(data_record)) record = json.loads(patch.data) self.assertEqual(len(record['history']), 2) self.assertAlmostEqual(datetime.datetime.strptime( record['history'][0]['date_edited'], "%Y-%m-%dT%H:%M:%S.%f"), datetime.datetime.now(), delta=datetime.timedelta(seconds=5)) for history in record['history']: data = json.loads(history['data']) self.assertNotIn('history', data)
def test_location_update_with_relation(self): with self.app.test_client() as c: user = self.create_user(c) headers = [('Content-Type', 'application/json')] json_data = self.create_location(c) json_data['records'].append({'year': 2014, 'month': 1}) # partner can update user = User.from_email(user.email) user.change_role('mapping') user_headers = headers + [ ('authorization', 'bearer ' + make_jwt(user)) ] patch = c.patch('/api/locations/%d' % json_data['id'], headers=user_headers, data=json.dumps(json_data)) location = json.loads(patch.data) self.assertEqual(patch.status_code, 200) self.assertEqual(len(location['records']), 0)
def register(): data = request.json # create user with the data, # all stormpath exceptions will be caught and passed on in standardized format user = User.create(**data) # if requires confirmation if current_app.config['AUTH_REQUIRE_CONFIRMATION']: token = generate_token( (user.email, user.custom_data['email_verification_token']), current_app.config['SECRET_KEY']) # Send Email # link = 'https://croplands.org/app/a/confirm?t=' + token send_confirmation_email(link, user.email) return JSONResponse(status_code=201, description='User created') # else just return token response_data = {'token': make_jwt(user)} return JSONResponse(status_code=201, description='User created', data=response_data)
def login(): user = User.from_login(request.json['email'], request.json['password']) return JSONResponse(status_code=200, description='User logged in', data={'token': make_jwt(user)})
def confirm(): token = request.json['token'] email, token = decode_token(token, current_app.config['SECRET_KEY']) user = User.from_email(email) user.verify(token) return JSONResponse(status_code=200, description='Email confirmed')