blob: 33ee666f6837e772f785c31c217fe6014a02ac4d [file] [log] [blame]
DavidPurcellb25f93d2017-01-27 12:46:27 -05001# Copyright 2017 AT&T Corporation.
DavidPurcell029d8c32017-01-06 15:27:41 -05002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Felipe Monteirob0595652017-01-23 16:51:58 -050016import logging
17
DavidPurcell029d8c32017-01-06 15:27:41 -050018from tempest import config
19from tempest.lib import exceptions
raiesmh088590c0c2017-03-14 18:06:52 +053020from tempest import test
DavidPurcell029d8c32017-01-06 15:27:41 -050021
22from patrole_tempest_plugin import rbac_auth
23from patrole_tempest_plugin import rbac_exceptions
24
25CONF = config.CONF
26LOG = logging.getLogger(__name__)
27
28
Rick Bartra12998942017-03-17 17:35:45 -040029def action(service, rule, expected_error_code=403):
DavidPurcell029d8c32017-01-06 15:27:41 -050030 def decorator(func):
31 def wrapper(*args, **kwargs):
Felipe Monteirocbd06172017-01-24 13:49:16 -050032 try:
raiesmh088590c0c2017-03-14 18:06:52 +053033 caller_ref = None
34 if args and isinstance(args[0], test.BaseTestCase):
35 caller_ref = args[0]
36 tenant_id = caller_ref.auth_provider.credentials.tenant_id
37 user_id = caller_ref.auth_provider.credentials.user_id
38 except AttributeError as e:
Felipe Monteiro889264e2017-03-01 17:19:35 -050039 msg = ("{0}: tenant_id/user_id not found in "
Felipe Monteirocbd06172017-01-24 13:49:16 -050040 "cls.auth_provider.credentials".format(e))
41 LOG.error(msg)
42 raise rbac_exceptions.RbacResourceSetupFailed(msg)
raiesmh088590c0c2017-03-14 18:06:52 +053043
Felipe Monteiro889264e2017-03-01 17:19:35 -050044 authority = rbac_auth.RbacAuthority(tenant_id, user_id, service)
DavidPurcell029d8c32017-01-06 15:27:41 -050045 allowed = authority.get_permission(rule, CONF.rbac.rbac_test_role)
Rick Bartra12998942017-03-17 17:35:45 -040046 expected_exception, irregular_msg = _get_exception_type(
47 expected_error_code)
DavidPurcell029d8c32017-01-06 15:27:41 -050048
49 try:
50 func(*args)
Rick Bartra503c5572017-03-09 13:49:58 -050051 except rbac_exceptions.RbacInvalidService as e:
Felipe Monteiro48c913d2017-03-15 12:07:48 -040052 msg = ("%s is not a valid service." % service)
53 LOG.error(msg)
54 raise exceptions.NotFound(
55 "%s RbacInvalidService was: %s" %
56 (msg, e))
Rick Bartra12998942017-03-17 17:35:45 -040057 except expected_exception as e:
DavidPurcell029d8c32017-01-06 15:27:41 -050058 if allowed:
59 msg = ("Role %s was not allowed to perform %s." %
60 (CONF.rbac.rbac_test_role, rule))
61 LOG.error(msg)
62 raise exceptions.Forbidden(
63 "%s exception was: %s" %
64 (msg, e))
Rick Bartra12998942017-03-17 17:35:45 -040065 if irregular_msg:
66 LOG.warning(irregular_msg.format(rule, service))
DavidPurcell029d8c32017-01-06 15:27:41 -050067 except rbac_exceptions.RbacActionFailed as e:
68 if allowed:
69 msg = ("Role %s was not allowed to perform %s." %
70 (CONF.rbac.rbac_test_role, rule))
71 LOG.error(msg)
72 raise exceptions.Forbidden(
73 "%s RbacActionFailed was: %s" %
74 (msg, e))
75 else:
76 if not allowed:
77 LOG.error("Role %s was allowed to perform %s" %
78 (CONF.rbac.rbac_test_role, rule))
79 raise rbac_exceptions.RbacOverPermission(
80 "OverPermission: Role %s was allowed to perform %s" %
81 (CONF.rbac.rbac_test_role, rule))
raiesmh088590c0c2017-03-14 18:06:52 +053082 finally:
83 caller_ref.rbac_utils.switch_role(caller_ref,
84 switchToRbacRole=False)
DavidPurcell029d8c32017-01-06 15:27:41 -050085 return wrapper
86 return decorator
Rick Bartra12998942017-03-17 17:35:45 -040087
88
89def _get_exception_type(expected_error_code):
90 expected_exception = None
91 irregular_msg = None
92 supported_error_codes = [403, 404]
93 if expected_error_code == 403:
94 expected_exception = exceptions.Forbidden
95 elif expected_error_code == 404:
96 expected_exception = exceptions.NotFound
97 irregular_msg = ("NotFound exception was caught for policy action "
98 "{0}. The service {1} throws a 404 instead of a 403, "
99 "which is irregular.")
100 else:
101 msg = ("Please pass an expected error code. Currently "
102 "supported codes: {0}".format(str(supported_error_codes)))
103 LOG.error(msg)
104 raise rbac_exceptions.RbacInvalidErrorCode()
105
106 return expected_exception, irregular_msg