-
Notifications
You must be signed in to change notification settings - Fork 241
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Commands for managing users in an org (#484)
* Add user list command * Show and remove user commands * User add and update command * Changes in add command and adding send-email-invite argument * Add a UT for user list * Some more UTs * Styling fixes * Minor * Pylint fix * Renaming access-level to license-type and resolcing PR comments * Minor table formatting * Pylint fix
- Loading branch information
Showing
6 changed files
with
262 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from azext_devops.vstsCompressed.member_entitlement_management.v4_1.models.models import (AccessLevel, | ||
GraphUser, | ||
JsonPatchOperation) | ||
from azext_devops.dev.common.services import (get_member_entitlement_management_client, | ||
resolve_instance) | ||
from azext_devops.dev.common.arguments import resolve_true_false | ||
from azext_devops.dev.common.identities import resolve_identity_as_id | ||
|
||
|
||
def get_user_entitlements(top=100, skip=None, organization=None, detect=None): | ||
"""List users for an organization. | ||
:param int top: Maximum number of the users to return. Max value is 10000. | ||
:param int skip: Offset: Number of records to skip. | ||
:rtype: [UserEntitlement] | ||
""" | ||
organization = resolve_instance(detect=detect, organization=organization) | ||
client = get_member_entitlement_management_client(organization) | ||
user_entitlements = client.get_user_entitlements(top=top, skip=skip) | ||
return user_entitlements | ||
|
||
|
||
def get_user_entitlement(user, organization=None, detect=None): | ||
"""Show user details. | ||
:param user: The Email id or UUID of the user. | ||
:type user: str | ||
:rtype: UserEntitlement | ||
""" | ||
organization = resolve_instance(detect=detect, organization=organization) | ||
if '@' in user: | ||
user = resolve_identity_as_id(user, organization) | ||
client = get_member_entitlement_management_client(organization) | ||
user_entitlement_details = client.get_user_entitlement(user_id=user) | ||
return user_entitlement_details | ||
|
||
|
||
def delete_user_entitlement(user, organization=None, detect=None): | ||
"""Remove user from an organization. | ||
:param user: The Email id or UUID of the user. | ||
:type user: str | ||
""" | ||
organization = resolve_instance(detect=detect, organization=organization) | ||
if '@' in user: | ||
user = resolve_identity_as_id(user, organization) | ||
client = get_member_entitlement_management_client(organization) | ||
delete_user_entitlement_details = client.delete_user_entitlement(user_id=user) | ||
return delete_user_entitlement_details | ||
|
||
|
||
def update_user_entitlement(user, license_type, organization=None, detect=None): | ||
"""Update license type for a user. | ||
:param user: The Email id or UUID of the user. | ||
:type user: str | ||
:param license_type: License type for the user. | ||
:type license_type: str | ||
:rtype: UserEntitlementsPatchResponse | ||
""" | ||
patch_document = [] | ||
value = {} | ||
value['accountLicenseType'] = license_type | ||
patch_document.append(_create_patch_operation('replace', '/accessLevel', value)) | ||
organization = resolve_instance(detect=detect, organization=organization) | ||
if '@' in user: | ||
user = resolve_identity_as_id(user, organization) | ||
client = get_member_entitlement_management_client(organization) | ||
user_entitlement_update = client.update_user_entitlement(document=patch_document, user_id=user) | ||
return user_entitlement_update.user_entitlement | ||
|
||
|
||
def add_user_entitlement(user, license_type, send_email_invite='true', organization=None, detect=None): | ||
"""Add user. | ||
:param user: The Email id of the user. | ||
:type user: str | ||
:param license_type: License type for the user. | ||
:type license_type: str | ||
:rtype: UserEntitlementsPatchResponse | ||
""" | ||
do_not_send_invite = False | ||
do_not_send_invite = not resolve_true_false(send_email_invite) | ||
organization = resolve_instance(detect=detect, organization=organization) | ||
client = get_member_entitlement_management_client(organization) | ||
user_access_level = AccessLevel() | ||
user_access_level.account_license_type = license_type | ||
graph_user = GraphUser() | ||
graph_user.subject_kind = 'user' | ||
graph_user.principal_name = user | ||
value = {} | ||
value['accessLevel'] = user_access_level | ||
value['extensions'] = [] | ||
value['projectEntitlements'] = [] | ||
value['user'] = graph_user | ||
patch_document = [] | ||
patch_document.append(_create_patch_operation('add', '', value)) | ||
user_entitlement_details = client.update_user_entitlements(document=patch_document, | ||
do_not_send_invite_for_new_users=do_not_send_invite) | ||
return user_entitlement_details.results[0].result | ||
|
||
|
||
def _create_patch_operation(op, path, value): | ||
patch_operation = JsonPatchOperation() | ||
patch_operation.op = op | ||
patch_operation.path = path | ||
patch_operation.value = value | ||
return patch_operation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
import unittest | ||
|
||
try: | ||
# Attempt to load mock (works on Python 3.3 and above) | ||
from unittest.mock import patch | ||
except ImportError: | ||
# Attempt to load mock (works on Python version below 3.3) | ||
from mock import patch | ||
|
||
from azext_devops.vstsCompressed.member_entitlement_management.v4_1.member_entitlement_management_client import (MemberEntitlementManagementClient) | ||
from azext_devops.dev.team.user import (get_user_entitlements, | ||
get_user_entitlement, | ||
add_user_entitlement, | ||
delete_user_entitlement, | ||
update_user_entitlement) | ||
|
||
from azext_devops.dev.common.services import clear_connection_cache | ||
|
||
|
||
class TestUserMethods(unittest.TestCase): | ||
|
||
_TEST_DEVOPS_ORGANIZATION = 'https://someorganization.visualstudio.com' | ||
_TEST_PROJECT_NAME = 'sample_project' | ||
_TOP_VALUE = 10 | ||
_SKIP_VALUE = 2 | ||
_OFF = 'Off' | ||
_TEST_USER_ID = 'adda517c-0398-42dc-b2a8-0d3f240757f9' | ||
_USER_MGMT_CLIENT_LOCATION = 'azext_devops.vstsCompressed.member_entitlement_management.v4_1.member_entitlement_management_client.MemberEntitlementManagementClient.' | ||
|
||
def setUp(self): | ||
self.get_client = patch('azext_devops.vstsCompressed.vss_connection.VssConnection.get_client') | ||
self.get_credential_patcher = patch('azext_devops.dev.common.services.get_credential') | ||
self.get_patch_op_patcher = patch('azext_devops.dev.team.user._create_patch_operation') | ||
self.list_user_patcher = patch(self._USER_MGMT_CLIENT_LOCATION + 'get_user_entitlements') | ||
self.get_user_patcher = patch(self._USER_MGMT_CLIENT_LOCATION + 'get_user_entitlement') | ||
self.add_user_patcher = patch(self._USER_MGMT_CLIENT_LOCATION + 'update_user_entitlements') | ||
self.remove_user_patcher = patch(self._USER_MGMT_CLIENT_LOCATION + 'delete_user_entitlement') | ||
self.update_user_patcher = patch(self._USER_MGMT_CLIENT_LOCATION + 'update_user_entitlement') | ||
|
||
self.mock_get_client = self.get_client.start() | ||
self.mock_get_users = self.list_user_patcher.start() | ||
self.mock_add_user = self.add_user_patcher.start() | ||
self.mock_get_user = self.get_user_patcher.start() | ||
self.mock_remove_user = self.remove_user_patcher.start() | ||
self.mock_update_user = self.update_user_patcher.start() | ||
self.mock_get_credential = self.get_credential_patcher.start() | ||
|
||
#set return values | ||
self.mock_get_client.return_value = MemberEntitlementManagementClient(base_url=self._TEST_DEVOPS_ORGANIZATION) | ||
|
||
#clear connection cache before running each test | ||
clear_connection_cache() | ||
|
||
def tearDown(self): | ||
patch.stopall() | ||
|
||
def test_list_user(self): | ||
get_user_entitlements(top=self._TOP_VALUE, skip=self._SKIP_VALUE, | ||
organization=self._TEST_DEVOPS_ORGANIZATION, detect=self._OFF) | ||
#assert | ||
self.mock_get_users.assert_called_once() | ||
list_user_param = self.mock_get_users.call_args_list[0][1] | ||
self.assertEqual(10,list_user_param['top']) | ||
self.assertEqual(2, list_user_param['skip']) | ||
|
||
def test_show_user(self): | ||
get_user_entitlement(user=self._TEST_USER_ID, organization=self._TEST_DEVOPS_ORGANIZATION, detect=self._OFF) | ||
#assert | ||
self.mock_get_user.assert_called_once_with(user_id = 'adda517c-0398-42dc-b2a8-0d3f240757f9') | ||
|
||
def test_add_user(self): | ||
add_user_entitlement(user='someuser@xyz.com', license_type='stakeholder', | ||
organization=self._TEST_DEVOPS_ORGANIZATION, detect=self._OFF) | ||
#assert | ||
self.mock_add_user.assert_called_once() | ||
add_user_param = self.mock_add_user.call_args_list[0][1] | ||
add_user_param_document = add_user_param['document'][0].value | ||
self.assertEqual(False, add_user_param['do_not_send_invite_for_new_users']) | ||
self.assertEqual('stakeholder', add_user_param_document['accessLevel'].account_license_type) | ||
self.assertEqual('user', add_user_param_document['user'].subject_kind) | ||
self.assertEqual('someuser@xyz.com', add_user_param_document['user'].principal_name) | ||
|
||
def test_remove_user(self): | ||
delete_user_entitlement(user=self._TEST_USER_ID, organization= self._TEST_DEVOPS_ORGANIZATION, detect=self._OFF) | ||
#assert | ||
self.mock_remove_user.assert_called_once() | ||
|
||
def test_update_user(self): | ||
update_user_entitlement(user=self._TEST_USER_ID, license_type='express', | ||
organization=self._TEST_DEVOPS_ORGANIZATION, detect=self._OFF) | ||
#assert | ||
self.mock_update_user.assert_called_once() | ||
update_user_param = self.mock_update_user.call_args_list[0][1] | ||
update_user_param_document = update_user_param['document'][0].value | ||
print(update_user_param_document) | ||
self.assertEqual('express', update_user_param_document['accountLicenseType']) | ||
self.assertEqual('adda517c-0398-42dc-b2a8-0d3f240757f9', update_user_param['user_id']) | ||
|