def api_send_verification_email(): """ @TODO: allow POST only @TODO: Send Verification Email to user_id :rtype: Response :return the success or failed in json format """ user_id = get_safe_int(request.form.get('user_id')) user = UserEntity.get_by_id(user_id) user = UserEntity.get_by_id(1) user.email = app.config['MAIL_SENDER_SUPPORT'] try: emails.send_verification_email(user) return jsonify_success({"message": "Verification email was sent."}) except Exception as exc: details = "Connection config: {}/{}:{}".format( app.config['MAIL_USERNAME'], app.config['MAIL_SERVER'], app.config['MAIL_PORT']) app.logger.debug(details) return jsonify_error({ "message": "Unable to send email due: {} {}".format(exc, details) })
def api_deactivate_account(): """ De-activate an user. @TODO: should change expiration date too? :rtype: Response :return the success or failed in json format """ user_id = get_safe_int(request.form.get('user_id')) user = UserEntity.get_by_id(user_id) user = UserEntity.update(user, active=False) return jsonify_success({"message": "User deactivated."})
def api_extend_account(): """ Change the `User.usrAccessExpiresAt` to today's date + 180 days :rtype: Response :return the success or failed in json format """ user_id = request.form.get('user_id') today_plus_180 = get_expiration_date(180) user = UserEntity.get_by_id(user_id) user = UserEntity.update(user, access_expires_at=today_plus_180) return jsonify_success( {"message": "Updated expiration date to {}".format(today_plus_180)})
def api_save_user(): """ Save a new user to the database TODO: Add support for reading a password field """ email = request.form['email'] first = request.form['first'] last = request.form['last'] minitial = request.form['minitial'] roles = request.form.getlist('roles[]') email_exists = False try: existing_user = UserEntity.query.filter_by(email=email).one() email_exists = existing_user is not None except: pass if email_exists: return utils.jsonify_error( {'message': 'Sorry. This email is already taken.'}) # @TODO: use a non-gatorlink password here password = email salt, password_hash = utils.generate_auth(app.config['SECRET_KEY'], password) added_date = datetime.today() access_end_date = utils.get_expiration_date(180) # Note: we store the salt as a prefix user = UserEntity.create(email=email, first=first, last=last, minitial=minitial, added_at=added_date, modified_at=added_date, access_expires_at=access_end_date, password_hash="{}:{}".format(salt, password_hash)) user_roles = [] try: for role_name in roles: role_entity = RoleEntity.query.filter_by(name=role_name).one() user_roles.append(role_entity) except Exception as exc: app.logger.debug("Problem saving user: {}".format(exc)) [user.roles.append(rol) for rol in user_roles] user = UserEntity.save(user) app.logger.debug("saved user: {}".format(user)) LogEntity.account_created(session['uuid'], user) return utils.jsonify_success({'user': user.serialize()})
def api_expire_account(): """ Change the `User.usrAccessExpiresAt` to today's date and 00:00:00 time effectively blocking the user access. :rtype: Response :return the success or failed in json format """ user_id = get_safe_int(request.form.get('user_id')) user = UserEntity.get_by_id(user_id) today = datetime.today() today_start = datetime(today.year, today.month, today.day) user = UserEntity.update(user, access_expires_at=today_start) return jsonify_success({"message": "User access was expired."})
def api_activate_account(): """ Activate an user. @TODO: should change expiration date too? :rtype: Response :return the success or failed in json format """ user_id = utils.get_safe_int(request.form.get('user_id')) user = UserEntity.get_by_id(user_id) user = UserEntity.update(user, active=True) LogEntity.account_modified(session['uuid'], "User activated: {}".format(user)) return utils.jsonify_success({"message": "User activated."})
def api_save_user(): """ Add New User to the database """ email = request.form['email'] first = request.form['first'] last = request.form['last'] minitial = request.form['minitial'] roles = request.form.getlist('roles[]') app.logger.debug("roles: {}".format(roles)) email_exists = False try: existing_user = UserEntity.query.filter_by(email=email).one() email_exists = existing_user is not None except: pass if email_exists: return make_response( pack_error("Sorry. This email is already taken.")) # @TODO: fix hardcoded values # password = '******' # salt, hashed_pass = generate_auth(app.config['SECRET_KEY'], password) added_date = datetime.today() access_end_date = get_expiration_date(180) user = UserEntity.create(email=email, first=first, last=last, minitial=minitial, added_at=added_date, modified_at=added_date, access_expires_at=access_end_date, password_hash="") # roles=user_roles) user_roles = [] try: for role_name in roles: role_entity = RoleEntity.query.filter_by(name=role_name).one() user_roles.append(role_entity) except Exception as exc: app.logger.debug("Problem saving user: {}".format(exc)) [user.roles.append(rol) for rol in user_roles] user = UserEntity.save(user) app.logger.debug("saved user: {}".format(user)) return make_response(pack_success_result(user.serialize()))
def api_save_user(): """ Add New User to the database """ email = request.form['email'] first = request.form['first'] last = request.form['last'] minitial = request.form['minitial'] roles = request.form.getlist('roles[]') app.logger.debug("roles: {}".format(roles)) email_exists = False try: existing_user = UserEntity.query.filter_by(email=email).one() email_exists = existing_user is not None except: pass if email_exists: return jsonify_error( {'message': 'Sorry. This email is already taken.'}) # @TODO: fix hardcoded values # password = '******' # salt, hashed_pass = generate_auth(app.config['SECRET_KEY'], password) added_date = datetime.today() access_end_date = get_expiration_date(180) user = UserEntity.create(email=email, first=first, last=last, minitial=minitial, added_at=added_date, modified_at=added_date, access_expires_at=access_end_date, password_hash="") # roles=user_roles) user_roles = [] try: for role_name in roles: role_entity = RoleEntity.query.filter_by(name=role_name).one() user_roles.append(role_entity) except Exception as exc: app.logger.debug("Problem saving user: {}".format(exc)) [user.roles.append(rol) for rol in user_roles] user = UserEntity.save(user) app.logger.debug("saved user: {}".format(user)) return jsonify_success({'user': user.serialize()})
def api_save_user(): """ Save a new user to the database TODO: Add support for reading a password field """ request_data = __extract_user_information(request) credentials = __generate_credentials(request_data["email"]) date_data = __get_date_information() if __check_is_existing_user(request_data["email"]): return utils.jsonify_error( {'message': 'Sorry. This email is already taken.'}) user = UserEntity.create(email=request_data["email"], first=request_data["first"], last=request_data["last"], minitial=request_data["minitial"], added_at=date_data["added_at"], modified_at=date_data["added_at"], access_expires_at=date_data["access_expires_at"], password_hash="{}:{}" .format(credentials["salt"], credentials["password_hash"])) __assign_roles(request_data["roles"], user) app.logger.debug("saved user: {}".format(user)) LogEntity.account_created(session['uuid'], user) return utils.jsonify_success({'user': user.serialize()})
def create_sample_data(self): """ Add some data """ # == Create users added_date = datetime.today() access_end_date = utils.get_expiration_date(180) user = UserEntity.create(email="*****@*****.**", first="First", last="Last", minitial="M", added_at=added_date, modified_at=added_date, email_confirmed_at=added_date, access_expires_at=access_end_date) # == Create roles role_admin = RoleEntity.create(name=ROLE_ADMIN, description='role') role_tech = RoleEntity.create(name=ROLE_TECHNICIAN, description='role') role_res1 = RoleEntity.create(name=ROLE_RESEARCHER_ONE, description='') role_res2 = RoleEntity.create(name=ROLE_RESEARCHER_TWO, description='') user.roles.extend([role_admin, role_tech, role_res1, role_res2]) # == Create subject subject = SubjectEntity.create( redcap_id="001", added_at=added_date, last_checked_at=added_date, was_deleted=0) # == Create events evt = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 1', day_offset=1, added_at=added_date) evt2 = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 2', day_offset=2.3, added_at=added_date) self.assertIsNotNone(evt.id) self.assertIsNotNone(evt2.id) files = [ {'name': 'a.png', 'size': '123', 'event': evt.id}, {'name': 'b.png', 'size': '1234', 'event': evt.id}, {'name': 'c.png', 'size': '12345', 'event': evt2.id}, {'name': 'd.png', 'size': '123456', 'event': evt2.id}, {'name': 'e.png', 'size': '1234567', 'event': evt2.id}, ] # Create subject files for fdata in files: subject_file = SubjectFileEntity.create( subject_id=subject.id, event_id=fdata['event'], file_name=fdata['name'], file_check_sum=utils.compute_text_md5(fdata['name']), file_size=fdata['size'], uploaded_at=added_date, user_id=user.id) self.assertIsNotNone(subject_file.id)
def api_expire_account(): """ Change the `User.usrAccessExpiresAt` to today's date and 00:00:00 time effectively blocking the user access. :rtype: Response :return the success or failed in json format """ user_id = utils.get_safe_int(request.form.get('user_id')) user = UserEntity.get_by_id(user_id) today = datetime.today() today_start = datetime(today.year, today.month, today.day) user = UserEntity.update(user, access_expires_at=today_start) # @TODO: add dedicated log type LogEntity.account_modified(session['uuid'], "User access was expired. {}".format(user.email)) return utils.jsonify_success({"message": "User access was expired."})
def api_extend_account(): """ Change the `User.usrAccessExpiresAt` to today's date + 180 days :rtype: Response :return the success or failed in json format """ user_id = request.form.get('user_id') today_plus_180 = utils.get_expiration_date(180) user = UserEntity.get_by_id(user_id) user = UserEntity.update(user, access_expires_at=today_plus_180) # @TODO: add dedicated log type LogEntity.account_modified( session['uuid'], "Updated expiration date to {}. {}".format(today_plus_180, user.email)) return utils.jsonify_success( {"message": "Updated expiration date to {}".format(today_plus_180)})
def api_expire_account(): """ Change the `User.usrAccessExpiresAt` to today's date and 00:00:00 time effectively blocking the user access. :rtype: Response :return the success or failed in json format """ user_id = utils.get_safe_int(request.form.get('user_id')) user = UserEntity.get_by_id(user_id) today = datetime.today() today_start = datetime(today.year, today.month, today.day) user = UserEntity.update(user, access_expires_at=today_start) # @TODO: add dedicated log type LogEntity.account_modified( session['uuid'], "User access was expired. {}".format(user.email)) return utils.jsonify_success({"message": "User access was expired."})
def api_extend_account(): """ Change the `User.usrAccessExpiresAt` to today's date + 180 days :rtype: Response :return the success or failed in json format """ user_id = request.form.get('user_id') today_plus_180 = utils.get_expiration_date(180) user = UserEntity.get_by_id(user_id) user = UserEntity.update(user, access_expires_at=today_plus_180) # @TODO: add dedicated log type LogEntity.account_modified(session['uuid'], "Updated expiration date to {}. {}".format( today_plus_180, user.email)) return utils.jsonify_success( {"message": "Updated expiration date to {}".format(today_plus_180)})
def __assign_roles(roles_required, user): """ Delete all roles for the user if not in the provided `roles_required` list and assing new roles. """ all_roles = RoleEntity.query.all() user_roles = [role for role in all_roles if role.name in roles_required] user = UserEntity.update(user, roles=user_roles) return user
def test_subject(self): """ verify save and find operations """ added_date = datetime.today() subject = SubjectEntity.create( redcap_id="001", added_at=added_date, last_checked_at=added_date, was_deleted=False) self.assertEquals(1, subject.id) self.assertEquals("001", subject.redcap_id) self.assertIsNotNone(subject.added_at) self.assertIsNotNone(subject.last_checked_at) self.assertFalse(subject.was_deleted) self.assertEqual(subject.added_at, subject.last_checked_at) subjects = SubjectEntity.query.all() self.assertEquals(1, len(subjects)) # test usage of CRUDMixin.get_by_id() and create() subject = SubjectEntity.update(subject, redcap_id="002") self.assertEquals("002", subject.redcap_id) evt = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 1', added_at=added_date) fdata = {'name': 'a.png', 'size': '1MB', 'event': evt.id} user = UserEntity.create(email="*****@*****.**", first="", last="", minitial="", added_at=added_date, modified_at=added_date, access_expires_at=added_date) subject_file = SubjectFileEntity.create( subject_id=subject.id, event_id=fdata['event'], file_name=fdata['name'], file_check_sum=utils.compute_text_md5(fdata['name']), file_size=fdata['size'], uploaded_at=added_date, user_id=user.get_id()) self.assertIsNotNone(subject_file.id) actual_count = SubjectFileEntity.query.count() self.assertEqual(1, actual_count) actual_count = SubjectFileEntity.query.filter_by( event_id=1).count() self.assertEqual(1, actual_count) sfile = SubjectFileEntity.query.first() self.assertEqual(user.id, sfile.user_id)
def test_subject(self): """ verify save and find operations """ added_date = datetime.today() subject = SubjectEntity.create(redcap_id="001", added_at=added_date, last_checked_at=added_date, was_deleted=False) self.assertEquals(1, subject.id) self.assertEquals("001", subject.redcap_id) self.assertIsNotNone(subject.added_at) self.assertIsNotNone(subject.last_checked_at) self.assertFalse(subject.was_deleted) self.assertEqual(subject.added_at, subject.last_checked_at) subjects = SubjectEntity.query.all() self.assertEquals(1, len(subjects)) # test usage of CRUDMixin.get_by_id() and create() subject = SubjectEntity.update(subject, redcap_id="002") self.assertEquals("002", subject.redcap_id) evt = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 1', added_at=added_date) fdata = {'name': 'a.png', 'size': '1MB', 'event': evt.id} user = UserEntity.create(email="*****@*****.**", first="", last="", minitial="", added_at=added_date, modified_at=added_date, access_expires_at=added_date) subject_file = SubjectFileEntity.create( subject_id=subject.id, event_id=fdata['event'], file_name=fdata['name'], file_check_sum=utils.compute_text_md5(fdata['name']), file_size=fdata['size'], uploaded_at=added_date, user_id=user.get_id()) self.assertIsNotNone(subject_file.id) actual_count = SubjectFileEntity.query.count() self.assertEqual(1, actual_count) actual_count = SubjectFileEntity.query.filter_by(event_id=1).count() self.assertEqual(1, actual_count) sfile = SubjectFileEntity.query.first() self.assertEqual(user.id, sfile.user_id)
def create_sample_data(self): """ Add some data """ # == Create users added_date = datetime.today() access_end_date = utils.get_expiration_date(180) user = UserEntity.create(email="*****@*****.**", first="First", last="Last", minitial="M", added_at=added_date, modified_at=added_date, access_expires_at=access_end_date) # == Create roles role_admin = RoleEntity.create(name=ROLE_ADMIN, description='role') role_tech = RoleEntity.create(name=ROLE_TECHNICIAN, description='role') user.roles.extend([role_admin, role_tech]) # == Create subject subject = SubjectEntity.create( redcap_id="001", added_at=added_date, last_checked_at=added_date, was_deleted=0) # == Create events evt = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 1', added_at=added_date) evt2 = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 2', added_at=added_date) assert evt.id is not None files = [ {'name': 'a.png', 'size': '1MB', 'event': evt.id}, {'name': 'b.png', 'size': '2MB', 'event': evt.id}, {'name': 'c.png', 'size': '3MB', 'event': evt2.id}, {'name': 'd.png', 'size': '4MB', 'event': evt2.id}, {'name': 'e.png', 'size': '5MB', 'event': evt2.id}, ] # Create subject files for fdata in files: subject_file = SubjectFileEntity.create( subject_id=subject.id, event_id=fdata['event'], file_name=fdata['name'], file_check_sum=utils.compute_text_md5(fdata['name']), file_size=fdata['size'], uploaded_at=added_date, user_id=user.id) app.logger.debug("Init test case with: {}".format(subject_file))
def api_send_verification_email(): """ @TODO: allow POST only @TODO: Send Verification Email to user_id :rtype: Response :return the success or failed in json format """ user_id = get_safe_int(request.form.get('user_id')) user = UserEntity.get_by_id(user_id) user = UserEntity.get_by_id(1) user.email = app.config['MAIL_SENDER_SUPPORT'] try: emails.send_verification_email(user) return jsonify_success({"message": "Verification email was sent."}) except Exception as exc: details = "Connection config: {}/{}:{}".format( app.config['MAIL_USERNAME'], app.config['MAIL_SERVER'], app.config['MAIL_PORT']) app.logger.debug(details) return jsonify_error({"message": "Unable to send email due: {} {}" .format(exc, details)})
def test_user(self): """ verify save and find operations """ added_date = datetime.today() access_end_date = utils.get_expiration_date(180) user = UserEntity.create(email="*****@*****.**", first="", last="", minitial="", added_at=added_date, modified_at=added_date, access_expires_at=access_end_date) self.assertEqual(1, user.id) self.assertEqual("*****@*****.**", user.email) with self.assertRaises(NoResultFound): UserEntity.query.filter_by(email="[email protected]").one() found = UserEntity.query.filter_by(email="*****@*****.**").one() self.assertIsNotNone(found) # two unbound objects ... role_admin = self.get_role(ROLE_ADMIN) role_tech = self.get_role(ROLE_TECHNICIAN) # save them to the database... db.session.add(role_admin) db.session.add(role_tech) db.session.commit() saved_role = RoleEntity.query.filter_by(name=ROLE_ADMIN).one() self.assertEqual(1, saved_role.id) # ...then use them user.roles.append(role_admin) user.roles.append(role_tech) user_roles = UserRoleEntity.query.all() self.assertEqual(2, len(user_roles)) user_role = UserRoleEntity.get_by_id(1) self.assertEqual(1, user_role.id) self.assertEqual(ROLE_ADMIN, user_role.role.name)
def api_verify_email(): """ @TODO: add counter/log to track failed attempts :rtype: Response :return the success or failed in json format """ if 'POST' == request.method: token = utils.clean_str(request.form.get('tok')) else: token = utils.clean_str(request.args.get('tok')) if not token: return utils.jsonify_error({'message': 'No token specified.'}) try: email = utils.get_email_from_token(token, app.config["SECRET_KEY"], app.config["SECRET_KEY"]) except Exception as exc: # @TODO: add dedicated log type app.logger.error("api_verify_email: {}".format(exc.message)) return utils.jsonify_error({'message': exc.message}) app.logger.debug("Decoded email from token: {}".format(email)) user = UserEntity.query.filter_by(email=email).first() if user is None: app.logger.error("Attempt to verify email with incorrect token: {}" .format(token)) return utils.jsonify_error({'message': 'Sorry.'}) user = UserEntity.update(user, email_confirmed_at=datetime.today()) app.logger.debug("Verified token {} for user {}".format(token, user.email)) # @TODO: add dedicated log type LogEntity.account_modified(session['uuid'], "Verified token {} for user {}".format( token, user.email)) return utils.jsonify_success( {"message": "Email was verified for {}.".format(email)})
def api_verify_email(): """ @TODO: add column for verification hash @TODO: add counter/log to track failed attempts :rtype: Response :return the success or failed in json format """ token = request.form.get('tok') # user = UserEntity.query.filter_by(email_token=token).first() user = UserEntity.get_by_id(1) if user is None: app.logger.error( "Attempt to verify email with incorrect token: {}".format(token)) return jsonify_error({'message': 'Sorry.'}) app.logger.debug("Verified token {} for user {}".format(token, user.email)) # implement update User set usrEmailConfirmedAt = NOW() return jsonify_success({"message": "Verification email was sent."})
def api_verify_email(): """ @TODO: add column for verification hash @TODO: add counter/log to track failed attempts :rtype: Response :return the success or failed in json format """ token = request.form.get('tok') # user = UserEntity.query.filter_by(email_token=token).first() user = UserEntity.get_by_id(1) if user is None: app.logger.error("Attempt to verify email with incorrect token: {}" .format(token)) return jsonify_error({'message': 'Sorry.'}) app.logger.debug("Verified token {} for user {}".format(token, user.email)) # implement update User set usrEmailConfirmedAt = NOW() return jsonify_success({"message": "Verification email was sent."})
def api_edit_user(): """ Edit an existing user in the database TODO: Add support for reading a password field """ request_data = __extract_user_information(request) credentials = __generate_credentials(request_data["email"]) date_data = __get_date_information() user = UserEntity.get_by_id(id=request_data["usr_id"]) user.update(email=request_data["email"], first=request_data["first"], last=request_data["last"], minitial=request_data["minitial"], added_at=date_data["added_at"], modified_at=date_data["added_at"], access_expires_at=date_data["access_expires_at"], password_hash="{}:{}".format(credentials["salt"], credentials["password_hash"])) __assign_roles(request_data["roles"], user) app.logger.debug("updated user: {}".format(user)) LogEntity.account_updated(session['uuid'], user) return utils.jsonify_success({'user': user.serialize()})
def load_user(user_id): """Return the user from the database""" return UserEntity.get_by_id(user_id)
def create_sample_data(self): """ Add some data """ # == Create users added_date = datetime.today() access_end_date = utils.get_expiration_date(180) user = UserEntity.create(email="*****@*****.**", first="First", last="Last", minitial="M", added_at=added_date, modified_at=added_date, access_expires_at=access_end_date) # == Create roles role_admin = RoleEntity.create(name=ROLE_ADMIN, description='role') role_tech = RoleEntity.create(name=ROLE_TECHNICIAN, description='role') user.roles.extend([role_admin, role_tech]) # == Create subject subject = SubjectEntity.create(redcap_id="001", added_at=added_date, last_checked_at=added_date, was_deleted=0) # == Create events evt = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 1', added_at=added_date) evt2 = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 2', added_at=added_date) assert evt.id is not None files = [ { 'name': 'a.png', 'size': '1MB', 'event': evt.id }, { 'name': 'b.png', 'size': '2MB', 'event': evt.id }, { 'name': 'c.png', 'size': '3MB', 'event': evt2.id }, { 'name': 'd.png', 'size': '4MB', 'event': evt2.id }, { 'name': 'e.png', 'size': '5MB', 'event': evt2.id }, ] # Create subject files for fdata in files: subject_file = SubjectFileEntity.create( subject_id=subject.id, event_id=fdata['event'], file_name=fdata['name'], file_check_sum=utils.compute_text_md5(fdata['name']), file_size=fdata['size'], uploaded_at=added_date, user_id=user.id) app.logger.debug("Init test case with: {}".format(subject_file))
def create_sample_data(self): """ Add some data """ # == Create users added_date = datetime.today() access_end_date = utils.get_expiration_date(180) user = UserEntity.create(email="*****@*****.**", first="First", last="Last", minitial="M", added_at=added_date, modified_at=added_date, email_confirmed_at=added_date, access_expires_at=access_end_date) # == Create roles role_admin = RoleEntity.create(name=ROLE_ADMIN, description='role') role_tech = RoleEntity.create(name=ROLE_TECHNICIAN, description='role') role_res1 = RoleEntity.create(name=ROLE_RESEARCHER_ONE, description='') role_res2 = RoleEntity.create(name=ROLE_RESEARCHER_TWO, description='') user.roles.extend([role_admin, role_tech, role_res1, role_res2]) # == Create subject subject = SubjectEntity.create(redcap_id="001", added_at=added_date, last_checked_at=added_date, was_deleted=0) # == Create events evt = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 1', day_offset=1, added_at=added_date) evt2 = EventEntity.create(redcap_arm='Arm 1', redcap_event='Event 2', day_offset=2.3, added_at=added_date) self.assertIsNotNone(evt.id) self.assertIsNotNone(evt2.id) files = [ { 'name': 'a.png', 'size': '123', 'event': evt.id }, { 'name': 'b.png', 'size': '1234', 'event': evt.id }, { 'name': 'c.png', 'size': '12345', 'event': evt2.id }, { 'name': 'd.png', 'size': '123456', 'event': evt2.id }, { 'name': 'e.png', 'size': '1234567', 'event': evt2.id }, ] # Create subject files for fdata in files: subject_file = SubjectFileEntity.create( subject_id=subject.id, event_id=fdata['event'], file_name=fdata['name'], file_check_sum=utils.compute_text_md5(fdata['name']), file_size=fdata['size'], uploaded_at=added_date, user_id=user.id) self.assertIsNotNone(subject_file.id)