Exemple #1
0
def test_overwrite_filelocking():
    path = 'tests/fixtures/empty_repo.conf'
    mocked_path = MagicMock()
    mocked_path.__str__ = lambda x: path

    mocked_fcntl = MagicMock()
    mocked_open = MagicMock()

    with patch('pyolite.repo.open', mocked_open, create=True):
        manager = mocked_open.return_value.__enter__.return_value

        # asserts file locking has been put in place before writing
        manager.write = lambda text: ([
            mocked_fcntl.flock.assert_called_once_with(manager, mocked_fcntl.
                                                       LOCK_EX),
            mocked_fcntl.reset_mock()
        ])

        with patch.multiple('pyolite.repo', fcntl=mocked_fcntl):
            repo = Repo(path)

            mocked_fcntl.reset_mock()
            repo.overwrite('some_text')

            # asserts lock has been removed after writing
            mocked_fcntl.flock.assert_called_once_with(manager,
                                                       mocked_fcntl.LOCK_UN)
Exemple #2
0
def test_overwrite_filelocking():
    path = 'tests/fixtures/empty_repo.conf'
    mocked_path = MagicMock()
    mocked_path.__str__ = lambda x: path

    mocked_fcntl = MagicMock()
    mocked_open = MagicMock()

    with patch('pyolite.repo.open', mocked_open, create=True):
        manager = mocked_open.return_value.__enter__.return_value

        # asserts file locking has been put in place before writing
        manager.write = lambda text: ([
            mocked_fcntl.flock.assert_called_once_with(
                manager, mocked_fcntl.LOCK_EX
            ),
            mocked_fcntl.reset_mock()
        ])

        with patch.multiple('pyolite.repo', fcntl=mocked_fcntl):
            repo = Repo(path)

            mocked_fcntl.reset_mock()
            repo.overwrite('some_text')

            # asserts lock has been removed after writing
            mocked_fcntl.flock.assert_called_once_with(manager,
                                                       mocked_fcntl.LOCK_UN)
Exemple #3
0
def test_replace_filelocking():
    mocked_re = MagicMock()
    mocked_fcntl = MagicMock()

    mocked_open = MagicMock()
    path = 'tests/fixtures/config.conf'

    with patch('pyolite.repo.open', mocked_open, create=True):
        manager = mocked_open.return_value.__enter__.return_value

        # asserts file locking has been put in place before reading
        manager.read = lambda: ([
            mocked_fcntl.flock.assert_called_once_with(manager, mocked_fcntl.
                                                       LOCK_EX),
            mocked_fcntl.reset_mock()
        ])

        with patch.multiple('pyolite.repo', re=mocked_re, fcntl=mocked_fcntl):
            repo = Repo(path)

            mocked_fcntl.reset_mock()
            repo.replace('pattern', 'string')

            # asserts lock has been removed after operating on file
            mocked_fcntl.flock.assert_called_once_with(manager,
                                                       mocked_fcntl.LOCK_UN)
Exemple #4
0
def test_replace_filelocking():
    mocked_re = MagicMock()
    mocked_fcntl = MagicMock()

    mocked_open = MagicMock()
    path = 'tests/fixtures/config.conf'

    with patch('pyolite.repo.open', mocked_open, create=True):
        manager = mocked_open.return_value.__enter__.return_value

        # asserts file locking has been put in place before reading
        manager.read = lambda: ([
            mocked_fcntl.flock.assert_called_once_with(
                manager, mocked_fcntl.LOCK_EX
            ),
            mocked_fcntl.reset_mock()
        ])

        with patch.multiple('pyolite.repo', re=mocked_re,
                            fcntl=mocked_fcntl):
            repo = Repo(path)

            mocked_fcntl.reset_mock()
            repo.replace('pattern', 'string')

            # asserts lock has been removed after operating on file
            mocked_fcntl.flock.assert_called_once_with(manager,
                                                       mocked_fcntl.LOCK_UN)
Exemple #5
0
    def __init__(self, name, path, git):
        self.name = name
        self.path = path
        self.git = git

        self.repo = Repo(Path(path, "conf/repos/%s.conf" % name))

        self.users = ListUsers(self)
Exemple #6
0
def test_it_should_overwrite_the_repo_config():
    path = 'tests/fixtures/empty_repo.conf'

    Repo(path).write('some_text')

    Repo(path).overwrite('another_text')

    with open(path, 'r+') as f:
        assert f.read() == 'another_text'

        f.seek(0)
        f.write('')
        f.truncate()
Exemple #7
0
def test_it_should_replace_a_given_string_in_repo_conf():
    mocked_re = MagicMock()
    path = 'tests/fixtures/config.conf'

    mocked_re.sub.return_value = 'another_text'

    with patch.multiple('pyolite.repo', re=mocked_re):
        repo = Repo(path)
        repo.replace('pattern', 'string')

        with open('tests/fixtures/config.conf') as f:
            assert f.read() == 'another_text'

        mocked_re.sub.assert_called_once_with('pattern', 'string',
                                              'another_text')
Exemple #8
0
def test_it_should_replace_a_given_string_in_repo_conf():
    mocked_re = MagicMock()
    path = 'tests/fixtures/config.conf'

    mocked_re.sub.return_value = 'another_text'

    with patch.multiple('pyolite.repo', re=mocked_re):
        repo = Repo(path)
        repo.replace('pattern', 'string')

        with open('tests/fixtures/config.conf') as f:
            assert f.read() == 'another_text'

        mocked_re.sub.assert_called_once_with('pattern', 'string',
                                              'another_text')
Exemple #9
0
def test_users_filelocking():
    path = 'tests/fixtures/repo_users.conf'
    mocked_path = MagicMock()
    mocked_path.__str__ = lambda x: path

    mocked_path.exists.return_value = True

    mocked_re = MagicMock()
    mocked_fcntl = MagicMock()
    mocked_open = MagicMock()

    with patch('pyolite.repo.open', mocked_open, create=True):
        manager = mocked_open.return_value.__enter__.return_value

        # asserts file locking has been put in place before reading
        manager.read = lambda: ([
            mocked_fcntl.flock.assert_called_once_with(manager, mocked_fcntl.
                                                       LOCK_EX),
            mocked_fcntl.reset_mock()
        ])

        with patch.multiple('pyolite.repo', re=mocked_re, fcntl=mocked_fcntl):
            repo = Repo(mocked_path)

            mocked_fcntl.reset_mock()
            repo.users

            # asserts lock has been removed after reading
            mocked_fcntl.flock.assert_called_once_with(manager,
                                                       mocked_fcntl.LOCK_UN)
Exemple #10
0
    def __init__(self, name, path, git):
        self.name = name
        self.path = path
        self.git = git

        self.repo = Repo(Path(path,
                              "conf/repos/%s.conf" % name))

        self.users = ListUsers(self)
Exemple #11
0
    def test_it_should_write_to_repo_config(self):
        path = 'tests/fixtures/empty_repo.conf'

        Repo(path).write('some_text')

        with open(path, 'r+') as f:
            eq_('some_text', f.read())

            f.seek(0)
            f.write('')
            f.truncate()
Exemple #12
0
def test_setting_config_will_not_overwrite_users():
    path = 'tests/fixtures/empty_repo.conf'

    Repo(path).write('''
repo test-repo
    RW+   =    @support
    R     =    gitweb
    config test = testconfig
''')

    Repo(path).write_config("    config another = anotherconfig\n")

    with open(path, 'r+') as f:
        assert f.read() == '''
repo test-repo
    RW+   =    @support
    R     =    gitweb

    config another = anotherconfig
'''

        f.seek(0)
        f.write('')
        f.truncate()
Exemple #13
0
def test_it_should_retrieve_all_users_from_repo():
    path = 'tests/fixtures/repo_users.conf'
    mocked_path = MagicMock()
    mocked_path.__str__ = lambda x: path

    mocked_path.exists.return_value = True

    mocked_re = MagicMock()
    mocked_user1 = MagicMock()
    mocked_user2 = MagicMock()

    mocked_re.compile('=( *)(\w+)').finditer.return_value = [
        mocked_user1, mocked_user2
    ]
    mocked_user1.group.return_value = 'user1'
    mocked_user2.group.return_value = 'user2'

    with patch.multiple('pyolite.repo', re=mocked_re):
        repo = Repo(mocked_path)
        assert repo.users == ['user1', 'user2']
Exemple #14
0
class ListUsers(object):
  def __init__(self, repository):
    self.repository_model = repository
    self.repo = Repo(Path(repository.path,
                          "conf/repos/%s.conf" % repository.name))

  def with_user(func):
    def decorated(self, string_user, *args, **kwargs):
      try:
        user = User.get(string_user, self.repository_model.path,
                        self.repository_model.git)
      except ValueError:
        user = User(self.repository_model.path, self.repository_model.git,
                    string_user)

      return func(self, user, *args, **kwargs)
    return decorated

  @with_user
  def add(self, user, permission):
    if user.name in self.repo.users:
      raise ValueError('User %s already exists. Please check '
                       'example/repository.py in order to see how you can '
                       'delete or change permissions' % user.name)

    if set(map(lambda permission: permission.upper(), permission)) - \
       ACCEPTED_PERMISSIONS != set([]):
      raise ValueError('Invalid permissions. They must be from %s' %
                       ACCEPTED_PERMISSIONS)

    self.repo.write("    %s     =    %s\n" % (permission, user.name))

    commit_message = 'User %s added to repo %s with permissions: %s' %\
                     (user, self.repository_model.name, permission)
    self.repository_model.git.commit(['conf'], commit_message)

    user.repos.append(self.repo)
    return user

  @with_user
  def edit(self, user, permission):
    pattern = r'(\s*)([RW+DC]*)(\s*)=(\s*)%s' % user.name
    string = r"\n    %s    =    %s" % (permission, user.name)

    self.repo.replace(pattern, string)

    self.repository_model.git.commit(['conf'],
                         "User %s has %s permission for repository %s" %
                         (user.name, permission, self.repository_model.name))
    return user

  @with_user
  def remove(self, user):
    pattern = r'(\s*)([RW+DC]*)(\s*)=(\s*)%s' % user.name
    self.repo.replace(pattern, "")

    self.repository_model.git.commit(['conf'],
                         "Deleted user %s from repository %s" %
                         (user.name, self.repository_model.name))

  def __iter__(self):
    for user in self._user:
      yield user

  def __getitem__(self, item):
    return self._users[item]

  def __setitem__(self, item, value):
    self._users[item] = value

  def __add__(self, items):
    for item in items:
      self.append(item)

  def __str__(self):
    return "['%s']" % ', '.join(self.repo.users)
Exemple #15
0
 def __init__(self, repository):
   self.repository_model = repository
   self.repo = Repo(Path(repository.path,
                         "conf/repos/%s.conf" % repository.name))
Exemple #16
0
class ListUsers(object):
    def __init__(self, repository):
        self.repository_model = repository
        self.repo = Repo(Path(repository.path,
                              "conf/repos/%s.conf" % repository.name))

    @with_user
    def add(self, user, permission):
        if user.name in self.repo.users:
            raise ValueError('User %s already exists. Please check '
                             'example/repository.py in order to see how you can '
                             'delete or change permissions' % user.name)

        if set(map(lambda permission: permission.upper(), permission)) - \
                ACCEPTED_PERMISSIONS != set([]):
            raise ValueError('Invalid permissions. They must be from %s' %
                             ACCEPTED_PERMISSIONS)

        self.repo.write("    %s     =    %s\n" % (permission, user.name))

        commit_message = 'User %s added to repo %s with permissions: %s' % \
                         (user, self.repository_model.name, permission)
        self.repository_model.git.commit(['conf'], commit_message)

        user.repos.append(self.repo)
        return user

    @with_user
    def edit(self, user, permission):
        pattern = USER_PATTERN % user.name
        string = r"\n    %s    =    %s" % (permission, user.name)

        self.repo.replace(pattern, string)

        self.repository_model.git.commit(['conf'],
                                         "User %s has %s permission for repository %s" %
                                         (user.name, permission,
                                          self.repository_model.name))
        return user

    @with_user
    def remove(self, user):
        pattern = USER_PATTERN % user.name
        self.repo.replace(pattern, "")

        self.repository_model.git.commit(['conf'],
                                         "Deleted user %s from repository %s" %
                                         (user.name,
                                          self.repository_model.name))

    @with_user
    def get_or_create(self, user):
        return user

    def set(self, users=None, overwrite_config=False):
        users_serialized = "repo {}\n".format(self.repository_model.name)
        if isinstance(users, dict):
            users = users.iteritems()

        if users:
            for user, permission in users:
                if not hasattr(user, 'name'):
                    user = self.get_or_create(user)

                users_serialized += "    %s     =    %s\n" % (permission,
                                                              user.name)
        config = "" if overwrite_config else self.repository_model.get_config()
        self.repo.overwrite(users_serialized + config)

        users = ", ".join((user for user, permission in users))
        commit_message = "Initialized repository %s with users: %s" % (
            self.repository_model.name, users
        )
        self.repository_model.git.commit(['conf'], commit_message)

    def __iter__(self):
        for user in self._users:
            yield user

    def __getitem__(self, item):
        return self._users[item]

    def __setitem__(self, item, value):
        self._users[item] = value

    def __add__(self, items):
        for item in items:
            self.append(item)

    def __str__(self):
        return "['%s']" % ', '.join(self.repo.users)
Exemple #17
0
class ListUsers(object):
    def __init__(self, repository):
        self.repository_model = repository
        self.repo = Repo(Path(repository.path,
                              "conf/repos/%s.conf" % repository.name))

    def with_user(func):
        def decorated(self, string_user, *args, **kwargs):
            try:
                user = User.get(string_user, self.repository_model.path,
                                self.repository_model.git)
            except ValueError:
                user = User(self.repository_model.path,
                            self.repository_model.git,
                            string_user)
            return func(self, user, *args, **kwargs)

        return decorated

    @with_user
    def add(self, user, permission):
        if user.name in self.repo.users:
            raise ValueError('User %s already exists. Please check '
                             'example/repository.py in order to see how you can '
                             'delete or change permissions' % user.name)

        if set(map(lambda permission: permission.upper(), permission)) - \
                ACCEPTED_PERMISSIONS != set([]):
            raise ValueError('Invalid permissions. They must be from %s' %
                             ACCEPTED_PERMISSIONS)

        self.repo.write("    %s     =    %s\n" % (permission, user.name))

        commit_message = 'User %s added to repo %s with permissions: %s' % \
                         (user, self.repository_model.name, permission)
        self.repository_model.git.commit(['conf'], commit_message)

        user.repos.append(self.repo)
        return user

    @with_user
    def edit(self, user, permission):
        if user.name not in self.repo.users:
            raise ValueError('User %s not exists in repo %s' %
                             (user.name, self.repository_model.name))

        if set(map(lambda permission: permission.upper(), permission)) - \
                ACCEPTED_PERMISSIONS != set([]):
            raise ValueError('Invalid permissions. They must be from %s' %
                             ACCEPTED_PERMISSIONS)

        pattern = r'(\s*)([RW+DC]*)(\s*)=(\s*)%s' % user.name
        string = r"\n    %s    =    %s" % (permission, user.name)

        self.repo.replace(pattern, string)

        self.repository_model.git.commit(['conf'],
                                         "User %s has %s permission for repository %s" %
                                         (user.name, permission,
                                          self.repository_model.name))
        return user

    @with_user
    def remove(self, user):
        pattern = r'(\s*)([RW+DC]*)(\s*)=(\s*)%s' % user.name
        self.repo.replace(pattern, "")

        self.repository_model.git.commit(['conf'],
                                         "Deleted user %s from repository %s" %
                                         (user.name,
                                          self.repository_model.name))

    @with_user
    def get_or_create(self, user):
        return user

    def set(self, users=None):
        users_serialized = "repo {}\n".format(self.repository_model.name)
        if isinstance(users, dict):
            users = users.iteritems()

        if users:
            for user, permission in users:
                if not hasattr(user, 'name'):
                    user = self.get_or_create(user)

                users_serialized += "    %s     =    %s\n" % (permission,
                                                              user.name)

        self.repo.overwrite(users_serialized)

        users = ", ".join((user for user, permission in users))
        commit_message = "Initialized repository %s with users: %s" % (
            self.repository_model.name, users
        )
        self.repository_model.git.commit(['conf'], commit_message)

    # def __iter__(self):
    #     for user in self._user:
    #         yield user

    # def __getitem__(self, item):
    #     return self._users[item]

    # def __setitem__(self, item, value):
    #     self._users[item] = value

    # def __add__(self, items):
    #     for item in items:
    #         self.append(item)

    def __str__(self):
        return "['%s']" % ', '.join(self.repo.users)
Exemple #18
0
 def __init__(self, repository):
     self.repository_model = repository
     self.repo = Repo(Path(repository.path,
                           "conf/repos/%s.conf" % repository.name))
Exemple #19
0
class Repository(object):
    def __init__(self, name, path, git):
        self.name = name
        self.path = path
        self.git = git

        self.repo = Repo(Path(path,
                              "conf/repos/%s.conf" % name))

        self.users = ListUsers(self)

    @classmethod
    def get_by_name(cls, lookup_repo, path, git):
        for obj in Path(path, 'conf').walk():
            if obj.isdir():
                continue

            with open(str(obj)) as f:
                try:
                    first_line = f.read().split('\n')[0]
                except IndexError:
                    return None

                if "repo %s" % lookup_repo == first_line.strip():
                    return cls(lookup_repo, path, git)
        return None

    def get_config(self):
        return self._serialize_config()

    def add_config(self, values):
        if isinstance(values, dict):
            raw_values = values.items()
        elif isinstance(values, list) or isinstance(values, set) or isinstance(values, tuple):
            if len(values) > 2:
                raise ValueError("Use a dict if you want to set multiple values.")
            raw_values = [values]
        else:
            raise ValueError("Accepted config types are: dict, tuple, list and set.")

        current_config = self._read_current_config()
        for config in raw_values:
            current_config[config[0]] = config[1]

        self.repo.write_config(self._serialize_config(current_config))
        self.git.commit(['conf'], "Update %s's config" % self.name)

    def _serialize_config(self, structured_config=None):
        structured_config = structured_config or self._read_current_config()

        config = ""
        for name, value in structured_config.items():
            config += "    config %s    =    %s\n" % (name, value)
        return config

    def _read_current_config(self):
        return OrderedDict(**{
            result.group(3): result.group(6)
            for result in re.finditer(CONFIG_PATTERN, self.repo.read())
        })

    def __str__(self):
        return "< %s >" % self.name
Exemple #20
0
class Repository(object):
    def __init__(self, name, path, git):
        self.name = name
        self.path = path
        self.git = git

        self.repo = Repo(Path(path, "conf/repos/%s.conf" % name))

        self.users = ListUsers(self)

    @classmethod
    def get_by_name(cls, lookup_repo, path, git):
        for obj in Path(path, 'conf').walk():
            if obj.isdir():
                continue

            with open(str(obj)) as f:
                try:
                    first_line = f.read().split('\n')[0]
                except IndexError:
                    return None

                if "repo %s" % lookup_repo == first_line.strip():
                    return cls(lookup_repo, path, git)
        return None

    def get_config(self):
        return self._serialize_config()

    def add_config(self, values):
        if isinstance(values, dict):
            raw_values = values.items()
        elif isinstance(values, list) or isinstance(values, set) or isinstance(
                values, tuple):
            if len(values) > 2:
                raise ValueError(
                    "Use a dict if you want to set multiple values.")
            raw_values = [values]
        else:
            raise ValueError(
                "Accepted config types are: dict, tuple, list and set.")

        current_config = self._read_current_config()
        for config in raw_values:
            current_config[config[0]] = config[1]

        self.repo.write_config(self._serialize_config(current_config))
        self.git.commit(['conf'], "Update %s's config" % self.name)

    def _serialize_config(self, structured_config=None):
        structured_config = structured_config or self._read_current_config()

        config = ""
        for name, value in structured_config.items():
            config += "    config %s    =    %s\n" % (name, value)
        return config

    def _read_current_config(self):
        return OrderedDict(
            **{
                result.group(3): result.group(6)
                for result in re.finditer(CONFIG_PATTERN, self.repo.read())
            })

    def __str__(self):
        return "< %s >" % self.name