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_create_notification(self): with test_context(self.app): usrs = [self.u1, self.u2] def send_email(recipients, subject, body='', html_body='', headers=None, author=None): assert recipients == ['*****@*****.**'] assert subject == 'Test Message' assert body == u"hi there" assert '>hi there<' in html_body assert author.username == 'u1' with mock.patch.object(kallithea.lib.celerylib.tasks, 'send_email', send_email): 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() 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_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_my_account_add_api_keys(self, desc, lifetime): usr = self.log_user('test_regular2', 'test12') user = User.get(usr['user_id']) response = self.app.post(url('my_account_api_keys'), {'description': desc, 'lifetime': lifetime}) self.checkSessionFlash(response, 'Api key successfully created') try: response = response.follow() user = User.get(usr['user_id']) for api_key in user.api_keys: response.mustcontain(api_key) finally: for api_key in UserApiKeys.query().all(): Session().delete(api_key) Session().commit()
def test_my_account_add_api_keys(self, desc, lifetime): usr = self.log_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS) user = User.get(usr['user_id']) response = self.app.post(url('my_account_api_keys'), {'description': desc, 'lifetime': lifetime, '_authentication_token': self.authentication_token()}) self.checkSessionFlash(response, 'API key successfully created') try: response = response.follow() user = User.get(usr['user_id']) for api_key in user.api_keys: response.mustcontain(api_key) finally: for api_key in UserApiKeys.query().all(): Session().delete(api_key) Session().commit()
def __load_data(self): c.user = User.get(self.authuser.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') raise HTTPFound(location=url('users')) c.EXTERN_TYPE_INTERNAL = EXTERN_TYPE_INTERNAL
def create_new_iteration(self, old_pull_request, new_rev, title, description, reviewers): owner = User.get(request.authuser.user_id) new_org_rev = self._get_ref_rev(old_pull_request.org_repo, 'rev', new_rev) new_other_rev = self._get_ref_rev(old_pull_request.other_repo, old_pull_request.other_ref_parts[0], old_pull_request.other_ref_parts[1]) try: cmd = CreatePullRequestIterationAction(old_pull_request, new_org_rev, new_other_rev, title, description, owner, reviewers) except CreatePullRequestAction.ValidationError as e: h.flash(e, category='error', logf=log.error) raise HTTPNotFound try: pull_request = cmd.execute() Session().commit() except Exception: h.flash(_('Error occurred while creating pull request'), category='error') log.error(traceback.format_exc()) raise HTTPFound(location=old_pull_request.url()) h.flash(_('New pull request iteration created'), category='success') raise HTTPFound(location=pull_request.url())
def test_create_on_top_level_without_permissions(self): usr = self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) # revoke user_model = UserModel() # disable fork and create on default user user_model.revoke_perm(User.DEFAULT_USER, 'hg.create.repository') user_model.grant_perm(User.DEFAULT_USER, 'hg.create.none') user_model.revoke_perm(User.DEFAULT_USER, 'hg.fork.repository') user_model.grant_perm(User.DEFAULT_USER, 'hg.fork.none') # disable on regular user user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.repository') user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.none') user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.repository') user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.none') Session().commit() user = User.get(usr['user_id']) repo_name = self.NEW_REPO + u'no_perms' description = 'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _authentication_token=self.authentication_token())) response.mustcontain('<span class="error-message">Invalid value</span>') RepoModel().delete(repo_name) Session().commit()
def test_my_account_api_keys(self): usr = self.log_user(base.TEST_USER_REGULAR2_LOGIN, base.TEST_USER_REGULAR2_PASS) user = User.get(usr['user_id']) response = self.app.get(base.url('my_account_api_keys')) response.mustcontain(user.api_key) response.mustcontain('Expires: Never')
def __load_data(self): c.user = User.get(request.authuser.user_id) if c.user.is_default_user: h.flash(_("You can't edit this user since it's" " crucial for entire application"), category='warning') raise HTTPFound(location=url('users'))
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 kallithea import EXTENSIONS callback = getattr(EXTENSIONS, 'PULL_HOOK', None) if callable(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 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 kallithea import EXTENSIONS callback = getattr(EXTENSIONS, 'PULL_HOOK', None) if callable(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 #ui.status(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 ui.status(safe_str(_http_ret.title)) return 0
def index(self): # Return a rendered template p = safe_int(request.GET.get('page'), 1) c.user = User.get(request.authuser.user_id) c.following = UserFollowing.query() \ .filter(UserFollowing.user_id == request.authuser.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_aggregate = self._get_daily_aggregate(c.journal_pager) if request.environ.get('HTTP_X_PARTIAL_XHR'): return render('journal/journal_data.html') repos_list = Repository.query(sorted=True) \ .filter_by(owner_id=request.authuser.user_id).all() repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list, admin=True) #data used to render the grid c.data = repos_data return render('journal/journal.html')
def test_my_account_remove_api_key(self): usr = self.log_user(base.TEST_USER_REGULAR2_LOGIN, base.TEST_USER_REGULAR2_PASS) user = User.get(usr['user_id']) response = self.app.post( base.url('my_account_api_keys'), { 'description': 'desc', 'lifetime': -1, '_session_csrf_secret_token': self.session_csrf_secret_token() }) self.checkSessionFlash(response, 'API key successfully created') response = response.follow() # now delete our key keys = UserApiKeys.query().all() assert 1 == len(keys) response = self.app.post( base.url('my_account_api_keys_delete'), { 'del_api_key': keys[0].api_key, '_session_csrf_secret_token': self.session_csrf_secret_token() }) self.checkSessionFlash(response, 'API key successfully deleted') keys = UserApiKeys.query().all() assert 0 == len(keys)
def test_create_on_top_level_without_permissions(self): usr = self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) # revoke user_model = UserModel() # disable fork and create on default user user_model.revoke_perm(User.DEFAULT_USER, 'hg.create.repository') user_model.grant_perm(User.DEFAULT_USER, 'hg.create.none') user_model.revoke_perm(User.DEFAULT_USER, 'hg.fork.repository') user_model.grant_perm(User.DEFAULT_USER, 'hg.fork.none') # disable on regular user user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.repository') user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.none') user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.repository') user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.none') Session().commit() user = User.get(usr['user_id']) repo_name = self.NEW_REPO+'no_perms' description = 'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _authentication_token=self.authentication_token())) response.mustcontain('no permission to create repository in root location') RepoModel().delete(repo_name) Session().commit()
def __load_data(self): c.user = User.get(self.authuser.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')) c.EXTERN_TYPE_INTERNAL = EXTERN_TYPE_INTERNAL
def test_my_account_add_api_keys(self, desc, lifetime): usr = self.log_user('test_regular2', 'test12') user = User.get(usr['user_id']) response = self.app.post(url('my_account_api_keys'), { 'description': desc, 'lifetime': lifetime }) self.checkSessionFlash(response, 'Api key successfully created') try: response = response.follow() user = User.get(usr['user_id']) for api_key in user.api_keys: response.mustcontain(api_key) finally: for api_key in UserApiKeys.query().all(): Session().delete(api_key) Session().commit()
def post(self, repo_name, pull_request_id): pull_request = PullRequest.get_or_404(pull_request_id) if pull_request.is_closed(): raise HTTPForbidden() assert pull_request.other_repo.repo_name == repo_name # only owner or admin can update it owner = pull_request.owner_id == request.authuser.user_id repo_admin = h.HasRepoPermissionLevel('admin')(c.repo_name) if not (h.HasPermissionAny('hg.admin')() or repo_admin or owner): raise HTTPForbidden() _form = PullRequestPostForm()().to_python(request.POST) cur_reviewers = set(pull_request.get_reviewer_users()) new_reviewers = set(_get_reviewer(s) for s in _form['review_members']) old_reviewers = set( _get_reviewer(s) for s in _form['org_review_members']) other_added = cur_reviewers - old_reviewers other_removed = old_reviewers - cur_reviewers if other_added: h.flash( _('Meanwhile, the following reviewers have been added: %s') % (', '.join(u.username for u in other_added)), category='warning') if other_removed: h.flash( _('Meanwhile, the following reviewers have been removed: %s') % (', '.join(u.username for u in other_removed)), category='warning') if _form['updaterev']: return self.create_new_iteration(pull_request, _form['updaterev'], _form['pullrequest_title'], _form['pullrequest_desc'], new_reviewers) added_reviewers = new_reviewers - old_reviewers - cur_reviewers removed_reviewers = (old_reviewers - new_reviewers) & cur_reviewers old_description = pull_request.description pull_request.title = _form['pullrequest_title'] pull_request.description = _form['pullrequest_desc'].strip() or _( 'No description') pull_request.owner = User.get_by_username(_form['owner']) user = User.get(request.authuser.user_id) PullRequestModel().mention_from_description(user, pull_request, old_description) PullRequestModel().add_reviewers(user, pull_request, added_reviewers) PullRequestModel().remove_reviewers(user, pull_request, removed_reviewers) Session().commit() h.flash(_('Pull request updated'), category='success') raise HTTPFound(location=pull_request.url())
def test_delete(self, create_test_user): self.log_user() cur_user = self._get_logged_user() with test_context(self.app): u1 = create_test_user( dict(username='******', password='******', email='*****@*****.**', firstname=u'u1', lastname=u'u1', active=True)) u2 = create_test_user( dict(username='******', password='******', email='*****@*****.**', firstname=u'u2', lastname=u'u2', active=True)) # 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] 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_delete', notification_id=notification.notification_id), params={'_authentication_token': self.authentication_token()}) assert response.body == 'ok' cur_user = User.get(cur_usr_id) assert cur_user.notifications == []
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_tmpl = ex.action + ':%s' revs = [] 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_tmpl % ','.join(revs) action_logger(ex.username, action, ex.repository, ex.ip, commit=True) # extension hook call from kallithea import EXTENSIONS callback = getattr(EXTENSIONS, 'PUSH_HOOK', None) if callable(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 person_by_id(id_, show_attr="username"): from kallithea.model.db import User # 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 getattr(user, show_attr) return id_
def test_mark_all_read(self, create_test_user): self.log_user() with test_context(self.app): u0 = self._get_logged_user() u1 = create_test_user( dict(username='******', password='******', email='*****@*****.**', firstname=u'u1', lastname=u'u1', active=True)) u2 = create_test_user( dict(username='******', password='******', email='*****@*****.**', firstname=u'u2', lastname=u'u2', active=True)) notif = NotificationModel().create(created_by=u1, subject=u'subject', body=u'body', recipients=[u0, u2]) u0_id, u1_id, u2_id = u0.user_id, u1.user_id, u2.user_id assert [n.read for n in u0.notifications] == [False] assert u1.notifications == [] assert [n.read for n in u2.notifications] == [False] # Mark all read for current user. response = self.app.get( url('notifications_mark_all_read'), # TODO: should be POST extra_environ=dict(HTTP_X_PARTIAL_XHR='1')) assert response.status_int == 200 response.mustcontain('id="notification_%s"' % notif.notification_id) u0 = User.get(u0_id) u1 = User.get(u1_id) u2 = User.get(u2_id) assert [n.read for n in u0.notifications] == [True] assert u1.notifications == [] assert [n.read for n in u2.notifications] == [False]
def test_my_account_add_api_keys(self, desc, lifetime): usr = self.log_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS) user = User.get(usr['user_id']) response = self.app.post( url('my_account_api_keys'), { 'description': desc, 'lifetime': lifetime, '_authentication_token': self.authentication_token() }) self.checkSessionFlash(response, 'API key successfully created') try: response = response.follow() user = User.get(usr['user_id']) for api_key in user.api_keys: response.mustcontain(api_key) finally: for api_key in UserApiKeys.query().all(): Session().delete(api_key) Session().commit()
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_authuser(), 'ip_addr', '') 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 = u'' 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()
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_authuser(), 'ip_addr', '') 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 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()
def log_push_action(ui, repo, **kwargs): """ Register that changes have been pushed. Mercurial invokes this directly as a hook, git uses handle_git_receive. """ ex = _extract_extras() action_tmpl = ex.action + ':%s' revs = [] 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_tmpl % ','.join(revs) action_logger(ex.username, action, ex.repository, ex.ip, commit=True) # extension hook call from kallithea import EXTENSIONS callback = getattr(EXTENSIONS, 'PUSH_HOOK', None) if callable(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)) ui.status(safe_str('Released lock on repo `%s`\n' % ex.repository)) 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 ui.status(safe_str(_http_ret.title)) return 0
def person_by_id(id_, show_attr="username"): from kallithea.model.db import User # 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 _destroy_project_tree(test_u1_id): Session.remove() repo_group = RepoGroup.get_by_group_name(group_name=u'g0') for el in reversed(repo_group.recursive_groups_and_repos()): if isinstance(el, Repository): RepoModel().delete(el) elif isinstance(el, RepoGroup): RepoGroupModel().delete(el, force_delete=True) u = User.get(test_u1_id) Session().delete(u) Session().commit()
def _get_reviewer(user_id): """Look up user by ID and validate it as a potential reviewer.""" try: user = User.get(int(user_id)) except ValueError: user = None if user is None or user.is_default_user: h.flash(_('Invalid reviewer "%s" specified') % user_id, category='error') raise HTTPBadRequest() return user
def _destroy_project_tree(test_u1_id): Session.remove() repo_group = RepoGroup.get_by_group_name(group_name='g0') for el in reversed(repo_group.recursive_groups_and_repos()): if isinstance(el, Repository): RepoModel().delete(el) elif isinstance(el, RepoGroup): RepoGroupModel().delete(el, force_delete=True) u = User.get(test_u1_id) Session().delete(u) Session().commit()
def post(self, repo_name, pull_request_id): pull_request = PullRequest.get_or_404(pull_request_id) if pull_request.is_closed(): raise HTTPForbidden() assert pull_request.other_repo.repo_name == repo_name #only owner or admin can update it owner = pull_request.owner_id == request.authuser.user_id repo_admin = h.HasRepoPermissionLevel('admin')(c.repo_name) if not (h.HasPermissionAny('hg.admin')() or repo_admin or owner): raise HTTPForbidden() _form = PullRequestPostForm()().to_python(request.POST) cur_reviewers = set(pull_request.get_reviewer_users()) new_reviewers = set(_get_reviewer(s) for s in _form['review_members']) old_reviewers = set(_get_reviewer(s) for s in _form['org_review_members']) other_added = cur_reviewers - old_reviewers other_removed = old_reviewers - cur_reviewers if other_added: h.flash(_('Meanwhile, the following reviewers have been added: %s') % (', '.join(u.username for u in other_added)), category='warning') if other_removed: h.flash(_('Meanwhile, the following reviewers have been removed: %s') % (', '.join(u.username for u in other_removed)), category='warning') if _form['updaterev']: return self.create_new_iteration(pull_request, _form['updaterev'], _form['pullrequest_title'], _form['pullrequest_desc'], new_reviewers) added_reviewers = new_reviewers - old_reviewers - cur_reviewers removed_reviewers = (old_reviewers - new_reviewers) & cur_reviewers old_description = pull_request.description pull_request.title = _form['pullrequest_title'] pull_request.description = _form['pullrequest_desc'].strip() or _('No description') pull_request.owner = User.get_by_username(_form['owner']) user = User.get(request.authuser.user_id) PullRequestModel().mention_from_description(user, pull_request, old_description) PullRequestModel().add_reviewers(user, pull_request, added_reviewers) PullRequestModel().remove_reviewers(user, pull_request, removed_reviewers) Session().commit() h.flash(_('Pull request updated'), category='success') raise HTTPFound(location=pull_request.url())
def test_my_account_reset_main_api_key(self): usr = self.log_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS) user = User.get(usr['user_id']) api_key = user.api_key response = self.app.get(url('my_account_api_keys')) response.mustcontain(api_key) response.mustcontain('Expires: Never') response = self.app.post(url('my_account_api_keys_delete'), {'del_api_key_builtin': api_key, '_authentication_token': self.authentication_token()}) self.checkSessionFlash(response, 'API key successfully reset') response = response.follow() response.mustcontain(no=[api_key])
def pre_pull(ui, repo, **kwargs): # pre pull function ... 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 ui.status(safe_str(_http_ret.title)) else: raise _http_ret
def my_account_api_keys_delete(self): api_key = request.POST.get('del_api_key') if request.POST.get('del_api_key_builtin'): user = User.get(request.authuser.user_id) user.api_key = generate_api_key() Session().commit() h.flash(_("API key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, request.authuser.user_id) Session().commit() h.flash(_("API key successfully deleted"), category='success') raise HTTPFound(location=url('my_account_api_keys'))
def test_my_account_reset_main_api_key(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_api_keys')) response.mustcontain(api_key) response.mustcontain('expires: never') response = self.app.post(url('my_account_api_keys'), {'_method': 'delete', 'del_api_key_builtin': api_key}) self.checkSessionFlash(response, 'Api key successfully reset') response = response.follow() response.mustcontain(no=[api_key])
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 test_mark_all_read(self, create_test_user): self.log_user() with test_context(self.app): u0 = self._get_logged_user() u1 = create_test_user(dict(username='******', password='******', email='*****@*****.**', firstname=u'u1', lastname=u'u1', active=True)) u2 = create_test_user(dict(username='******', password='******', email='*****@*****.**', firstname=u'u2', lastname=u'u2', active=True)) notif = NotificationModel().create(created_by=u1, subject=u'subject', body=u'body', recipients=[u0, u2]) u0_id, u1_id, u2_id = u0.user_id, u1.user_id, u2.user_id assert [n.read for n in u0.notifications] == [False] assert u1.notifications == [] assert [n.read for n in u2.notifications] == [False] # Mark all read for current user. response = self.app.get(url('notifications_mark_all_read'), # TODO: should be POST extra_environ=dict(HTTP_X_PARTIAL_XHR='1')) assert response.status_int == 200 response.mustcontain('id="notification_%s"' % notif.notification_id) u0 = User.get(u0_id) u1 = User.get(u1_id) u2 = User.get(u2_id) assert [n.read for n in u0.notifications] == [True] assert u1.notifications == [] assert [n.read for n in u2.notifications] == [False]
def test_delete(self, create_test_user): self.log_user() cur_user = self._get_logged_user() with test_context(self.app): u1 = create_test_user(dict(username='******', password='******', email='*****@*****.**', firstname=u'u1', lastname=u'u1', active=True)) u2 = create_test_user(dict(username='******', password='******', email='*****@*****.**', firstname=u'u2', lastname=u'u2', active=True)) # 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] 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_delete', notification_id=notification.notification_id), params={'_authentication_token': self.authentication_token()}) assert response.body == 'ok' cur_user = User.get(cur_usr_id) assert cur_user.notifications == []
def test_my_account_reset_main_api_key(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_api_keys')) response.mustcontain(api_key) response.mustcontain('expires: never') response = self.app.post(url('my_account_api_keys'), { '_method': 'delete', 'del_api_key_builtin': api_key }) self.checkSessionFlash(response, 'Api key successfully reset') response = response.follow() response.mustcontain(no=[api_key])
def my_account_api_keys_delete(self): api_key = request.POST.get('del_api_key') user_id = self.authuser.user_id if request.POST.get('del_api_key_builtin'): user = User.get(user_id) if user: user.api_key = generate_api_key(user.username) Session().add(user) Session().commit() h.flash(_("Api key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, self.authuser.user_id) Session().commit() h.flash(_("Api key successfully deleted"), category='success') return redirect(url('my_account_api_keys'))
def test_my_account_reset_main_api_key(self): usr = self.log_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS) user = User.get(usr['user_id']) api_key = user.api_key response = self.app.get(url('my_account_api_keys')) response.mustcontain(api_key) response.mustcontain('Expires: Never') response = self.app.post( url('my_account_api_keys_delete'), { 'del_api_key_builtin': api_key, '_authentication_token': self.authentication_token() }) self.checkSessionFlash(response, 'API key successfully reset') response = response.follow() response.mustcontain(no=[api_key])
def create(self, repo_name): repo = c.db_repo try: _form = PullRequestForm(repo.repo_id)().to_python(request.POST) except formencode.Invalid as errors: log.error(traceback.format_exc()) log.error(str(errors)) msg = _('Error creating pull request: %s') % errors.msg h.flash(msg, 'error') raise HTTPBadRequest # heads up: org and other might seem backward here ... org_ref = _form[ 'org_ref'] # will have merge_rev as rev but symbolic name org_repo = Repository.guess_instance(_form['org_repo']) other_ref = _form[ 'other_ref'] # will have symbolic name and head revision other_repo = Repository.guess_instance(_form['other_repo']) reviewers = [] title = _form['pullrequest_title'] description = _form['pullrequest_desc'].strip() owner = User.get(request.authuser.user_id) try: cmd = CreatePullRequestAction(org_repo, other_repo, org_ref, other_ref, title, description, owner, reviewers) except CreatePullRequestAction.ValidationError as e: h.flash(e, category='error', logf=log.error) raise HTTPNotFound try: pull_request = cmd.execute() Session().commit() except Exception: h.flash(_('Error occurred while creating pull request'), category='error') log.error(traceback.format_exc()) raise HTTPFound( location=url('pullrequest_home', repo_name=repo_name)) h.flash(_('Successfully opened new pull request'), category='success') raise HTTPFound(location=pull_request.url())
def test_my_account_remove_api_key(self): usr = self.log_user('test_regular2', 'test12') user = User.get(usr['user_id']) response = self.app.post(url('my_account_api_keys'), {'description': 'desc', 'lifetime': -1}) self.checkSessionFlash(response, 'Api key successfully created') response = response.follow() #now delete our key keys = UserApiKeys.query().all() self.assertEqual(1, len(keys)) response = self.app.post(url('my_account_api_keys'), {'_method': 'delete', 'del_api_key': keys[0].api_key}) self.checkSessionFlash(response, 'Api key successfully deleted') keys = UserApiKeys.query().all() self.assertEqual(0, len(keys))
def delete_api_key(self, id): c.user = self._get_user_or_raise_if_default(id) api_key = request.POST.get('del_api_key') if request.POST.get('del_api_key_builtin'): user = User.get(c.user.user_id) if user is not None: user.api_key = generate_api_key() Session().add(user) Session().commit() h.flash(_("API key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, c.user.user_id) Session().commit() h.flash(_("API key successfully deleted"), category='success') raise HTTPFound(location=url('edit_user_api_keys', id=c.user.user_id))
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_add_api_keys(self, desc, lifetime): self.log_user() user = User.get_by_username(TEST_USER_REGULAR_LOGIN) user_id = user.user_id response = self.app.post(url('edit_user_api_keys', id=user_id), {'_method': 'put', 'description': desc, 'lifetime': lifetime}) self.checkSessionFlash(response, 'Api key successfully created') try: response = response.follow() user = User.get(user_id) for api_key in user.api_keys: response.mustcontain(api_key) finally: for api_key in UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all(): Session().delete(api_key) Session().commit()
def test_my_account_remove_api_key(self): usr = self.log_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS) user = User.get(usr['user_id']) response = self.app.post(url('my_account_api_keys'), {'description': 'desc', 'lifetime': -1, '_authentication_token': self.authentication_token()}) self.checkSessionFlash(response, 'API key successfully created') response = response.follow() #now delete our key keys = UserApiKeys.query().all() assert 1 == len(keys) response = self.app.post(url('my_account_api_keys_delete'), {'del_api_key': keys[0].api_key, '_authentication_token': self.authentication_token()}) self.checkSessionFlash(response, 'API key successfully deleted') keys = UserApiKeys.query().all() assert 0 == len(keys)
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