def test_delete(self): self.log_user() cur_user = self._get_logged_user() u1 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u1', lastname='u1') u2 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u2', lastname='u2') # make notifications notification = NotificationModel().create(created_by=cur_user, subject=u'test', body=u'hi there', recipients=[cur_user, u1, u2]) self.Session().commit() u1 = User.get(u1.user_id) u2 = User.get(u2.user_id) # check DB get_notif = lambda un: [x.notification for x in un] self.assertEqual(get_notif(cur_user.notifications), [notification]) self.assertEqual(get_notif(u1.notifications), [notification]) self.assertEqual(get_notif(u2.notifications), [notification]) cur_usr_id = cur_user.user_id response = self.app.delete(url('notification', notification_id= notification.notification_id)) cur_user = User.get(cur_usr_id) self.assertEqual(cur_user.notifications, [])
def test_create_notification(self): self.assertEqual([], Notification.query().all()) self.assertEqual([], UserNotification.query().all()) usrs = [self.u1, self.u2] notification = NotificationModel().create(created_by=self.u1, subject=u'subj', body=u'hi there', recipients=usrs) Session().commit() u1 = User.get(self.u1) u2 = User.get(self.u2) u3 = User.get(self.u3) notifications = Notification.query().all() self.assertEqual(len(notifications), 1) self.assertEqual(notifications[0].recipients, [u1, u2]) self.assertEqual(notification.notification_id, notifications[0].notification_id) unotification = UserNotification.query()\ .filter(UserNotification.notification == notification).all() self.assertEqual(len(unotification), len(usrs)) self.assertEqual(set([x.user.user_id for x in unotification]), set(usrs))
def test_delete(self): self.log_user() cur_user = self._get_logged_user() u1 = UserModel().create_or_update( username="******", password="******", email="*****@*****.**", firstname="u1", lastname="u1" ) u2 = UserModel().create_or_update( username="******", password="******", email="*****@*****.**", firstname="u2", lastname="u2" ) # make notifications notification = NotificationModel().create( created_by=cur_user, subject=u"test", body=u"hi there", recipients=[cur_user, u1, u2] ) Session().commit() u1 = User.get(u1.user_id) u2 = User.get(u2.user_id) # check DB get_notif = lambda un: [x.notification for x in un] self.assertEqual(get_notif(cur_user.notifications), [notification]) self.assertEqual(get_notif(u1.notifications), [notification]) self.assertEqual(get_notif(u2.notifications), [notification]) cur_usr_id = cur_user.user_id response = self.app.delete(url("notification", notification_id=notification.notification_id)) self.assertEqual(response.body, "ok") cur_user = User.get(cur_usr_id) self.assertEqual(cur_user.notifications, [])
def test_delete(self): self.log_user() cur_user = self._get_logged_user() u1 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u1', lastname='u1') u2 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u2', lastname='u2') # make notifications notification = NotificationModel().create(created_by=cur_user, subject=u'test', body=u'hi there', recipients=[cur_user, u1, u2]) Session().commit() u1 = User.get(u1.user_id) u2 = User.get(u2.user_id) # check DB get_notif = lambda un: [x.notification for x in un] self.assertEqual(get_notif(cur_user.notifications), [notification]) self.assertEqual(get_notif(u1.notifications), [notification]) self.assertEqual(get_notif(u2.notifications), [notification]) cur_usr_id = cur_user.user_id response = self.app.delete(url('notification', notification_id= notification.notification_id)) self.assertEqual(response.body, 'ok') cur_user = User.get(cur_usr_id) self.assertEqual(cur_user.notifications, [])
def test_my_account_remove_auth_token(self): # TODO: without this cleanup it fails when run with the whole # test suite, so there must be some interference with other tests. UserApiKeys.query().delete() usr = self.log_user('test_regular2', 'test12') User.get(usr['user_id']) response = self.app.post(url('my_account_auth_tokens'), { 'description': 'desc', 'lifetime': -1, 'csrf_token': self.csrf_token }) assert_session_flash(response, 'Auth token successfully created') response = response.follow() # now delete our key keys = UserApiKeys.query().all() assert 1 == len(keys) response = self.app.post( url('my_account_auth_tokens'), { '_method': 'delete', 'del_auth_token': keys[0].api_key, 'csrf_token': self.csrf_token }) assert_session_flash(response, 'Auth token successfully deleted') keys = UserApiKeys.query().all() assert 0 == len(keys)
def test_create_notification(self): self.assertEqual([], Notification.query().all()) self.assertEqual([], UserNotification.query().all()) usrs = [self.u1, self.u2] notification = NotificationModel().create(created_by=self.u1, subject=u'subj', body=u'hi there', recipients=usrs) Session().commit() u1 = User.get(self.u1) u2 = User.get(self.u2) u3 = User.get(self.u3) notifications = Notification.query().all() self.assertEqual(len(notifications), 1) self.assertEqual(notifications[0].recipients, [u1, u2]) self.assertEqual(notification.notification_id, notifications[0].notification_id) unotification = UserNotification.query()\ .filter(UserNotification.notification == notification).all() self.assertEqual(len(unotification), len(usrs)) self.assertEqual(set([x.user.user_id for x in unotification]), set(usrs))
def log_pull_action(ui, repo, **kwargs): """ Logs user last pull action :param ui: :param repo: """ ex = _extract_extras() user = User.get_by_username(ex.username) action = 'pull' action_logger(user, action, ex.repository, ex.ip, commit=True) # extension hook call from rhodecode import EXTENSIONS callback = getattr(EXTENSIONS, 'PULL_HOOK', None) if isfunction(callback): kw = {} kw.update(ex) callback(**kw) if ex.make_lock is not None and ex.make_lock: Repository.lock(Repository.get_by_repo_name(ex.repository), user.user_id) #msg = 'Made lock on repo `%s`' % repository #sys.stdout.write(msg) if ex.locked_by[0]: locked_by = User.get(ex.locked_by[0]).username _http_ret = HTTPLockedRC(ex.repository, locked_by) if str(_http_ret.code).startswith('2'): #2xx Codes don't raise exceptions sys.stdout.write(_http_ret.title) return 0
def __load_data(self): c.user = User.get(c.rhodecode_user.user_id) if c.user.username == User.DEFAULT_USER: h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') return redirect(url('users'))
def index(self): # Return a rendered template p = safe_int(request.GET.get('page', 1), 1) c.user = User.get(c.rhodecode_user.user_id) following = self.sa.query(UserFollowing)\ .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\ .options(joinedload(UserFollowing.follows_repository))\ .all() journal = self._get_journal_data(following) def url_generator(**kw): return url.current(filter=c.search_term, **kw) c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render('journal/journal_data.html') if request.is_xhr: return c.journal_data return render('journal/journal.html')
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 update_object_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 2 reset defaults and set them from form data self._set_new_user_perms( perm_user, form_result, preserve=[ 'default_repo_group_create', 'default_user_group_create', 'default_repo_create_on_write', 'default_repo_create', 'default_fork_create', 'default_inherit_default_permissions', 'default_register', 'default_extern_activate' ]) # overwrite default repo permissions if form_result['overwrite_default_repo']: _def_name = form_result['default_repo_perm'].split( 'repository.')[-1] _def = Permission.get_by_key('repository.' + _def_name) 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) # overwrite default repo group permissions if form_result['overwrite_default_group']: _def_name = form_result['default_group_perm'].split( 'group.')[-1] _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) # overwrite default user group permissions if form_result['overwrite_default_user_group']: _def_name = form_result['default_user_group_perm'].split( 'usergroup.')[-1] # user groups _def = Permission.get_by_key('usergroup.' + _def_name) for g2p in self.sa.query(UserUserGroupToPerm)\ .filter(UserUserGroupToPerm.user == perm_user)\ .all(): g2p.permission = _def self.sa.add(g2p) self.sa.commit() except (DatabaseError, ): log.exception('Failed to set default object permissions') self.sa.rollback() raise
def pre_push(extras): """ Hook executed before pushing code. It bans pushing when the repository is locked. """ usr = User.get_by_username(extras.username) output = '' if extras.locked_by[0] and usr.user_id != int(extras.locked_by[0]): locked_by = User.get(extras.locked_by[0]).username reason = extras.locked_by[2] # this exception is interpreted in git/hg middlewares and based # on that proper return code is server to client _http_ret = HTTPLockedRC( _locked_by_explanation(extras.repository, locked_by, reason)) if str(_http_ret.code).startswith('2'): # 2xx Codes don't raise exceptions output = _http_ret.title else: raise _http_ret # Calling hooks after checking the lock, for consistent behavior pre_push_extension(repo_store_path=Repository.base_path(), **extras) return HookResponse(0, output)
def index(self): # Return a rendered template p = int(request.params.get('page', 1)) c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name)).all() c.user_repos = ScmModel().get_repos(all_repos) c.following = self.sa.query(UserFollowing)\ .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\ .options(joinedload(UserFollowing.follows_repository))\ .all() journal = self._get_journal_data(c.following) c.journal_pager = Page(journal, page=p, items_per_page=20) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render('journal/journal_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.journal_data return render('journal/journal.html')
def pre_push(ui, repo, **kwargs): # pre push function, currently used to ban pushing when # repository is locked try: rc_extras = json.loads(os.environ.get('RC_SCM_DATA', "{}")) except: rc_extras = {} extras = dict(repo.ui.configitems('rhodecode_extras')) if 'username' in extras: username = extras['username'] repository = extras['repository'] scm = extras['scm'] locked_by = extras['locked_by'] elif 'username' in rc_extras: username = rc_extras['username'] repository = rc_extras['repository'] scm = rc_extras['scm'] locked_by = rc_extras['locked_by'] else: raise Exception('Missing data in repo.ui and os.environ') usr = User.get_by_username(username) if locked_by[0] and usr.user_id != int(locked_by[0]): locked_by = User.get(locked_by[0]).username raise HTTPLockedRC(repository, locked_by)
def index(self): # Return a rendered template p = int(request.params.get('page', 1)) c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name)).all() c.user_repos = ScmModel().get_repos(all_repos) c.following = self.sa.query(UserFollowing)\ .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\ .options(joinedload(UserFollowing.follows_repository))\ .all() journal = self._get_journal_data(c.following) c.journal_pager = Page(journal, page=p, items_per_page=20) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render('journal/journal_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.journal_data return render('journal/journal.html')
def deactivate_last_users(self, expected_users): """ Deactivate accounts that are over the license limits. Algorithm of which accounts to disabled is based on the formula: Get current user, then super admins in creation order, then regular active users in creation order. Using that list we mark all accounts from the end of it as inactive. This way we block only latest created accounts. :param expected_users: list of users in special order, we deactivate the end N ammoun of users from that list """ list_of_accounts = self.get_accounts_in_creation_order() for acc_id in list_of_accounts[expected_users + 1:]: user = User.get(acc_id) log.info('Deactivating account %s for license unlock', user) user.active = False Session().add(user) Session().commit() return
def my_account(self): """ GET /_admin/my_account Displays info about my account """ # url('admin_settings_my_account') c.user = User.get(self.rhodecode_user.user_id) c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id, ip_addr=self.ip_addr) c.ldap_dn = c.user.ldap_dn if c.user.username == 'default': h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') return redirect(url('users')) #json used to render the grid c.data = self._load_my_repos_data() defaults = c.user.get_dict() c.form = htmlfill.render( render('admin/users/user_edit_my_account_form.html'), defaults=defaults, encoding="UTF-8", force_defaults=False ) return render('admin/users/user_edit_my_account.html')
def my_account(self): """ GET /_admin/my_account Displays info about my account """ # url('admin_settings_my_account') c.user = User.get(self.rhodecode_user.user_id) c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id, ip_addr=self.ip_addr) c.ldap_dn = c.user.ldap_dn if c.user.username == 'default': h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') return redirect(url('users')) #json used to render the grid c.data = self._load_my_repos_data() defaults = c.user.get_dict() c.form = htmlfill.render( render('admin/users/user_edit_my_account_form.html'), defaults=defaults, encoding="UTF-8", force_defaults=False) return render('admin/users/user_edit_my_account.html')
def my_account_update(self): """PUT /_admin/my_account_update: 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('admin_settings_my_account_update'), # method='put') # url('admin_settings_my_account_update', id=ID) user_model = UserModel() uid = self.rhodecode_user.user_id _form = UserForm(edit=True, old_data={'user_id': uid, 'email': self.rhodecode_user.email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) user_model.update_my_account(uid, form_result) h.flash(_('Your account was updated successfully'), category='success') Session.commit() except formencode.Invalid, errors: c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name))\ .all() c.user_repos = ScmModel().get_repos(all_repos) return htmlfill.render( render('admin/users/user_edit_my_account.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8")
def my_account(self): """ GET /_admin/my_account Displays info about my account """ # url('admin_settings_my_account') c.user = User.get(self.rhodecode_user.user_id) all_repos = self.sa.query(Repository)\ .filter(Repository.user_id == c.user.user_id)\ .order_by(func.lower(Repository.repo_name)).all() c.user_repos = ScmModel().get_repos(all_repos) if c.user.username == 'default': h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') return redirect(url('users')) defaults = c.user.get_dict() return htmlfill.render( render('admin/users/user_edit_my_account.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
def post_pull(extras): """Hook executed after client pulls the code.""" user = User.get_by_username(extras.username) action = 'pull' action_logger(user, action, extras.repository, extras.ip, commit=True) # extension hook call post_pull_extension(**extras) output = '' # make lock is a tri state False, True, None. We only make lock on True if extras.make_lock is True: Repository.lock(Repository.get_by_repo_name(extras.repository), user.user_id, lock_reason=Repository.LOCK_PULL) msg = 'Made lock on repo `%s`' % (extras.repository, ) output += msg if extras.locked_by[0]: locked_by = User.get(extras.locked_by[0]).username reason = extras.locked_by[2] _http_ret = HTTPLockedRC( _locked_by_explanation(extras.repository, locked_by, reason)) if str(_http_ret.code).startswith('2'): # 2xx Codes don't raise exceptions output += _http_ret.title return HookResponse(0, output)
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 log_pull_action(ui, repo, **kwargs): """ Logs user last pull action :param ui: :param repo: """ ex = _extract_extras() user = User.get_by_username(ex.username) action = 'pull' action_logger(user, action, ex.repository, ex.ip, commit=True) # extension hook call from rhodecode import EXTENSIONS callback = getattr(EXTENSIONS, 'PULL_HOOK', None) if isfunction(callback): kw = {} kw.update(ex) callback(**kw) if ex.make_lock is not None and ex.make_lock: Repository.lock(Repository.get_by_repo_name(ex.repository), user.user_id) #msg = 'Made lock on repo `%s`' % repository #sys.stdout.write(msg) if ex.locked_by[0]: locked_by = User.get(ex.locked_by[0]).username _http_ret = HTTPLockedRC(ex.repository, locked_by) if str(_http_ret.code).startswith('2'): #2xx Codes don't raise exceptions sys.stdout.write(_http_ret.title) return 0
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 log_push_action(ui, repo, **kwargs): """ Maps user last push action to new changeset id, from mercurial :param ui: :param repo: repo object containing the `ui` object """ ex = _extract_extras() action = ex.action + ':%s' if ex.scm == 'hg': node = kwargs['node'] def get_revs(repo, rev_opt): if rev_opt: revs = revrange(repo, rev_opt) if len(revs) == 0: return (nullrev, nullrev) return (max(revs), min(revs)) else: return (len(repo) - 1, 0) stop, start = get_revs(repo, [node + ':']) h = binascii.hexlify revs = [h(repo[r].node()) for r in xrange(start, stop + 1)] elif ex.scm == 'git': revs = kwargs.get('_git_revs', []) if '_git_revs' in kwargs: kwargs.pop('_git_revs') action = action % ','.join(revs) action_logger(ex.username, action, ex.repository, ex.ip, commit=True) # extension hook call from rhodecode import EXTENSIONS callback = getattr(EXTENSIONS, 'PUSH_HOOK', None) if isfunction(callback): kw = {'pushed_revs': revs} kw.update(ex) callback(**kw) if ex.make_lock is not None and not ex.make_lock: Repository.unlock(Repository.get_by_repo_name(ex.repository)) msg = 'Released lock on repo `%s`\n' % ex.repository sys.stdout.write(msg) if ex.locked_by[0]: locked_by = User.get(ex.locked_by[0]).username _http_ret = HTTPLockedRC(ex.repository, locked_by) if str(_http_ret.code).startswith('2'): #2xx Codes don't raise exceptions sys.stdout.write(_http_ret.title) return 0
def log_push_action(ui, repo, **kwargs): """ Maps user last push action to new changeset id, from mercurial :param ui: :param repo: repo object containing the `ui` object """ ex = _extract_extras() action = ex.action + ':%s' if ex.scm == 'hg': node = kwargs['node'] def get_revs(repo, rev_opt): if rev_opt: revs = revrange(repo, rev_opt) if len(revs) == 0: return (nullrev, nullrev) return (max(revs), min(revs)) else: return (len(repo) - 1, 0) stop, start = get_revs(repo, [node + ':']) h = binascii.hexlify revs = [h(repo[r].node()) for r in xrange(start, stop + 1)] elif ex.scm == 'git': revs = kwargs.get('_git_revs', []) if '_git_revs' in kwargs: kwargs.pop('_git_revs') action = action % ','.join(revs) action_logger(ex.username, action, ex.repository, ex.ip, commit=True) # extension hook call from rhodecode import EXTENSIONS callback = getattr(EXTENSIONS, 'PUSH_HOOK', None) if isfunction(callback): kw = {'pushed_revs': revs} kw.update(ex) callback(**kw) if ex.make_lock is not None and not ex.make_lock: Repository.unlock(Repository.get_by_repo_name(ex.repository)) msg = 'Released lock on repo `%s`\n' % ex.repository sys.stdout.write(msg) if ex.locked_by[0]: locked_by = User.get(ex.locked_by[0]).username _http_ret = HTTPLockedRC(ex.repository, locked_by) if str(_http_ret.code).startswith('2'): #2xx Codes don't raise exceptions sys.stdout.write(_http_ret.title) return 0
def test_delete(self, user, password): self.log_user(user, password) cur_user = self._get_logged_user() u1 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u1', lastname='u1') u2 = UserModel().create_or_update(username='******', password='******', email='*****@*****.**', firstname='u2', lastname='u2') self.destroy_users.add('u1') self.destroy_users.add('u2') # make notifications notification = NotificationModel().create( created_by=cur_user, notification_subject=u'test', notification_body=u'hi there', recipients=[cur_user, u1, u2]) Session().commit() u1 = User.get(u1.user_id) u2 = User.get(u2.user_id) # check DB get_notif = lambda un: [x.notification for x in un] assert get_notif(cur_user.notifications) == [notification] assert get_notif(u1.notifications) == [notification] assert get_notif(u2.notifications) == [notification] cur_usr_id = cur_user.user_id response = self.app.post(url( 'notification', notification_id=notification.notification_id), params={ '_method': 'delete', 'csrf_token': self.csrf_token }) assert response.body == 'ok' cur_user = User.get(cur_usr_id) assert cur_user.notifications == []
def test_my_account_add_auth_tokens(self, desc, lifetime): usr = self.log_user('test_regular2', 'test12') user = User.get(usr['user_id']) response = self.app.post( url('my_account_auth_tokens'), { 'description': desc, 'lifetime': lifetime, 'csrf_token': self.csrf_token }) assert_session_flash(response, 'Auth token successfully created') try: response = response.follow() user = User.get(usr['user_id']) for auth_token in user.auth_tokens: response.mustcontain(auth_token) finally: for auth_token in UserApiKeys.query().all(): Session().delete(auth_token) Session().commit()
def person_by_id(id_, show_attr="username_and_name"): # attr to return from fetched user person_getter = lambda usr: getattr(usr, show_attr) #maybe it's an ID ? if str(id_).isdigit() or isinstance(id_, int): id_ = int(id_) user = User.get(id_) if user is not None: return person_getter(user) return id_
def person_by_id(id_, show_attr="username_and_name"): # attr to return from fetched user person_getter = lambda usr: getattr(usr, show_attr) #maybe it's an ID ? if str(id_).isdigit() or isinstance(id_, int): id_ = int(id_) user = User.get(id_) if user is not None: return person_getter(user) return id_
def test_create_notification(self): usrs = [self.u1, self.u2] notification = NotificationModel().create( created_by=self.u1, notification_subject=u'subj', notification_body=u'hi there', recipients=usrs) Session().commit() u1 = User.get(self.u1) u2 = User.get(self.u2) notifications = Notification.query().all() assert len(notifications) == 1 assert notifications[0].recipients, [u1 == u2] assert notification.notification_id == notifications[0].notification_id unotification = UserNotification.query()\ .filter(UserNotification.notification == notification).all() assert len(unotification) == len(usrs) assert set([x.user.user_id for x in unotification]) == set(usrs)
def _destroy_project_tree(test_u1_id): Session.remove() repos_group = RepoGroup.get_by_group_name(group_name='g0') for el in reversed(repos_group.recursive_groups_and_repos()): if isinstance(el, Repository): RepoModel().delete(el) elif isinstance(el, RepoGroup): ReposGroupModel().delete(el, force_delete=True) u = User.get(test_u1_id) Session().delete(u) Session().commit()
def _destroy_project_tree(test_u1_id): Session.remove() repos_group = RepoGroup.get_by_group_name(group_name='g0') for el in reversed(repos_group.recursive_groups_and_repos()): if isinstance(el, Repository): RepoModel().delete(el) elif isinstance(el, RepoGroup): ReposGroupModel().delete(el, force_delete=True) u = User.get(test_u1_id) Session().delete(u) Session().commit()
def pre_pull(ui, repo, **kwargs): # pre push function, currently used to ban pushing when # repository is locked ex = _extract_extras() if ex.locked_by[0]: locked_by = User.get(ex.locked_by[0]).username # this exception is interpreted in git/hg middlewares and based # on that proper return code is server to client _http_ret = HTTPLockedRC(ex.repository, locked_by) if str(_http_ret.code).startswith('2'): #2xx Codes don't raise exceptions sys.stdout.write(_http_ret.title) else: raise _http_ret
def pre_pull(ui, repo, **kwargs): # pre push function, currently used to ban pushing when # repository is locked ex = _extract_extras() if ex.locked_by[0]: locked_by = User.get(ex.locked_by[0]).username # this exception is interpreted in git/hg middlewares and based # on that proper return code is server to client _http_ret = HTTPLockedRC(ex.repository, locked_by) if str(_http_ret.code).startswith('2'): #2xx Codes don't raise exceptions sys.stdout.write(_http_ret.title) else: raise _http_ret
def my_account_auth_tokens_delete(self): auth_token = request.POST.get('del_auth_token') user_id = c.rhodecode_user.user_id if request.POST.get('del_auth_token_builtin'): user = User.get(user_id) if user: user.api_key = generate_auth_token(user.username) Session().add(user) Session().commit() h.flash(_("Auth token successfully reset"), category='success') elif auth_token: AuthTokenModel().delete(auth_token, c.rhodecode_user.user_id) Session().commit() h.flash(_("Auth token successfully deleted"), category='success') return redirect(url('my_account_auth_tokens'))
def validate_python(self, value, state): if value in ["default", "new_user"]: msg = M(self, "system_invalid_username", state, username=value) raise formencode.Invalid(msg, value, state) # check if user is unique old_un = None if edit: old_un = User.get(old_data.get("user_id")).username if old_un != value or not edit: if User.get_by_username(value, case_insensitive=True): msg = M(self, "username_exists", state, username=value) raise formencode.Invalid(msg, value, state) if re.match(r"^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$", value) is None: msg = M(self, "invalid_username", state) raise formencode.Invalid(msg, value, state)
def validate_python(self, value, state): if value in ['default', 'new_user']: msg = M(self, 'system_invalid_username', state, username=value) raise formencode.Invalid(msg, value, state) #check if user is unique old_un = None if edit: old_un = User.get(old_data.get('user_id')).username if old_un != value or not edit: if User.get_by_username(value, case_insensitive=True): msg = M(self, 'username_exists', state, username=value) raise formencode.Invalid(msg, value, state) if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]*$', value) is None: msg = M(self, 'invalid_username', state) raise formencode.Invalid(msg, value, state)
def test_my_account_reset_main_auth_token(self): usr = self.log_user('test_regular2', 'test12') user = User.get(usr['user_id']) api_key = user.api_key response = self.app.get(url('my_account_auth_tokens')) response.mustcontain(api_key) response.mustcontain('expires: never') response = self.app.post( url('my_account_auth_tokens'), { '_method': 'delete', 'del_auth_token_builtin': api_key, 'csrf_token': self.csrf_token }) assert_session_flash(response, 'Auth token successfully reset') response = response.follow() response.mustcontain(no=[api_key])
def _check_locking_state(self, environ, action, repo, user_id): """ Checks locking on this repository, if locking is enabled and lock is present returns a tuple of make_lock, locked, locked_by. make_lock can have 3 states None (do nothing) True, make lock False release lock, This value is later propagated to hooks, which do the locking. Think about this as signals passed to hooks what to do. """ locked = False # defines that locked error should be thrown to user make_lock = None repo = Repository.get_by_repo_name(repo) user = User.get(user_id) # this is kind of hacky, but due to how mercurial handles client-server # server see all operation on changeset; bookmarks, phases and # obsolescence marker in different transaction, we don't want to check # locking on those obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',] locked_by = repo.locked if repo and repo.enable_locking and not obsolete_call: if action == 'push': #check if it's already locked !, if it is compare users user_id, _date = repo.locked if user.user_id == user_id: log.debug('Got push from user %s, now unlocking' % (user)) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with 423 ! locked = True if action == 'pull': if repo.locked[0] and repo.locked[1]: locked = True else: log.debug('Setting lock on repo %s by %s' % (repo, user)) make_lock = True else: log.debug('Repository %s do not have locking enabled' % (repo)) log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s' % (make_lock, locked, locked_by)) return make_lock, locked, locked_by
def _check_locking_state(self, environ, action, repo, user_id): """ Checks locking on this repository, if locking is enabled and lock is present returns a tuple of make_lock, locked, locked_by. make_lock can have 3 states None (do nothing) True, make lock False release lock, This value is later propagated to hooks, which do the locking. Think about this as signals passed to hooks what to do. """ locked = False # defines that locked error should be thrown to user make_lock = None repo = Repository.get_by_repo_name(repo) user = User.get(user_id) # this is kind of hacky, but due to how mercurial handles client-server # server see all operation on changeset; bookmarks, phases and # obsolescence marker in different transaction, we don't want to check # locking on those obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',] locked_by = repo.locked if repo and repo.enable_locking and not obsolete_call: if action == 'push': #check if it's already locked !, if it is compare users user_id, _date = repo.locked if user.user_id == user_id: log.debug('Got push from user %s, now unlocking' % (user)) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with 423 ! locked = True if action == 'pull': if repo.locked[0] and repo.locked[1]: locked = True else: log.debug('Setting lock on repo %s by %s' % (repo, user)) make_lock = True else: log.debug('Repository %s do not have locking enabled' % (repo)) log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s' % (make_lock, locked, locked_by)) return make_lock, locked, locked_by
def validate_python(self, value, state): if value in ['default', 'new_user']: raise formencode.Invalid(_('Invalid username'), value, state) #check if user is unique old_un = None if edit: old_un = User.get(old_data.get('user_id')).username if old_un != value or not edit: if User.get_by_username(value, case_insensitive=True): raise formencode.Invalid(_('This username already ' 'exists') , value, state) if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None: raise formencode.Invalid( _('Username may only contain alphanumeric characters ' 'underscores, periods or dashes and must begin with ' 'alphanumeric character'), value, state )
def delete_auth_token(self, user_id): user_id = safe_int(user_id) c.user = User.get_or_404(user_id) if c.user.username == User.DEFAULT_USER: h.flash(_("You can't edit this user"), category='warning') return redirect(url('users')) auth_token = request.POST.get('del_auth_token') if request.POST.get('del_auth_token_builtin'): user = User.get(c.user.user_id) if user: user.api_key = generate_auth_token(user.username) Session().add(user) Session().commit() h.flash(_("Auth token successfully reset"), category='success') elif auth_token: AuthTokenModel().delete(auth_token, c.user.user_id) Session().commit() h.flash(_("Auth token successfully deleted"), category='success') return redirect(url('edit_user_auth_tokens', user_id=c.user.user_id))
def edit(self, id, format='html'): """GET /users/id/edit: Form to edit an existing item""" # url('edit_user', id=ID) c.user = User.get(id) if not c.user: return redirect(url('users')) if c.user.username == 'default': h.flash(_("You can't edit this user"), category='warning') return redirect(url('users')) c.user.permissions = {} c.granted_permissions = UserModel().fill_perms(c.user)\ .permissions['global'] defaults = c.user.get_dict() perm = Permission.get_by_key('hg.create.repository') defaults.update({'create_repo_perm': UserModel().has_perm(id, perm)}) return htmlfill.render(render('admin/users/user_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def my_account_update(self): """PUT /_admin/my_account_update: 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('admin_settings_my_account_update'), # method='put') # url('admin_settings_my_account_update', id=ID) uid = self.rhodecode_user.user_id c.user = User.get(self.rhodecode_user.user_id) c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id, ip_addr=self.ip_addr) c.ldap_dn = c.user.ldap_dn email = self.rhodecode_user.email _form = UserForm(edit=True, old_data={ 'user_id': uid, 'email': email })() form_result = {} try: form_result = _form.to_python(dict(request.POST)) skip_attrs = ['admin', 'active'] # skip attr for my account if c.ldap_dn: #forbid updating username for ldap accounts skip_attrs.append('username') UserModel().update(uid, form_result, skip_attrs=skip_attrs) h.flash(_('Your account was updated successfully'), category='success') Session().commit() except formencode.Invalid, errors: #json used to render the grid c.data = self._load_my_repos_data() c.form = htmlfill.render( render('admin/users/user_edit_my_account_form.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8") return render('admin/users/user_edit_my_account.html')
def update_user_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 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_register', 'default_extern_activate' ]) self.sa.commit() except (DatabaseError, ): log.error(traceback.format_exc()) self.sa.rollback() raise
def edit(self, id, format='html'): """GET /users/id/edit: Form to edit an existing item""" # url('edit_user', id=ID) c.user = User.get(id) if not c.user: return redirect(url('users')) if c.user.username == 'default': h.flash(_("You can't edit this user"), category='warning') return redirect(url('users')) c.user.permissions = {} c.granted_permissions = UserModel().fill_perms(c.user)\ .permissions['global'] defaults = c.user.get_dict() perm = Permission.get_by_key('hg.create.repository') defaults.update({'create_repo_perm': UserModel().has_perm(id, perm)}) return htmlfill.render( render('admin/users/user_edit.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
def my_account_update(self): """PUT /_admin/my_account_update: 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('admin_settings_my_account_update'), # method='put') # url('admin_settings_my_account_update', id=ID) uid = self.rhodecode_user.user_id c.user = User.get(self.rhodecode_user.user_id) c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id, ip_addr=self.ip_addr) c.ldap_dn = c.user.ldap_dn email = self.rhodecode_user.email _form = UserForm(edit=True, old_data={'user_id': uid, 'email': email})() form_result = {} try: form_result = _form.to_python(dict(request.POST)) skip_attrs = ['admin', 'active'] # skip attr for my account if c.ldap_dn: #forbid updating username for ldap accounts skip_attrs.append('username') UserModel().update(uid, form_result, skip_attrs=skip_attrs) h.flash(_('Your account was updated successfully'), category='success') Session().commit() except formencode.Invalid, errors: #json used to render the grid c.data = self._load_my_repos_data() c.form = htmlfill.render( render('admin/users/user_edit_my_account_form.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8") return render('admin/users/user_edit_my_account.html')
def index(self): # Return a rendered template p = safe_int(request.GET.get('page', 1), 1) c.user = User.get(self.rhodecode_user.user_id) c.following = self.sa.query(UserFollowing)\ .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\ .options(joinedload(UserFollowing.follows_repository))\ .all() journal = self._get_journal_data(c.following) def url_generator(**kw): return url.current(filter=c.search_term, **kw) c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render('journal/journal_data.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.journal_data repos_list = Session().query(Repository)\ .filter(Repository.user_id == self.rhodecode_user.user_id)\ .order_by(func.lower(Repository.repo_name)).all() repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list, admin=True) #json used to render the grid c.data = json.dumps(repos_data) watched_repos_data = [] ## watched repos _render = RepoModel._render_datatable def quick_menu(repo_name): return _render('quick_menu', repo_name) def repo_lnk(name, rtype, private, fork_of): return _render('repo_name', name, rtype, private, fork_of, short_name=False, admin=False) def last_rev(repo_name, cs_cache): return _render('revision', repo_name, cs_cache.get('revision'), cs_cache.get('raw_id'), cs_cache.get('author'), cs_cache.get('message')) def desc(desc): from pylons import tmpl_context as c if c.visual.stylify_metatags: return h.urlify_text(h.desc_stylize(h.truncate(desc, 60))) else: return h.urlify_text(h.truncate(desc, 60)) def repo_actions(repo_name): return _render('repo_actions', repo_name) def owner_actions(user_id, username): return _render('user_name', user_id, username) def toogle_follow(repo_id): return _render('toggle_follow', repo_id) for entry in c.following: repo = entry.follows_repository cs_cache = repo.changeset_cache row = { "menu": quick_menu(repo.repo_name), "raw_name": repo.repo_name.lower(), "name": repo_lnk(repo.repo_name, repo.repo_type, repo.private, repo.fork), "last_changeset": last_rev(repo.repo_name, cs_cache), "raw_tip": cs_cache.get('revision'), "action": toogle_follow(repo.repo_id) } watched_repos_data.append(row) c.watched_data = json.dumps({ "totalRecords": len(c.following), "startIndex": 0, "sort": "name", "dir": "asc", "records": watched_repos_data }) return render('journal/journal.html')