コード例 #1
0
ファイル: controller.py プロジェクト: jasonamyers/cagenix-web
def practitioners_edit(*args, **kwargs):
    print request.method
    if request.method == 'PUT':
        data = json.loads(request.data)
        user = User.by_id(kwargs.get('user_id'))
        if not user or not user.activated:
            response = jsonify(
                request=request.json,
                response={'error': 'Invalid Practitioner.'})
            response.status_code = 404
            return response

        user.map_data(data)
        db.session.add(user)
        db.session.commit()
        response = jsonify(
            request=data,
            response={
                'practitioner_id': user.id,
                'active': user.active
            }
        )
        response.status_code = 200
        return response
    elif request.method == 'DELETE':
        data = json.loads(request.data)
        user = User.by_id(int(kwargs.get('user_id')))
        requester = User.by_email(request.headers.get('key'))
        if user == requester:
            status = 'Success'
            status_code = 200
            db.session.delete(user)
            db.session.commit()
        else:
            status = 'Not Authorized'
            status_code = 401

        response = jsonify(
            request=data,
            response={
                'status': status
            }
        )
        response.status_code = status_code
        return response
    else:
        print request.method
        response = jsonify(
            request=request.json,
            response={'error': 'This request type not supported'})
        response.status_code = 400
        return response
コード例 #2
0
ファイル: controller.py プロジェクト: jasonamyers/cagenix-web
def practitioners_get(*args, **kwargs):
    user = User.by_id(kwargs.get('user_id'))
    if not user or not user.activated:
        response = jsonify(
            request=request.json,
            response={'error': 'Invalid Practitioner.'})
        response.status_code = 404
        return response

    practice = None
    if user.practice:
        practice = practice.id

    response = jsonify(
        request={
            'practitioner_id': user.id,
        },
        response={
            'active': user.active,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'address_one': user.address_one,
            'address_two': user.address_two,
            'city': user.city,
            'state': user.state,
            'zip_code': user.zip_code,
            'email': user.email,
            'activation_code': user.activation_code,
            'primary_color': user.primary_color,
            'secondary_color': user.secondary_color,
            'practice': practice,
        }
    )
    response.status_code = 200
    return response
コード例 #3
0
ファイル: controller.py プロジェクト: jasonamyers/cagenix-web
def practitioners_login(*args, **kwargs):
    if request.method == 'POST':
        data = json.loads(request.data)
        user = User.by_email(data['email'])
        if not user or not user.activated:
            data.pop('password')
            response = jsonify(
                request=data,
                response={'error': 'Invalid Practitioner'})
            response.status_code = 404
            return response

        if not verify_password(data['password'], user.password):
            data.pop('password')
            response = jsonify(
                request=data,
                response={'error': 'Authentication Failed'})
            response.status_code = 401
            return response
        else:
            data.pop('password')
            response = jsonify(
                request=data,
                response={'secret': user.secret})
            response.status_code = 200
            return response
    else:
        response = jsonify(
            request=request.json,
            response={'error': 'This request type not supported'})
        response.status_code = 400
        return response
コード例 #4
0
        def decorated_function(*args, **kwargs):
            ''' authenticate_request validates the use of the provided credentials.
            It cycles through a tuple of required_headers and checks the presence
            of each header for validation. It then validates the licensekey and
            will allow the consumer to use the decorated handler
            '''

            required_headers = ('datetime', 'body_hash', 'key', 'signature')
            for header in required_headers:
                if header not in request.headers:
                    response = jsonify(request=request.json, response={'error': 'Required headers missing'})
                    response.status_code = 403
                    return response

            sent_timestamp = request.headers.get('datetime', '')
            sent_body_hash = request.headers.get('body_hash', '')
            sent_key = request.headers.get('key', '')
            sent_signature = request.headers.get('signature', '')

            user = User.by_email(sent_key)
            if not user or not user.active or not user.activated:
                response = jsonify(request=request.json, response={'error': 'Invalid Practitioner'})
                response.status_code = 403
                return response

            recreated_signature = hashlib.sha256(unicode(sent_body_hash + sent_timestamp + user.secret)).hexdigest()

            if not sent_signature == recreated_signature:
                response = jsonify(request=request.json, response={'error': 'Invalid Practitioner'})
                response.status_code = 403
                return response

            return f(*args, **kwargs)
コード例 #5
0
ファイル: test_api.py プロジェクト: jasonamyers/cagenix-web
    def teardown_method(self, method):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        from cagenix.users.models import User

        user = User.by_email('*****@*****.**')
        if user:
            db.session.delete(user)
            db.session.commit()
コード例 #6
0
ファイル: views.py プロジェクト: jasonamyers/cagenix-web
def users_create():
    """This function handles the /users/create endpoint for the blueprint

    It allows PNT-Admins to create users.  It uses the :ref:`users-forms-label`
    to display UsersCreateForm

    :returns: users/index.html
    :rtype: template
    """
    user = User()
    form = UserCreateForm()
    if form.validate_on_submit():
        form.populate_obj(user)
        user.activation_code = ''.join(random.sample('0123456789ABCDEFGHJKMNPQRTVWXYZ', 15))
        msg = Message("Welcome to Cagenix", recipients=[user.email])
        msg.body = "Welcome to the cagenix app, please use the code %(activation_code)s to activate the application" % {'activation_code': user.activation_code}
        mail.send(msg)
        db.session.add(user)
        db.session.commit()
        return redirect(url_for('users.users_home'))
    return render_template('users/create.html', form=form, admin=True)
コード例 #7
0
ファイル: test_api.py プロジェクト: jasonamyers/cagenix-web
    def setup_method(self, method):
        """ setup any state tied to the execution of the given method in a
        class.  setup_method is invoked for every test method of a class.
        """
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        from cagenix.users.models import User

        self.user = User(first_name='Chocolate', last_name='Chip', email='*****@*****.**', activation_code='DPJE3XFBVM271HC', password=encrypt_password('cookies'))
        self.user.gen_secret()
        db.session.add(self.user)
        db.session.commit()
コード例 #8
0
ファイル: views.py プロジェクト: jasonamyers/cagenix-web
def users_delete(id):
    """This function handles the /users/delete endpoint for the blueprint

    It allows PNT-Admins to delete a user.  It is called via a button on
    the ``users/edit.html`` template

    :param id: The id of the user being deleted
    :type id: int
    :returns: users.users_home
    :rtype: redirect
    """
    user = User.by_id(id)
    if not user:
        abort(404)
    db.session.delete(user)
    db.session.commit()
    return redirect(url_for('users.users_home'))
コード例 #9
0
ファイル: test_api.py プロジェクト: jasonamyers/cagenix-web
 def setup_method(self, method):
     """ setup any state tied to the execution of the given method in a
     class.  setup_method is invoked for every test method of a class.
     """
     os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
     from cagenix import db
     from cagenix.users.models import User
     from cagenix.practices.models import Practice
     from cagenix.patients.models import Patient
     self.practice = Practice(practice_name='Cookie Dental Clinic', address_one='123 Cookie Lane', city='Cookieville', state='TN', zip_code='37037', phone='+16155555555', active=True)
     db.session.add(self.practice)
     db.session.commit()
     self.user = User(first_name='Chocolate', last_name='Chip', email='*****@*****.**', activation_code='DPJE3XFBVM271HC', password=encrypt_password('cookies'))
     self.user.gen_secret()
     self.user.activated = True
     db.session.add(self.user)
     db.session.commit()
     self.patient = Patient(first_name='Chocolate', last_name='Chip', address_one='123 Cookie Lane', city='Cookieville', state='TN', zip_code='37201', email='[email protected]', practice=self.practice, dentist=self.user)
     db.session.add(self.patient)
     db.session.commit()
コード例 #10
0
ファイル: views.py プロジェクト: jasonamyers/cagenix-web
def users_edit(id):
    """This function handles the /users/edit endpoint for the bcornerstone/users/views.py

    It allows PNT-Admins to edit users.  It uses the :ref:`users-forms-label`
    to display UsersEditForm

    :param id: The id of the user being edited
    :type id: int
    :returns: users/edit.html
    :rtype: template
    """
    user = User.by_id(id)
    if not user:
        abort(404)

    form = UserEditForm(obj=user)
    if form.validate_on_submit():
        form.populate_obj(user)
        db.session.add(user)
        db.session.commit()
        return redirect(url_for('users.users_home'))
    return render_template('users/edit.html', form=form, user_id=user.id, admin=True)
コード例 #11
0
        def decorated_function(*args, **kwargs):
            ''' authenticate_request validates the use of the provided credentials.
            It cycles through a tuple of required_headers and checks the presence
            of each header for validation. It then validates the licensekey and
            will allow the consumer to use the decorated handler
            '''
            user = User.by_email(request.args.get('email'))
            if not user or not user.active or not user.activated:
                response = jsonify(request=None, response={'error': 'Invalid Practitioner'})
                response.status_code = 403
                return response

            query_string = urlparse(request.url).query

            is_valid_sig, message = check_signature(user.secret, query_string)

            if not is_valid_sig:
                response = jsonify(request=None, response={'error': 'Invalid Practitioner'})
                response.status_code = 403
                return response

            return f(*args, **kwargs)
コード例 #12
0
ファイル: views.py プロジェクト: jasonamyers/cagenix-web
def users_changepassword(id):
    """This function handles the /users/changepassword endpoint for the blueprint

    It allows PNT-Admins to change a users password.  It uses the
    :ref:`users-forms-label` to display UsersChangePasswordForm

    :param id: The id of the user being edited
    :type id: int
    :returns: users/change_password.html
    :rtype: template
    """
    user = User.by_id(id)
    if not user:
        abort(404)

    form = UserChangePasswordForm(obj=user)
    if form.validate_on_submit():
        form.populate_obj(user)
        user.password = encrypt_password(user.password)
        db.session.add(user)
        db.session.commit()
        return redirect(url_for('users.users_home'))
    return render_template('users/change_password.html', form=form, user_id=user.id, admin=True)
コード例 #13
0
ファイル: controller.py プロジェクト: jasonamyers/cagenix-web
def practitioners_create(*args, **kwargs):
    if request.method == 'POST':
        data = json.loads(request.data)
        user = User.by_email(data['email'])
        if not user or user.activated:
            response = jsonify(
                request=request.json,
                response={'error': 'Practitioner or Activiation Code does not exist.'})
            response.status_code = 404
            return response

        if not user.activation_code == data['activation_code']:
            response = jsonify(
                request=request.json,
                response={'error': 'Bad activation code.'})
            response.status_code = 401
            return response
        else:
            user.map_data(data)
            user.password = encrypt_password(data['password'])
            user.gen_secret()
            user.activated = True
            db.session.add(user)
            db.session.commit()
            data.pop('password')
            response = jsonify(
                request=data,
                response={'practitioner_id': user.id})
            response.status_code = 201
            return response
    else:
        response = jsonify(
            request=request.json,
            response={'error': 'This request type not supported'})
        response.status_code = 400
        return response
コード例 #14
0
ファイル: test_api.py プロジェクト: jasonamyers/cagenix-web
class TestPractitionersAPI:
    api_url_base = 'http://127.0.0.1:5000/api/v1/practitioners/'
    bad_data = {'cookies': 'cookies'}
    bad_headers_bad_content_type = {'cookies': 'cookies'}
    bad_headers_good_content_type = {'content-type': 'application/json'}
    bad_data_type = {
        'first_name': 'Chocolate',
        'last_name': 'Chip',
        'address_one': '123 Cookie Lane',
        'address_two': '',
        'city': 'Cookieville',
        'state': 'TN',
        'zip_code': '37201',
        'email': '*****@*****.**',
        'password': '******',
        'activation_code': '0342QB6FWP9ZY5J',
        'primary_color': '',
        'secondary_color': '',
        'practice': '',
    }

    good_create_data = {
        'first_name': 'Chocolate',
        'last_name': 'Chip',
        'address_one': '123 Cookie Lane',
        'city': 'Cookieville',
        'state': 'TN',
        'zip_code': '37201',
        'email': '*****@*****.**',
        'password': '******',
        'activation_code': 'DPJE3XFBVM271HC',
    }

    good_edit_data = {
        'first_name': 'Chocolate',
        'last_name': 'Chip',
        'address_one': '123 Cookie Lane',
        'city': 'Cookieville2',
        'state': 'TN',
        'zip_code': '37201',
        'email': '*****@*****.**',
    }

    bad_auth_data = {
        'email': '*****@*****.**',
        'password': '******',
    }

    good_auth_data = {
        'email': '*****@*****.**',
        'password': '******',
    }

    def setup_method(self, method):
        """ setup any state tied to the execution of the given method in a
        class.  setup_method is invoked for every test method of a class.
        """
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        from cagenix.users.models import User

        self.user = User(first_name='Chocolate', last_name='Chip', email='*****@*****.**', activation_code='DPJE3XFBVM271HC', password=encrypt_password('cookies'))
        self.user.gen_secret()
        db.session.add(self.user)
        db.session.commit()

    def teardown_method(self, method):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        from cagenix.users.models import User

        user = User.by_email('*****@*****.**')
        if user:
            db.session.delete(user)
            db.session.commit()

    def test_bad_method(self):
        url = self.api_url_base + 'create'
        request = requests.get(url, headers=self.bad_headers_bad_content_type, data=self.bad_data)
        assert request.status_code == 403

    def test_bad_or_no_content_type(self):
        url = self.api_url_base + 'create'
        response = {
            'request': None,
            'response': {
                'error': 'Content-type not set or Content-type not application/json'
            }
        }
        request = requests.post(url, headers=self.bad_headers_bad_content_type, data=self.bad_data)
        assert request.status_code == 405
        assert response == json.loads(request.text)

    def test_practitioner_create_bad_data(self):
        headers = {
            'content-type': 'application/json',
        }
        url = self.api_url_base + 'create'
        response = {
            'request': {
                'cookies': 'cookies'
            },
            'response': {
                'error': "additional property 'cookies' not defined by 'properties' or 'patternProperties' are not allowed in field '_data'"
            }
        }
        status_code, request = make_post_request(headers, self.bad_data, url)
        assert status_code == 400
        assert response == json.loads(request)

    def test_practitioner_create_bad_data_type(self):
        headers = {
            'content-type': 'application/json',
        }
        url = self.api_url_base + 'create'
        response = {
            'request': {
                'activation_code': '0342QB6FWP9ZY5J',
                'address_one': '123 Cookie Lane',
                'address_two': '',
                'city': 'Cookieville',
                'email': '*****@*****.**',
                'first_name': 'Chocolate',
                'last_name': 'Chip',
                'practice': '',
                'primary_color': '',
                'secondary_color': '',
                'state': 'TN',
                'zip_code': '37201'
            },
            'response': {
                'error': "Value u'' for field 'practice' is not of type integer"
            }
        }
        status_code, request = make_post_request(headers, self.bad_data_type, url)
        assert status_code == 400
        assert response == json.loads(request)

    def test_practitioner_create(self):
        headers = {
            'content-type': 'application/json',
        }
        url = self.api_url_base + 'create'
        response = {
            'request': {
                'first_name': 'Chocolate',
                'last_name': 'Chip',
                'address_one': '123 Cookie Lane',
                'city': 'Cookieville',
                'state': 'TN',
                'zip_code': '37201',
                'email': '*****@*****.**',
                'activation_code': 'DPJE3XFBVM271HC',
            },
            'response': {
                'practitioner_id': 2
            }
        }
        status_code, request = make_post_request(headers, self.good_create_data, url)
        assert status_code == 201
        assert response == json.loads(request)

    def test_practitioner_good_edit(self):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        self.user.activated = True
        db.session.add(self.user)
        db.session.commit()
        url = self.api_url_base + str(self.user.id)
        response = {
            'request': {
                'first_name': 'Chocolate',
                'last_name': 'Chip',
                'address_one': '123 Cookie Lane',
                'city': 'Cookieville2',
                'state': 'TN',
                'zip_code': '37201',
                'email': '*****@*****.**',
            },
            'response': {
                'practitioner_id': 2,
                'active': True
            }
        }
        headers = make_headers(self.good_edit_data, self.user.email, self.user.secret)
        status_code, request = make_put_request(headers, self.good_edit_data, url)
        assert status_code == 200
        assert response == json.loads(request)

    def test_practitioner_get(self):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        self.user.activated = True
        db.session.add(self.user)
        db.session.commit()
        url = self.api_url_base + str(self.user.id) + '?'
        response = {
            u'request': {
                u'practitioner_id': 2
            },
            u'response': {
                u'city': None,
                u'first_name': u'Chocolate',
                u'last_name': u'Chip',
                u'practice': None,
                u'secondary_color': None,
                u'address_two': None,
                u'primary_color': None,
                u'state': None,
                u'address_one': None,
                u'active': True,
                u'activation_code': u'DPJE3XFBVM271HC',
                u'email': u'*****@*****.**',
                u'zip_code': None
            }
        }
        status_code, request = make_get_request(self.user, url)
        assert status_code == 200
        assert response == json.loads(request)

    def test_practitioner_delete(self):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        self.user.activated = True
        db.session.add(self.user)
        db.session.commit()
        url = self.api_url_base + str(self.user.id)
        response = {
            'request': {
                'practitioner_id': self.user.id,
            },
            'response': {
                'status': 'Success',
            }
        }

        good_delete_data = {
            'practitioner_id': 2,
        }

        headers = make_headers(good_delete_data, self.user.email, self.user.secret)
        status_code, request = make_delete_request(headers, good_delete_data, url)
        assert status_code == 200
        assert response == json.loads(request)

    def test_practitioner_bad_login(self):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        self.user.activated = True
        db.session.add(self.user)
        db.session.commit()

        headers = {
            'content-type': 'application/json',
        }
        url = self.api_url_base + 'login'
        response = {
            'request': {
                'email': '*****@*****.**',
            },
            'response': {
                'error': 'Authentication Failed'
            }
        }
        status_code, request = make_post_request(headers, self.bad_auth_data, url)
        assert status_code == 401
        assert response == json.loads(request)

    def test_practitioner_good_login(self):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        self.user.activated = True
        db.session.add(self.user)
        db.session.commit()

        headers = {
            'content-type': 'application/json',
        }
        url = self.api_url_base + 'login'
        response = {
            'request': {
                'email': '*****@*****.**',
            },
            'response': {
                'secret': self.user.secret,
            }
        }
        status_code, request = make_post_request(headers, self.good_auth_data, url)
        assert status_code == 200
        assert response == json.loads(request)
コード例 #15
0
ファイル: test_api.py プロジェクト: jasonamyers/cagenix-web
class TestPatientsAPI:
    api_url_base = 'http://127.0.0.1:5000/api/v1/patients/'

    def setup_method(self, method):
        """ setup any state tied to the execution of the given method in a
        class.  setup_method is invoked for every test method of a class.
        """
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        from cagenix.users.models import User
        from cagenix.practices.models import Practice
        from cagenix.patients.models import Patient
        self.practice = Practice(practice_name='Cookie Dental Clinic', address_one='123 Cookie Lane', city='Cookieville', state='TN', zip_code='37037', phone='+16155555555', active=True)
        db.session.add(self.practice)
        db.session.commit()
        self.user = User(first_name='Chocolate', last_name='Chip', email='*****@*****.**', activation_code='DPJE3XFBVM271HC', password=encrypt_password('cookies'))
        self.user.gen_secret()
        self.user.activated = True
        db.session.add(self.user)
        db.session.commit()
        self.patient = Patient(first_name='Chocolate', last_name='Chip', address_one='123 Cookie Lane', city='Cookieville', state='TN', zip_code='37201', email='[email protected]', practice=self.practice, dentist=self.user)
        db.session.add(self.patient)
        db.session.commit()

    def teardown_method(self, method):
        os.environ['DATABASE_URL'] = 'sqlite:////tmp/test.db'
        from cagenix import db
        from cagenix.patients.models import Patient
        db.session.delete(self.practice)
        db.session.delete(self.user)

        patient = Patient.by_email('*****@*****.**')
        if patient:
            db.session.delete(patient)
        if self.patient:
            db.session.delete(self.patient)

        db.session.commit()

    def test_patient_create(self):
        url = self.api_url_base + 'create'
        good_create_data = {
            'first_name': 'Chocolate',
            'last_name': 'Chip',
            'address_one': '123 Cookie Lane',
            'city': 'Cookieville',
            'state': 'TN',
            'zip_code': '37201',
            'email': '*****@*****.**',
            'practice_id': self.practice.id,
            'dentist_id': self.user.id,
        }
        response = {
            'request': {
                u'city': u'Cookieville',
                u'first_name': u'Chocolate',
                u'last_name': u'Chip',
                u'dentist_id': 2,
                u'practice_id': 1,
                u'state': u'TN',
                u'address_one': u'123 Cookie Lane',
                u'email': u'*****@*****.**',
                u'zip_code': u'37201',
                u'practice_id': self.practice.id,
                u'dentist_id': self.user.id,
            },
            'response': {
                'patient_id': 2
            }
        }
        headers = make_headers(good_create_data, self.user.email, self.user.secret)
        status_code, request = make_post_request(headers, good_create_data, url)
        assert status_code == 201
        assert response == json.loads(request)

    def test_patient_delete(self):
        url = self.api_url_base + str(self.patient.id)
        response = {
            'request': {
                'patient_id': self.patient.id,
            },
            'response': {
                'status': 'Success',
            }
        }

        good_delete_data = {
            'patient_id': self.patient.id,
        }

        headers = make_headers(good_delete_data, self.user.email, self.user.secret)
        status_code, request = make_delete_request(headers, good_delete_data, url)
        assert status_code == 200
        assert response == json.loads(request)

    def test_patient_good_edit(self):
        url = self.api_url_base + str(self.patient.id)
        good_edit_data = {
            u'active': True,
            u'first_name': u'Chocolate',
            u'last_name': u'Chip',
            u'address_one': u'123 Cookie Lane',
            u'city': u'Cookieville',
            u'state': u'TN',
            u'zip_code': u'37201',
            u'email': u'[email protected]',
            u'choice_one': '',
            u'choice_two': '',
            u'choice_three': '',
            u'practice_id': 1,
            u'dentist_id': 2,
        }
        response = {
            'request': {
                u'active': True,
                u'first_name': u'Chocolate',
                u'last_name': u'Chip',
                u'address_one': u'123 Cookie Lane',
                u'city': u'Cookieville',
                u'state': u'TN',
                u'zip_code': u'37201',
                u'email': u'[email protected]',
                u'choice_one': '',
                u'choice_two': '',
                u'choice_three': '',
                u'practice_id': 1,
                u'dentist_id': 2,
            },
            'response': {
                'patient_id': 1,
                'active': True
            }
        }
        headers = make_headers(good_edit_data, self.user.email, self.user.secret)
        status_code, request = make_put_request(headers, good_edit_data, url)
        print json.loads(request)
        assert status_code == 200
        assert response == json.loads(request)

    def test_practitioner_get(self):
        url = self.api_url_base + str(self.patient.id) + '?'
        response = {
            u'request': {
                u'patient_id': 1
            },
            u'response': {
                u'active': True,
                u'first_name': u'Chocolate',
                u'last_name': u'Chip',
                u'address_one': u'123 Cookie Lane',
                u'address_two': None,
                u'city': u'Cookieville',
                u'state': u'TN',
                u'zip_code': u'37201',
                u'email': u'[email protected]',
                u'choice_one': None,
                u'choice_two': None,
                u'choice_three': None,
                u'practice': 1,
                u'practitioner': 2,
            }
        }
        status_code, request = make_get_request(self.user, url)
        assert status_code == 200
        assert response == json.loads(request)