def edit_user(request): """ Edit user :param request: :return: """ user_id = request.matchdict.get('id') email = request.json_body.get('email') telephone = request.json_body.get('telephone') password = request.json_body.get('password') role = request.json_body.get('role') user = get(request, User, as_dict=False) data = get_values(request, attrs, required_attrs) # only admin or owner of user profile can edit profile if user_id != request.authenticated_userid: admin_user = get_user(user_id=request.authenticated_userid, role=Administrator) if not admin_user: raise exc.HTTPForbidden() if telephone: usr = get_user(telephone=telephone) if usr and (usr.id != user_id): raise exc.HTTPBadRequest(json_body={'message': 'User with telephone number %s already exists' % telephone}) if email: usr = get_user(email=email) if usr and (usr.id != user_id): raise exc.HTTPBadRequest(json_body={'message': 'User with email %s already exists' % email}) if not request.json_body.get('role'): raise exc.HTTPBadRequest(json_body={'message': 'User role is required'}) if request.json_body.get('confirmed_registration') is None: data['confirmed_registration'] = False edit(user, **data) if password: user.set_password(password) # update user role existing_role = session.query(Role).filter(Role.name == role).first() user_role = session.query(UserRole).filter(UserRole.user_id == user_id, UserRole.role_id == existing_role.id).first() if not user_role: user.roles = [] user.roles.append(existing_role) return user.as_dict()
def list_dashboards_view(request): """ List dashboards :param request: :return: """ filters = request.params.copy() query = session.query(Dashboard) # filter dashboards either by collection or users if 'collection_id' in filters: # filter for dashboards in a collection, and dashboard not in a collection if filters['collection_id']: query = query.filter( Dashboard.collection_id == filters['collection_id']).order_by( Dashboard.index) else: query = query.filter(Dashboard.collection_id == None).order_by( Dashboard.index) user = get_user(request.authenticated_userid) if not user.has_role(Administrator) or filters.get('user_id'): # filter by users that can view the dashboards query = query.join(Dashboard.users).filter( User.id == user.id).order_by(Dashboard.index) return [ dashboard.as_dict(request.authenticated_userid) for dashboard in query.all() ]
def list_collections(request): """ List collections :param request: :return: """ filters = request.params query = session.query(Collection) user = get_user(request.authenticated_userid) if not user.has_role(Administrator): # list collections with user access query = query.join( Collection.users).filter(User.id == request.authenticated_userid) collections = [] for collection in query.order_by(Collection.title).all(): cdata = collection.as_dict(request.authenticated_userid) if 'list_dashboards' in filters: dashboards = session.query(Dashboard).filter( Dashboard.collection_id == collection.id) if not user.has_role(Administrator): # list dashboards with user access dashboards = dashboards.join(Dashboard.users).filter( User.id == request.authenticated_userid) cdata['dashboards'] = [ dash.as_dict(request.authenticated_userid) for dash in dashboards.all() ] collections.append(cdata) return collections
def login(request): """ User login :param request: :return a token: """ password = request.json_body.get('password', None) email = request.json_body.get('email', None) if email is None: raise exc.HTTPBadRequest( json_body={ 'message': 'Need at least telephone or email and password' }) request.response.headerlist.extend( (('Cache-Control', 'no-store'), ('Pragma', 'no-cache'))) email = email.strip() user = get_user(email=email) if not user: log.info('Login failed, user not found for %s' % email) raise exc.HTTPBadRequest( json_body={'message': 'No account exists for "%s"' % email}) else: if not user.confirmed_registration: # temporary redirect to validate account request.response.status = 308 return { 'message': 'You have not yet confirmed your account. ' 'Please check your email for further instructions.', 'user_id': user.id, 'secrets': services.generate_and_send_otp(request, user) } if not password: log.info('Login failed, missing password for "%s"' % email) raise exc.HTTPBadRequest( json_body={'message': 'Login failed, missing password'}) if not user.validate_password(password): log.info('Login failed, incorrect password for "%s"' % email) raise exc.HTTPBadRequest( json_body={'message': 'Login failed, incorrect password'}) usr_roles = [r.name for r in user.roles] registry = request.registry headers = remember(request, user.id, max_age=registry.settings.get('authentication.timeout')) request.response.headerlist.extend(headers) user_data = user.as_dict() user_data['access_token'] = security.create_token(request, user.id, usr_roles) return user_data
def test_set_new_password(self): """ test setting a new password. """ self.request.json_body = { 'firstname': 'Julius', 'surname': 'Jones', 'email': '*****@*****.**', 'password': '******', 'role': 'User', 'application_url': '/' } register_user(self.request) user = get_user(email='*****@*****.**') self.request.json_body = {'email': user.email, 'application_url': '/'} response = reset_password(self.request) secret = response['secrets']['emailsecret'] otp = self.session.query(OTP).filter(OTP.user_id == user.id).first() self.request.method = 'POST' self.request.json_body = {'secret': secret, 'otp': otp.otp, 'user_id': user.id, 'password': '******'} response = set_new_password(self.request) self.assertIn('email', list(response.keys())) user = get_user(user_id=user.id) self.assertTrue(user.validate_password('new_password')) # test forgetting password with case insensitive email self.request.json_body = {'email': '*****@*****.**', 'application_url': '/'} response = reset_password(self.request) secret = response['secrets']['emailsecret'] otp = self.session.query(OTP).filter(OTP.user_id == user.id).first() self.request.method = 'POST' self.request.json_body = {'secret': secret, 'otp': otp.otp, 'user_id': user.id, 'password': '******'} response = set_new_password(self.request) self.assertEqual(response['email'], user.email)
def test_confirm_registration(self): mock_otp() add_roles_and_permissions(self.session) req = dummy_request(self.session) req.json_body = { 'firstname': 'Julius', 'surname': 'Jones', 'email': '*****@*****.**', 'password': '******', 'role': 'User', 'application_url': '/' } secrets = register_user(req) self.assertIsNotNone(secrets.get('emailsecret')) user = get_user(email='*****@*****.**') otp = self.session.query(OTP).filter(OTP.user_id == user.id).first() req.json_body = {'otp': otp.otp, 'secret': secrets['emailsecret']} response = confirm_otp_registration(req) user = get_user(user_id=response.get('user_id')) self.assertEqual(user.confirmed_registration, True)
def get_user_view(request): """ Get a user :param request: :return: """ user_id = request.matchdict.get('id') # only admin can load other users if user_id != request.authenticated_userid: admin_user = get_user(request.authenticated_userid, role=Administrator) if not admin_user: raise exc.HTTPForbidden() return get(request, User)
def register_user(request): data = request.json_body email = data.get('email') firstname = data.get('firstname') surname = data.get('surname') role = data.get('role') password = data.get('password') if not firstname or not surname: raise exc.HTTPBadRequest( json_body={'message': 'Need first name and surname'}) if not email: raise exc.HTTPBadRequest(json_body={'message': 'Need email'}) if not password: raise exc.HTTPBadRequest(json_body={'message': 'Need password'}) if not role: raise exc.HTTPBadRequest(json_body={'message': 'Need role'}) # check duplicate users if get_user(email=email): raise exc.HTTPBadRequest( json_body={'message': 'User with email %s already exists' % email}) user = User(firstname=firstname, surname=surname, address=data.get('address'), telephone=data.get('telephone'), email=email) user.set_password(password) session.add(user) session.flush() user_role = session.query(Role).filter(Role.name == role).first() user.roles.append(user_role) session.add(user) session.flush() registration_confirmation = services.generate_and_send_otp(request, user) return registration_confirmation
def test_set_new_password(self): mock_otp() add_roles_and_permissions(self.session) req = dummy_request(self.session) user = add_user(self.session) req.json_body = {'application_url': '/'} secrets = generate_and_send_otp(req, user) otp = self.session.query(OTP).filter(OTP.user_id == user.id).first() req.json_body = { 'user_id': user.id, 'password': '******', 'otp': otp.otp, 'secret': secrets.get('emailsecret'), } response = set_new_password(req) user = get_user(user_id=response.get('id')) self.assertTrue(user.validate_password('new_password'))
def reset_password(request): """ Request to reset the user password. Send user an email or sms with OTP """ email = request.json_body.get('email', None) telephone = request.json_body.get('telephone', None) if not (email or telephone): request.response.status = 401 return {'message': 'Need email or telephone'} usr = get_user(email=email, telephone=telephone) if not usr: request.response.status = 404 return { 'message': 'We could not find your user account. ' 'Please make sure you entered your email address correctly' } secrets = services.generate_and_send_otp(request, usr, 'set-password') return {'user_id': usr.id, 'secrets': secrets}
def delete_user(request): """ Delete a user view :param request: :return: """ user_id = request.matchdict.get('id') if not user_id: raise exc.HTTPBadRequest(json_body={'message': 'Need user id.'}) user = get_user(user_id) if not user: raise exc.HTTPNotFound(json_body={'message': 'No user found.'}) session.query(UserRole). \ filter(UserRole.user_id == user_id). \ delete(synchronize_session='fetch') session.query(User). \ filter(User.id == user_id). \ delete(synchronize_session='fetch')
def get_collection_view(request): """ Get a collection :param request: :return: """ collection = get(request, Collection, as_dict=False) collection_data = collection.as_dict(request.authenticated_userid) # include user dashboards with access user = get_user(request.authenticated_userid) dashboards = session.query(Dashboard).filter( Dashboard.collection_id == collection.id) if not user.has_role(Administrator): dashboards = dashboards.join( Dashboard.users).filter(User.id == request.authenticated_userid) collection_data['dashboards'] = [ dash.as_dict(request.authenticated_userid) for dash in dashboards.all() ] return collection_data
def test_user_login(self): mock_otp() user = add_user(self.session, email='*****@*****.**', password='******') user2 = add_user(self.session, email='*****@*****.**', telephone='02188911', password='******') req = dummy_request(self.session) req.method = 'POST' with self.assertRaises(exc.HTTPBadRequest): req.json_body = {} login(req) # Attempt to login to account with no password set with self.assertRaises(exc.HTTPBadRequest): req.json_body = { 'email': user2.email, 'application_url': '/' } login(req) # Attempt successful login req.json_body = { 'email': user2.email, 'password': '******' } response = login(req) self.assertIsNotNone(response.get('access_token')) # Check that log in with email is case insensitive req.json_body = { 'email': user2.email.upper(), 'password': '******' } response = login(req) self.assertIsNotNone(response.get('access_token')) # Attempt to login to invalid account user3 = add_user(self.session, email='*****@*****.**', password='******', confirmed_registration=False) req.json_body = { 'email': user3.email, 'application_url': '/' } response = login(req) self.assertEqual(response.get('message'), 'You have not yet confirmed your account. Please check your email for further instructions.') # Validate account otp = self.session.query(OTP).filter(OTP.user_id == user3.id).first() req.json_body = {'otp': otp.otp, 'secret': response.get('secrets').get('emailsecret')} response = confirm_otp_registration(req) self.assertIsNotNone(response.get('id')) user3 = get_user(user_id=response.get('id')) self.assertEqual(user3.confirmed_registration, True) # Attempt missing password login req.json_body = { 'email': user.email, 'password': '' } with self.assertRaises(exc.HTTPBadRequest): login(req) # Attempt wrong password login req.json_body = { 'email': user.email, 'password': '******' } with self.assertRaises(exc.HTTPBadRequest): login(req) # Attempt successful login req.json_body = { 'email': user.email, 'password': '******' } response = login(req) self.assertEqual(response.get('id'), user.id) self.assertEqual(response.get('firstname'), user.firstname) self.assertEqual(response.get('surname'), user.surname) # Attempt login with case insensitive email req.json_body = { 'email': '*****@*****.**', 'password': '******' } response = login(req) self.assertEqual(response.get('id'), user.id)
def test_register_user(self): mock_otp() add_roles_and_permissions(self.session) req = dummy_request(self.session) # Test error validation with self.assertRaises(exc.HTTPBadRequest): req.json_body = { 'surname': 'Jones', 'email': '*****@*****.**', 'password': '******', 'role': 'User' } register_user(req) with self.assertRaises(exc.HTTPBadRequest): req.json_body = { 'firstname': 'Julius', 'email': '*****@*****.**', 'password': '******', 'role': 'User' } register_user(req) with self.assertRaises(exc.HTTPBadRequest): req.json_body = { 'firstname': 'Julius', 'surname': 'Jones', 'password': '******', 'role': 'User' } register_user(req) with self.assertRaises(exc.HTTPBadRequest): req.json_body = { 'firstname': 'Julius', 'surname': 'Jones', 'password': '******', 'role': 'User' } register_user(req) with self.assertRaises(exc.HTTPBadRequest): req.json_body = { 'firstname': 'Julius', 'surname': 'Jones', 'email': '*****@*****.**', 'role': 'User' } register_user(req) with self.assertRaises(exc.HTTPBadRequest): req.json_body = { 'firstname': 'Julius', 'surname': 'Jones', 'email': '*****@*****.**', 'password': '******', } register_user(req) req.json_body = { 'firstname': 'Julius', 'surname': 'Jones', 'email': '*****@*****.**', 'password': '******', 'role': 'User', 'application_url': 'api' } secrets = register_user(req) self.assertIsNotNone(secrets.get('emailsecret')) user = get_user(email='*****@*****.**').as_dict() self.assertEqual(user.get('firstname'), 'Julius') self.assertEqual(user.get('surname'), 'Jones') self.assertEqual(user.get('email'), '*****@*****.**') self.assertEqual(user.get('role'), 'User') with self.assertRaises(exc.HTTPBadRequest): register_user(req)