This file is indexed.

/usr/lib/python2.7/dist-packages/osc_lib/api/auth.py is in python-osc-lib 1.9.0-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#   Licensed under the Apache License, Version 2.0 (the "License"); you may
#   not use this file except in compliance with the License. You may obtain
#   a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#   License for the specific language governing permissions and limitations
#   under the License.
#

"""Authentication Library"""

import argparse

from keystoneauth1.identity.v3 import k2k
from keystoneauth1.loading import base

from osc_lib import exceptions as exc
from osc_lib.i18n import _
from osc_lib import utils


# Initialize the list of Authentication plugins early in order
# to get the command-line options
PLUGIN_LIST = None

# List of plugin command line options
OPTIONS_LIST = {}


def get_plugin_list():
    """Gather plugin list and cache it"""

    global PLUGIN_LIST

    if PLUGIN_LIST is None:
        PLUGIN_LIST = base.get_available_plugin_names()
    return PLUGIN_LIST


def get_options_list():
    """Gather plugin options so the help action has them available"""

    global OPTIONS_LIST

    if not OPTIONS_LIST:
        for plugin_name in get_plugin_list():
            plugin_options = base.get_plugin_options(plugin_name)
            for o in plugin_options:
                os_name = o.name.lower().replace('_', '-')
                os_env_name = 'OS_' + os_name.upper().replace('-', '_')
                OPTIONS_LIST.setdefault(
                    os_name, {'env': os_env_name, 'help': ''},
                )
                # TODO(mhu) simplistic approach, would be better to only add
                # help texts if they vary from one auth plugin to another
                # also the text rendering is ugly in the CLI ...
                OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % (
                    plugin_name,
                    o.help,
                )
    return OPTIONS_LIST


def check_valid_authorization_options(options, auth_plugin_name):
    """Validate authorization options, and provide helpful error messages."""
    if (options.auth.get('project_id') and not
            options.auth.get('domain_id') and not
            options.auth.get('domain_name') and not
            options.auth.get('project_name') and not
            options.auth.get('tenant_id') and not
            options.auth.get('tenant_name')):
        raise exc.CommandError(_(
            'Missing parameter(s): '
            'Set either a project or a domain scope, but not both. Set a '
            'project scope with --os-project-name, OS_PROJECT_NAME, or '
            'auth.project_name. Alternatively, set a domain scope with '
            '--os-domain-name, OS_DOMAIN_NAME or auth.domain_name.'
        ))


def check_valid_authentication_options(options, auth_plugin_name):
    """Validate authentication options, and provide helpful error messages

    :param required_scope: indicate whether a scoped token is required

    """

    # Get all the options defined within the plugin.
    plugin_opts = base.get_plugin_options(auth_plugin_name)
    plugin_opts = {opt.dest: opt for opt in plugin_opts}

    # NOTE(aloga): this is an horrible hack. We need a way to specify the
    # required options in the plugins. Using the "required" argument for
    # the oslo_config.cfg.Opt does not work, as it is not possible to load the
    # plugin if the option is not defined, so the error will simply be:
    # "NoMatchingPlugin: The plugin foobar could not be found"
    msgs = []

    # when no auth params are passed in, user advised to use os-cloud
    if not options.auth:
        msgs.append(_(
            'Set a cloud-name with --os-cloud or OS_CLOUD'
        ))
    else:
        if 'password' in plugin_opts and not options.auth.get('username'):
            msgs.append(_(
                'Set a username with --os-username, OS_USERNAME,'
                ' or auth.username'
            ))
        if 'auth_url' in plugin_opts and not options.auth.get('auth_url'):
            msgs.append(_(
                'Set an authentication URL, with --os-auth-url,'
                ' OS_AUTH_URL or auth.auth_url'
            ))
        if 'url' in plugin_opts and not options.auth.get('url'):
            msgs.append(_(
                'Set a service URL, with --os-url, OS_URL or auth.url'
            ))
        if 'token' in plugin_opts and not options.auth.get('token'):
            msgs.append(_(
                'Set a token with --os-token, OS_TOKEN or auth.token'
            ))

    if msgs:
        raise exc.CommandError(
            _('Missing parameter(s): \n%s') % '\n'.join(msgs)
        )


def build_auth_plugins_option_parser(parser):
    """Auth plugins options builder

    Builds dynamically the list of options expected by each available
    authentication plugin.

    """
    available_plugins = list(get_plugin_list())
    parser.add_argument(
        '--os-auth-type',
        metavar='<auth-type>',
        dest='auth_type',
        default=utils.env('OS_AUTH_TYPE'),
        help=_('Select an authentication type. Available types: %s.'
               ' Default: selected based on --os-username/--os-token'
               ' (Env: OS_AUTH_TYPE)') % ', '.join(available_plugins),
        choices=available_plugins
    )
    # Maintain compatibility with old tenant env vars
    envs = {
        'OS_PROJECT_NAME': utils.env(
            'OS_PROJECT_NAME',
            default=utils.env('OS_TENANT_NAME')
        ),
        'OS_PROJECT_ID': utils.env(
            'OS_PROJECT_ID',
            default=utils.env('OS_TENANT_ID')
        ),
    }
    for o in get_options_list():
        # Remove tenant options from KSC plugins and replace them below
        if 'tenant' not in o:
            parser.add_argument(
                '--os-' + o,
                metavar='<auth-%s>' % o,
                dest=o.replace('-', '_'),
                default=envs.get(
                    OPTIONS_LIST[o]['env'],
                    utils.env(OPTIONS_LIST[o]['env']),
                ),
                help=_('%(help)s\n(Env: %(env)s)') % {
                    'help': OPTIONS_LIST[o]['help'],
                    'env': OPTIONS_LIST[o]['env'],
                },
            )
    # add tenant-related options for compatibility
    # this is deprecated but still used in some tempest tests...
    parser.add_argument(
        '--os-tenant-name',
        metavar='<auth-tenant-name>',
        dest='os_project_name',
        help=argparse.SUPPRESS,
    )
    parser.add_argument(
        '--os-tenant-id',
        metavar='<auth-tenant-id>',
        dest='os_project_id',
        help=argparse.SUPPRESS,
    )
    return parser


def get_keystone2keystone_auth(local_auth, service_provider,
                               project_id=None, project_name=None,
                               project_domain_id=None,
                               project_domain_name=None):
    """Return Keystone 2 Keystone authentication for service provider.

    :param local_auth: authentication to use with the local Keystone
    :param service_provider: service provider id as registered in Keystone
    :param project_id: project id to scope to in the service provider
    :param project_name: project name to scope to in the service provider
    :param project_domain_id: id of domain in the service provider
    :param project_domain_name: name of domain to in the service provider
    :return: Keystone2Keystone auth object for service provider
    """
    return k2k.Keystone2Keystone(local_auth,
                                 service_provider,
                                 project_id=project_id,
                                 project_name=project_name,
                                 project_domain_id=project_domain_id,
                                 project_domain_name=project_domain_name)