From e8ae7d3122801ab435cf90242445a81712e97c0e Mon Sep 17 00:00:00 2001 From: Roberto Mena <17350786+Angeluz-07@users.noreply.github.com> Date: Wed, 10 Feb 2021 11:03:34 -0500 Subject: [PATCH 1/3] build: TT-151 add build deps for cryptography package (#256) --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3fb32d00..20909f15 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM python:3.8-alpine +FROM python:3.9-alpine -ARG buildDeps='g++ gnupg curl libffi-dev openssl-dev' +ARG buildDeps='g++ gnupg curl libffi-dev openssl-dev musl-dev cargo' WORKDIR /usr/src/app From 45dbfb169d0981a518f3c7c2abf5addc4db28e5c Mon Sep 17 00:00:00 2001 From: roberto Date: Mon, 8 Feb 2021 16:06:03 -0500 Subject: [PATCH 2/3] feat: TT-147 add endpoint to retrieve user --- time_tracker_api/users/users_namespace.py | 10 ++++++++++ utils/azure_users.py | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/time_tracker_api/users/users_namespace.py b/time_tracker_api/users/users_namespace.py index 8cf181c2..e822c7e1 100644 --- a/time_tracker_api/users/users_namespace.py +++ b/time_tracker_api/users/users_namespace.py @@ -40,6 +40,16 @@ user_response_fields.update(common_fields) +@ns.route('/') +@ns.param('id', 'The unique identifier of the user') +class User(Resource): + @ns.doc('get_user') + @ns.marshal_list_with(user_response_fields) + def get(self, id): + """Get an user""" + return AzureConnection().get_user(id) + + @ns.route('') class Users(Resource): @ns.doc('list_users') diff --git a/utils/azure_users.py b/utils/azure_users.py index 9d3e4dce..279584b1 100644 --- a/utils/azure_users.py +++ b/utils/azure_users.py @@ -86,6 +86,14 @@ def get_token(self): error_info = f"{response['error']} {response['error_description']}" raise ValueError(error_info) + def get_user(self, user_id) -> AzureUser: + endpoint = "{endpoint}/users/{user_id}?api-version=1.6".format( + endpoint=self.config.ENDPOINT, user_id=user_id + ) + response = requests.get(endpoint, auth=BearerAuth(self.access_token)) + assert 200 == response.status_code + return self.to_azure_user(response.json()) + def users(self) -> List[AzureUser]: role_fields_params = ','.join( [field_name for field_name, _ in ROLE_FIELD_VALUES.values()] From 05fb6ef1b019e1a33ea0d0f7f15a1174194ae3f4 Mon Sep 17 00:00:00 2001 From: roberto Date: Mon, 8 Feb 2021 16:16:17 -0500 Subject: [PATCH 3/3] test: TT-147 add test for user namespace --- .../users/users_namespace_test.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/time_tracker_api/users/users_namespace_test.py b/tests/time_tracker_api/users/users_namespace_test.py index de61beb5..a7f7a985 100644 --- a/tests/time_tracker_api/users/users_namespace_test.py +++ b/tests/time_tracker_api/users/users_namespace_test.py @@ -1,10 +1,33 @@ from unittest.mock import Mock, patch from flask import json +from faker import Faker from flask.testing import FlaskClient from flask_restplus._http import HTTPStatus from pytest import mark +@patch('utils.azure_users.AzureConnection.get_msal_client', Mock()) +@patch('utils.azure_users.AzureConnection.get_token', Mock()) +@patch('utils.azure_users.AzureConnection.get_user') +def test_get_user_response_contains_expected_props( + get_user_mock, client: FlaskClient, valid_header: dict, +): + get_user_mock.return_value = { + 'name': 'dummy', + 'email': 'dummy', + 'roles': ['dummy-role'], + } + user_id = (Faker().uuid4(),) + response = client.get(f'/users/{user_id}', headers=valid_header) + + get_user_mock.assert_called() + assert HTTPStatus.OK == response.status_code + assert 'name' in json.loads(response.data) + assert 'email' in json.loads(response.data) + assert 'roles' in json.loads(response.data) + assert ['dummy-role'] == json.loads(response.data)['roles'] + + @patch('utils.azure_users.AzureConnection.get_msal_client', Mock()) @patch('utils.azure_users.AzureConnection.get_token', Mock()) @patch(