"Fossies" - the Fresh Open Source Software Archive

Member "keystone-17.0.0/keystone/tests/unit/test_v3_application_credential.py" (13 May 2020, 27269 Bytes) of package /linux/misc/openstack/keystone-17.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_v3_application_credential.py": 16.0.1_vs_17.0.0.

    1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
    2 # not use this file except in compliance with the License. You may obtain
    3 # a copy of the License at
    4 #
    5 #      http://www.apache.org/licenses/LICENSE-2.0
    6 #
    7 # Unless required by applicable law or agreed to in writing, software
    8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   10 # License for the specific language governing permissions and limitations
   11 # under the License.
   12 
   13 import datetime
   14 from testtools import matchers
   15 import uuid
   16 
   17 import http.client
   18 
   19 from keystone.common import provider_api
   20 import keystone.conf
   21 from keystone.tests import unit
   22 from keystone.tests.unit import test_v3
   23 
   24 
   25 CONF = keystone.conf.CONF
   26 PROVIDERS = provider_api.ProviderAPIs
   27 MEMBER_PATH_FMT = '/users/%(user_id)s/application_credentials/%(app_cred_id)s'
   28 
   29 
   30 class ApplicationCredentialTestCase(test_v3.RestfulTestCase):
   31     """Test CRUD operations for application credentials."""
   32 
   33     def config_overrides(self):
   34         super(ApplicationCredentialTestCase, self).config_overrides()
   35         self.config_fixture.config(group='auth',
   36                                    methods='password,application_credential')
   37 
   38     def _app_cred_body(self, roles=None, name=None, expires=None, secret=None,
   39                        access_rules=None):
   40         name = name or uuid.uuid4().hex
   41         description = 'Credential for backups'
   42         app_cred_data = {
   43             'name': name,
   44             'description': description
   45         }
   46         if roles:
   47             app_cred_data['roles'] = roles
   48         if expires:
   49             app_cred_data['expires_at'] = expires
   50         if secret:
   51             app_cred_data['secret'] = secret
   52         if access_rules is not None:
   53             app_cred_data['access_rules'] = access_rules
   54         return {'application_credential': app_cred_data}
   55 
   56     def test_create_application_credential(self):
   57         with self.test_client() as c:
   58             roles = [{'id': self.role_id}]
   59             app_cred_body = self._app_cred_body(roles=roles)
   60             token = self.get_scoped_token()
   61             resp = c.post(
   62                 '/v3/users/%s/application_credentials' % self.user_id,
   63                 json=app_cred_body,
   64                 expected_status_code=http.client.CREATED,
   65                 headers={'X-Auth-Token': token})
   66         # Create operation returns the secret
   67         self.assertIn('secret', resp.json['application_credential'])
   68         # But not the stored hash
   69         self.assertNotIn('secret_hash', resp.json['application_credential'])
   70 
   71     def test_create_application_credential_with_secret(self):
   72         with self.test_client() as c:
   73             secret = 'supersecuresecret'
   74             roles = [{'id': self.role_id}]
   75             app_cred_body = self._app_cred_body(roles=roles, secret=secret)
   76             token = self.get_scoped_token()
   77             resp = c.post(
   78                 '/v3/users/%s/application_credentials' % self.user_id,
   79                 json=app_cred_body,
   80                 expected_status_code=http.client.CREATED,
   81                 headers={'X-Auth-Token': token})
   82         self.assertEqual(secret, resp.json['application_credential']['secret'])
   83 
   84     def test_create_application_credential_roles_from_token(self):
   85         with self.test_client() as c:
   86             app_cred_body = self._app_cred_body()
   87             token = self.get_scoped_token()
   88             resp = c.post(
   89                 '/v3/users/%s/application_credentials' % self.user_id,
   90                 json=app_cred_body,
   91                 expected_status_code=http.client.CREATED,
   92                 headers={'X-Auth-Token': token})
   93             self.assertThat(resp.json['application_credential']['roles'],
   94                             matchers.HasLength(1))
   95             self.assertEqual(
   96                 resp.json['application_credential']['roles'][0]['id'],
   97                 self.role_id)
   98 
   99     def test_create_application_credential_wrong_user(self):
  100         wrong_user = unit.create_user(PROVIDERS.identity_api,
  101                                       test_v3.DEFAULT_DOMAIN_ID)
  102         with self.test_client() as c:
  103             roles = [{'id': self.role_id}]
  104             app_cred_body = self._app_cred_body(roles=roles)
  105             token = self.get_scoped_token()
  106             c.post('/v3/users/%s/application_credentials' % wrong_user['id'],
  107                    json=app_cred_body,
  108                    expected_status_code=http.client.FORBIDDEN,
  109                    headers={'X-Auth-Token': token})
  110 
  111     def test_create_application_credential_bad_role(self):
  112         with self.test_client() as c:
  113             roles = [{'id': uuid.uuid4().hex}]
  114             app_cred_body = self._app_cred_body(roles=roles)
  115             token = self.get_scoped_token()
  116             c.post('/v3/users/%s/application_credentials' % self.user_id,
  117                    json=app_cred_body,
  118                    expected_status_code=http.client.BAD_REQUEST,
  119                    headers={'X-Auth-Token': token})
  120 
  121     def test_create_application_credential_with_expiration(self):
  122         with self.test_client() as c:
  123             roles = [{'id': self.role_id}]
  124             expires = datetime.datetime.utcnow() + datetime.timedelta(days=365)
  125             expires = str(expires)
  126             app_cred_body = self._app_cred_body(roles=roles, expires=expires)
  127             token = self.get_scoped_token()
  128             c.post('/v3/users/%s/application_credentials' % self.user_id,
  129                    json=app_cred_body,
  130                    expected_status_code=http.client.CREATED,
  131                    headers={'X-Auth-Token': token})
  132 
  133     def test_create_application_credential_invalid_expiration_fmt(self):
  134         with self.test_client() as c:
  135             roles = [{'id': self.role_id}]
  136             expires = 'next tuesday'
  137             app_cred_body = self._app_cred_body(roles=roles, expires=expires)
  138             token = self.get_scoped_token()
  139             c.post('/v3/users/%s/application_credentials' % self.user_id,
  140                    json=app_cred_body,
  141                    expected_status_code=http.client.BAD_REQUEST,
  142                    headers={'X-Auth-Token': token})
  143 
  144     def test_create_application_credential_already_expired(self):
  145         with self.test_client() as c:
  146             roles = [{'id': self.role_id}]
  147             expires = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
  148             app_cred_body = self._app_cred_body(roles=roles, expires=expires)
  149             token = self.get_scoped_token()
  150             c.post('/v3/users/%s/application_credentials' % self.user_id,
  151                    json=app_cred_body,
  152                    expected_status_code=http.client.BAD_REQUEST,
  153                    headers={'X-Auth-Token': token})
  154 
  155     def test_create_application_credential_with_application_credential(self):
  156         with self.test_client() as c:
  157             roles = [{'id': self.role_id}]
  158             app_cred_body_1 = self._app_cred_body(roles=roles)
  159             token = self.get_scoped_token()
  160             app_cred_1 = c.post(
  161                 '/v3/users/%s/application_credentials' % self.user_id,
  162                 json=app_cred_body_1,
  163                 expected_status_code=http.client.CREATED,
  164                 headers={'X-Auth-Token': token})
  165             auth_data = self.build_authentication_request(
  166                 app_cred_id=app_cred_1.json['application_credential']['id'],
  167                 secret=app_cred_1.json['application_credential']['secret'])
  168             token_data = self.v3_create_token(
  169                 auth_data, expected_status=http.client.CREATED)
  170             app_cred_body_2 = self._app_cred_body(roles=roles)
  171             token = token_data.headers['x-subject-token']
  172             c.post('/v3/users/%s/application_credentials' % self.user_id,
  173                    json=app_cred_body_2,
  174                    expected_status_code=http.client.FORBIDDEN,
  175                    headers={'X-Auth-Token': token})
  176 
  177     def test_create_application_credential_with_trust(self):
  178         second_role = unit.new_role_ref(name='reader')
  179         PROVIDERS.role_api.create_role(second_role['id'], second_role)
  180         PROVIDERS.assignment_api.add_role_to_user_and_project(
  181             self.user_id, self.project_id, second_role['id'])
  182         with self.test_client() as c:
  183             pw_token = self.get_scoped_token()
  184             # create a self-trust - only the roles are important for this test
  185             trust_ref = unit.new_trust_ref(
  186                 trustor_user_id=self.user_id,
  187                 trustee_user_id=self.user_id,
  188                 project_id=self.project_id,
  189                 role_ids=[second_role['id']])
  190             resp = c.post('/v3/OS-TRUST/trusts',
  191                           headers={'X-Auth-Token': pw_token},
  192                           json={'trust': trust_ref})
  193             trust_id = resp.json['trust']['id']
  194             trust_auth = self.build_authentication_request(
  195                 user_id=self.user_id,
  196                 password=self.user['password'],
  197                 trust_id=trust_id)
  198             trust_token = self.v3_create_token(
  199                 trust_auth).headers['X-Subject-Token']
  200             app_cred = self._app_cred_body(roles=[{'id': self.role_id}])
  201             # only the roles from the trust token should be allowed, even if
  202             # the user has the role assigned on the project
  203             c.post('/v3/users/%s/application_credentials' % self.user_id,
  204                    headers={'X-Auth-Token': trust_token},
  205                    json=app_cred,
  206                    expected_status_code=http.client.BAD_REQUEST)
  207 
  208     def test_create_application_credential_allow_recursion(self):
  209         with self.test_client() as c:
  210             roles = [{'id': self.role_id}]
  211             app_cred_body_1 = self._app_cred_body(roles=roles)
  212             app_cred_body_1['application_credential']['unrestricted'] = True
  213             token = self.get_scoped_token()
  214             app_cred_1 = c.post(
  215                 '/v3/users/%s/application_credentials' % self.user_id,
  216                 json=app_cred_body_1,
  217                 expected_status_code=http.client.CREATED,
  218                 headers={'X-Auth-Token': token})
  219             auth_data = self.build_authentication_request(
  220                 app_cred_id=app_cred_1.json['application_credential']['id'],
  221                 secret=app_cred_1.json['application_credential']['secret'])
  222             token_data = self.v3_create_token(
  223                 auth_data, expected_status=http.client.CREATED)
  224             app_cred_body_2 = self._app_cred_body(roles=roles)
  225             c.post('/v3/users/%s/application_credentials' % self.user_id,
  226                    json=app_cred_body_2,
  227                    expected_status_code=http.client.CREATED,
  228                    headers={
  229                        'x-Auth-Token': token_data.headers['x-subject-token']})
  230 
  231     def test_create_application_credential_with_access_rules(self):
  232         roles = [{'id': self.role_id}]
  233         access_rules = [
  234             {
  235                 'path': '/v3/projects',
  236                 'method': 'POST',
  237                 'service': 'identity',
  238             }
  239         ]
  240         app_cred_body = self._app_cred_body(roles=roles,
  241                                             access_rules=access_rules)
  242         with self.test_client() as c:
  243             token = self.get_scoped_token()
  244             resp = c.post(
  245                 '/v3/users/%s/application_credentials' % self.user_id,
  246                 headers={'X-Auth-Token': token},
  247                 json=app_cred_body,
  248                 expected_status_code=http.client.CREATED)
  249             app_cred_id = resp.json['application_credential']['id']
  250             resp_access_rules = (
  251                 resp.json['application_credential']['access_rules'])
  252             access_rule_id = resp_access_rules[0].pop('id')
  253             self.assertEqual(access_rules[0], resp_access_rules[0])
  254             resp = c.get('/v3/users/%s/access_rules' % self.user_id,
  255                          headers={'X-Auth-Token': token})
  256             resp_access_rule = resp.json['access_rules'][0]
  257             resp_access_rule.pop('id')
  258             resp_access_rule.pop('links')
  259             self.assertEqual(access_rules[0], resp_access_rule)
  260             resp = c.get('/v3/users/%s/access_rules/%s' % (
  261                 self.user_id, access_rule_id), headers={'X-Auth-Token': token})
  262             resp_access_rule = resp.json['access_rule']
  263             resp_access_rule.pop('id')
  264             resp_access_rule.pop('links')
  265             self.assertEqual(access_rules[0], resp_access_rule)
  266             # can't delete an access rule in use
  267             c.delete('/v3/users/%s/access_rules/%s' % (
  268                      self.user_id, access_rule_id),
  269                      headers={'X-Auth-Token': token},
  270                      expected_status_code=http.client.FORBIDDEN)
  271             c.delete('/v3/users/%s/application_credentials/%s' % (
  272                      self.user_id, app_cred_id),
  273                      headers={'X-Auth-Token': token})
  274             c.delete('/v3/users/%s/access_rules/%s' % (
  275                      self.user_id, access_rule_id),
  276                      headers={'X-Auth-Token': token})
  277 
  278     def test_create_application_credential_with_duplicate_access_rule(self):
  279         roles = [{'id': self.role_id}]
  280         access_rules = [
  281             {
  282                 'path': '/v3/projects',
  283                 'method': 'POST',
  284                 'service': 'identity',
  285             }
  286         ]
  287         app_cred_body_1 = self._app_cred_body(roles=roles,
  288                                               access_rules=access_rules)
  289         with self.test_client() as c:
  290             token = self.get_scoped_token()
  291             resp = c.post(
  292                 '/v3/users/%s/application_credentials' % self.user_id,
  293                 headers={'X-Auth-Token': token},
  294                 json=app_cred_body_1,
  295                 expected_status_code=http.client.CREATED)
  296         resp_access_rules = resp.json['application_credential']['access_rules']
  297         self.assertIn('id', resp_access_rules[0])
  298         access_rule_id = resp_access_rules[0].pop('id')
  299         self.assertEqual(access_rules[0], resp_access_rules[0])
  300 
  301         app_cred_body_2 = self._app_cred_body(roles=roles,
  302                                               access_rules=access_rules)
  303         with self.test_client() as c:
  304             token = self.get_scoped_token()
  305             resp = c.post(
  306                 '/v3/users/%s/application_credentials' % self.user_id,
  307                 headers={'X-Auth-Token': token},
  308                 json=app_cred_body_2,
  309                 expected_status_code=http.client.CREATED)
  310         resp_access_rules = resp.json['application_credential']['access_rules']
  311         self.assertEqual(access_rule_id, resp_access_rules[0]['id'])
  312 
  313     def test_create_application_credential_with_access_rule_by_id(self):
  314         roles = [{'id': self.role_id}]
  315         access_rules = [
  316             {
  317                 'path': '/v3/projects',
  318                 'method': 'POST',
  319                 'service': 'identity',
  320             }
  321         ]
  322         app_cred_body_1 = self._app_cred_body(roles=roles,
  323                                               access_rules=access_rules)
  324         with self.test_client() as c:
  325             token = self.get_scoped_token()
  326             resp = c.post(
  327                 '/v3/users/%s/application_credentials' % self.user_id,
  328                 headers={'X-Auth-Token': token},
  329                 json=app_cred_body_1,
  330                 expected_status_code=http.client.CREATED)
  331         resp_access_rules = resp.json['application_credential']['access_rules']
  332         access_rule_id = resp_access_rules
  333         self.assertIn('id', resp_access_rules[0])
  334         access_rule_id = resp_access_rules[0].pop('id')
  335         self.assertEqual(access_rules[0], resp_access_rules[0])
  336 
  337         access_rules = [{'id': access_rule_id}]
  338         app_cred_body_2 = self._app_cred_body(roles=roles,
  339                                               access_rules=access_rules)
  340         with self.test_client() as c:
  341             token = self.get_scoped_token()
  342             resp = c.post(
  343                 '/v3/users/%s/application_credentials' % self.user_id,
  344                 headers={'X-Auth-Token': token},
  345                 json=app_cred_body_2,
  346                 expected_status_code=http.client.CREATED)
  347         resp_access_rules = resp.json['application_credential']['access_rules']
  348         self.assertEqual(access_rule_id, resp_access_rules[0]['id'])
  349 
  350     def test_list_application_credentials(self):
  351         with self.test_client() as c:
  352             token = self.get_scoped_token()
  353             resp = c.get('/v3/users/%s/application_credentials' % self.user_id,
  354                          expected_status_code=http.client.OK,
  355                          headers={'X-Auth-Token': token})
  356             self.assertEqual([], resp.json['application_credentials'])
  357             roles = [{'id': self.role_id}]
  358             app_cred_body = self._app_cred_body(roles=roles)
  359             c.post('/v3/users/%s/application_credentials' % self.user_id,
  360                    json=app_cred_body,
  361                    expected_status_code=http.client.CREATED,
  362                    headers={'X-Auth-Token': token})
  363             resp = c.get('/v3/users/%s/application_credentials' % self.user_id,
  364                          expected_status_code=http.client.OK,
  365                          headers={'X-Auth-Token': token})
  366             self.assertEqual(1, len(resp.json['application_credentials']))
  367             self.assertNotIn('secret', resp.json['application_credentials'][0])
  368             self.assertNotIn('secret_hash',
  369                              resp.json['application_credentials'][0])
  370             app_cred_body['application_credential']['name'] = 'two'
  371             c.post('/v3/users/%s/application_credentials' % self.user_id,
  372                    json=app_cred_body,
  373                    expected_status_code=http.client.CREATED,
  374                    headers={'X-Auth-Token': token})
  375             resp = c.get('/v3/users/%s/application_credentials' % self.user_id,
  376                          expected_status_code=http.client.OK,
  377                          headers={'X-Auth-Token': token})
  378             self.assertEqual(2, len(resp.json['application_credentials']))
  379             for ac in resp.json['application_credentials']:
  380                 self.assertNotIn('secret', ac)
  381                 self.assertNotIn('secret_hash', ac)
  382 
  383     def test_list_application_credentials_by_name(self):
  384         with self.test_client() as c:
  385             roles = [{'id': self.role_id}]
  386             app_cred_body = self._app_cred_body(roles=roles)
  387             token = self.get_scoped_token()
  388             name = app_cred_body['application_credential']['name']
  389             search_path = ('/v3/users/%(user_id)s/application_credentials?'
  390                            'name=%(name)s') % {'user_id': self.user_id,
  391                                                'name': name}
  392             resp = c.get(search_path,
  393                          expected_status_code=http.client.OK,
  394                          headers={'X-Auth-Token': token})
  395             self.assertEqual([], resp.json['application_credentials'])
  396             resp = c.post(
  397                 '/v3/users/%s/application_credentials' % self.user_id,
  398                 json=app_cred_body,
  399                 expected_status_code=http.client.CREATED,
  400                 headers={'X-Auth-Token': token})
  401             resp = c.get(search_path, expected_status_code=http.client.OK,
  402                          headers={'X-Auth-Token': token})
  403             self.assertEqual(1, len(resp.json['application_credentials']))
  404             self.assertNotIn('secret', resp.json['application_credentials'][0])
  405             self.assertNotIn('secret_hash',
  406                              resp.json['application_credentials'][0])
  407             app_cred_body['application_credential']['name'] = 'two'
  408             c.post('/v3/users/%s/application_credentials' % self.user_id,
  409                    json=app_cred_body,
  410                    expected_status_code=http.client.CREATED,
  411                    headers={'X-Auth-Token': token})
  412             resp = c.get(search_path, expected_status_code=http.client.OK,
  413                          headers={'X-Auth-Token': token})
  414             self.assertEqual(1, len(resp.json['application_credentials']))
  415             self.assertEqual(resp.json['application_credentials'][0]['name'],
  416                              name)
  417 
  418     def test_get_head_application_credential(self):
  419         with self.test_client() as c:
  420             roles = [{'id': self.role_id}]
  421             app_cred_body = self._app_cred_body(roles=roles)
  422             token = self.get_scoped_token()
  423             resp = c.post(
  424                 '/v3/users/%s/application_credentials' % self.user_id,
  425                 json=app_cred_body,
  426                 expected_status_code=http.client.CREATED,
  427                 headers={'X-Auth-Token': token})
  428             app_cred_id = resp.json['application_credential']['id']
  429             c.head('/v3%s' % MEMBER_PATH_FMT % {'user_id': self.user_id,
  430                                                 'app_cred_id': app_cred_id},
  431                    expected_status_code=http.client.OK,
  432                    headers={'X-Auth-Token': token})
  433             expected_response = resp.json
  434             expected_response['application_credential'].pop('secret')
  435             resp = c.get('/v3%s' % MEMBER_PATH_FMT % {'user_id': self.user_id,
  436                          'app_cred_id': app_cred_id},
  437                          expected_status_code=http.client.OK,
  438                          headers={'X-Auth-Token': token})
  439             self.assertDictEqual(resp.json, expected_response)
  440 
  441     def test_get_head_application_credential_not_found(self):
  442         with self.test_client() as c:
  443             token = self.get_scoped_token()
  444             c.head('/v3%s' % MEMBER_PATH_FMT % {'user_id': self.user_id,
  445                    'app_cred_id': uuid.uuid4().hex},
  446                    expected_status_code=http.client.NOT_FOUND,
  447                    headers={'X-Auth-Token': token})
  448             c.get('/v3%s' % MEMBER_PATH_FMT % {'user_id': self.user_id,
  449                   'app_cred_id': uuid.uuid4().hex},
  450                   expected_status_code=http.client.NOT_FOUND,
  451                   headers={'X-Auth-Token': token})
  452 
  453     def test_delete_application_credential(self):
  454         with self.test_client() as c:
  455             roles = [{'id': self.role_id}]
  456             app_cred_body = self._app_cred_body(roles=roles)
  457             token = self.get_scoped_token()
  458             resp = c.post(
  459                 '/v3/users/%s/application_credentials' % self.user_id,
  460                 json=app_cred_body,
  461                 expected_status_code=http.client.CREATED,
  462                 headers={'X-Auth-Token': token})
  463             app_cred_id = resp.json['application_credential']['id']
  464             c.delete('/v3%s' % MEMBER_PATH_FMT % {'user_id': self.user_id,
  465                      'app_cred_id': app_cred_id},
  466                      expected_status_code=http.client.NO_CONTENT,
  467                      headers={'X-Auth-Token': token})
  468 
  469     def test_delete_application_credential_not_found(self):
  470         with self.test_client() as c:
  471             token = self.get_scoped_token()
  472             c.delete('/v3%s' % MEMBER_PATH_FMT % {'user_id': self.user_id,
  473                      'app_cred_id': uuid.uuid4().hex},
  474                      expected_status_code=http.client.NOT_FOUND,
  475                      headers={'X-Auth-Token': token})
  476 
  477     def test_delete_application_credential_with_application_credential(self):
  478         with self.test_client() as c:
  479             roles = [{'id': self.role_id}]
  480             app_cred_body = self._app_cred_body(roles=roles)
  481             token = self.get_scoped_token()
  482             app_cred = c.post(
  483                 '/v3/users/%s/application_credentials' % self.user_id,
  484                 json=app_cred_body,
  485                 expected_status_code=http.client.CREATED,
  486                 headers={'X-Auth-Token': token})
  487             auth_data = self.build_authentication_request(
  488                 app_cred_id=app_cred.json['application_credential']['id'],
  489                 secret=app_cred.json['application_credential']['secret'])
  490             token_data = self.v3_create_token(
  491                 auth_data, expected_status=http.client.CREATED)
  492             member_path = '/v3%s' % MEMBER_PATH_FMT % {
  493                 'user_id': self.user_id,
  494                 'app_cred_id': app_cred.json['application_credential']['id']}
  495             token = token_data.headers['x-subject-token']
  496             c.delete(member_path,
  497                      json=app_cred_body,
  498                      expected_status_code=http.client.FORBIDDEN,
  499                      headers={'X-Auth-Token': token})
  500 
  501     def test_delete_application_credential_allow_recursion(self):
  502         with self.test_client() as c:
  503             roles = [{'id': self.role_id}]
  504             app_cred_body = self._app_cred_body(roles=roles)
  505             app_cred_body['application_credential']['unrestricted'] = True
  506             token = self.get_scoped_token()
  507             app_cred = c.post(
  508                 '/v3/users/%s/application_credentials' % self.user_id,
  509                 json=app_cred_body,
  510                 expected_status_code=http.client.CREATED,
  511                 headers={'X-Auth-Token': token})
  512             auth_data = self.build_authentication_request(
  513                 app_cred_id=app_cred.json['application_credential']['id'],
  514                 secret=app_cred.json['application_credential']['secret'])
  515             token_data = self.v3_create_token(
  516                 auth_data, expected_status=http.client.CREATED)
  517             member_path = '/v3%s' % MEMBER_PATH_FMT % {
  518                 'user_id': self.user_id,
  519                 'app_cred_id': app_cred.json['application_credential']['id']}
  520             c.delete(member_path,
  521                      json=app_cred_body,
  522                      expected_status_code=http.client.NO_CONTENT,
  523                      headers={
  524                          'x-Auth-Token': token_data.headers['x-subject-token']
  525                      })
  526 
  527     def test_update_application_credential(self):
  528         with self.test_client() as c:
  529             roles = [{'id': self.role_id}]
  530             app_cred_body = self._app_cred_body(roles=roles)
  531             token = self.get_scoped_token()
  532             resp = c.post(
  533                 '/v3/users/%s/application_credentials' % self.user_id,
  534                 json=app_cred_body,
  535                 expected_status_code=http.client.CREATED,
  536                 headers={'X-Auth-Token': token})
  537             # Application credentials are immutable
  538             app_cred_body['application_credential'][
  539                 'description'] = "New Things"
  540             app_cred_id = resp.json['application_credential']['id']
  541             # NOTE(morgan): when the whole test case is converted to using
  542             # flask test_client, this extra v3 prefix will
  543             # need to be rolled into the base MEMBER_PATH_FMT
  544             member_path = '/v3%s' % MEMBER_PATH_FMT % {
  545                 'user_id': self.user_id,
  546                 'app_cred_id': app_cred_id}
  547             c.patch(member_path,
  548                     json=app_cred_body,
  549                     expected_status_code=http.client.METHOD_NOT_ALLOWED,
  550                     headers={'X-Auth-Token': token})