コード例 #1
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
    def test_get_project_permissions(self):
        mock_requests = MagicMock()
        page1 = {
            "results": [
                {
                    "project": {
                        "id": "8593ab3c-9999-11e8-9eb6-529269fb1459",
                    },
                    "user": {
                        "id": "8593aeac-9999-11e8-9eb6-529269fb1459",
                    },
                    "auth_role": {
                        "id": "project_admin",
                    }
                }
            ]
        }
        mock_requests.get.side_effect = [
            fake_response_with_pages(status_code=200, json_return_value=page1, num_pages=1),
        ]
        api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                             http=mock_requests)

        response = api.get_project_permissions(project_id='123')

        args, kwargs = mock_requests.get.call_args
        self.assertEqual(args[0], 'something.com/v1/projects/123/permissions/')
        results = response.json()['results']
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0]['project']['id'], '8593ab3c-9999-11e8-9eb6-529269fb1459')
        self.assertEqual(results[0]['user']['id'], '8593aeac-9999-11e8-9eb6-529269fb1459')
        self.assertEqual(results[0]['auth_role']['id'], 'project_admin')
コード例 #2
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_check_err_with_404_with_flag(self):
     resp = Mock(headers={}, status_code=404)
     resp.json.return_value = {"code": "resource_not_consistent"}
     url_suffix = ""
     data = None
     with self.assertRaises(DSResourceNotConsistentError):
         DataServiceApi._check_err(resp, url_suffix, data, allow_pagination=False)
コード例 #3
0
 def test_get_collection_one_page(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200,
                                  json_return_value={"results": [1, 2, 3]},
                                  num_pages=1)
     ]
     api = DataServiceApi(auth=None,
                          url="something.com/v1/",
                          http=mock_requests)
     response = api._get_collection(url_suffix="users",
                                    data={},
                                    content_type=ContentType.json)
     self.assertEqual([1, 2, 3], response.json()["results"])
     call_args_list = mock_requests.get.call_args_list
     self.assertEqual(1, len(call_args_list))
     # Check first request
     call_args = call_args_list[0]
     first_param = call_args[0][0]
     self.assertEqual('something.com/v1/users', first_param)
     dict_param = call_args[1]
     self.assertEqual('application/json',
                      dict_param['headers']['Content-Type'])
     self.assertIn("DukeDSClient/", dict_param['headers']['User-Agent'])
     self.assertIn('"per_page": 100', dict_param['params'])
コード例 #4
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_collection_two_pages(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200,
                                  json_return_value={"results": [1, 2, 3]},
                                  num_pages=2),
         fake_response_with_pages(status_code=200,
                                  json_return_value={"results": [4, 5]},
                                  num_pages=2)
     ]
     api = DataServiceApi(self.create_mock_auth(config_page_size=100), url="something.com/v1/", http=mock_requests)
     response = api._get_collection(url_suffix="projects", data={})
     self.assertEqual([1, 2, 3, 4, 5], response.json()["results"])
     call_args_list = mock_requests.get.call_args_list
     self.assertEqual(2, len(call_args_list))
     # Check first request
     call_args = call_args_list[0]
     first_param = call_args[0][0]
     self.assertEqual('something.com/v1/projects', first_param)
     dict_param = call_args[1]
     self.assertEqual('application/x-www-form-urlencoded', dict_param['headers']['Content-Type'])
     self.assertIn("DukeDSClient/", dict_param['headers']['User-Agent'])
     self.assertEqual(100, dict_param['params']['per_page'])
     self.assertEqual(1, dict_param['params']['page'])
     # Check second request
     call_args = call_args_list[1]
     first_param = call_args[0][0]
     self.assertEqual('something.com/v1/projects', first_param)
     dict_param = call_args[1]
     self.assertEqual('application/x-www-form-urlencoded', dict_param['headers']['Content-Type'])
     self.assertIn("DukeDSClient/", dict_param['headers']['User-Agent'])
     self.assertEqual(100, dict_param['params']['per_page'])
     self.assertEqual(2, dict_param['params']['page'])
コード例 #5
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_projects(self):
     page1 = {
         "results": [
             {
                 "id": "1234"
             }
         ]
     }
     page2 = {
         "results": [
             {
                 "id": "1235"
             }
         ]
     }
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value=page1, num_pages=2),
         fake_response_with_pages(status_code=200, json_return_value=page2, num_pages=2),
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                          http=mock_requests)
     resp = api.get_projects()
     self.assertEqual(2, len(resp.json()['results']))
     self.assertEqual("1234", resp.json()['results'][0]['id'])
     self.assertEqual("1235", resp.json()['results'][1]['id'])
     self.assertEqual(2, mock_requests.get.call_count)
     first_call_second_arg = mock_requests.get.call_args_list[0][1]
     self.assertEqual('application/x-www-form-urlencoded', first_call_second_arg['headers']['Content-Type'])
     self.assertEqual(100, first_call_second_arg['params']['per_page'])
     self.assertEqual(1, first_call_second_arg['params']['page'])
     second_call_second_arg = mock_requests.get.call_args_list[0][1]
     self.assertEqual(100, second_call_second_arg['params']['per_page'])
     self.assertEqual(1, second_call_second_arg['params']['page'])
コード例 #6
0
 def test_get_collection_two_pages(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200,
                       json_return_value={"results": [1, 2, 3]},
                       num_pages=2),
         fake_response_with_pages(status_code=200,
                       json_return_value={"results": [4, 5]},
                       num_pages=2)
     ]
     api = DataServiceApi(auth=None, url="something.com/v1/", http=mock_requests)
     response = api._get_collection(url_suffix="projects", data={}, content_type=ContentType.json)
     self.assertEqual([1, 2, 3, 4, 5], response.json()["results"])
     call_args_list = mock_requests.get.call_args_list
     self.assertEqual(2, len(call_args_list))
     # Check first request
     call_args = call_args_list[0]
     first_param = call_args[0][0]
     self.assertEqual('something.com/v1/projects', first_param)
     dict_param = call_args[1]
     self.assertEqual({'Content-Type': 'application/json'}, dict_param['headers'])
     self.assertIn('"per_page": 100', dict_param['params'])
     # Check second request
     call_args = call_args_list[1]
     first_param = call_args[0][0]
     self.assertEqual('something.com/v1/projects', first_param)
     dict_param = call_args[1]
     self.assertEqual({'Content-Type': 'application/json'}, dict_param['headers'])
     self.assertIn('"per_page": 100', dict_param['params'])
     self.assertIn('"page": 2', dict_param['params'])
コード例 #7
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_check_err_with_404(self):
     resp = Mock(headers={}, status_code=404)
     resp.json.return_value = {"code": "not_found"}
     url_suffix = ""
     data = None
     with self.assertRaises(DataServiceError):
         DataServiceApi._check_err(resp, url_suffix, data, allow_pagination=False)
コード例 #8
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_put_create_upload_url_invalid_number(self):
     mock_requests = MagicMock()
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100),
                          url="something.com/v1",
                          http=mock_requests)
     with self.assertRaises(ValueError) as raised_exception:
         api.create_upload_url(upload_id='someId', number=0, size=200, hash_value='somehash', hash_alg='md5')
     self.assertEqual(str(raised_exception.exception), "Chunk number must be > 0")
コード例 #9
0
 def test_get_single_page_works_on_paging_response(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value={"ok": True}, num_pages=3)
     ]
     api = DataServiceApi(auth=None, url="something.com/v1/", http=mock_requests)
     resp = api._get_single_page(url_suffix='stuff', data={}, content_type=ContentType.json, page_num=1)
     self.assertEqual(True, resp.json()['ok'])
コード例 #10
0
 def __init__(self, config):
     """
     Setup to allow fetching project tree.
     :param config: ddsc.config.Config settings to use for connecting to the dataservice.
     """
     self.config = config
     auth = DataServiceAuth(self.config)
     self.data_service = DataServiceApi(auth, self.config.url)
コード例 #11
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_single_page_works_on_paging_response(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value={"ok": True}, num_pages=3)
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1/",
                          http=mock_requests)
     resp = api._get_single_page(url_suffix='stuff', data={}, page_num=1)
     self.assertEqual(True, resp.json()['ok'])
コード例 #12
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_single_item_raises_error_on_paging_response(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value={}, num_pages=3)
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1/",
                          http=mock_requests)
     with self.assertRaises(UnexpectedPagingReceivedError):
         api._get_single_item(url_suffix='stuff', data={})
コード例 #13
0
 def test_get_single_item_raises_error_on_paging_response(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value={}, num_pages=3)
     ]
     api = DataServiceApi(auth=None, url="something.com/v1/", http=mock_requests)
     with self.assertRaises(ValueError) as er:
         resp = api._get_single_item(url_suffix='stuff', data={})
     self.assertEqual(UNEXPECTED_PAGING_DATA_RECEIVED, str(er.exception))
コード例 #14
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_folder(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response(status_code=200, json_return_value={})
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="base/v1", http=mock_requests)
     api.get_folder(folder_id='1023aef')
     mock_requests.get.assert_called()
     args, kw = mock_requests.get.call_args
     self.assertEqual(args[0], 'base/v1/folders/1023aef')
コード例 #15
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_auth_provider_affiliates_username(self):
     mock_requests, json_results = self.make_mock_requests_for_auth_provider_affiliates()
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                          http=mock_requests)
     result = api.get_auth_provider_affiliates('provider_id_123', username='******')
     self.assertEqual(200, result.status_code)
     self.assertEqual(json_results, result.json())
     mock_requests.get.assert_called_with('something.com/v1/auth_providers/provider_id_123/affiliates/',
                                          headers=ANY,
                                          params={'username': '******', 'page': 1, 'per_page': 100})
コード例 #16
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_delete_file(self):
     mock_requests = MagicMock()
     mock_requests.delete.side_effect = [
         fake_response(status_code=200, json_return_value={})
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="base/v1", http=mock_requests)
     api.delete_file(file_id='1023cde')
     mock_requests.delete.assert_called()
     args, kw = mock_requests.delete.call_args
     self.assertEqual(args[0], 'base/v1/files/1023cde')
コード例 #17
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_auth_provider(self):
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response(status_code=200, json_return_value={"ok": True})
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                          http=mock_requests)
     result = api.get_auth_provider('provider_id_123')
     self.assertEqual(200, result.status_code)
     mock_requests.get.assert_called_with('something.com/v1/auth_providers/provider_id_123/',
                                          headers=ANY, params=ANY)
コード例 #18
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_put_create_upload_url(self):
     mock_requests = MagicMock()
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100),
                          url="something.com/v1",
                          http=mock_requests)
     mock_response = {
         "id": "8593aeac-9999-11e8-9eb6-529269fb1459"
     }
     mock_requests.put.side_effect = [
         fake_response(status_code=200, json_return_value=mock_response),
     ]
     resp = api.create_upload_url(upload_id='someId', number=1, size=200, hash_value='somehash', hash_alg='md5')
     self.assertEqual(resp.json(), mock_response)
コード例 #19
0
 def test_get_project_transfers(self):
     return_value = {"results": [{"id": "1234"}]}
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200,
                                  json_return_value=return_value,
                                  num_pages=1)
     ]
     api = DataServiceApi(auth=None,
                          url="something.com/v1/",
                          http=mock_requests)
     resp = api.get_project_transfers(project_id='4521')
     self.assertEqual(1, len(resp.json()['results']))
     self.assertEqual("1234", resp.json()['results'][0]['id'])
コード例 #20
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_auth_provider_add_user(self):
     user = {
         "id": "abc4e9-9987-47eb-bb4e-19f0203efbf6",
         "username": "******",
     }
     mock_requests = MagicMock()
     mock_requests.post.side_effect = [
         fake_response(status_code=200, json_return_value=user)
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                          http=mock_requests)
     result = api.auth_provider_add_user('123', "joe")
     self.assertEqual(200, result.status_code)
     self.assertEqual(user, result.json())
     expected_url = 'something.com/v1/auth_providers/123/affiliates/joe/dds_user/'
     self.assertEqual(expected_url, mock_requests.post.call_args_list[0][0][0])
コード例 #21
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_all_project_transfers(self):
     return_value = {
         "results": [
             {"id": "abcd"},
             {"id": "efgh"}
         ]
     }
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value=return_value, num_pages=1)
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1/",
                          http=mock_requests)
     resp = api.get_all_project_transfers()
     self.assertEqual(2, len(resp.json()['results']))
     self.assertEqual("abcd", resp.json()['results'][0]['id'])
     self.assertEqual("efgh", resp.json()['results'][1]['id'])
コード例 #22
0
 def test_auth_provider_add_user(self):
     user = {
         "id": "abc4e9-9987-47eb-bb4e-19f0203efbf6",
         "username": "******",
     }
     mock_requests = MagicMock()
     mock_requests.post.side_effect = [
         fake_response(status_code=200, json_return_value=user)
     ]
     api = DataServiceApi(auth=None,
                          url="something.com/v1",
                          http=mock_requests)
     result = api.auth_provider_add_user('123', "joe")
     self.assertEqual(200, result.status_code)
     self.assertEqual(user, result.json())
     expected_url = 'something.com/v1/auth_providers/123/affiliates/joe/dds_user/'
     self.assertEqual(expected_url,
                      mock_requests.post.call_args_list[0][0][0])
コード例 #23
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_list_auth_roles(self):
     return_value = {
         "results": [
             {
                 "id": "project_admin",
                 "name": "Project Admin",
             }
         ]
     }
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value=return_value, num_pages=1)
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1/",
                          http=mock_requests)
     resp = api.get_auth_roles(context='')
     self.assertEqual(1, len(resp.json()['results']))
     self.assertEqual("Project Admin", resp.json()['results'][0]['name'])
コード例 #24
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
    def test_get_project_files(self):
        mock_requests = MagicMock()
        page1 = {
            "results": [
                {
                    "id": "1234"
                }
            ]
        }
        mock_requests.get.side_effect = [
            fake_response_with_pages(status_code=200, json_return_value=page1, num_pages=1),
        ]
        api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                             http=mock_requests)

        api.get_project_files(project_id='123')

        args, kwargs = mock_requests.get.call_args
        self.assertEqual(args[0], 'something.com/v1/projects/123/files')
コード例 #25
0
 def test_list_auth_roles(self):
     return_value = {
         "results": [{
             "id": "project_admin",
             "name": "Project Admin",
         }]
     }
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200,
                                  json_return_value=return_value,
                                  num_pages=1)
     ]
     api = DataServiceApi(auth=None,
                          url="something.com/v1/",
                          http=mock_requests)
     resp = api.get_auth_roles(context='')
     self.assertEqual(1, len(resp.json()['results']))
     self.assertEqual("Project Admin", resp.json()['results'][0]['name'])
コード例 #26
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_project_children(self):
     mock_requests = MagicMock()
     page1 = {
         "results": [
             {
                 "id": "1234"
             }
         ]
     }
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value=page1, num_pages=1),
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                          http=mock_requests)
     api.get_project_children(project_id='123', name_contains='test', exclude_response_fields=['this', 'that'])
     args, kwargs = mock_requests.get.call_args
     params = kwargs['params']
     self.assertEqual('test', params['name_contains'])
     self.assertEqual('this that', params['exclude_response_fields'])
コード例 #27
0
 def rebuild_data_service(config, data_service_auth_data):
     """
     Deserialize value into DataServiceApi object.
     :param config:
     :param data_service_auth_data:
     :return:
     """
     auth = DataServiceAuth(config)
     auth.set_auth_data(data_service_auth_data)
     return DataServiceApi(auth, config.url)
コード例 #28
0
    def authenticate(self, token):
        """
        Authenticate a user with a DukeDS API token. Returns None if no user could be authenticated,
        and sets the errors list with the reasons
        :param token: A JWT token
        :return: an authenticated, populated user if found, or None if not.
        """
        self.failure_reason = None
        # 1. check if token is valid for this purpose
        try:
            check_jwt_token(token)
        except InvalidTokenError as e:
            self.failure_reason = e
            # Token may be expired or may not be valid for this service, so return None
            return None

        # Token is a JWT and not expired
        # 2. Check if token exists in database
        user = get_local_user(token)
        if user:
            # token matched a user, return it
            return user

        # 3. Token appears valid but we have not seen it before.
        # Fetch user details from DukeDS

        config = make_auth_config(token)
        auth = DataServiceAuth(config)
        api = DataServiceApi(auth, config.url)
        try:
            response = api.get_current_user()
            response.raise_for_status()
            user_dict = response.json()
        except HTTPError as e:
            self.failure_reason = e
            return None
        # DukeDS shouldn't stomp over existing user details
        user = self.save_user(user_dict, False)

        # 4. Have a user, save their token
        save_dukeds_token(user, token)
        self.handle_new_user(user, user_dict)
        return user
コード例 #29
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
    def test_get_users_no_filtering(self):
        mock_requests = MagicMock()
        page1 = {
            "results": [
                {
                    "id": "8593aeac-9999-11e8-9eb6-529269fb1459"
                }
            ]
        }
        mock_requests.get.side_effect = [
            fake_response_with_pages(status_code=200, json_return_value=page1, num_pages=1),
        ]
        api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                             http=mock_requests)
        response = api.get_users()

        mock_requests.get.assert_called_with('something.com/v1/users', headers=ANY, params={'page': 1, 'per_page': 100})

        results = response.json()['results']
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0]['id'], '8593aeac-9999-11e8-9eb6-529269fb1459')
コード例 #30
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_create_upload(self):
     mock_requests = MagicMock()
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100),
                          url="something.com/v1",
                          http=mock_requests)
     mock_requests.post.return_value = fake_response(status_code=201, json_return_value={})
     api.create_upload(project_id='123', filename='data.txt', content_type='sometype', size=10,
                       hash_value='somehash', hash_alg='md5', storage_provider_id='abc456')
     expected_data = json.dumps({
         "name": "data.txt",
         "content_type": "sometype",
         "size": 10,
         "hash": {
             "value": "somehash",
             "algorithm": "md5"
         },
         "chunked": True,
         "storage_provider": {"id": "abc456"}
     })
     mock_requests.post.assert_called_with('something.com/v1/projects/123/uploads',
                                           expected_data,
                                           headers=ANY)
コード例 #31
0
 def test_get_auth_providers(self):
     provider = {
         "id": "aca35ba3-a44a-47c2-8b3b-afe43a88360d",
         "service_id": "cfde039d-f550-47e7-833c-9ebc4e257847",
         "name": "Duke Authentication Service",
         "is_deprecated": True,
         "is_default": True,
         "login_initiation_url": "https://someurl"
     }
     json_results = {"results": [provider]}
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200,
                                  json_return_value=json_results,
                                  num_pages=1)
     ]
     api = DataServiceApi(auth=None,
                          url="something.com/v1",
                          http=mock_requests)
     result = api.get_auth_providers()
     self.assertEqual(200, result.status_code)
     self.assertEqual(json_results, result.json())
     self.assertEqual('something.com/v1/auth_providers',
                      mock_requests.get.call_args_list[0][0][0])
コード例 #32
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_get_auth_providers(self):
     provider = {
         "id": "aca35ba3-a44a-47c2-8b3b-afe43a88360d",
         "service_id": "cfde039d-f550-47e7-833c-9ebc4e257847",
         "name": "Duke Authentication Service",
         "is_deprecated": True,
         "is_default": True,
         "login_initiation_url": "https://someurl"
     }
     json_results = {
         "results": [
             provider
         ]
     }
     mock_requests = MagicMock()
     mock_requests.get.side_effect = [
         fake_response_with_pages(status_code=200, json_return_value=json_results, num_pages=1)
     ]
     api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="something.com/v1",
                          http=mock_requests)
     result = api.get_auth_providers()
     self.assertEqual(200, result.status_code)
     self.assertEqual(json_results, result.json())
     self.assertEqual('something.com/v1/auth_providers', mock_requests.get.call_args_list[0][0][0])
コード例 #33
0
ファイル: fileuploader.py プロジェクト: benneely/DukeDSClient
def upload_async(data_service_auth_data, config, upload_id, filename, index,
                 num_chunks_to_send, progress_queue):
    """
    Method run in another process called from ParallelChunkProcessor.make_and_start_process.
    :param data_service_auth_data: tuple of auth data for rebuilding DataServiceAuth
    :param config: dds.Config configuration settings to use during upload
    :param upload_id: uuid unique id of the 'upload' we are uploading chunks into
    :param filename: str path to file who's contents we will be uploading
    :param index: int offset into filename where we will start sending bytes from (must multiply by upload_bytes_per_chunk)
    :param num_chunks_to_send: int number of chunks of config.upload_bytes_per_chunk size to send.
    :param progress_queue: ProgressQueue queue to send notifications of progress or errors
    """
    auth = DataServiceAuth(config)
    auth.set_auth_data(data_service_auth_data)
    data_service = DataServiceApi(auth, config.url)
    sender = ChunkSender(data_service, upload_id, filename,
                         config.upload_bytes_per_chunk, index,
                         num_chunks_to_send, progress_queue)
    return sender.send()
コード例 #34
0
class RemoteStore(object):
    """
    Fetches project tree data from remote store.
    """
    def __init__(self, config):
        """
        Setup to allow fetching project tree.
        :param config: ddsc.config.Config settings to use for connecting to the dataservice.
        """
        self.config = config
        auth = DataServiceAuth(self.config)
        self.data_service = DataServiceApi(auth, self.config.url)

    def fetch_remote_project(self,
                             project_name,
                             must_exist=False,
                             include_children=True):
        """
        Retrieve the project via project_name.
        :param project_name: str name of the project to try and download
        :param must_exist: should we error if the project doesn't exist
        :param include_children: should we read children(folders/files)
        :return: RemoteProject project requested or None if not found(and must_exist=False)
        """
        project = self._get_my_project(project_name)
        if project:
            if include_children:
                self._add_project_children(project)
        else:
            if must_exist:
                raise NotFoundError(
                    u'There is no project with the name {}'.format(
                        project_name).encode('utf-8'))
        return project

    def fetch_remote_project_by_id(self, id):
        """
        Retrieves project from via id
        :param id: str id of project from data service
        :return: RemoteProject we downloaded
        """
        response = self.data_service.get_project_by_id(id).json()
        return RemoteProject(response)

    def _get_my_project(self, project_name):
        """
        Return project tree root for project_name.
        :param project_name: str name of the project to download
        :return: RemoteProject project we found or None
        """
        response = self.data_service.get_projects().json()
        for project in response['results']:
            if project['name'] == project_name:
                return RemoteProject(project)
        return None

    def _add_project_children(self, project):
        """
        Add the rest of the project tree from the remote store to the project object.
        :param project: RemoteProject root of the project tree to add children too
        """
        response = self.data_service.get_project_children(project.id,
                                                          '').json()
        project_children = RemoteProjectChildren(project.id,
                                                 response['results'])
        for child in project_children.get_tree():
            project.add_child(child)

    def lookup_or_register_user_by_email_or_username(self, email, username):
        """
        Lookup user by email or username. Only fill in one field.
        For username it will try to register if not found.
        :param email: str: email address of the user
        :param username: netid of the user to find
        :return: RemoteUser
        """
        if username:
            return self.get_or_register_user_by_username(username)
        else:
            # API doesn't support registering user by email address yet
            return self.lookup_user_by_email(email)

    def lookup_user_by_name(self, full_name):
        """
        Query remote store for a single user with the name full_name or raise error.
        :param full_name: str Users full name separated by a space.
        :return: RemoteUser user info for single user with full_name
        """
        res = self.data_service.get_users_by_full_name(full_name)
        json_data = res.json()
        results = json_data['results']
        found_cnt = len(results)
        if found_cnt == 0:
            raise NotFoundError("User not found:" + full_name)
        elif found_cnt > 1:
            raise ValueError("Multiple users with name:" + full_name)
        user = RemoteUser(results[0])
        if user.full_name.lower() != full_name.lower():
            raise NotFoundError("User not found:" + full_name)
        return user

    def lookup_user_by_username(self, username):
        """
        Finds the single user who has this username or raises ValueError.
        :param username: str username we are looking for
        :return: RemoteUser: user we found
        """
        matches = [
            user for user in self.fetch_all_users()
            if user.username == username
        ]
        if not matches:
            raise NotFoundError('Username not found: {}.'.format(username))
        if len(matches) > 1:
            raise ValueError(
                'Multiple users with same username found: {}.'.format(
                    username))
        return matches[0]

    def get_or_register_user_by_username(self, username):
        """
        Try to lookup user by username. If not found try registering the user.
        :param username: str: username to lookup
        :return: RemoteUser: user we found
        """
        try:
            return self.lookup_user_by_username(username)
        except NotFoundError:
            return self.register_user_by_username(username)

    def register_user_by_username(self, username):
        """
        Tries to register user with the first non-deprecated auth provider.
        Raises ValueError if the data service doesn't have any non-deprecated providers.
        :param username: str: netid of the user we are trying to register
        :return: RemoteUser: user that was created for our netid
        """
        current_providers = [
            prov.id for prov in self.get_auth_providers()
            if not prov.is_deprecated
        ]
        if not current_providers:
            raise ValueError(
                "Unable to register user: no non-deprecated providers found!")
        auth_provider_id = current_providers[0]
        return self._register_user_by_username(auth_provider_id, username)

    def _register_user_by_username(self, auth_provider_id, username):
        """
        Tries to register a user who has a valid netid but isn't registered with DukeDS yet under auth_provider_id.
        :param auth_provider_id: str: id from RemoteAuthProvider to use for registering
        :param username: str: netid of the user we are trying to register
        :return: RemoteUser: user that was created for our netid
        """
        user_json = self.data_service.auth_provider_add_user(
            auth_provider_id, username).json()
        return RemoteUser(user_json)

    def get_auth_providers(self):
        """
        Return the list of authorization providers.
        :return: [RemoteAuthProvider]: list of remote auth providers
        """
        providers = []
        response = self.data_service.get_auth_providers().json()
        for data in response['results']:
            providers.append(RemoteAuthProvider(data))
        return providers

    def lookup_user_by_email(self, email):
        """
        Finds the single user who has this email or raises ValueError.
        :param email: str email we are looking for
        :return: RemoteUser user we found
        """
        matches = [
            user for user in self.fetch_all_users() if user.email == email
        ]
        if not matches:
            raise ValueError('Email not found: {}.'.format(email))
        if len(matches) > 1:
            raise ValueError(
                'Multiple users with same email found: {}.'.format(email))
        return matches[0]

    def get_current_user(self):
        """
        Fetch info about the current user
        :return: RemoteUser user who we are logged in as(auth determines this).
        """
        response = self.data_service.get_current_user().json()
        return RemoteUser(response)

    def fetch_all_users(self):
        """
        Retrieves all users from data service.
        :return: [RemoteUser] list of all users we downloaded
        """
        users = []
        result = self.data_service.get_all_users()
        user_list_json = result.json()
        for user_json in user_list_json['results']:
            users.append(RemoteUser(user_json))
        return users

    def fetch_user(self, id):
        """
        Retrieves user from data service having a specific id
        :param id: str id of user from data service
        :return: RemoteUser user we downloaded
        """
        response = self.data_service.get_user_by_id(id).json()
        return RemoteUser(response)

    def set_user_project_permission(self, project, user, auth_role):
        """
        Update remote store for user giving auth_role permissions on project.
        :param project: RemoteProject project to give permissions to
        :param user: RemoteUser user who we are giving permissions to
        :param auth_role: str type of authorization to give user(project_admin)
        """
        self.data_service.set_user_project_permission(project.id, user.id,
                                                      auth_role)

    def revoke_user_project_permission(self, project, user):
        """
        Update remote store for user removing auth_role permissions on project.
        :param project: RemoteProject project to remove permissions from
        :param user: RemoteUser user who we are removing permissions from
        """
        # Server errors out with 500 if a user isn't found.
        try:
            self.data_service.get_user_project_permission(project.id, user.id)
            self.data_service.revoke_user_project_permission(
                project.id, user.id)
        except DataServiceError as e:
            if e.status_code != 404:
                raise

    def download_file(self, remote_file, path, watcher):
        """
        Download a remote file associated with the remote uuid(file_id) into local path.
        :param remote_file: RemoteFile file to retrieve
        :param path: str file system path to save the contents to.
        :param watcher: object implementing send_item(item, increment_amt) that updates UI
        """
        url_json = self.data_service.get_file_url(remote_file.id).json()
        http_verb = url_json['http_verb']
        host = url_json['host']
        url = url_json['url']
        http_headers = url_json['http_headers']
        response = self.data_service.receive_external(http_verb, host, url,
                                                      http_headers)
        with open(path, 'wb') as f:
            for chunk in response.iter_content(
                    chunk_size=DOWNLOAD_FILE_CHUNK_SIZE):
                if chunk:  # filter out keep-alive new chunks
                    f.write(chunk)
                    watcher.transferring_item(remote_file,
                                              increment_amt=len(chunk))

    def get_project_names(self):
        """
        Return a list of names of the remote projects owned by this user.
        :return: [str]: the list of project names
        """
        names = []
        response = self.data_service.get_projects().json()
        for project in response['results']:
            names.append(project['name'])
        return names

    def delete_project_by_name(self, project_name):
        """
        Find the project named project_name and delete it raise error if not found.
        :param project_name: str: Name of the project we want to be deleted
        """
        project = self._get_my_project(project_name)
        if project:
            self.data_service.delete_project(project.id)
        else:
            raise ValueError(
                "No project named '{}' found.\n".format(project_name))

    def get_active_auth_roles(self, context):
        """
        Retrieve non-deprecated authorization roles based on a context.
        Context should be RemoteAuthRole.PROJECT_CONTEXT or RemoteAuthRole.SYSTEM_CONTEXT.
        :param context: str: context for which auth roles to retrieve
        :return: [RemoteAuthRole]: list of active auth_role objects
        """
        response = self.data_service.get_auth_roles(context).json()
        return self.get_active_auth_roles_from_json(response)

    @staticmethod
    def get_active_auth_roles_from_json(json_data):
        """
        Given a json blob response containing a list of authorization roles return the active ones
        in an array of RemoteAuthRole objects.
        :param json_data: list of dictionaries - data from dds in auth_role format
        :return: [RemoteAuthRole] list of active auth_role objects
        """
        result = []
        for auth_role_properties in json_data['results']:
            auth_role = RemoteAuthRole(auth_role_properties)
            if not auth_role.is_deprecated:
                result.append(auth_role)
        return result
コード例 #35
0
    def test_relations_methods(self):
        api = DataServiceApi(auth=None, url="base/v1/", http=MagicMock())
        api._get_collection = MagicMock()
        api._get_single_item = MagicMock()
        api._post = MagicMock()
        api._delete = MagicMock()

        # This endpoint is a little strange with using object_kind and relation types as magic values
        api.get_relations('dds-file', '123')
        api._get_collection.assert_called_with('/relations/dds-file/123', {})
        api.get_relation('124')
        api._get_single_item.assert_called_with('/relations/124/', {})

        api.create_used_relation('125', 'dds-file', '456')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '456'
            },
            'activity': {
                'id': '125'
            }
        }
        api._post.assert_called_with('/relations/used', payload)

        api.create_was_generated_by_relation('126', 'dds-file', '457')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '457'
            },
            'activity': {
                'id': '126'
            }
        }
        api._post.assert_called_with('/relations/was_generated_by', payload)

        api.create_was_generated_by_relation('126', 'dds-file', '457')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '457'
            },
            'activity': {
                'id': '126'
            }
        }
        api._post.assert_called_with('/relations/was_generated_by', payload)

        api.create_was_invalidated_by_relation('127', 'dds-file', '458')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '458'
            },
            'activity': {
                'id': '127'
            }
        }
        api._post.assert_called_with('/relations/was_invalidated_by', payload)

        api.create_was_derived_from_relation('128', 'dds-file', '129',
                                             'dds-file')
        payload = {
            'generated_entity': {
                'kind': 'dds-file',
                'id': '129'
            },
            'used_entity': {
                'kind': 'dds-file',
                'id': '128'
            }
        }
        api._post.assert_called_with('/relations/was_derived_from', payload)

        api.delete_relation('130')
        api._delete.assert_called_with('/relations/130/', {})
コード例 #36
0
 def test_constructor_creates_session_when_passed_none(self):
     api = DataServiceApi(auth=None, url="something.com/v1/", http=None)
     self.assertIsNotNone(api.http)
     self.assertEqual(type(api.http), requests.sessions.Session)
コード例 #37
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
    def test_relations_methods(self):
        api = DataServiceApi(auth=self.create_mock_auth(config_page_size=100), url="base/v1/", http=MagicMock())
        api._get_collection = MagicMock()
        api._get_single_item = MagicMock()
        api._post = MagicMock()
        api._delete = MagicMock()

        # This endpoint is a little strange with using object_kind and relation types as magic values
        api.get_relations('dds-file', '123')
        api._get_collection.assert_called_with('/relations/dds-file/123', {})
        api.get_relation('124')
        api._get_single_item.assert_called_with('/relations/124/', {})

        api.create_used_relation('125', 'dds-file', '456')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '456'
            }, 'activity': {
                'id': '125'
            }
        }
        api._post.assert_called_with('/relations/used', payload)

        api.create_was_generated_by_relation('126', 'dds-file', '457')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '457'
            }, 'activity': {
                'id': '126'
            }
        }
        api._post.assert_called_with('/relations/was_generated_by', payload)

        api.create_was_generated_by_relation('126', 'dds-file', '457')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '457'
            }, 'activity': {
                'id': '126'
            }
        }
        api._post.assert_called_with('/relations/was_generated_by', payload)

        api.create_was_invalidated_by_relation('127', 'dds-file', '458')
        payload = {
            'entity': {
                'kind': 'dds-file',
                'id': '458'
            }, 'activity': {
                'id': '127'
            }
        }
        api._post.assert_called_with('/relations/was_invalidated_by', payload)

        api.create_was_derived_from_relation('128', 'dds-file', '129', 'dds-file')
        payload = {
            'generated_entity': {
                'kind': 'dds-file',
                'id': '129'
            }, 'used_entity': {
                'kind': 'dds-file',
                'id': '128'
            }
        }
        api._post.assert_called_with('/relations/was_derived_from', payload)

        api.delete_relation('130')
        api._delete.assert_called_with('/relations/130/', {})
コード例 #38
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_check_err_with_good_response(self):
     resp = Mock(headers={}, status_code=202)
     url_suffix = ""
     data = None
     DataServiceApi._check_err(resp, url_suffix, data, allow_pagination=False)
コード例 #39
0
ファイル: test_ddsapi.py プロジェクト: Duke-GCB/DukeDSClient
 def test_check_err_with_400(self):
     resp = Mock(headers={}, status_code=400)
     url_suffix = ""
     data = None
     with self.assertRaises(DataServiceError):
         DataServiceApi._check_err(resp, url_suffix, data, allow_pagination=False)