Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: TT-154 add is user member of a group endpoint
  • Loading branch information
PaulRC-ioet committed Feb 18, 2021
commit 68eb7b7cabf07615ac38b5f451011f882a7ba484
40 changes: 35 additions & 5 deletions tests/time_tracker_api/users/users_namespace_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
@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,
client: FlaskClient,
valid_header: dict,
):
get_user_mock.return_value = {
'name': 'dummy',
Expand All @@ -35,7 +37,9 @@ def test_get_user_response_contains_expected_props(
)
@patch('utils.azure_users.AzureConnection.users')
def test_users_response_contains_expected_props(
users_mock, client: FlaskClient, valid_header: dict,
users_mock,
client: FlaskClient,
valid_header: dict,
):
users_mock.return_value = [
{'name': 'dummy', 'email': 'dummy', 'roles': ['dummy-role']}
Expand All @@ -54,7 +58,8 @@ def test_users_response_contains_expected_props(
@patch('utils.azure_users.AzureConnection.get_token', Mock())
@patch('utils.azure_users.AzureConnection.update_role')
@mark.parametrize(
'role_id,action', [('test', 'grant'), ('admin', 'revoke')],
'role_id,action',
[('test', 'grant'), ('admin', 'revoke')],
)
def test_update_role_response_contains_expected_props(
update_role_mock,
Expand All @@ -70,7 +75,8 @@ def test_update_role_response_contains_expected_props(
'roles': [],
}
response = client.post(
f'/users/{user_id}/roles/{role_id}/{action}', headers=valid_header,
f'/users/{user_id}/roles/{role_id}/{action}',
headers=valid_header,
)
assert HTTPStatus.OK == response.status_code
assert 'name' in json.loads(response.data)
Expand Down Expand Up @@ -101,10 +107,34 @@ def test_update_role_is_called_properly_on_each_action(
):
update_role_mock.return_value = {}
response = client.post(
f'/users/{user_id}/roles/{role_id}/{action}', headers=valid_header,
f'/users/{user_id}/roles/{role_id}/{action}',
headers=valid_header,
)

assert HTTPStatus.OK == response.status_code
update_role_mock.assert_called_once_with(
user_id, role_id, is_grant=is_grant
)


@patch('utils.azure_users.AzureConnection.get_msal_client', Mock())
@patch('utils.azure_users.AzureConnection.get_token', Mock())
@patch('utils.azure_users.AzureConnection.is_user_in_group')
@mark.parametrize(
'group_name, expected_value', [('admin', True), ('admin', False)]
)
def test_if_user_is_in_group(
is_user_in_group_mock,
client: FlaskClient,
valid_header: dict,
user_id: str,
group_name,
expected_value,
):
is_user_in_group_mock.return_value = {'value': expected_value}
response = client.get(
f'/users/{user_id}/groups/{group_name}/is-member-of',
headers=valid_header,
)
assert HTTPStatus.OK == response.status_code
assert 'value' in json.loads(response.data)
51 changes: 49 additions & 2 deletions tests/utils/azure_users_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
],
)
def test_azure_connection_is_test_user(
get_mock, field_name, field_value, is_test_user_expected_value,
get_mock,
field_name,
field_value,
is_test_user_expected_value,
):
response_mock = Mock()
response_mock.status_code = 200
Expand All @@ -33,7 +36,12 @@ def test_azure_connection_get_test_user_ids(get_mock):
response_mock = Mock()
response_mock.status_code = 200
response_mock.json = Mock(
return_value={'value': [{'objectId': 'ID1'}, {'objectId': 'ID2'},]}
return_value={
'value': [
{'objectId': 'ID1'},
{'objectId': 'ID2'},
]
}
)
get_mock.return_value = response_mock

Expand All @@ -56,3 +64,42 @@ def test_azure_connection_get_non_test_users(
non_test_users = [non_test_user]
az_conn = AzureConnection()
assert az_conn.get_non_test_users() == non_test_users


@patch('utils.azure_users.AzureConnection.get_msal_client', Mock())
@patch('utils.azure_users.AzureConnection.get_token', Mock())
@patch('requests.get')
def test_azure_connection_get_group_id_by_group_name(get_mock):
response_mock = Mock()
response_mock.status_code = 200
response_mock.json = Mock(return_value={'value': [{'objectId': 'ID1'}]})
get_mock.return_value = response_mock

group_id = 'ID1'
azure_connection = AzureConnection()
assert (
azure_connection.get_group_id_by_group_name('group_name') == group_id
)


@patch('utils.azure_users.AzureConnection.get_msal_client', Mock())
@patch('utils.azure_users.AzureConnection.get_token', Mock())
@patch('utils.azure_users.AzureConnection.get_group_id_by_group_name')
@patch('requests.post')
@mark.parametrize('expected_value', [True, False])
def test_is_user_in_group(
post_mock, get_group_id_by_group_name_mock, expected_value
):
response_expected = {'value': expected_value}
response_mock = Mock()
response_mock.status_code = 200
response_mock.json = Mock(return_value=response_expected)
post_mock.return_value = response_mock

get_group_id_by_group_name_mock.return_value = 'group_id'

azure_connection = AzureConnection()
assert (
azure_connection.is_user_in_group('user_id', 'group_name')
== response_expected
)
17 changes: 16 additions & 1 deletion time_tracker_api/users/users_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@
description='List of the roles assigned to the user by the tenant',
),
example=Faker().words(
3, ['time-tracker-admin', 'test-user', 'guest',],
3,
[
'time-tracker-admin',
'test-user',
'guest',
],
),
),
},
Expand Down Expand Up @@ -94,3 +99,13 @@ class RevokeRole(Resource):
def post(self, user_id, role_id):
"""Revoke role to user"""
return AzureConnection().update_role(user_id, role_id, is_grant=False)


@ns.route('/<string:user_id>/groups/<string:group_id>/is-member-of')
@ns.param('user_id', 'The user identifier')
@ns.param('group_id', 'The group name identifier')
class UserInGroup(Resource):
@ns.doc('user_in_group')
def get(self, user_id, group_id):
"""Is User in the Group"""
return AzureConnection().is_user_in_group(user_id, group_id)
34 changes: 34 additions & 0 deletions utils/azure_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,37 @@ def get_test_user_ids(self):
assert 200 == response.status_code
assert 'value' in response.json()
return [item['objectId'] for item in response.json()['value']]

def get_group_id_by_group_name(self, group_name):
endpoint_get_groups = "{endpoint}/groups?api-version=1.6&$select=objectId&$filter=displayName eq '{group_name}'".format(
endpoint=self.config.ENDPOINT, group_name=group_name
)

response_get_groups = requests.get(
endpoint_get_groups, auth=BearerAuth(self.access_token)
)

assert 200 == response_get_groups.status_code

return response_get_groups.json()['value'][0]['objectId']

def is_user_in_group(self, user_id, group_name):
group_id = self.get_group_id_by_group_name(group_name=group_name)

endpoint = "{endpoint}/isMemberOf?api-version=1.6".format(
endpoint=self.config.ENDPOINT
)

data = {"groupId": group_id, "memberId": user_id}

response = requests.post(
endpoint,
auth=BearerAuth(self.access_token),
data=json.dumps(data),
headers=HTTP_PATCH_HEADERS,
)

assert 200 == response.status_code

item = response.json()['value']
return {'value': item}