def get_container_username(environ, config, clean_username=False): """ Get's the container_auth username (or email). It tries to get username from REMOTE_USER if container_auth_enabled is enabled, if that fails it tries to get username from HTTP_X_FORWARDED_USER if proxypass_auth_enabled is enabled. clean_username extracts the username from this data if it's having @ in it. :param environ: :param config: :param clean_username: """ username = None if str2bool(config.get('container_auth_enabled', False)): from paste.httpheaders import REMOTE_USER username = REMOTE_USER(environ) log.debug('extracted REMOTE_USER:%s' % (username)) if not username and str2bool(config.get('proxypass_auth_enabled', False)): username = environ.get('HTTP_X_FORWARDED_USER') log.debug('extracted HTTP_X_FORWARDED_USER:%s' % (username)) if username and clean_username: # Removing realm and domain from username username = username.partition('@')[0] username = username.rpartition('\\')[2] log.debug('Received username %s from container' % username) return username
def gravatar_url(email_address, size=30): from pylons import url ## doh, we need to re-import url to mock it later if(str2bool(config['app_conf'].get('use_gravatar')) and config['app_conf'].get('alternative_gravatar_url')): tmpl = config['app_conf'].get('alternative_gravatar_url', '') parsed_url = urlparse.urlparse(url.current(qualified=True)) tmpl = tmpl.replace('{email}', email_address)\ .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \ .replace('{netloc}', parsed_url.netloc)\ .replace('{scheme}', parsed_url.scheme)\ .replace('{size}', str(size)) return tmpl if (not str2bool(config['app_conf'].get('use_gravatar')) or not email_address or email_address == '*****@*****.**'): f = lambda a, l: min(l, key=lambda x: abs(x - a)) return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30])) ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme') default = 'identicon' baseurl_nossl = "http://www.gravatar.com/avatar/" baseurl_ssl = "https://secure.gravatar.com/avatar/" baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl if isinstance(email_address, unicode): #hashlib crashes on unicode items email_address = safe_str(email_address) # construct the url gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?" gravatar_url += urllib.urlencode({'d': default, 's': str(size)}) return gravatar_url
def __before__(self): c.rhodecode_version = __version__ c.rhodecode_instanceid = config.get('instance_id') c.rhodecode_name = config.get('rhodecode_title') c.use_gravatar = str2bool(config.get('use_gravatar')) c.ga_code = config.get('rhodecode_ga_code') # Visual options c.visual = AttributeDict({}) rc_config = RhodeCodeSetting.get_app_settings() c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon')) c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon')) c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags')) c.visual.lightweight_dashboard = str2bool(rc_config.get('rhodecode_lightweight_dashboard')) c.visual.lightweight_dashboard_items = safe_int(config.get('dashboard_items', 100)) c.repo_name = get_repo_slug(request) c.backends = BACKENDS.keys() c.unread_notifications = NotificationModel()\ .get_unread_cnt_for_user(c.rhodecode_user.user_id) self.cut_off_limit = int(config.get('cut_off_limit')) self.sa = meta.Session self.scm_model = ScmModel(self.sa) self.ip_addr = ''
def send_email(recipients, subject, body='', html_body='', email_config=None): """ Sends an email with defined parameters from the .ini files. :param recipients: list of recipients, it this is empty the defined email address from field 'email_to' is used instead :param subject: subject of the mail :param body: body of the mail :param html_body: html version of body """ log = get_logger(send_email) email_config = email_config or config subject = "%s %s" % (email_config.get('email_prefix', ''), subject) if not recipients: # if recipients are not defined we send to email_config + all admins admins = [ u.email for u in User.query().filter(User.admin == True).all() ] recipients = [email_config.get('email_to')] + admins mail_server = email_config.get('smtp_server') or None if mail_server is None: log.error("SMTP server information missing. Sending email failed. " "Make sure that `smtp_server` variable is configured " "inside the .ini file") return False mail_from = email_config.get('app_email_from', 'RhodeCode') user = email_config.get('smtp_username') passwd = email_config.get('smtp_password') mail_port = email_config.get('smtp_port') tls = str2bool(email_config.get('smtp_use_tls')) ssl = str2bool(email_config.get('smtp_use_ssl')) debug = str2bool(email_config.get('debug')) smtp_auth = email_config.get('smtp_auth') try: m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth, mail_port, ssl, tls, debug=debug) m.send(recipients, subject, body, html_body) except Exception: log.exception('Mail sending failed') return False return True
def __before__(self): """ __before__ is called before controller methods and after __call__ """ c.rhodecode_version = __version__ c.rhodecode_instanceid = config.get('instance_id') c.rhodecode_name = config.get('rhodecode_title') c.rhodecode_bugtracker = config.get('bugtracker', 'http://bitbucket.org/marcinkuzminski/rhodecode/issues') c.use_gravatar = str2bool(config.get('use_gravatar')) c.ga_code = config.get('rhodecode_ga_code') # Visual options c.visual = AttributeDict({}) rc_config = RhodeCodeSetting.get_app_settings() ## DB stored c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon')) c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon')) c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags')) c.visual.dashboard_items = safe_int(rc_config.get('rhodecode_dashboard_items', 100)) c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields')) c.visual.show_version = str2bool(rc_config.get('rhodecode_show_version')) ## INI stored self.cut_off_limit = int(config.get('cut_off_limit')) c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True)) c.visual.allow_custom_hooks_settings = str2bool(config.get('allow_custom_hooks_settings', True)) c.repo_name = get_repo_slug(request) # can be empty c.backends = BACKENDS.keys() c.unread_notifications = NotificationModel()\ .get_unread_cnt_for_user(c.rhodecode_user.user_id) self.sa = meta.Session self.scm_model = ScmModel(self.sa)
def update_perm(self, id): """PUT /users_perm/id: Update an existing item""" # url('users_group_perm', id=ID, method='put') users_group = UserGroup.get_or_404(id) grant_create_perm = str2bool(request.POST.get('create_repo_perm')) grant_fork_perm = str2bool(request.POST.get('fork_repo_perm')) inherit_perms = str2bool( request.POST.get('inherit_default_permissions')) usergroup_model = UserGroupModel() try: users_group.inherit_default_permissions = inherit_perms Session().add(users_group) if grant_create_perm: usergroup_model.revoke_perm(id, 'hg.create.none') usergroup_model.grant_perm(id, 'hg.create.repository') h.flash( _("Granted 'repository create' permission to user group"), category='success') else: usergroup_model.revoke_perm(id, 'hg.create.repository') usergroup_model.grant_perm(id, 'hg.create.none') h.flash( _("Revoked 'repository create' permission to user group"), category='success') if grant_fork_perm: usergroup_model.revoke_perm(id, 'hg.fork.none') usergroup_model.grant_perm(id, 'hg.fork.repository') h.flash( _("Granted 'repository fork' permission to user group"), category='success') else: usergroup_model.revoke_perm(id, 'hg.fork.repository') usergroup_model.grant_perm(id, 'hg.fork.none') h.flash( _("Revoked 'repository fork' permission to user group"), category='success') Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during permissions saving'), category='error') return redirect(url('edit_users_group', id=id))
def update_application_permissions(self, form_result): if 'perm_user_id' in form_result: perm_user = User.get(safe_int(form_result['perm_user_id'])) else: # used mostly to do lookup for default user perm_user = User.get_by_username(form_result['perm_user_name']) try: # stage 1 set anonymous access if perm_user.username == User.DEFAULT_USER: perm_user.active = str2bool(form_result['anonymous']) self.sa.add(perm_user) # stage 2 reset defaults and set them from form data self._set_new_user_perms(perm_user, form_result, preserve=[ 'default_repo_perm', 'default_group_perm', 'default_user_group_perm', 'default_repo_group_create', 'default_user_group_create', 'default_repo_create_on_write', 'default_repo_create', 'default_fork_create', 'default_inherit_default_permissions', ]) self.sa.commit() except (DatabaseError, ): log.error(traceback.format_exc()) self.sa.rollback() raise
def gravatar_url(email_address, size=30, ssl_enabled=True): from pylons import url # doh, we need to re-import url to mock it later from rhodecode import CONFIG _def = '*****@*****.**' # default gravatar use_gravatar = str2bool(CONFIG.get('use_gravatar')) alternative_gravatar_url = CONFIG.get('alternative_gravatar_url', '') email_address = email_address or _def if not use_gravatar or not email_address or email_address == _def: f = lambda a, l: min(l, key=lambda x: abs(x - a)) return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30])) if use_gravatar and alternative_gravatar_url: tmpl = alternative_gravatar_url parsed_url = urlparse.urlparse(url.current(qualified=True)) tmpl = tmpl.replace('{email}', email_address)\ .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \ .replace('{netloc}', parsed_url.netloc)\ .replace('{scheme}', parsed_url.scheme)\ .replace('{size}', str(size)) return tmpl default = 'identicon' baseurl_nossl = "http://www.gravatar.com/avatar/" baseurl_ssl = "https://secure.gravatar.com/avatar/" baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl if isinstance(email_address, unicode): #hashlib crashes on unicode items email_address = safe_str(email_address) # construct the url gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?" gravatar_url += urllib.urlencode({'d': default, 's': str(size)}) return gravatar_url
def test_str2bool(self): from rhodecode.lib.utils2 import str2bool test_cases = [ ("t", True), ("true", True), ("y", True), ("yes", True), ("on", True), ("1", True), ("Y", True), ("yeS", True), ("Y", True), ("TRUE", True), ("T", True), ("False", False), ("F", False), ("FALSE", False), ("0", False), ("-1", False), ("", False), ] for case in test_cases: self.assertEqual(str2bool(case[0]), case[1])
def gravatar_url(email_address, size=30): from pylons import url # doh, we need to re-import url to mock it later _def = '*****@*****.**' use_gravatar = str2bool(config['app_conf'].get('use_gravatar')) email_address = email_address or _def if (not use_gravatar or not email_address or email_address == _def): f = lambda a, l: min(l, key=lambda x: abs(x - a)) return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30])) if use_gravatar and config['app_conf'].get('alternative_gravatar_url'): tmpl = config['app_conf'].get('alternative_gravatar_url', '') parsed_url = urlparse.urlparse(url.current(qualified=True)) tmpl = tmpl.replace('{email}', email_address)\ .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \ .replace('{netloc}', parsed_url.netloc)\ .replace('{scheme}', parsed_url.scheme)\ .replace('{size}', str(size)) return tmpl ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme') default = 'identicon' baseurl_nossl = "http://www.gravatar.com/avatar/" baseurl_ssl = "https://secure.gravatar.com/avatar/" baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl if isinstance(email_address, unicode): #hashlib crashes on unicode items email_address = safe_str(email_address) # construct the url gravatar_url = baseurl + hashlib.md5( email_address.lower()).hexdigest() + "?" gravatar_url += urllib.urlencode({'d': default, 's': str(size)}) return gravatar_url
def list_enabled_social_plugins(self, settings): enabled = [] for plug in SOCIAL_PLUGINS_LIST: if str2bool(settings.get('rhodecode_auth_{}_enabled'.format(plug) )): enabled.append(plug) return enabled
def get_container_username(environ, config): username = None if str2bool(config.get('container_auth_enabled', False)): from paste.httpheaders import REMOTE_USER username = REMOTE_USER(environ) if not username and str2bool(config.get('proxypass_auth_enabled', False)): username = environ.get('HTTP_X_FORWARDED_USER') if username: # Removing realm and domain from username username = username.partition('@')[0] username = username.rpartition('\\')[2] log.debug('Received username %s from container' % username) return username
def update_perm(self, id): """PUT /users_perm/id: Update an existing item""" # url('users_group_perm', id=ID, method='put') users_group = UsersGroup.get_or_404(id) grant_create_perm = str2bool(request.POST.get('create_repo_perm')) grant_fork_perm = str2bool(request.POST.get('fork_repo_perm')) inherit_perms = str2bool(request.POST.get('inherit_default_permissions')) usersgroup_model = UsersGroupModel() try: users_group.inherit_default_permissions = inherit_perms Session().add(users_group) if grant_create_perm: usersgroup_model.revoke_perm(id, 'hg.create.none') usersgroup_model.grant_perm(id, 'hg.create.repository') h.flash(_("Granted 'repository create' permission to users group"), category='success') else: usersgroup_model.revoke_perm(id, 'hg.create.repository') usersgroup_model.grant_perm(id, 'hg.create.none') h.flash(_("Revoked 'repository create' permission to users group"), category='success') if grant_fork_perm: usersgroup_model.revoke_perm(id, 'hg.fork.none') usersgroup_model.grant_perm(id, 'hg.fork.repository') h.flash(_("Granted 'repository fork' permission to users group"), category='success') else: usersgroup_model.revoke_perm(id, 'hg.fork.repository') usersgroup_model.grant_perm(id, 'hg.fork.none') h.flash(_("Revoked 'repository fork' permission to users group"), category='success') Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during permissions saving'), category='error') return redirect(url('edit_users_group', id=id))
def update(self, form_result): perm_user = User.get_by_username(username=form_result['perm_user_name']) u2p = self.sa.query(UserToPerm).filter(UserToPerm.user == perm_user).all() try: def _make_new(usr, perm_name): new = UserToPerm() new.user = usr new.permission = Permission.get_by_key(perm_name) return new # clear current entries, to make this function idempotent # it will fix even if we define more permissions or permissions # are somehow missing for p in u2p: self.sa.delete(p) #create fresh set of permissions for def_perm_key in ['default_repo_perm', 'default_group_perm', 'default_register', 'default_create', 'default_fork']: p = _make_new(perm_user, form_result[def_perm_key]) self.sa.add(p) #stage 2 update all default permissions for repos if checked if form_result['overwrite_default_repo'] == True: _def_name = form_result['default_repo_perm'].split('repository.')[-1] _def = Permission.get_by_key('repository.' + _def_name) # repos for r2p in self.sa.query(UserRepoToPerm)\ .filter(UserRepoToPerm.user == perm_user)\ .all(): #don't reset PRIVATE repositories if not r2p.repository.private: r2p.permission = _def self.sa.add(r2p) if form_result['overwrite_default_group'] == True: _def_name = form_result['default_group_perm'].split('group.')[-1] # groups _def = Permission.get_by_key('group.' + _def_name) for g2p in self.sa.query(UserRepoGroupToPerm)\ .filter(UserRepoGroupToPerm.user == perm_user)\ .all(): g2p.permission = _def self.sa.add(g2p) # stage 3 set anonymous access if perm_user.username == 'default': perm_user.active = str2bool(form_result['anonymous']) self.sa.add(perm_user) self.sa.commit() except (DatabaseError,): log.error(traceback.format_exc()) self.sa.rollback() raise
def update(self, repo_name, pull_request_id): pull_request_id = safe_int(pull_request_id) pull_request = PullRequest.get_or_404(pull_request_id) # only owner or admin can update it allowed_to_update = PullRequestModel().check_user_update( pull_request, c.rhodecode_user) if allowed_to_update: if 'reviewers_ids' in request.POST: self._update_reviewers(pull_request_id) elif str2bool(request.POST.get('update_commits', 'false')): self._update_commits(pull_request) elif str2bool(request.POST.get('close_pull_request', 'false')): self._reject_close(pull_request) elif str2bool(request.POST.get('edit_pull_request', 'false')): self._edit_pull_request(pull_request) else: raise HTTPBadRequest() return True raise HTTPForbidden()
def __before__(self): c.rhodecode_version = __version__ c.rhodecode_instanceid = config.get("instance_id") c.rhodecode_name = config.get("rhodecode_title") c.use_gravatar = str2bool(config.get("use_gravatar")) c.ga_code = config.get("rhodecode_ga_code") # Visual options c.visual = AttributeDict({}) c.visual.show_public_icon = str2bool(config.get("rhodecode_show_public_icon")) c.visual.show_private_icon = str2bool(config.get("rhodecode_show_private_icon")) c.visual.stylify_metatags = str2bool(config.get("rhodecode_stylify_metatags")) c.repo_name = get_repo_slug(request) c.backends = BACKENDS.keys() c.unread_notifications = NotificationModel().get_unread_cnt_for_user(c.rhodecode_user.user_id) self.cut_off_limit = int(config.get("cut_off_limit")) self.sa = meta.Session self.scm_model = ScmModel(self.sa) self.ip_addr = ""
def __call__(self, environ, start_response): self.__fixup(environ) debug = str2bool(self.config.get('debug')) is_ssl = environ['wsgi.url_scheme'] == 'https' def custom_start_response(status, headers, exc_info=None): if is_ssl and str2bool(self.config.get('use_htsts')) and not debug: headers.append(('Strict-Transport-Security', 'max-age=8640000; includeSubDomains')) return start_response(status, headers, exc_info) return self.application(environ, custom_start_response)
def _check_ssl(self, environ, start_response): """ Checks the SSL check flag and returns False if SSL is not present and required True otherwise """ org_proto = environ["wsgi._org_proto"] # check if we have SSL required ! if not it's a bad request ! require_ssl = str2bool(RhodeCodeUi.get_by_key("push_ssl").ui_value) if require_ssl and org_proto == "http": log.debug("proto is %s and SSL is required BAD REQUEST !" % org_proto) return False return True
def __init__(self, application, config): self.application = application self.config = config # base path of repo locations self.basepath = self.config['base_path'] # authenticate this VCS request using authfunc auth_ret_code_detection = \ str2bool(self.config.get('auth_ret_code_detection', False)) self.authenticate = BasicAuth('', authenticate, config.get('auth_ret_code'), auth_ret_code_detection) self.ip_addr = '0.0.0.0'
def _check_ssl(self, environ, start_response): """ Checks the SSL check flag and returns False if SSL is not present and required True otherwise """ org_proto = environ['wsgi._org_proto'] #check if we have SSL required ! if not it's a bad request ! require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value) if require_ssl and org_proto == 'http': log.debug('proto is %s and SSL is required BAD REQUEST !' % org_proto) return False return True
def includeme(config): settings = config.get_settings() # Create admin navigation registry and add it to the pyramid registry. labs_active = str2bool(settings.get('labs_settings_active', False)) navigation_registry = NavigationRegistry(labs_active=labs_active) config.registry.registerUtility(navigation_registry) config.add_route(name='admin_settings_open_source', pattern=ADMIN_PREFIX + '/settings/open_source') # Scan module for configuration decorators. config.scan()
def fixups(models, _SESSION): from pylons import config from rhodecode.lib.utils2 import str2bool Optional = models.Optional def get_by_name(cls, key): return cls.query().filter(cls.app_settings_name == key).scalar() def create_or_update(cls, key, val=Optional(''), type=Optional('unicode')): res = get_by_name(cls, key) if not res: val = Optional.extract(val) type = Optional.extract(type) res = cls(key, val, type) else: res.app_settings_name = key if not isinstance(val, Optional): # update if set res.app_settings_value = val if not isinstance(type, Optional): # update if set res.app_settings_type = type return res notify('migrating options from .ini file') use_gravatar = str2bool(config.get('use_gravatar')) print('Setting gravatar use to: %s' % use_gravatar) sett = create_or_update(models.RhodeCodeSetting, 'use_gravatar', use_gravatar, 'bool') _SESSION().add(sett) _SESSION.commit() # set the new format of gravatar URL gravatar_url = models.User.DEFAULT_GRAVATAR_URL if config.get('alternative_gravatar_url'): gravatar_url = config.get('alternative_gravatar_url') print('Setting gravatar url to:%s' % gravatar_url) sett = create_or_update(models.RhodeCodeSetting, 'gravatar_url', gravatar_url, 'unicode') _SESSION().add(sett) _SESSION.commit() # now create new changed value of clone_url clone_uri_tmpl = models.Repository.DEFAULT_CLONE_URI print('settings new clone url template to %s' % clone_uri_tmpl) sett = create_or_update(models.RhodeCodeSetting, 'clone_uri_tmpl', clone_uri_tmpl, 'unicode') _SESSION().add(sett) _SESSION.commit()
def __before__(self): super(FeedController, self).__before__() #common values for feeds self.description = _('Changes on %s repository') self.title = self.title = _('%s %s feed') % (c.rhodecode_name, '%s') self.language = 'en-us' self.ttl = "5" import rhodecode CONF = rhodecode.CONFIG self.include_diff = str2bool(CONF.get('rss_include_diff', False)) self.feed_nr = safe_int(CONF.get('rss_items_per_page', 20)) # we need to protect from parsing huge diffs here other way # we can kill the server self.feed_diff_limit = safe_int(CONF.get('rss_cut_off_limit', 32 * 1024))
def command(self): from pylons import config try: CELERY_ON = str2bool(config['app_conf'].get('use_celery')) except KeyError: CELERY_ON = False if not CELERY_ON: raise Exception('Please enable celery_on in .ini config ' 'file before running celeryd') rhodecode.CELERY_ON = CELERY_ON load_rcextensions(config['here']) cmd = self.celery_command(app_or_default()) return cmd.run(**vars(self.options))
def __before__(self): c.rhodecode_version = __version__ c.rhodecode_instanceid = config.get('instance_id') c.rhodecode_name = config.get('rhodecode_title') c.use_gravatar = str2bool(config.get('use_gravatar')) c.ga_code = config.get('rhodecode_ga_code') c.repo_name = get_repo_slug(request) c.backends = BACKENDS.keys() c.unread_notifications = NotificationModel()\ .get_unread_cnt_for_user(c.rhodecode_user.user_id) self.cut_off_limit = int(config.get('cut_off_limit')) self.sa = meta.Session self.scm_model = ScmModel(self.sa)
def show_all(self, repo_name): # filter types c.active = 'open' c.source = str2bool(request.GET.get('source')) c.closed = str2bool(request.GET.get('closed')) c.my = str2bool(request.GET.get('my')) c.awaiting_review = str2bool(request.GET.get('awaiting_review')) c.awaiting_my_review = str2bool(request.GET.get('awaiting_my_review')) c.repo_name = repo_name opened_by = None if c.my: c.active = 'my' opened_by = [c.rhodecode_user.user_id] statuses = [PullRequest.STATUS_NEW, PullRequest.STATUS_OPEN] if c.closed: c.active = 'closed' statuses = [PullRequest.STATUS_CLOSED] if c.awaiting_review and not c.source: c.active = 'awaiting' if c.source and not c.awaiting_review: c.active = 'source' if c.awaiting_my_review: c.active = 'awaiting_my' data = self._get_pull_requests_list(repo_name=repo_name, opened_by=opened_by, statuses=statuses) if not request.is_xhr: c.data = json.dumps(data['data']) c.records_total = data['recordsTotal'] return render('/pullrequests/pullrequests.html') else: return json.dumps(data)
def show_id(cs): """ Configurable function that shows ID by default it's r123:fffeeefffeee :param cs: changeset instance """ from rhodecode import CONFIG def_len = safe_int(CONFIG.get('show_sha_length', 12)) show_rev = str2bool(CONFIG.get('show_revision_number', True)) raw_id = cs.raw_id[:def_len] if show_rev: return 'r%s:%s' % (cs.revision, raw_id) else: return '%s' % (raw_id)
def fixups(models, _SESSION): notify('Fixing default auth modules') plugins = 'rhodecode.lib.auth_modules.auth_rhodecode' opts = [] ldap_enabled = str2bool( getattr(get_by_name(models.RhodeCodeSetting, 'ldap_active'), 'app_settings_value', False)) if ldap_enabled: plugins += ',rhodecode.lib.auth_modules.auth_ldap' opts.append(('auth_ldap_enabled', 'True', 'bool')) opts.append(('auth_plugins', plugins, 'list'), ) opts.append(('auth_rhodecode_enabled', 'True', 'bool')) for name, default, type_ in opts: setting = get_by_name(models.RhodeCodeSetting, name) if not setting: # if we don't have this option create it setting = models.RhodeCodeSetting(name, default, type_) _SESSION().add(setting) _SESSION().commit() #copy over the LDAP settings old_ldap = [ ('ldap_active', 'false', 'bool'), ('ldap_host', '', 'unicode'), ('ldap_port', '389', 'int'), ('ldap_tls_kind', 'PLAIN', 'unicode'), ('ldap_tls_reqcert', '', 'unicode'), ('ldap_dn_user', '', 'unicode'), ('ldap_dn_pass', '', 'unicode'), ('ldap_base_dn', '', 'unicode'), ('ldap_filter', '', 'unicode'), ('ldap_search_scope', '', 'unicode'), ('ldap_attr_login', '', 'unicode'), ('ldap_attr_firstname', '', 'unicode'), ('ldap_attr_lastname', '', 'unicode'), ('ldap_attr_email', '', 'unicode') ] for k, v, t in old_ldap: old_setting = get_by_name(models.RhodeCodeSetting, k) name = 'auth_%s' % k setting = get_by_name(models.RhodeCodeSetting, name) if not setting: # if we don't have this option create it setting = models.RhodeCodeSetting(name, old_setting.app_settings_value, t) _SESSION().add(setting) _SESSION().commit()
def propagate_data(self): user_model = UserModel() self.anonymous_user = User.get_by_username('default', cache=True) is_user_loaded = False # try go get user by api key if self._api_key and self._api_key != self.anonymous_user.api_key: log.debug('Auth User lookup by API KEY %s' % self._api_key) is_user_loaded = user_model.fill_data(self, api_key=self._api_key) # lookup by userid elif (self.user_id is not None and self.user_id != self.anonymous_user.user_id): log.debug('Auth User lookup by USER ID %s' % self.user_id) is_user_loaded = user_model.fill_data(self, user_id=self.user_id) # lookup by username elif self.username and \ str2bool(config.get('container_auth_enabled', False)): log.debug('Auth User lookup by USER NAME %s' % self.username) dbuser = login_container_auth(self.username) if dbuser is not None: log.debug('filling all attributes to object') for k, v in dbuser.get_dict().items(): setattr(self, k, v) self.set_authenticated() is_user_loaded = True else: log.debug('No data in %s that could been used to log in' % self) if not is_user_loaded: # if we cannot authenticate user try anonymous if self.anonymous_user.active: user_model.fill_data(self, user_id=self.anonymous_user.user_id) # then we set this user is logged in self.is_authenticated = True else: self.user_id = None self.username = None self.is_authenticated = False if not self.username: self.username = '******' log.debug('Auth User is now %s' % self) user_model.fill_perms(self)
def test_create(self, repo_stub): model = VcsSettingsModel(repo=repo_stub.repo_name) model._create_or_update_ui(model.repo_settings, 'test-section', 'test-key', active=False, value='False') Session().commit() created_ui = model.repo_settings.get_ui_by_section_and_key( 'test-section', 'test-key') try: assert created_ui.ui_active is False assert str2bool(created_ui.ui_value) is False finally: Session().delete(created_ui) Session().commit()
def delete_repos_group_user_perm(self, group_name): """ DELETE an existing repositories group permission user :param group_name: """ try: recursive = str2bool(request.POST.get('recursive', False)) ReposGroupModel().delete_permission( repos_group=group_name, obj=request.POST['user_id'], obj_type='user', recursive=recursive ) Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of group user'), category='error') raise HTTPInternalServerError()
def _get_config(self): import rhodecode config = rhodecode.CONFIG return { 'language': 'en-us', 'feed_ttl': '5', # TTL of feed, 'feed_include_diff': str2bool(config.get('rss_include_diff', False)), 'feed_items_per_page': safe_int(config.get('rss_items_per_page', 20)), 'feed_diff_limit': # we need to protect from parsing huge diffs here other way # we can kill the server safe_int(config.get('rss_cut_off_limit', 32 * 1024)), }
def gravatar_url(email_address, size=30): if (not str2bool(config['app_conf'].get('use_gravatar')) or not email_address or email_address == '*****@*****.**'): f = lambda a, l: min(l, key=lambda x: abs(x - a)) return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30])) ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme') default = 'identicon' baseurl_nossl = "http://www.gravatar.com/avatar/" baseurl_ssl = "https://secure.gravatar.com/avatar/" baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl if isinstance(email_address, unicode): #hashlib crashes on unicode items email_address = safe_str(email_address) # construct the url gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?" gravatar_url += urllib.urlencode({'d': default, 's': str(size)}) return gravatar_url
def delete_repos_group_users_group_perm(self, group_name): """ DELETE an existing repository group permission user group :param group_name: """ try: recursive = str2bool(request.POST.get('recursive', False)) ReposGroupModel().delete_permission( repos_group=group_name, obj=request.POST['users_group_id'], obj_type='users_group', recursive=recursive) Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of group' ' user groups'), category='error') raise HTTPInternalServerError()
def gravatar_url(email_address, size=30): if (not str2bool(config['app_conf'].get('use_gravatar')) or not email_address or email_address == '*****@*****.**'): f = lambda a, l: min(l, key=lambda x: abs(x - a)) return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30])) ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme') default = 'identicon' baseurl_nossl = "http://www.gravatar.com/avatar/" baseurl_ssl = "https://secure.gravatar.com/avatar/" baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl if isinstance(email_address, unicode): #hashlib crashes on unicode items email_address = safe_str(email_address) # construct the url gravatar_url = baseurl + hashlib.md5( email_address.lower()).hexdigest() + "?" gravatar_url += urllib.urlencode({'d': default, 's': str(size)}) return gravatar_url
def __fixup(self, environ): """ Function to fixup the environ as needed. In order to use this middleware you should set this header inside your proxy ie. nginx, apache etc. """ # DETECT PROTOCOL ! if 'HTTP_X_URL_SCHEME' in environ: proto = environ.get('HTTP_X_URL_SCHEME') elif 'HTTP_X_FORWARDED_SCHEME' in environ: proto = environ.get('HTTP_X_FORWARDED_SCHEME') elif 'HTTP_X_FORWARDED_PROTO' in environ: proto = environ.get('HTTP_X_FORWARDED_PROTO') else: proto = 'http' org_proto = proto # if we have force, just override if str2bool(self.config.get('force_https')): proto = 'https' environ['wsgi.url_scheme'] = proto environ['wsgi._org_proto'] = org_proto
def delete_repos_group_user_perm(self, group_name): """ DELETE an existing repository group permission user :param group_name: """ try: if not c.rhodecode_user.is_admin: if c.rhodecode_user.user_id == safe_int(request.POST['user_id']): msg = _('Cannot revoke permission for yourself as admin') h.flash(msg, category='warning') raise Exception('revoke admin permission on self') recursive = str2bool(request.POST.get('recursive', False)) ReposGroupModel().delete_permission( repos_group=group_name, obj=request.POST['user_id'], obj_type='user', recursive=recursive ) Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during deletion of group user'), category='error') raise HTTPInternalServerError()
def _get_hg_ui_settings(self): ret = RhodeCodeUi.query().all() if not ret: raise Exception('Could not get application ui settings !') settings = {} for each in ret: k = each.ui_key v = each.ui_value if k == '/': k = 'root_path' if k == 'push_ssl': v = str2bool(v) if k.find('.') != -1: k = k.replace('.', '_') if each.ui_section in ['hooks', 'extensions']: v = each.ui_active settings[each.ui_section + '_' + k] = v return settings
def test_update(self, repo_stub, settings_util): model = VcsSettingsModel(repo=repo_stub.repo_name) largefiles, phases = model.HG_SETTINGS section = 'test-section' key = 'test-key' settings_util.create_repo_rhodecode_ui(repo_stub, section, 'True', key=key, active=True) model._create_or_update_ui(model.repo_settings, section, key, active=False, value='False') Session().commit() created_ui = model.repo_settings.get_ui_by_section_and_key( section, key) assert created_ui.ui_active is False assert str2bool(created_ui.ui_value) is False
def test_str2bool(self): from rhodecode.lib.utils2 import str2bool test_cases = [ ('t', True), ('true', True), ('y', True), ('yes', True), ('on', True), ('1', True), ('Y', True), ('yeS', True), ('Y', True), ('TRUE', True), ('T', True), ('False', False), ('F', False), ('FALSE', False), ('0', False), ('-1', False), ('', False), ] for case in test_cases: self.assertEqual(str2bool(case[0]), case[1])
def _get_username(self, environ, settings): username = None environ = environ or {} if not environ: log.debug('got empty environ: %s' % environ) settings = settings or {} if settings.get('header'): header = settings.get('header') username = environ.get(header) log.debug('extracted %s:%s' % (header, username)) # fallback mode if not username and settings.get('fallback_header'): header = settings.get('fallback_header') username = environ.get(header) log.debug('extracted %s:%s' % (header, username)) if username and str2bool(settings.get('clean_username')): log.debug('Received username `%s` from headers' % username) username = self._clean_username(username) log.debug('New cleanup user is:%s' % username) return username
def delete(self, user_group_id): """DELETE /user_groups/user_group_id: Delete an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="DELETE" /> # Or using helpers: # h.form(url('users_group', user_group_id=ID), # method='delete') # url('users_group', user_group_id=ID) user_group_id = safe_int(user_group_id) c.user_group = UserGroup.get_or_404(user_group_id) force = str2bool(request.POST.get('force')) try: UserGroupModel().delete(c.user_group, force=force) Session().commit() h.flash(_('Successfully deleted user group'), category='success') except UserGroupAssignedException as e: h.flash(str(e), category='error') except Exception: log.exception("Exception during deletion of user group") h.flash(_('An error occurred during deletion of user group'), category='error') return redirect(url('users_groups'))
def __fixup(self, environ): """ Function to fixup the environ as needed. In order to use this middleware you should set this header inside your proxy ie. nginx, apache etc. """ if str2bool(self.config.get("force_https")): proto = "https" else: if "HTTP_X_URL_SCHEME" in environ: proto = environ.get("HTTP_X_URL_SCHEME") elif "HTTP_X_FORWARDED_SCHEME" in environ: proto = environ.get("HTTP_X_FORWARDED_SCHEME") elif "HTTP_X_FORWARDED_PROTO" in environ: proto = environ.get("HTTP_X_FORWARDED_PROTO") else: proto = "http" if proto == "https": environ["wsgi.url_scheme"] = proto else: environ["wsgi.url_scheme"] = "http" return None
def load_environment(global_conf, app_conf, initial=False): """ Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict( root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')] ) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='rhodecode', paths=paths) # store some globals into rhodecode rhodecode.CELERY_ON = str2bool(config['app_conf'].get('use_celery')) rhodecode.CELERY_EAGER = str2bool(config['app_conf'].get('celery.always.eager')) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = helpers rhodecode.CONFIG = config load_rcextensions(root_path=config['here']) # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) # sets the c attribute access when don't existing attribute are accessed config['pylons.strict_tmpl_context'] = True test = os.path.split(config['__file__'])[-1] == 'test.ini' if test: if os.environ.get('TEST_DB'): # swap config if we pass enviroment variable config['sqlalchemy.db1.url'] = os.environ.get('TEST_DB') from rhodecode.lib.utils import create_test_env, create_test_index from rhodecode.tests import TESTS_TMP_PATH # set RC_NO_TMP_PATH=1 to disable re-creating the database and # test repos if not int(os.environ.get('RC_NO_TMP_PATH', 0)): create_test_env(TESTS_TMP_PATH, config) # set RC_WHOOSH_TEST_DISABLE=1 to disable whoosh index during tests if not int(os.environ.get('RC_WHOOSH_TEST_DISABLE', 0)): create_test_index(TESTS_TMP_PATH, config, True) #check git version check_git_version() DbManage.check_waitress() # MULTIPLE DB configs # Setup the SQLAlchemy database engine sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.') init_model(sa_engine_db1) repos_path = make_ui('db').configitems('paths')[0][1] repo2db_mapper(ScmModel().repo_scan(repos_path), remove_obsolete=False, install_git_hook=False) set_available_permissions(config) config['base_path'] = repos_path set_rhodecode_config(config) instance_id = rhodecode.CONFIG.get('instance_id') if instance_id == '*': instance_id = '%s-%s' % (os.uname()[1], os.getpid()) rhodecode.CONFIG['instance_id'] = instance_id # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) # store config reference into our module to skip import magic of # pylons rhodecode.CONFIG.update(config) return config
def authenticate(username, password): """ Authentication function used for access control, firstly checks for db authentication then if ldap is enabled for ldap authentication, also creates ldap user if not in database :param username: username :param password: password """ user_model = UserModel() user = User.get_by_username(username) log.debug('Authenticating user using RhodeCode account') if user is not None and not user.ldap_dn: if user.active: if user.username == 'default' and user.active: log.info('user %s authenticated correctly as anonymous user' % username) return True elif user.username == username and check_password(password, user.password): log.info('user %s authenticated correctly' % username) return True else: log.warning('user %s tried auth but is disabled' % username) else: log.debug('Regular authentication failed') user_obj = User.get_by_username(username, case_insensitive=True) if user_obj is not None and not user_obj.ldap_dn: log.debug('this user already exists as non ldap') return False ldap_settings = RhodeCodeSetting.get_ldap_settings() #====================================================================== # FALLBACK TO LDAP AUTH IF ENABLE #====================================================================== if str2bool(ldap_settings.get('ldap_active')): log.debug("Authenticating user using ldap") kwargs = { 'server': ldap_settings.get('ldap_host', ''), 'base_dn': ldap_settings.get('ldap_base_dn', ''), 'port': ldap_settings.get('ldap_port'), 'bind_dn': ldap_settings.get('ldap_dn_user'), 'bind_pass': ldap_settings.get('ldap_dn_pass'), 'tls_kind': ldap_settings.get('ldap_tls_kind'), 'tls_reqcert': ldap_settings.get('ldap_tls_reqcert'), 'ldap_filter': ldap_settings.get('ldap_filter'), 'search_scope': ldap_settings.get('ldap_search_scope'), 'attr_login': ldap_settings.get('ldap_attr_login'), 'ldap_version': 3, } log.debug('Checking for ldap authentication') try: aldap = AuthLdap(**kwargs) (user_dn, ldap_attrs) = aldap.authenticate_ldap(username, password) log.debug('Got ldap DN response %s' % user_dn) get_ldap_attr = lambda k: ldap_attrs.get(ldap_settings\ .get(k), [''])[0] user_attrs = { 'name': safe_unicode(get_ldap_attr('ldap_attr_firstname')), 'lastname': safe_unicode(get_ldap_attr('ldap_attr_lastname')), 'email': get_ldap_attr('ldap_attr_email'), 'active': 'hg.extern_activate.auto' in User.get_default_user()\ .AuthUser.permissions['global'] } # don't store LDAP password since we don't need it. Override # with some random generated password _password = PasswordGenerator().gen_password(length=8) # create this user on the fly if it doesn't exist in rhodecode # database if user_model.create_ldap(username, _password, user_dn, user_attrs): log.info('created new ldap user %s' % username) Session().commit() return True except (LdapUsernameError, LdapPasswordError, LdapImportError): pass except (Exception,): log.error(traceback.format_exc()) pass return False
def to_python(self, value, state): perms_update = OrderedSet() perms_new = OrderedSet() # build a list of permission to update and new permission to create #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using new_perms_group = defaultdict(dict) for k, v in value.copy().iteritems(): if k.startswith('perm_new_member'): del value[k] _type, part = k.split('perm_new_member_') args = part.split('_') if len(args) == 1: new_perms_group[args[0]]['perm'] = v elif len(args) == 2: _key, pos = args new_perms_group[pos][_key] = v # fill new permissions in order of how they were added for k in sorted(map(int, new_perms_group.keys())): perm_dict = new_perms_group[str(k)] new_member = perm_dict.get('name') new_perm = perm_dict.get('perm') new_type = perm_dict.get('type') if new_member and new_perm and new_type: perms_new.add((new_member, new_perm, new_type)) for k, v in value.iteritems(): if k.startswith('u_perm_') or k.startswith('g_perm_'): member = k[7:] t = {'u': 'user', 'g': 'users_group' }[k[0]] if member == 'default': if str2bool(value.get('repo_private')): # set none for default when updating to # private repo protects agains form manipulation v = EMPTY_PERM perms_update.add((member, v, t)) value['perms_updates'] = list(perms_update) value['perms_new'] = list(perms_new) # update permissions for k, v, t in perms_new: try: if t is 'user': self.user_db = User.query()\ .filter(User.active == True)\ .filter(User.username == k).one() if t is 'users_group': self.user_db = UserGroup.query()\ .filter(UserGroup.users_group_active == True)\ .filter(UserGroup.users_group_name == k).one() except Exception: log.exception('Updated permission failed') msg = M(self, 'perm_new_member_type', state) raise formencode.Invalid(msg, value, state, error_dict=dict(perm_new_member_name=msg) ) return value
def app_settings_value(self): v = self._app_settings_value if v == "ldap_active": v = str2bool(v) return v
def app_settings_value(self): v = self._app_settings_value if self.app_settings_name == 'ldap_active': v = str2bool(v) return v
def diff(self, repo_name, f_path): ignore_whitespace = request.GET.get('ignorews') == '1' line_context = request.GET.get('context', 3) diff1 = request.GET.get('diff1', '') diff2 = request.GET.get('diff2', '') c.action = request.GET.get('diff') c.no_changes = diff1 == diff2 c.f_path = f_path c.big_diff = False c.anchor_url = anchor_url c.ignorews_url = _ignorews_url c.context_url = _context_url c.changes = OrderedDict() c.changes[diff2] = [] #special case if we want a show rev only, it's impl here #to reduce JS and callbacks if request.GET.get('show_rev'): if str2bool(request.GET.get('annotate', 'False')): _url = url('files_annotate_home', repo_name=c.repo_name, revision=diff1, f_path=c.f_path) else: _url = url('files_home', repo_name=c.repo_name, revision=diff1, f_path=c.f_path) return redirect(_url) try: if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) try: node1 = c.changeset_1.get_node(f_path) except NodeDoesNotExistError: c.changeset_1 = EmptyChangeset(cs=diff1, revision=c.changeset_1.revision, repo=c.rhodecode_repo) node1 = FileNode(f_path, '', changeset=c.changeset_1) else: c.changeset_1 = EmptyChangeset(repo=c.rhodecode_repo) node1 = FileNode(f_path, '', changeset=c.changeset_1) if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]: c.changeset_2 = c.rhodecode_repo.get_changeset(diff2) try: node2 = c.changeset_2.get_node(f_path) except NodeDoesNotExistError: c.changeset_2 = EmptyChangeset(cs=diff2, revision=c.changeset_2.revision, repo=c.rhodecode_repo) node2 = FileNode(f_path, '', changeset=c.changeset_2) else: c.changeset_2 = EmptyChangeset(repo=c.rhodecode_repo) node2 = FileNode(f_path, '', changeset=c.changeset_2) except (RepositoryError, NodeError): log.error(traceback.format_exc()) return redirect(url('files_home', repo_name=c.repo_name, f_path=f_path)) if c.action == 'download': _diff = diffs.get_gitdiff(node1, node2, ignore_whitespace=ignore_whitespace, context=line_context) diff = diffs.DiffProcessor(_diff, format='gitdiff') diff_name = '%s_vs_%s.diff' % (diff1, diff2) response.content_type = 'text/plain' response.content_disposition = ( 'attachment; filename=%s' % diff_name ) return diff.as_raw() elif c.action == 'raw': _diff = diffs.get_gitdiff(node1, node2, ignore_whitespace=ignore_whitespace, context=line_context) diff = diffs.DiffProcessor(_diff, format='gitdiff') response.content_type = 'text/plain' return diff.as_raw() else: fid = h.FID(diff2, node2.path) line_context_lcl = get_line_ctx(fid, request.GET) ign_whitespace_lcl = get_ignore_ws(fid, request.GET) lim = request.GET.get('fulldiff') or self.cut_off_limit _, cs1, cs2, diff, st = diffs.wrapped_diff(filenode_old=node1, filenode_new=node2, cut_off_limit=lim, ignore_whitespace=ign_whitespace_lcl, line_context=line_context_lcl, enable_comments=False) op = '' filename = node1.path cs_changes = { 'fid': [cs1, cs2, op, filename, diff, st] } c.changes = cs_changes return render('files/file_diff.html')