This file is indexed.

/usr/lib/python2.7/dist-packages/murano/utils.py is in python-murano 1:2.0.0-1.

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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#    Copyright (c) 2013 Mirantis, Inc.
#
#    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.

import contextlib
import errno
import functools
import os

from oslo_concurrency import lockutils
from oslo_log import log as logging
from webob import exc

from murano.common.i18n import _
from murano.db import models
from murano.db.services import sessions
from murano.db import session as db_session
from murano.services import states

LOG = logging.getLogger(__name__)


def check_env(request, environment_id):
    unit = db_session.get_session()
    environment = unit.query(models.Environment).get(environment_id)
    if environment is None:
        msg = _('Environment with id {env_id}'
                ' not found').format(env_id=environment_id)
        LOG.error(msg)
        raise exc.HTTPNotFound(explanation=msg)

    if hasattr(request, 'context'):
        if environment.tenant_id != request.context.tenant:
            msg = _('User is not authorized to access'
                    ' these tenant resources')
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)
    return environment


def check_session(request, environment_id, session, session_id):
    """Validate, that a session is ok."""
    if session is None:
        msg = _('Session <SessionId {id}> is not found').format(id=session_id)
        LOG.error(msg)
        raise exc.HTTPNotFound(explanation=msg)

    if session.environment_id != environment_id:
        msg = _('Session <SessionId {session_id}> is not tied '
                'with Environment <EnvId {environment_id}>').format(
                    session_id=session_id,
                    environment_id=environment_id)
        LOG.error(msg)
        raise exc.HTTPBadRequest(explanation=msg)

    check_env(request, environment_id)


def verify_env(func):
    @functools.wraps(func)
    def __inner(self, request, environment_id, *args, **kwargs):
        check_env(request, environment_id)
        return func(self, request, environment_id, *args, **kwargs)
    return __inner


def verify_env_template(func):
    @functools.wraps(func)
    def __inner(self, request, env_template_id, *args, **kwargs):
        unit = db_session.get_session()
        template = unit.query(models.EnvironmentTemplate).get(env_template_id)
        if template is None:
            msg = _('Environment Template with id {id} not found'
                    ).format(id=env_template_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)

        if hasattr(request, 'context'):
            if template.tenant_id != request.context.tenant:
                msg = _('User is not authorized to access'
                        ' this tenant resources')
                LOG.error(msg)
                raise exc.HTTPForbidden(explanation=msg)

        return func(self, request, env_template_id, *args, **kwargs)
    return __inner


def verify_session(func):
    @functools.wraps(func)
    def __inner(self, request, *args, **kwargs):
        if hasattr(request, 'context') and not request.context.session:
            msg = _('X-Configuration-Session header which indicates'
                    ' to the session is missed')
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        session_id = request.context.session

        unit = db_session.get_session()
        session = unit.query(models.Session).get(session_id)

        if session is None:
            msg = _('Session <SessionId {0}> is not found').format(session_id)
            LOG.error(msg)
            raise exc.HTTPNotFound(explanation=msg)

        if not sessions.SessionServices.validate(session):
            msg = _('Session <SessionId {0}> '
                    'is invalid: environment has been updated or '
                    'updating right now with other session').format(session_id)
            LOG.error(msg)
            raise exc.HTTPForbidden(explanation=msg)

        if session.state == states.SessionState.DEPLOYING:
            msg = _('Session <SessionId {0}> is already in deployment state'
                    ).format(session_id)
            raise exc.HTTPForbidden(explanation=msg)
        return func(self, request, *args, **kwargs)
    return __inner


def ensure_tree(path):
    """Create a directory (and any ancestor directories required).

    :param path: Directory to create
    :return: bool, whether the directory has actually been created
    """
    try:
        os.makedirs(path)
    except OSError as e:
        if e.errno == errno.EEXIST:
            if not os.path.isdir(path):
                raise
            else:
                return False
        elif e.errno == errno.EISDIR:
            return False
        else:
            raise
    else:
        return True


ExclusiveInterProcessLock = lockutils.InterProcessLock
if os.name == 'nt':
    # no shared locks on windows
    SharedInterProcessLock = lockutils.InterProcessLock
else:
    import fcntl

    class SharedInterProcessLock(lockutils.InterProcessLock):
        def trylock(self):
            # LOCK_EX instead of LOCK_EX
            fcntl.lockf(self.lockfile, fcntl.LOCK_SH | fcntl.LOCK_NB)

        def _do_open(self):
            # the file has to be open in read mode, therefore this method has
            # to be overriden
            basedir = os.path.dirname(self.path)
            if basedir:
                made_basedir = ensure_tree(basedir)
                if made_basedir:
                    self.logger.debug(
                        'Created lock base path `%s`', basedir)
            # The code here is mostly copy-pasted from oslo_concurrency and
            # fasteners. The file has to be open with read permissions to be
            # suitable for shared locking
            if self.lockfile is None or self.lockfile.closed:
                try:
                    # ensure the file is there, but do not obtain an extra file
                    # descriptor, as closing it would release fcntl lock
                    fd = os.open(self.path, os.O_CREAT | os.O_EXCL)
                    os.close(fd)
                except OSError:
                    pass
                self.lockfile = open(self.path, 'r')


class ReaderWriterLock(lockutils.ReaderWriterLock):

    @contextlib.contextmanager
    def write_lock(self, blocking=True):
        """Context manager that grants a write lock.
        Will wait until no active readers. Blocks readers after acquiring.
        Raises a ``RuntimeError`` if an active reader attempts to acquire
        a lock.
        """
        timeout = None if blocking else 0.00001
        me = self._current_thread()
        i_am_writer = self.is_writer(check_pending=False)
        if self.is_reader() and not i_am_writer:
            raise RuntimeError("Reader %s to writer privilege"
                               " escalation not allowed" % me)
        if i_am_writer:
            # Already the writer; this allows for basic reentrancy.
            yield self
        else:
            with self._cond:
                self._pending_writers.append(me)
                while True:
                    # No readers, and no active writer, am I next??
                    if len(self._readers) == 0 and self._writer is None:
                        if self._pending_writers[0] == me:
                            self._writer = self._pending_writers.popleft()
                            break

                    # NOTE(kzaitsev): this actually means, that we can wait
                    # more than timeout times, since if we get True value we
                    # would get another spin inside of the while loop
                    # Should we do anything about it?
                    acquired = self._cond.wait(timeout)
                    if not acquired:
                        yield False
                        return
            try:
                yield True
            finally:
                with self._cond:
                    self._writer = None
                    self._cond.notify_all()