def add_doc(self, writer, path, repo, repo_name): """ Adding doc to writer this function itself fetches data from the instance of vcs backend """ node = self.get_node(repo, path) indexed = indexed_w_content = 0 # we just index the content of chosen files, and skip binary files if node.extension in INDEX_EXTENSIONS and not node.is_binary: u_content = node.content if not isinstance(u_content, unicode): log.warning(' >> %s Could not get this content as unicode ' 'replacing with empty content' % path) u_content = u'' else: log.debug(' >> %s [WITH CONTENT]' % path) indexed_w_content += 1 else: log.debug(' >> %s' % path) # just index file name without it's content u_content = u'' indexed += 1 writer.add_document( owner=unicode(repo.contact), repository=safe_unicode(repo_name), path=safe_unicode(path), content=u_content, modtime=self.get_node_mtime(node), extension=node.extension ) return indexed, indexed_w_content
def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): """ Action logger for various actions made by users :param user: user that made this action, can be a unique username string or object containing user_id attribute :param action: action to log, should be on of predefined unique actions for easy translations :param repo: string name of repository or object containing repo_id, that action was made on :param ipaddr: optional ip address from what the action was made :param sa: optional sqlalchemy session """ if not sa: sa = meta.Session() # if we don't get explicit IP address try to get one from registered user # in tmpl context var if not ipaddr: ipaddr = getattr(get_current_rhodecode_user(), 'ip_addr', '') try: if getattr(user, 'user_id', None): user_obj = User.get(user.user_id) elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: raise Exception('You have to provide a user object or a username') if getattr(repo, 'repo_id', None): repo_obj = Repository.get(repo.repo_id) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip('/') repo_obj = Repository.get_by_repo_name(repo_name) else: repo_obj = None repo_name = '' user_log = UserLog() user_log.user_id = user_obj.user_id user_log.username = user_obj.username action = safe_unicode(action) user_log.action = action[:1200000] user_log.repository = repo_obj user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) log.info('Logging action:`%s` on repo:`%s` by user:%s ip:%s', action, safe_unicode(repo), user_obj, ipaddr) if commit: sa.commit() except Exception: log.error(traceback.format_exc()) raise
def commit_change(self, repo, repo_name, cs, user, author, message, content, f_path): if repo.alias == 'hg': from rhodecode.lib.vcs.backends.hg import \ MercurialInMemoryChangeset as IMC elif repo.alias == 'git': from rhodecode.lib.vcs.backends.git import \ GitInMemoryChangeset as IMC # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit content = safe_str(content) path = safe_str(f_path) # message and author needs to be unicode # proper backend should then translate that into required type message = safe_unicode(message) author = safe_unicode(author) m = IMC(repo) m.change(FileNode(path, content)) tip = m.commit(message=message, author=author, parents=[cs], branch=cs.branch) new_cs = tip.short_id action = 'push_local:%s' % new_cs action_logger(user, action, repo_name) self.mark_for_invalidation(repo_name)
def commit_change(self, repo, repo_name, cs, user, author, message, content, f_path): """ Commits changes :param repo: SCM instance """ if repo.alias == 'hg': from rhodecode.lib.vcs.backends.hg import \ MercurialInMemoryChangeset as IMC elif repo.alias == 'git': from rhodecode.lib.vcs.backends.git import \ GitInMemoryChangeset as IMC # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit content = safe_str(content) path = safe_str(f_path) # message and author needs to be unicode # proper backend should then translate that into required type message = safe_unicode(message) author = safe_unicode(author) m = IMC(repo) m.change(FileNode(path, content)) tip = m.commit(message=message, author=author, parents=[cs], branch=cs.branch) action = 'push_local:%s' % tip.raw_id action_logger(user, action, repo_name) self.mark_for_invalidation(repo_name) return tip
def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] start = time.time() try: self.ip_addr = _get_ip_addr(environ) # make sure that we update permissions each time we call controller api_key = request.GET.get("api_key") cookie_store = CookieStoreWrapper(session.get("rhodecode_user")) user_id = cookie_store.get("user_id", None) username = get_container_username(environ, config) auth_user = AuthUser(user_id, api_key, username) request.user = auth_user self.rhodecode_user = c.rhodecode_user = auth_user if not self.rhodecode_user.is_authenticated and self.rhodecode_user.user_id is not None: self.rhodecode_user.set_authenticated(cookie_store.get("is_authenticated")) log.info("IP: %s User: %s accessed %s" % (self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))) return WSGIController.__call__(self, environ, start_response) finally: log.info( "IP: %s Request to %s time: %.3fs" % (_get_ip_addr(environ), safe_unicode(_get_access_path(environ)), time.time() - start) ) meta.Session.remove()
def index(self): def _branchtags(localrepo): bt_closed = {} for bn, heads in localrepo.branchmap().iteritems(): tip = heads[-1] if 'close' in localrepo.changelog.read(tip)[5]: bt_closed[bn] = tip return bt_closed cs_g = c.rhodecode_repo.get_changeset c.repo_closed_branches = {} if c.rhodecode_db_repo.repo_type == 'hg': bt_closed = _branchtags(c.rhodecode_repo._repo) _closed_branches = [(safe_unicode(n), cs_g(binascii.hexlify(h)),) for n, h in bt_closed.items()] c.repo_closed_branches = OrderedDict(sorted(_closed_branches, key=lambda ctx: ctx[0], reverse=False)) _branches = [(safe_unicode(n), cs_g(h)) for n, h in c.rhodecode_repo.branches.items()] c.repo_branches = OrderedDict(sorted(_branches, key=lambda ctx: ctx[0], reverse=False)) return render('branches/branches.html')
def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] start = time.time() try: # make sure that we update permissions each time we call controller api_key = request.GET.get('api_key') cookie_store = CookieStoreWrapper(session.get('rhodecode_user')) user_id = cookie_store.get('user_id', None) username = get_container_username(environ, config) auth_user = AuthUser(user_id, api_key, username) request.user = auth_user self.rhodecode_user = c.rhodecode_user = auth_user if not self.rhodecode_user.is_authenticated and \ self.rhodecode_user.user_id is not None: self.rhodecode_user.set_authenticated( cookie_store.get('is_authenticated') ) log.info('User: %s accessed %s' % ( auth_user, safe_unicode(environ.get('PATH_INFO'))) ) return WSGIController.__call__(self, environ, start_response) finally: log.info('Request to %s time: %.3fs' % ( safe_unicode(environ.get('PATH_INFO')), time.time() - start) ) meta.Session.remove()
def commit_change(self, repo, repo_name, cs, user, author, message, content, f_path): """ Commits changes :param repo: SCM instance """ user = self._get_user(user) IMC = self._get_IMC_module(repo.alias) # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit content = safe_str(content) path = safe_str(f_path) # message and author needs to be unicode # proper backend should then translate that into required type message = safe_unicode(message) author = safe_unicode(author) imc = IMC(repo) imc.change(FileNode(path, content, mode=cs.get_file_mode(f_path))) tip = imc.commit(message=message, author=author, parents=[cs], branch=cs.branch) self.mark_for_invalidation(repo_name) self._handle_push(repo, username=user.username, action='push_local', repo_name=repo_name, revisions=[tip.raw_id]) return tip
def index(self): def _branchtags(localrepo): bt_closed = {} for bn, heads in localrepo.branchmap().iteritems(): tip = heads[-1] if 'close' in localrepo.changelog.read(tip)[5]: bt_closed[bn] = tip return bt_closed cs_g = c.rhodecode_repo.get_changeset c.repo_closed_branches = {} if c.rhodecode_db_repo.repo_type == 'hg': bt_closed = _branchtags(c.rhodecode_repo._repo) _closed_branches = [( safe_unicode(n), cs_g(binascii.hexlify(h)), ) for n, h in bt_closed.items()] c.repo_closed_branches = OrderedDict( sorted(_closed_branches, key=lambda ctx: ctx[0], reverse=False)) _branches = [(safe_unicode(n), cs_g(h)) for n, h in c.rhodecode_repo.branches.items()] c.repo_branches = OrderedDict( sorted(_branches, key=lambda ctx: ctx[0], reverse=False)) return render('branches/branches.html')
def test_merge_failed(self, pull_request, merge_extras): user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) self.merge_mock.return_value = MergeResponse( False, False, '6126b7bfcc82ad2d3deaee22af926b082ce54cc6', MergeFailureReason.MERGE_FAILED) PullRequestModel().merge(pull_request, pull_request.author, extras=merge_extras) message = ( u'Merge pull request #{pr_id} from {source_repo} {source_ref_name}' u'\n\n {pr_title}'.format( pr_id=pull_request.pull_request_id, source_repo=safe_unicode( pull_request.source_repo.scm_instance().name), source_ref_name=pull_request.source_ref_parts.name, pr_title=safe_unicode(pull_request.title))) self.merge_mock.assert_called_once_with( pull_request.target_ref_parts, pull_request.source_repo.scm_instance(), pull_request.source_ref_parts, self.workspace_id, user_name=user.username, user_email=user.email, message=message) pull_request = PullRequest.get(pull_request.pull_request_id) assert self.invalidation_mock.called is False assert pull_request.merge_rev is None
def commit_change(self, repo, repo_name, cs, user, author, message, content, f_path): """ Commits changes :param repo: SCM instance """ user = self._get_user(user) IMC = self._get_IMC_module(repo.alias) # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit content = safe_str(content) path = safe_str(f_path) # message and author needs to be unicode # proper backend should then translate that into required type message = safe_unicode(message) author = safe_unicode(author) imc = IMC(repo) imc.change(FileNode(path, content, mode=cs.get_file_mode(f_path))) try: tip = imc.commit(message=message, author=author, parents=[cs], branch=cs.branch) except Exception, e: log.error(traceback.format_exc()) raise IMCCommitError(str(e))
def test_change_non_ascii(self): to_add = [ FileNode('żółwik/zwierzątko', content='ćććć'), FileNode(u'żółwik/zwierzątko_uni', content=u'ćććć'), ] for node in to_add: self.imc.add(node) tip = self.imc.commit(u'Initial', u'*****@*****.**') # Change node's content node = FileNode('żółwik/zwierzątko', content='My **changed** content') self.imc.change(node) self.imc.commit(u'Changed %s' % safe_unicode(node.path), u'*****@*****.**') node_uni = FileNode(u'żółwik/zwierzątko_uni', content=u'My **changed** content') self.imc.change(node_uni) self.imc.commit(u'Changed %s' % safe_unicode(node_uni.path), u'*****@*****.**') newtip = self.repo.get_commit() assert tip != newtip assert tip.id != newtip.id self.assert_nodes_in_commit(newtip, (node, node_uni))
def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): """ Action logger for various actions made by users :param user: user that made this action, can be a unique username string or object containing user_id attribute :param action: action to log, should be on of predefined unique actions for easy translations :param repo: string name of repository or object containing repo_id, that action was made on :param ipaddr: optional ip address from what the action was made :param sa: optional sqlalchemy session """ if not sa: sa = meta.Session() # if we don't get explicit IP address try to get one from registered user # in tmpl context var if not ipaddr: ipaddr = getattr(get_current_rhodecode_user(), 'ip_addr', '') try: if hasattr(user, 'user_id'): user_obj = User.get(user.user_id) elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: raise Exception('You have to provide a user object or a username') if hasattr(repo, 'repo_id'): repo_obj = Repository.get(repo.repo_id) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip('/') repo_obj = Repository.get_by_repo_name(repo_name) else: repo_obj = None repo_name = '' user_log = UserLog() user_log.user_id = user_obj.user_id user_log.username = user_obj.username user_log.action = safe_unicode(action) user_log.repository = repo_obj user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) log.info('Logging action:%s on %s by user:%s ip:%s' % (action, safe_unicode(repo), user_obj, ipaddr)) if commit: sa.commit() except Exception: log.error(traceback.format_exc()) raise
def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): """ Action logger for various actions made by users :param user: user that made this action, can be a unique username string or object containing user_id attribute :param action: action to log, should be on of predefined unique actions for easy translations :param repo: string name of repository or object containing repo_id, that action was made on :param ipaddr: optional ip address from what the action was made :param sa: optional sqlalchemy session """ if not sa: sa = meta.Session try: if hasattr(user, 'user_id'): user_obj = user elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: raise Exception('You have to provide user object or username') if hasattr(repo, 'repo_id'): repo_obj = Repository.get(repo.repo_id) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip('/') repo_obj = Repository.get_by_repo_name(repo_name) else: raise Exception('You have to provide repository to action logger') user_log = UserLog() user_log.user_id = user_obj.user_id user_log.action = safe_unicode(action) user_log.repository_id = repo_obj.repo_id user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) log.info( 'Adding user %s, action %s on %s' % (user_obj, action, safe_unicode(repo)) ) if commit: sa.commit() except: log.error(traceback.format_exc()) raise
def __before__(self): super(BaseRepoController, self).__before__() if c.repo_name: # extracted from routes db_repo = Repository.get_by_repo_name(c.repo_name) if not db_repo: return log.debug( 'Found repository in database %s with state `%s`', safe_unicode(db_repo), safe_unicode(db_repo.repo_state)) route = getattr(request.environ.get('routes.route'), 'name', '') # allow to delete repos that are somehow damages in filesystem if route in ['delete_repo']: return if db_repo.repo_state in [Repository.STATE_PENDING]: if route in ['repo_creating_home']: return check_url = url('repo_creating_home', repo_name=c.repo_name) return redirect(check_url) self.rhodecode_db_repo = db_repo missing_requirements = False try: self.rhodecode_repo = self.rhodecode_db_repo.scm_instance() except RepositoryRequirementError as e: missing_requirements = True self._handle_missing_requirements(e) if self.rhodecode_repo is None and not missing_requirements: log.error('%s this repository is present in database but it ' 'cannot be created as an scm instance', c.repo_name) h.flash(_( "The repository at %(repo_name)s cannot be located.") % {'repo_name': c.repo_name}, category='error', ignore_duplicate=True) redirect(url('home')) # update last change according to VCS data if not missing_requirements: commit = db_repo.get_commit( pre_load=["author", "date", "message", "parents"]) db_repo.update_commit_cache(commit) # Prepare context c.rhodecode_db_repo = db_repo c.rhodecode_repo = self.rhodecode_repo c.repository_requirements_missing = missing_requirements self._update_global_counters(self.scm_model, db_repo)
def rst(cls, source, safe=True): source = safe_unicode(source) try: from docutils.core import publish_parts from docutils.parsers.rst import directives docutils_settings = dict([ (alias, None) for alias in cls.RESTRUCTUREDTEXT_DISALLOWED_DIRECTIVES ]) docutils_settings.update({ 'input_encoding': 'unicode', 'report_level': 4 }) for k, v in docutils_settings.iteritems(): directives.register_directive(k, v) parts = publish_parts(source=source, writer_name="html4css1", settings_overrides=docutils_settings) return parts['html_title'] + parts["fragment"] except ImportError: log.warning('Install docutils to use this function') return cls.plain(source) except Exception: log.error(traceback.format_exc()) if safe: return source else: raise
def create_ldap(self, username, password, user_dn, attrs, cur_user=None): """ Checks if user is in database, if not creates this user marked as ldap user :param username: :param password: :param user_dn: :param attrs: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) from rhodecode.lib.auth import get_crypt_password log.debug('Checking for such ldap account in RhodeCode database') if self.get_by_username(username, case_insensitive=True) is None: # autogenerate email for container account without one generate_email = lambda usr: '******' % usr password = get_crypt_password(password) firstname = attrs['name'] lastname = attrs['lastname'] active = attrs.get('active', True) email = attrs['email'] or generate_email(username) from rhodecode.lib.hooks import log_create_user, check_allowed_create_user user_data = { 'username': username, 'password': password, 'email': email, 'firstname': firstname, 'lastname': lastname, 'active': attrs.get('active', True), 'admin': False } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) try: new_user = User() username = username.lower() # add ldap account always lowercase new_user.username = username new_user.password = password new_user.api_key = generate_api_key(username) new_user.email = email new_user.active = active new_user.ldap_dn = safe_unicode(user_dn) new_user.name = firstname new_user.lastname = lastname self.sa.add(new_user) log_create_user(new_user.get_dict(), cur_user) return new_user except (DatabaseError, ): log.error(traceback.format_exc()) self.sa.rollback() raise log.debug('this %s user exists skipping creation of ldap account', username) return None
def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent_id: :param clone_uri: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group if new_parent_id: paths = RepoGroup.get(new_parent_id).full_path.split(RepoGroup.url_sep()) new_parent_path = os.sep.join(paths) else: new_parent_path = "" # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str(x), [self.repos_path, new_parent_path, repo_name])) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception("This path %s is a valid repository" % repo_path) # check if this path is a group if is_valid_repos_group(repo_path, self.repos_path): raise Exception("This path %s is a valid group" % repo_path) log.info("creating repo %s in %s @ %s" % (repo_name, safe_unicode(repo_path), clone_uri)) backend = get_backend(alias) backend(repo_path, create=True, src_url=clone_uri)
def prepare(self, request, pylonsapp): UserLog.query().delete() Session().commit() def strptime(val): fmt = '%Y-%m-%d %H:%M:%S' if '.' not in val: return datetime.datetime.strptime(val, fmt) nofrag, frag = val.split(".") date = datetime.datetime.strptime(nofrag, fmt) frag = frag[:6] # truncate to microseconds frag += (6 - len(frag)) * '0' # add 0s return date.replace(microsecond=int(frag)) with open(os.path.join(FIXTURES, 'journal_dump.csv')) as f: for row in csv.DictReader(f): ul = UserLog() for k, v in row.iteritems(): v = safe_unicode(v) if k == 'action_date': v = strptime(v) if k in ['user_id', 'repository_id']: # nullable due to FK problems v = None setattr(ul, k, v) Session().add(ul) Session().commit() @request.addfinalizer def cleanup(): UserLog.query().delete() Session().commit()
def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] try: self.ip_addr = _get_ip_addr(environ) # make sure that we update permissions each time we call controller api_key = request.GET.get('api_key') cookie_store = CookieStoreWrapper(session.get('rhodecode_user')) user_id = cookie_store.get('user_id', None) username = get_container_username(environ, config) try: auth_user = AuthUser(user_id, api_key, username, self.ip_addr) except UserCreationError, e: from rhodecode.lib import helpers as h h.flash(e, 'error') # container auth or other auth functions that create users on # the fly can throw this exception signaling that there's issue # with user creation, explanation should be provided in # Exception itself auth_user = AuthUser(ip_addr=self.ip_addr) request.user = auth_user self.rhodecode_user = c.rhodecode_user = auth_user if not self.rhodecode_user.is_authenticated and \ self.rhodecode_user.user_id is not None: self.rhodecode_user.set_authenticated( cookie_store.get('is_authenticated') ) log.info('IP: %s User: %s accessed %s' % ( self.ip_addr, auth_user, safe_unicode(_get_access_path(environ))) ) return WSGIController.__call__(self, environ, start_response)
def safe_unicode(str_, from_encoding=None): """ safe unicode function. Does few trick to turn str_ into unicode In case of UnicodeDecode error we try to return it with encoding detected by chardet library if it fails fallback to unicode with errors replaced :param str_: string to decode :rtype: unicode :returns: unicode object """ from rhodecode.lib.utils2 import safe_unicode return safe_unicode(str_, from_encoding) if isinstance(str_, unicode): return str_ try: return unicode(str_) except UnicodeDecodeError: pass try: return unicode(str_, from_encoding) except UnicodeDecodeError: pass try: import chardet encoding = chardet.detect(str_)['encoding'] if encoding is None: raise Exception() return str_.decode(encoding) except (ImportError, UnicodeDecodeError, Exception): return unicode(str_, from_encoding, 'replace')
def _get_diff_from_pr_or_version(self, pr_or_version, context): source_repo = pr_or_version.source_repo # we swap org/other ref since we run a simple diff on one repo target_ref_id = pr_or_version.target_ref_parts.commit_id source_ref_id = pr_or_version.source_ref_parts.commit_id target_commit = source_repo.get_commit( commit_id=safe_str(target_ref_id)) source_commit = source_repo.get_commit( commit_id=safe_str(source_ref_id)) vcs_repo = source_repo.scm_instance() # TODO: johbo: In the context of an update, we cannot reach # the old commit anymore with our normal mechanisms. It needs # some sort of special support in the vcs layer to avoid this # workaround. if (source_commit.raw_id == vcs_repo.EMPTY_COMMIT_ID and vcs_repo.alias == 'git'): source_commit.raw_id = safe_str(source_ref_id) log.debug( 'calculating diff between ' 'source_ref:%s and target_ref:%s for repo `%s`', target_ref_id, source_ref_id, safe_unicode(vcs_repo.path)) vcs_diff = vcs_repo.get_diff(commit1=target_commit, commit2=source_commit, context=context) return vcs_diff
def get_users(self, name_contains=None, limit=20, only_active=True): # TODO: mikhail: move this method to the UserModel. query = self.sa.query(User) if only_active: query = query.filter(User.active == true()) if name_contains: ilike_expression = u'%{}%'.format(safe_unicode(name_contains)) query = query.filter( or_(User.name.ilike(ilike_expression), User.lastname.ilike(ilike_expression), User.username.ilike(ilike_expression))) query = query.limit(limit) users = query.all() _users = [{ 'id': user.user_id, 'first_name': user.name, 'last_name': user.lastname, 'username': user.username, 'icon_link': h.gravatar_url(user.email, 14), 'value_display': h.person(user.email), 'value': user.username, 'value_type': 'user', 'active': user.active, } for user in users] return _users
def app_settings_value(self, val): """ Setter that will always make sure we use unicode in app_settings_value :param val: """ self._app_settings_value = safe_unicode(val)
def rst(cls, source, safe=True): source = safe_unicode(source) try: from docutils.core import publish_parts from docutils.parsers.rst import directives docutils_settings = dict([(alias, None) for alias in cls.RESTRUCTUREDTEXT_DISALLOWED_DIRECTIVES]) docutils_settings.update({'input_encoding': 'unicode', 'report_level': 4}) for k, v in docutils_settings.iteritems(): directives.register_directive(k, v) parts = publish_parts(source=source, writer_name="html4css1", settings_overrides=docutils_settings) return parts['html_title'] + parts["fragment"] except ImportError: log.warning('Install docutils to use this function') return cls.plain(source) except Exception: log.error(traceback.format_exc()) if safe: return source else: raise
def markdown(cls, source): source = safe_unicode(source) try: import markdown as __markdown return __markdown.markdown(source, ['codehilite']) except ImportError: log.warning('Install markdown to use this function') return cls.plain(source)
def index_changesets(self, writer, repo_name, repo, start_rev=None): """ Add all changeset in the vcs repo starting at start_rev to the index writer :param writer: the whoosh index writer to add to :param repo_name: name of the repository from whence the changeset originates including the repository group :param repo: the vcs repository instance to index changesets for, the presumption is the repo has changesets to index :param start_rev=None: the full sha id to start indexing from if start_rev is None then index from the first changeset in the repo """ if start_rev is None: start_rev = repo[0].raw_id log.debug('indexing changesets in %s starting at rev: %s' % (repo_name, start_rev)) indexed = 0 cs_iter = repo.get_changesets(start=start_rev) total = len(cs_iter) for cs in cs_iter: log.debug(' >> %s/%s' % (cs, total)) writer.add_document( raw_id=unicode(cs.raw_id), owner=unicode(repo.contact), date=cs._timestamp, repository=safe_unicode(repo_name), author=cs.author, message=cs.message, last=cs.last, added=u' '.join([safe_unicode(node.path) for node in cs.added]).lower(), removed=u' '.join( [safe_unicode(node.path) for node in cs.removed]).lower(), changed=u' '.join( [safe_unicode(node.path) for node in cs.changed]).lower(), parents=u' '.join([cs.raw_id for cs in cs.parents]), ) indexed += 1 log.debug('indexed %d changesets for repo %s' % (indexed, repo_name)) return indexed
def plain(cls, source, universal_newline=True): source = safe_unicode(source) if universal_newline: newline = '\n' source = newline.join(source.splitlines()) source = cls.urlify_text(source) return '<br />' + source.replace("\n", '<br />')
def __changes(self, cs): changes = [] a = [safe_unicode(n.path) for n in cs.added] if a: changes.append('\nA ' + '\nA '.join(a)) m = [safe_unicode(n.path) for n in cs.changed] if m: changes.append('\nM ' + '\nM '.join(m)) d = [safe_unicode(n.path) for n in cs.removed] if d: changes.append('\nD ' + '\nD '.join(d)) changes.append('</pre>') return ''.join(changes)
def __call__(self, environ, start_response): start = time.time() try: return self.application(environ, start_response) finally: log = logging.getLogger('rhodecode.' + self.__class__.__name__) log.info('IP: %s Request to %s time: %.3fs' % ( _get_ip_addr(environ), safe_unicode(_get_access_path(environ)), time.time() - start) )
def index_changesets(self, writer, repo_name, repo, start_rev=None): """ Add all changeset in the vcs repo starting at start_rev to the index writer :param writer: the whoosh index writer to add to :param repo_name: name of the repository from whence the changeset originates including the repository group :param repo: the vcs repository instance to index changesets for, the presumption is the repo has changesets to index :param start_rev=None: the full sha id to start indexing from if start_rev is None then index from the first changeset in the repo """ if start_rev is None: start_rev = repo[0].raw_id log.debug('indexing changesets in %s starting at rev: %s' % (repo_name, start_rev)) indexed = 0 cs_iter = repo.get_changesets(start=start_rev) total = len(cs_iter) for cs in cs_iter: log.debug(' >> %s/%s' % (cs, total)) writer.add_document( raw_id=unicode(cs.raw_id), owner=unicode(repo.contact), date=cs._timestamp, repository=safe_unicode(repo_name), author=cs.author, message=cs.message, last=cs.last, added=u' '.join([safe_unicode(node.path) for node in cs.added]).lower(), removed=u' '.join([safe_unicode(node.path) for node in cs.removed]).lower(), changed=u' '.join([safe_unicode(node.path) for node in cs.changed]).lower(), parents=u' '.join([cs.raw_id for cs in cs.parents]), ) indexed += 1 log.debug('indexed %d changesets for repo %s' % (indexed, repo_name)) return indexed
def __create_repo(self, repo_name, alias, parent, clone_uri=False, repo_store_location=None): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent_id: :param clone_uri: :param repo_path: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group from rhodecode.model.scm import ScmModel if parent: new_parent_path = os.sep.join(parent.full_path_splitted) else: new_parent_path = '' if repo_store_location: _paths = [repo_store_location] else: _paths = [self.repos_path, new_parent_path, repo_name] # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str(x), _paths)) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception('This path %s is a valid repository' % repo_path) # check if this path is a group if is_valid_repos_group(repo_path, self.repos_path): raise Exception('This path %s is a valid group' % repo_path) log.info( 'creating repo %s in %s @ %s' % (repo_name, safe_unicode(repo_path), obfuscate_url_pw(clone_uri))) backend = get_backend(alias) if alias == 'hg': repo = backend(repo_path, create=True, src_url=clone_uri) elif alias == 'git': repo = backend(repo_path, create=True, src_url=clone_uri, bare=True) # add rhodecode hook into this repo ScmModel().install_git_hook(repo=repo) else: raise Exception('Undefined alias %s' % alias) return repo
def create_node(self, repo, repo_name, cs, user, author, message, content, f_path): if repo.alias == 'hg': from rhodecode.lib.vcs.backends.hg import MercurialInMemoryChangeset as IMC elif repo.alias == 'git': from rhodecode.lib.vcs.backends.git import GitInMemoryChangeset as IMC # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit if isinstance(content, (basestring, )): content = safe_str(content) elif isinstance(content, ( file, cStringIO.OutputType, )): content = content.read() else: raise Exception('Content is of unrecognized type %s' % (type(content))) message = safe_unicode(message) author = safe_unicode(author) path = safe_str(f_path) m = IMC(repo) if isinstance(cs, EmptyChangeset): # EmptyChangeset means we we're editing empty repository parents = None else: parents = [cs] m.add(FileNode(path, content=content)) tip = m.commit(message=message, author=author, parents=parents, branch=cs.branch) new_cs = tip.short_id action = 'push_local:%s' % new_cs action_logger(user, action, repo_name) self.mark_for_invalidation(repo_name)
def create_node(self, repo, repo_name, cs, user, author, message, content, f_path): user = self._get_user(user) IMC = self._get_IMC_module(repo.alias) # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit if isinstance(content, (basestring, )): content = safe_str(content) elif isinstance(content, ( file, cStringIO.OutputType, )): content = content.read() else: raise Exception('Content is of unrecognized type %s' % (type(content))) message = safe_unicode(message) author = safe_unicode(author) path = safe_str(f_path) m = IMC(repo) if isinstance(cs, EmptyChangeset): # EmptyChangeset means we we're editing empty repository parents = None else: parents = [cs] m.add(FileNode(path, content=content)) tip = m.commit(message=message, author=author, parents=parents, branch=cs.branch) self.mark_for_invalidation(repo_name) self._handle_push(repo, username=user.username, action='push_local', repo_name=repo_name, revisions=[tip.raw_id]) return tip
def _line_counter(self, l): """ Checks each line and bumps total adds/removes for this diff :param l: """ if l.startswith('+') and not l.startswith('+++'): self.adds += 1 elif l.startswith('-') and not l.startswith('---'): self.removes += 1 return safe_unicode(l)
def create_or_update(self, username, password, email, firstname='', lastname='', active=True, admin=False, ldap_dn=None): """ Creates a new instance if not found, or updates current one :param username: :param password: :param email: :param active: :param firstname: :param lastname: :param active: :param admin: :param ldap_dn: """ from rhodecode.lib.auth import get_crypt_password log.debug('Checking for %s account in RhodeCode database' % username) user = User.get_by_username(username, case_insensitive=True) if user is None: log.debug('creating new user %s' % username) new_user = User() edit = False else: log.debug('updating user %s' % username) new_user = user edit = True try: new_user.username = username new_user.admin = admin # set password only if creating an user or password is changed if not edit or user.password != password: new_user.password = get_crypt_password(password) new_user.api_key = generate_api_key(username) new_user.email = email new_user.active = active new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None new_user.name = firstname new_user.lastname = lastname self.sa.add(new_user) return new_user except (DatabaseError, ): log.error(traceback.format_exc()) raise
def get_repo_landing_revs(self, repo=None): """ Generates select option with tags branches and bookmarks (for hg only) grouped by type :param repo: """ hist_l = [] choices = [] repo = self._get_repo(repo) hist_l.append(['rev:tip', _('latest tip')]) choices.append('rev:tip') if not repo: return choices, hist_l repo = repo.scm_instance() branches_group = ([(u'branch:%s' % safe_unicode(b), safe_unicode(b)) for b in repo.branches], _("Branches")) hist_l.append(branches_group) choices.extend([x[0] for x in branches_group[0]]) if repo.alias == 'hg': bookmarks_group = ([(u'book:%s' % safe_unicode(b), safe_unicode(b)) for b in repo.bookmarks], _("Bookmarks")) hist_l.append(bookmarks_group) choices.extend([x[0] for x in bookmarks_group[0]]) tags_group = ([(u'tag:%s' % safe_unicode(t), safe_unicode(t)) for t in repo.tags], _("Tags")) hist_l.append(tags_group) choices.extend([x[0] for x in tags_group[0]]) return choices, hist_l
def commit_change(self, repo, repo_name, commit, user, author, message, content, f_path): """ Commits changes :param repo: SCM instance """ user = self._get_user(user) # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit content = safe_str(content) path = safe_str(f_path) # message and author needs to be unicode # proper backend should then translate that into required type message = safe_unicode(message) author = safe_unicode(author) imc = repo.in_memory_commit imc.change(FileNode(path, content, mode=commit.get_file_mode(f_path))) try: # TODO: handle pre-push action ! tip = imc.commit(message=message, author=author, parents=[commit], branch=commit.branch) except Exception as e: log.error(traceback.format_exc()) raise IMCCommitError(str(e)) finally: # always clear caches, if commit fails we want fresh object also self.mark_for_invalidation(repo_name) # We trigger the post-push action hooks_utils.trigger_post_push_hook(username=user.username, action='push_local', repo_name=repo_name, repo_alias=repo.alias, commit_ids=[tip.raw_id]) return tip
def create(self, created_by, org_repo, org_ref, other_repo, other_ref, revisions, reviewers, title, description=None): created_by_user = self._get_user(created_by) org_repo = self._get_repo(org_repo) other_repo = self._get_repo(other_repo) new = PullRequest() new.org_repo = org_repo new.org_ref = org_ref new.other_repo = other_repo new.other_ref = other_ref new.revisions = revisions new.title = title new.description = description new.author = created_by_user self.sa.add(new) Session().flush() #members for member in reviewers: _usr = self._get_user(member) reviewer = PullRequestReviewers(_usr, new) self.sa.add(reviewer) #notification to reviewers notif = NotificationModel() pr_url = h.url('pullrequest_show', repo_name=other_repo.repo_name, pull_request_id=new.pull_request_id, qualified=True, ) subject = safe_unicode( h.link_to( _('%(user)s wants you to review pull request #%(pr_id)s') % \ {'user': created_by_user.username, 'pr_id': new.pull_request_id}, pr_url ) ) body = description kwargs = { 'pr_title': title, 'pr_user_created': h.person(created_by_user.email), 'pr_repo_url': h.url('summary_home', repo_name=other_repo.repo_name, qualified=True,), 'pr_url': pr_url, 'pr_revisions': revisions } notif.create(created_by=created_by_user, subject=subject, body=body, recipients=reviewers, type_=Notification.TYPE_PULL_REQUEST, email_kwargs=kwargs) return new
def create_node(self, repo, repo_name, cs, user, author, message, content, f_path): if repo.alias == 'hg': from rhodecode.lib.vcs.backends.hg import MercurialInMemoryChangeset as IMC elif repo.alias == 'git': from rhodecode.lib.vcs.backends.git import GitInMemoryChangeset as IMC # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit if isinstance(content, (basestring,)): content = safe_str(content) elif isinstance(content, (file, cStringIO.OutputType,)): content = content.read() else: raise Exception('Content is of unrecognized type %s' % ( type(content) )) message = safe_unicode(message) author = safe_unicode(author) path = safe_str(f_path) m = IMC(repo) if isinstance(cs, EmptyChangeset): # EmptyChangeset means we we're editing empty repository parents = None else: parents = [cs] m.add(FileNode(path, content=content)) tip = m.commit(message=message, author=author, parents=parents, branch=cs.branch) new_cs = tip.short_id action = 'push_local:%s' % new_cs action_logger(user, action, repo_name) self.mark_for_invalidation(repo_name)
def create_node(self, repo, repo_name, cs, user, author, message, content, f_path): user = self._get_user(user) IMC = self._get_IMC_module(repo.alias) # decoding here will force that we have proper encoded values # in any other case this will throw exceptions and deny commit if isinstance(content, (basestring,)): content = safe_str(content) elif isinstance(content, (file, cStringIO.OutputType,)): content = content.read() else: raise Exception('Content is of unrecognized type %s' % ( type(content) )) message = safe_unicode(message) author = safe_unicode(author) path = safe_str(f_path) m = IMC(repo) if isinstance(cs, EmptyChangeset): # EmptyChangeset means we we're editing empty repository parents = None else: parents = [cs] m.add(FileNode(path, content=content)) tip = m.commit(message=message, author=author, parents=parents, branch=cs.branch) self.mark_for_invalidation(repo_name) self._handle_push(repo, username=user.username, action='push_local', repo_name=repo_name, revisions=[tip.raw_id]) return tip
def __call__(self, user, repo_name): # repo_name MUST be unicode, since we handle keys in permission # dict by unicode repo_name = safe_unicode(repo_name) usr = AuthUser(user.user_id) try: self.user_perms = set([usr.permissions['repositories'][repo_name]]) except Exception: log.error('Exception while accessing permissions %s' % traceback.format_exc()) self.user_perms = set() self.username = user.username self.repo_name = repo_name return self.check_permissions()
def markdown(cls, source, safe=True): source = safe_unicode(source) try: import markdown as __markdown return __markdown.markdown(source, ['codehilite']) except ImportError: log.warning('Install markdown to use this function') return cls.plain(source) except Exception: log.error(traceback.format_exc()) if safe: return source else: raise
def __create_repo(self, repo_name, alias, parent, clone_uri=False, repo_store_location=None): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent_id: :param clone_uri: :param repo_path: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group from rhodecode.model.scm import ScmModel if parent: new_parent_path = os.sep.join(parent.full_path_splitted) else: new_parent_path = '' if repo_store_location: _paths = [repo_store_location] else: _paths = [self.repos_path, new_parent_path, repo_name] # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str(x), _paths)) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception('This path %s is a valid repository' % repo_path) # check if this path is a group if is_valid_repos_group(repo_path, self.repos_path): raise Exception('This path %s is a valid group' % repo_path) log.info('creating repo %s in %s @ %s' % ( repo_name, safe_unicode(repo_path), obfuscate_url_pw(clone_uri) ) ) backend = get_backend(alias) if alias == 'hg': repo = backend(repo_path, create=True, src_url=clone_uri) elif alias == 'git': repo = backend(repo_path, create=True, src_url=clone_uri, bare=True) # add rhodecode hook into this repo ScmModel().install_git_hook(repo=repo) else: raise Exception('Undefined alias %s' % alias) return repo
def update(self, id): """PUT /users_groups/id: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: # h.form(url('users_group', id=ID), # method='put') # url('users_group', id=ID) c.users_group = UsersGroup.get(id) c.group_members_obj = [x.user for x in c.users_group.members] c.group_members = [(x.user_id, x.username) for x in c.group_members_obj] c.available_members = [(x.user_id, x.username) for x in User.query().all()] available_members = [safe_unicode(x[0]) for x in c.available_members] users_group_form = UsersGroupForm(edit=True, old_data=c.users_group.get_dict(), available_members=available_members)() try: form_result = users_group_form.to_python(request.POST) UsersGroupModel().update(c.users_group, form_result) gr = form_result['users_group_name'] action_logger(self.rhodecode_user, 'admin_updated_users_group:%s' % gr, None, self.ip_addr, self.sa) h.flash(_('updated users group %s') % gr, category='success') Session().commit() except formencode.Invalid, errors: ug_model = UsersGroupModel() defaults = errors.value e = errors.error_dict or {} defaults.update({ 'create_repo_perm': ug_model.has_perm(id, 'hg.create.repository'), 'fork_repo_perm': ug_model.has_perm(id, 'hg.fork.repository'), '_method': 'put' }) return htmlfill.render( render('admin/users_groups/users_group_edit.html'), defaults=defaults, errors=e, prefix_error=False, encoding="UTF-8")
def plain(cls, source): source = safe_unicode(source) def urlify_text(text): url_pat = re.compile(r'(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]' '|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)') def url_func(match_obj): url_full = match_obj.groups()[0] return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full}) return url_pat.sub(url_func, text) source = urlify_text(source) return '<br />' + source.replace("\n", '<br />')
def changed_tooltip(nodes): """ Generates a html string for changed nodes in changeset page. It limits the output to 30 entries :param nodes: LazyNodesGenerator """ if nodes: pref = ': <br/> ' suf = '' if len(nodes) > 30: suf = '<br/>' + _(' and %s more') % (len(nodes) - 30) return literal(pref + '<br/> '.join([safe_unicode(x.path) for x in nodes[:30]]) + suf) else: return ': ' + _('No Files')
def create_or_update( self, username, password, email, firstname="", lastname="", active=True, admin=False, ldap_dn=None ): """ Creates a new instance if not found, or updates current one :param username: :param password: :param email: :param active: :param firstname: :param lastname: :param active: :param admin: :param ldap_dn: """ from rhodecode.lib.auth import get_crypt_password log.debug("Checking for %s account in RhodeCode database" % username) user = User.get_by_username(username, case_insensitive=True) if user is None: log.debug("creating new user %s" % username) new_user = User() edit = False else: log.debug("updating user %s" % username) new_user = user edit = True try: new_user.username = username new_user.admin = admin # set password only if creating an user or password is changed if not edit or user.password != password: new_user.password = get_crypt_password(password) new_user.api_key = generate_api_key(username) new_user.email = email new_user.active = active new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None new_user.name = firstname new_user.lastname = lastname self.sa.add(new_user) return new_user except (DatabaseError,): log.error(traceback.format_exc()) raise
def _escaper(self, string): """ Escaper for diff escapes special chars and checks the diff limit :param string: """ self.cur_diff_size += len(string) # escaper get's iterated on each .next() call and it checks if each # parsed line doesn't exceed the diff limit if self.diff_limit is not None and self.cur_diff_size > self.diff_limit: raise DiffLimitExceeded('Diff Limit Exceeded') return safe_unicode(string).replace('&', '&')\ .replace('<', '<')\ .replace('>', '>')
def __call__(self, repo_name, rev, paths): if isinstance(paths, str): paths = safe_unicode(paths) url_l = [link_to(repo_name, url('files_home', repo_name=repo_name, revision=rev, f_path=''))] paths_l = paths.split('/') for cnt, p in enumerate(paths_l): if p != '': url_l.append(link_to(p, url('files_home', repo_name=repo_name, revision=rev, f_path='/'.join(paths_l[:cnt + 1]) ) ) ) return literal('/'.join(url_l))