def test_api_lock_repo_lock_optional_locked(self, backend):
        # TODO: Provide a fixture locked_repository or similar
        repo = Repository.get_by_repo_name(backend.repo_name)
        user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
        Repository.lock(repo, user.user_id, lock_reason=Repository.LOCK_API)

        id_, params = build_data(self.apikey, 'lock', repoid=backend.repo_name)
        response = api_call(self.app, params)
        time_ = response.json['result']['locked_since']
        expected = {
            'repo':
            backend.repo_name,
            'locked':
            True,
            'locked_since':
            time_,
            'locked_by':
            TEST_USER_ADMIN_LOGIN,
            'lock_state_changed':
            False,
            'lock_reason':
            Repository.LOCK_API,
            'msg': ('Repo `%s` locked by `%s` on `%s`.' %
                    (backend.repo_name, TEST_USER_ADMIN_LOGIN,
                     json.dumps(time_to_datetime(time_))))
        }
        assert_ok(id_, expected, given=response.body)
Exemple #2
0
    def _add_gist_to_context(self, gist_id):
        c.gist = Gist.get_or_404(gist_id)

        # Check if this gist is expired
        if c.gist.gist_expires != -1:
            if time.time() > c.gist.gist_expires:
                log.error('Gist expired at %s',
                          time_to_datetime(c.gist.gist_expires))
                raise HTTPNotFound()

        # check if this gist requires a login
        is_default_user = c.rhodecode_user.username == User.DEFAULT_USER
        if c.gist.acl_level == Gist.ACL_LEVEL_PRIVATE and is_default_user:
            log.error("Anonymous user %s tried to access protected gist `%s`",
                      c.rhodecode_user, gist_id)
            raise HTTPNotFound()
Exemple #3
0
    def show(self, gist_id, format='html', revision='tip', f_path=None):
        """GET /admin/gists/gist_id: Show a specific item"""
        # url('gist', gist_id=ID)
        c.gist = Gist.get_or_404(gist_id)

        #check if this gist is not expired
        if c.gist.gist_expires != -1:
            if time.time() > c.gist.gist_expires:
                log.error('Gist expired at %s' %
                          (time_to_datetime(c.gist.gist_expires)))
                raise HTTPNotFound()
        try:
            c.file_changeset, c.files = GistModel().get_gist_files(gist_id)
        except VCSError:
            log.error(traceback.format_exc())
            raise HTTPNotFound()
        if format == 'raw':
            content = '\n\n'.join([f.content for f in c.files if (f_path is None or f.path == f_path)])
            response.content_type = 'text/plain'
            return content
        return render('admin/gists/show.html')
Exemple #4
0
    def show(self, gist_id, format='html', revision='tip', f_path=None):
        """GET /admin/gists/gist_id: Show a specific item"""
        # url('gist', gist_id=ID)
        c.gist = Gist.get_or_404(gist_id)

        #check if this gist is not expired
        if c.gist.gist_expires != -1:
            if time.time() > c.gist.gist_expires:
                log.error('Gist expired at %s' %
                          (time_to_datetime(c.gist.gist_expires)))
                raise HTTPNotFound()
        try:
            c.file_changeset, c.files = GistModel().get_gist_files(gist_id)
        except VCSError:
            log.error(traceback.format_exc())
            raise HTTPNotFound()
        if format == 'raw':
            content = '\n\n'.join([
                f.content for f in c.files
                if (f_path is None or f.path == f_path)
            ])
            response.content_type = 'text/plain'
            return content
        return render('admin/gists/show.html')
Exemple #5
0
    def create(self, description, owner, gist_mapping,
               gist_type=Gist.GIST_PUBLIC, lifetime=-1):
        """

        :param description: description of the gist
        :param owner: user who created this gist
        :param gist_mapping: mapping {filename:{'content':content},...}
        :param gist_type: type of gist private/public
        :param lifetime: in minutes, -1 == forever
        """
        gist_id = safe_unicode(unique_id(20))
        lifetime = safe_int(lifetime, -1)
        gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
        log.debug('set GIST expiration date to: %s'
                  % (time_to_datetime(gist_expires)
                   if gist_expires != -1 else 'forever'))
        #create the Database version
        gist = Gist()
        gist.gist_description = description
        gist.gist_access_id = gist_id
        gist.gist_owner = owner.user_id
        gist.gist_expires = gist_expires
        gist.gist_type = safe_unicode(gist_type)
        self.sa.add(gist)
        self.sa.flush()
        if gist_type == Gist.GIST_PUBLIC:
            # use DB ID for easy to use GIST ID
            gist_id = safe_unicode(gist.gist_id)
            gist.gist_access_id = gist_id
            self.sa.add(gist)

        gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id)
        log.debug('Creating new %s GIST repo in %s' % (gist_type, gist_repo_path))
        repo = RepoModel()._create_repo(repo_name=gist_repo_path, alias='hg',
                                        parent=None)

        processed_mapping = {}
        for filename in gist_mapping:
            if filename != os.path.basename(filename):
                raise Exception('Filename cannot be inside a directory')

            content = gist_mapping[filename]['content']
            #TODO: expand support for setting explicit lexers
#             if lexer is None:
#                 try:
#                     lexer = pygments.lexers.guess_lexer_for_filename(filename,content)
#                 except pygments.util.ClassNotFound:
#                     lexer = 'text'
            processed_mapping[filename] = {'content': content}

        # now create single multifile commit
        message = 'added file'
        message += 's: ' if len(processed_mapping) > 1 else ': '
        message += ', '.join([x for x in processed_mapping])

        #fake RhodeCode Repository object
        fake_repo = AttributeDict(dict(
            repo_name=gist_repo_path,
            scm_instance_no_cache=lambda: repo,
        ))
        ScmModel().create_nodes(
            user=owner.user_id, repo=fake_repo,
            message=message,
            nodes=processed_mapping,
            trigger_push_hook=False
        )
        # store metadata inside the gist, this can be later used for imports
        # or gist identification
        metadata = {
            'gist_db_id': gist.gist_id,
            'gist_access_id': gist.gist_access_id,
            'gist_owner_id': owner.user_id,
            'gist_type': gist.gist_type,
            'gist_exipres': gist.gist_expires
        }
        with open(os.path.join(repo.path, '.hg', GIST_METADATA_FILE), 'wb') as f:
            f.write(json.dumps(metadata))
        return gist
Exemple #6
0
    def create(self, description, owner, gist_mapping,
               gist_type=Gist.GIST_PUBLIC, lifetime=-1, gist_id=None,
               gist_acl_level=Gist.ACL_LEVEL_PRIVATE):
        """
        Create a gist

        :param description: description of the gist
        :param owner: user who created this gist
        :param gist_mapping: mapping {filename:{'content':content},...}
        :param gist_type: type of gist private/public
        :param lifetime: in minutes, -1 == forever
        :param gist_acl_level: acl level for this gist
        """
        owner = self._get_user(owner)
        gist_id = safe_unicode(gist_id or unique_id(20))
        lifetime = safe_int(lifetime, -1)
        gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
        expiration = (time_to_datetime(gist_expires)
                      if gist_expires != -1 else 'forever')
        log.debug('set GIST expiration date to: %s', expiration)
        # create the Database version
        gist = Gist()
        gist.gist_description = description
        gist.gist_access_id = gist_id
        gist.gist_owner = owner.user_id
        gist.gist_expires = gist_expires
        gist.gist_type = safe_unicode(gist_type)
        gist.acl_level = gist_acl_level
        self.sa.add(gist)
        self.sa.flush()
        if gist_type == Gist.GIST_PUBLIC:
            # use DB ID for easy to use GIST ID
            gist_id = safe_unicode(gist.gist_id)
            gist.gist_access_id = gist_id
            self.sa.add(gist)

        gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id)
        log.debug('Creating new %s GIST repo in %s', gist_type, gist_repo_path)
        repo = RepoModel()._create_filesystem_repo(
            repo_name=gist_id, repo_type='hg', repo_group=GIST_STORE_LOC,
            use_global_config=True)

        processed_mapping = {}
        for filename in gist_mapping:
            if filename != os.path.basename(filename):
                raise Exception('Filename cannot be inside a directory')

            content = gist_mapping[filename]['content']
            # TODO: expand support for setting explicit lexers
#             if lexer is None:
#                 try:
#                     guess_lexer = pygments.lexers.guess_lexer_for_filename
#                     lexer = guess_lexer(filename,content)
#                 except pygments.util.ClassNotFound:
#                     lexer = 'text'
            processed_mapping[filename] = {'content': content}

        # now create single multifile commit
        message = 'added file'
        message += 's: ' if len(processed_mapping) > 1 else ': '
        message += ', '.join([x for x in processed_mapping])

        # fake RhodeCode Repository object
        fake_repo = AttributeDict({
            'repo_name': gist_repo_path,
            'scm_instance': lambda *args, **kwargs: repo,
        })

        ScmModel().create_nodes(
            user=owner.user_id, repo=fake_repo,
            message=message,
            nodes=processed_mapping,
            trigger_push_hook=False
        )

        self._store_metadata(repo, gist.gist_id, gist.gist_access_id,
                             owner.user_id, owner.username, gist.gist_type,
                             gist.gist_expires, gist_acl_level)
        return gist
Exemple #7
0
    def lock(self, apiuser, repoid, locked=Optional(None),
             userid=Optional(OAttr('apiuser'))):
        """
        Set locking state on particular repository by given user, if
        this command is runned by non-admin account userid is set to user
        who is calling this method

        :param apiuser:
        :param repoid:
        :param userid:
        :param locked:
        """
        repo = get_repo_or_error(repoid)
        if HasPermissionAnyApi('hg.admin')(user=apiuser):
            pass
        elif HasRepoPermissionAnyApi('repository.admin',
                                     'repository.write')(user=apiuser,
                                                         repo_name=repo.repo_name):
            #make sure normal user does not pass someone else userid,
            #he is not allowed to do that
            if not isinstance(userid, Optional) and userid != apiuser.user_id:
                raise JSONRPCError(
                    'userid is not the same as your user'
                )
        else:
            raise JSONRPCError('repository `%s` does not exist' % (repoid))

        if isinstance(userid, Optional):
            userid = apiuser.user_id

        user = get_user_or_error(userid)

        if isinstance(locked, Optional):
            lockobj = Repository.getlock(repo)

            if lockobj[0] is None:
                return ('Repo `%s` not locked. Locked=`False`.'
                        % (repo.repo_name))
            else:
                userid, time_ = lockobj
                user = get_user_or_error(userid)

                return ('Repo `%s` locked by `%s`. Locked=`True`. '
                        'Locked since: `%s`'
                    % (repo.repo_name, user.username,
                       json.dumps(time_to_datetime(time_))))

        else:
            locked = str2bool(locked)
            try:
                if locked:
                    Repository.lock(repo, user.user_id)
                else:
                    Repository.unlock(repo)

                return ('User `%s` set lock state for repo `%s` to `%s`'
                        % (user.username, repo.repo_name, locked))
            except Exception:
                log.error(traceback.format_exc())
                raise JSONRPCError(
                    'Error occurred locking repository `%s`' % repo.repo_name
                )