def settings_issuetracker(self): """GET /admin/settings/issue-tracker: All items in the collection""" # url('admin_settings_issuetracker') c.active = 'issuetracker' defaults = SettingsModel().get_all_settings() entry_key = 'rhodecode_issuetracker_pat_' c.issuetracker_entries = {} for k, v in defaults.items(): if k.startswith(entry_key): uid = k[len(entry_key):] c.issuetracker_entries[uid] = None for uid in c.issuetracker_entries: c.issuetracker_entries[uid] = AttributeDict({ 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid), 'url': defaults.get('rhodecode_issuetracker_url_' + uid), 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid), 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid), }) return render('admin/settings/settings.html')
def password_reset(self): settings = SettingsModel().get_all_settings() captcha_private_key = settings.get('rhodecode_captcha_private_key') captcha_active = bool(captcha_private_key) captcha_public_key = settings.get('rhodecode_captcha_public_key') render_ctx = { 'captcha_active': captcha_active, 'captcha_public_key': captcha_public_key, 'defaults': {}, 'errors': {}, } if self.request.POST: password_reset_form = PasswordResetForm()() try: form_result = password_reset_form.to_python( self.request.params) if captcha_active: response = submit( self.request.params.get('recaptcha_challenge_field'), self.request.params.get('recaptcha_response_field'), private_key=captcha_private_key, remoteip=get_ip_addr(self.request.environ)) if captcha_active and not response.is_valid: _value = form_result _msg = _('bad captcha') error_dict = {'recaptcha_field': _msg} raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) # Generate reset URL and send mail. user_email = form_result['email'] user = User.get_by_email(user_email) password_reset_url = self.request.route_url( 'reset_password_confirmation', _query={'key': user.api_key}) UserModel().reset_password_link( form_result, password_reset_url) # Display success message and redirect. self.session.flash( _('Your password reset link was sent'), queue='success') return HTTPFound(self.request.route_path('login')) except formencode.Invalid as errors: render_ctx.update({ 'defaults': errors.value, 'errors': errors.error_dict, }) return render_ctx
def error_handler(exception, request): # TODO: dan: replace the old pylons error controller with this from rhodecode.model.settings import SettingsModel from rhodecode.lib.utils2 import AttributeDict try: rc_config = SettingsModel().get_all_settings() except Exception: log.exception('failed to fetch settings') rc_config = {} base_response = HTTPInternalServerError() # prefer original exception for the response since it may have headers set if isinstance(exception, HTTPError): base_response = exception c = AttributeDict() c.error_message = base_response.status c.error_explanation = base_response.explanation or str(base_response) c.visual = AttributeDict() c.visual.rhodecode_support_url = ( request.registry.settings.get('rhodecode_support_url') or request.route_url('rhodecode_support')) c.redirect_time = 0 c.rhodecode_name = rc_config.get('rhodecode_title', '') if not c.rhodecode_name: c.rhodecode_name = 'Rhodecode' response = render_to_response('/errors/error_document.html', {'c': c}, request=request, response=base_response) return response
def register(self, defaults=None, errors=None): defaults = defaults or {} errors = errors or {} settings = SettingsModel().get_all_settings() captcha_public_key = settings.get('rhodecode_captcha_public_key') captcha_private_key = settings.get('rhodecode_captcha_private_key') captcha_active = bool(captcha_private_key) register_message = settings.get('rhodecode_register_message') or '' auto_active = 'hg.register.auto_activate' in User.get_default_user()\ .AuthUser.permissions['global'] render_ctx = self._get_template_context() render_ctx.update({ 'defaults': defaults, 'errors': errors, 'auto_active': auto_active, 'captcha_active': captcha_active, 'captcha_public_key': captcha_public_key, 'register_message': register_message, }) return render_ctx
def permission_application(self): c.active = 'application' self.__load_data() c.user = User.get_default_user() # TODO: johbo: The default user might be based on outdated state which # has been loaded from the cache. A call to refresh() ensures that the # latest state from the database is used. Session().refresh(c.user) app_settings = SettingsModel().get_all_settings() defaults = { 'anonymous': c.user.active, 'default_register_message': app_settings.get('rhodecode_register_message') } defaults.update(c.user.get_default_perms()) return htmlfill.render(render('admin/permissions/permissions.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def attach_context_attributes(context): rc_config = SettingsModel().get_all_settings(cache=True) context.rhodecode_version = rhodecode.__version__ context.rhodecode_edition = config.get('rhodecode.edition') # unique secret + version does not leak the version but keep consistency context.rhodecode_version_hash = md5( config.get('beaker.session.secret', '') + rhodecode.__version__)[:8] # Default language set for the incoming request context.language = translation.get_lang()[0] # Visual options context.visual = AttributeDict({}) # DB store context.visual.show_public_icon = str2bool( rc_config.get('rhodecode_show_public_icon')) context.visual.show_private_icon = str2bool( rc_config.get('rhodecode_show_private_icon')) context.visual.stylify_metatags = str2bool( rc_config.get('rhodecode_stylify_metatags')) context.visual.dashboard_items = safe_int( rc_config.get('rhodecode_dashboard_items', 100)) context.visual.admin_grid_items = safe_int( rc_config.get('rhodecode_admin_grid_items', 100)) context.visual.repository_fields = str2bool( rc_config.get('rhodecode_repository_fields')) context.visual.show_version = str2bool( rc_config.get('rhodecode_show_version')) context.visual.use_gravatar = str2bool( rc_config.get('rhodecode_use_gravatar')) context.visual.gravatar_url = rc_config.get('rhodecode_gravatar_url') context.visual.default_renderer = rc_config.get( 'rhodecode_markup_renderer', 'rst') context.visual.rhodecode_support_url = \ rc_config.get('rhodecode_support_url') or url('rhodecode_support') context.pre_code = rc_config.get('rhodecode_pre_code') context.post_code = rc_config.get('rhodecode_post_code') context.rhodecode_name = rc_config.get('rhodecode_title') context.default_encodings = aslist(config.get('default_encoding'), sep=',') # if we have specified default_encoding in the request, it has more # priority if request.GET.get('default_encoding'): context.default_encodings.insert(0, request.GET.get('default_encoding')) context.clone_uri_tmpl = rc_config.get('rhodecode_clone_uri_tmpl') # INI stored context.labs_active = str2bool( config.get('labs_settings_active', 'false')) context.visual.allow_repo_location_change = str2bool( config.get('allow_repo_location_change', True)) context.visual.allow_custom_hooks_settings = str2bool( config.get('allow_custom_hooks_settings', True)) context.debug_style = str2bool(config.get('debug_style', False)) context.rhodecode_instanceid = config.get('instance_id') # AppEnlight context.appenlight_enabled = str2bool(config.get('appenlight', 'false')) context.appenlight_api_public_key = config.get( 'appenlight.api_public_key', '') context.appenlight_server_url = config.get('appenlight.server_url', '') # END CONFIG VARS # TODO: This dosn't work when called from pylons compatibility tween. # Fix this and remove it from base controller. # context.repo_name = get_repo_slug(request) # can be empty context.csrf_token = auth.get_csrf_token() context.backends = rhodecode.BACKENDS.keys() context.backends.sort() context.unread_notifications = NotificationModel().get_unread_cnt_for_user( context.rhodecode_user.user_id)
def create_repo(form_data, cur_user): from rhodecode.model.repo import RepoModel from rhodecode.model.user import UserModel from rhodecode.model.settings import SettingsModel log = get_logger(create_repo) DBS = get_session() cur_user = UserModel(DBS)._get_user(cur_user) owner = cur_user repo_name = form_data['repo_name'] repo_name_full = form_data['repo_name_full'] repo_type = form_data['repo_type'] description = form_data['repo_description'] private = form_data['repo_private'] clone_uri = form_data.get('clone_uri') repo_group = safe_int(form_data['repo_group']) landing_rev = form_data['repo_landing_rev'] copy_fork_permissions = form_data.get('copy_permissions') copy_group_permissions = form_data.get('repo_copy_permissions') fork_of = form_data.get('fork_parent_id') state = form_data.get('repo_state', Repository.STATE_PENDING) # repo creation defaults, private and repo_type are filled in form defs = SettingsModel().get_default_repo_settings(strip_prefix=True) enable_statistics = form_data.get('enable_statistics', defs.get('repo_enable_statistics')) enable_locking = form_data.get('enable_locking', defs.get('repo_enable_locking')) enable_downloads = form_data.get('enable_downloads', defs.get('repo_enable_downloads')) try: RepoModel(DBS)._create_repo( repo_name=repo_name_full, repo_type=repo_type, description=description, owner=owner, private=private, clone_uri=clone_uri, repo_group=repo_group, landing_rev=landing_rev, fork_of=fork_of, copy_fork_permissions=copy_fork_permissions, copy_group_permissions=copy_group_permissions, enable_statistics=enable_statistics, enable_locking=enable_locking, enable_downloads=enable_downloads, state=state) action_logger(cur_user, 'user_created_repo', repo_name_full, '', DBS) DBS.commit() # now create this repo on Filesystem RepoModel(DBS)._create_filesystem_repo( repo_name=repo_name, repo_type=repo_type, repo_group=RepoModel(DBS)._get_repo_group(repo_group), clone_uri=clone_uri, ) repo = Repository.get_by_repo_name(repo_name_full) log_create_repository(created_by=owner.username, **repo.get_dict()) # update repo commit caches initially repo.update_commit_cache() # set new created state repo.set_state(Repository.STATE_CREATED) DBS.commit() except Exception as e: log.warning( 'Exception %s occurred when creating repository, ' 'doing cleanup...', e) # rollback things manually ! repo = Repository.get_by_repo_name(repo_name_full) if repo: Repository.delete(repo.repo_id) DBS.commit() RepoModel(DBS)._delete_filesystem_repo(repo) raise # it's an odd fix to make celery fail task when exception occurs def on_failure(self, *args, **kwargs): pass return True
def comment_pull_request(request, apiuser, repoid, pullrequestid, message=Optional(None), status=Optional(None), userid=Optional(OAttr('apiuser'))): """ Comment on the pull request specified with the `pullrequestid`, in the |repo| specified by the `repoid`, and optionally change the review status. :param apiuser: This is filled automatically from the |authtoken|. :type apiuser: AuthUser :param repoid: The repository name or repository ID. :type repoid: str or int :param pullrequestid: The pull request ID. :type pullrequestid: int :param message: The text content of the comment. :type message: str :param status: (**Optional**) Set the approval status of the pull request. Valid options are: * not_reviewed * approved * rejected * under_review :type status: str :param userid: Comment on the pull request as this user :type userid: Optional(str or int) Example output: .. code-block:: bash id : <id_given_in_input> result : { "pull_request_id": "<Integer>", "comment_id": "<Integer>" } error : null """ repo = get_repo_or_error(repoid) if not isinstance(userid, Optional): if (has_superadmin_permission(apiuser) or HasRepoPermissionAnyApi('repository.admin')( user=apiuser, repo_name=repo.repo_name)): apiuser = get_user_or_error(userid) else: raise JSONRPCError('userid is not the same as your user') pull_request = get_pull_request_or_error(pullrequestid) if not PullRequestModel().check_user_read(pull_request, apiuser, api=True): raise JSONRPCError('repository `%s` does not exist' % (repoid, )) message = Optional.extract(message) status = Optional.extract(status) if not message and not status: raise JSONRPCError('message and status parameter missing') if (status not in (st[0] for st in ChangesetStatus.STATUSES) and status is not None): raise JSONRPCError('unknown comment status`%s`' % status) allowed_to_change_status = PullRequestModel().check_user_change_status( pull_request, apiuser) text = message if status and allowed_to_change_status: st_message = (('Status change %(transition_icon)s %(status)s') % { 'transition_icon': '>', 'status': ChangesetStatus.get_status_lbl(status) }) text = message or st_message rc_config = SettingsModel().get_all_settings() renderer = rc_config.get('rhodecode_markup_renderer', 'rst') comment = ChangesetCommentsModel().create( text=text, repo=pull_request.target_repo.repo_id, user=apiuser.user_id, pull_request=pull_request.pull_request_id, f_path=None, line_no=None, status_change=(ChangesetStatus.get_status_lbl(status) if status and allowed_to_change_status else None), closing_pr=False, renderer=renderer) if allowed_to_change_status and status: ChangesetStatusModel().set_status( pull_request.target_repo.repo_id, status, apiuser.user_id, comment, pull_request=pull_request.pull_request_id) Session().flush() Session().commit() data = { 'pull_request_id': pull_request.pull_request_id, 'comment_id': comment.comment_id, 'status': status } return data
def repo2db_mapper(initial_repo_list, remove_obsolete=False): """ maps all repos given in initial_repo_list, non existing repositories are created, if remove_obsolete is True it also checks for db entries that are not in initial_repo_list and removes them. :param initial_repo_list: list of repositories found by scanning methods :param remove_obsolete: check for obsolete entries in database """ from rhodecode.model.repo import RepoModel from rhodecode.model.scm import ScmModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.settings import SettingsModel sa = meta.Session() repo_model = RepoModel() user = User.get_first_super_admin() added = [] # creation defaults defs = SettingsModel().get_default_repo_settings(strip_prefix=True) enable_statistics = defs.get('repo_enable_statistics') enable_locking = defs.get('repo_enable_locking') enable_downloads = defs.get('repo_enable_downloads') private = defs.get('repo_private') for name, repo in initial_repo_list.items(): group = map_groups(name) unicode_name = safe_unicode(name) db_repo = repo_model.get_by_repo_name(unicode_name) # found repo that is on filesystem not in RhodeCode database if not db_repo: log.info('repository %s not found, creating now', name) added.append(name) desc = (repo.description if repo.description != 'unknown' else '%s repository' % name) db_repo = repo_model._create_repo( repo_name=name, repo_type=repo.alias, description=desc, repo_group=getattr(group, 'group_id', None), owner=user, enable_locking=enable_locking, enable_downloads=enable_downloads, enable_statistics=enable_statistics, private=private, state=Repository.STATE_CREATED) sa.commit() # we added that repo just now, and make sure we updated server info if db_repo.repo_type == 'git': git_repo = db_repo.scm_instance() # update repository server-info log.debug('Running update server info') git_repo._update_server_info() db_repo.update_commit_cache() config = db_repo._config config.set('extensions', 'largefiles', '') ScmModel().install_hooks(db_repo.scm_instance(config=config), repo_type=db_repo.repo_type) removed = [] if remove_obsolete: # remove from database those repositories that are not in the filesystem for repo in sa.query(Repository).all(): if repo.repo_name not in initial_repo_list.keys(): log.debug("Removing non-existing repository found in db `%s`", repo.repo_name) try: RepoModel(sa).delete(repo, forks='detach', fs_remove=False) sa.commit() removed.append(repo.repo_name) except Exception: # don't hold further removals on error log.error(traceback.format_exc()) sa.rollback() def splitter(full_repo_name): _parts = full_repo_name.rsplit(RepoGroup.url_sep(), 1) gr_name = None if len(_parts) == 2: gr_name = _parts[0] return gr_name initial_repo_group_list = [ splitter(x) for x in initial_repo_list.keys() if splitter(x) ] # remove from database those repository groups that are not in the # filesystem due to parent child relationships we need to delete them # in a specific order of most nested first all_groups = [x.group_name for x in sa.query(RepoGroup).all()] nested_sort = lambda gr: len(gr.split('/')) for group_name in sorted(all_groups, key=nested_sort, reverse=True): if group_name not in initial_repo_group_list: repo_group = RepoGroup.get_by_group_name(group_name) if (repo_group.children.all() or not RepoGroupModel().check_exist_filesystem( group_name=group_name, exc_on_failure=False)): continue log.info( 'Removing non-existing repository group found in db `%s`', group_name) try: RepoGroupModel(sa).delete(group_name, fs_remove=False) sa.commit() removed.append(group_name) except Exception: # don't hold further removals on error log.exception('Unable to remove repository group `%s`', group_name) sa.rollback() raise return added, removed