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)
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()
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')
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')
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
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
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 )