def prepare(self, request, pylonsapp): UserLog.query().delete() Session().commit() def strptime(val): fmt = '%Y-%m-%d %H:%M:%S' if '.' not in val: return datetime.datetime.strptime(val, fmt) nofrag, frag = val.split(".") date = datetime.datetime.strptime(nofrag, fmt) frag = frag[:6] # truncate to microseconds frag += (6 - len(frag)) * '0' # add 0s return date.replace(microsecond=int(frag)) with open(os.path.join(FIXTURES, 'journal_dump.csv')) as f: for row in csv.DictReader(f): ul = UserLog() for k, v in row.iteritems(): v = safe_unicode(v) if k == 'action_date': v = strptime(v) if k in ['user_id', 'repository_id']: # nullable due to FK problems v = None setattr(ul, k, v) Session().add(ul) Session().commit() @request.addfinalizer def cleanup(): UserLog.query().delete() Session().commit()
def 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 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 test_api_comment_pull_request(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id author = pull_request.user_id repo = pull_request.target_repo.repo_id id_, params = build_data(self.apikey, 'comment_pull_request', repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, message='test message') response = api_call(self.app, params) pull_request = PullRequestModel().get(pull_request.pull_request_id) comments = ChangesetCommentsModel().get_comments( pull_request.target_repo.repo_id, pull_request=pull_request) expected = { 'pull_request_id': pull_request.pull_request_id, 'comment_id': comments[-1].comment_id, 'status': None } assert_ok(id_, expected, response.body) action = 'user_commented_pull_request:%d' % pull_request_id journal = UserLog.query()\ .filter(UserLog.user_id == author)\ .filter(UserLog.repository_id == repo)\ .filter(UserLog.action == action)\ .all() assert len(journal) == 2
def index(self): users_log = UserLog.query()\ .options(joinedload(UserLog.user))\ .options(joinedload(UserLog.repository)) #FILTERING c.search_term = request.GET.get('filter') try: users_log = _journal_filter(users_log, c.search_term) except: # we want this to crash for now raise users_log = users_log.order_by(UserLog.action_date.desc()) p = safe_int(request.params.get('page', 1), 1) def url_generator(**kw): return url.current(filter=c.search_term, **kw) c.users_log = Page(users_log, page=p, items_per_page=10, url=url_generator) c.log_data = render('admin/admin_log.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.log_data return render('admin/admin.html')
def test_comment_force_close_pull_request(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id reviewers_ids = [1, 2] PullRequestModel().update_reviewers(pull_request_id, reviewers_ids) author = pull_request.user_id repo = pull_request.target_repo.repo_id self.app.post( url(controller='pullrequests', action='comment', repo_name=pull_request.target_repo.scm_instance().name, pull_request_id=str(pull_request_id)), params={ 'changeset_status': 'forced_closed', 'csrf_token': csrf_token}, status=302) pull_request = PullRequest.get(pull_request_id) action = 'user_closed_pull_request:%d' % pull_request_id journal = UserLog.query().filter( UserLog.user_id == author, UserLog.repository_id == repo, UserLog.action == action).all() assert len(journal) == 1 # check only the latest status, not the review status status = ChangesetStatusModel().get_status( pull_request.source_repo, pull_request=pull_request) assert status == ChangesetStatus.STATUS_REJECTED
def test_comment_and_close_pull_request(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request(approved=True) pull_request_id = pull_request.pull_request_id author = pull_request.user_id repo = pull_request.target_repo.repo_id self.app.post( url(controller='pullrequests', action='comment', repo_name=pull_request.target_repo.scm_instance().name, pull_request_id=str(pull_request_id)), params={ 'changeset_status': ChangesetStatus.STATUS_APPROVED + '_closed', 'change_changeset_status': 'on', 'text': '', 'csrf_token': csrf_token}, status=302) action = 'user_closed_pull_request:%d' % pull_request_id journal = UserLog.query()\ .filter(UserLog.user_id == author)\ .filter(UserLog.repository_id == repo)\ .filter(UserLog.action == action)\ .all() assert len(journal) == 1
def index(self): users_log = UserLog.query()\ .options(joinedload(UserLog.user))\ .options(joinedload(UserLog.repository)) #FILTERING c.search_term = request.GET.get('filter') try: users_log = _journal_filter(users_log, c.search_term) except Exception: # we want this to crash for now raise users_log = users_log.order_by(UserLog.action_date.desc()) p = safe_int(request.GET.get('page', 1), 1) def url_generator(**kw): return url.current(filter=c.search_term, **kw) c.users_log = Page(users_log, page=p, items_per_page=10, url=url_generator) c.log_data = render('admin/admin_log.html') if request.environ.get('HTTP_X_PARTIAL_XHR'): return c.log_data return render('admin/admin.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 try: if hasattr(user, 'user_id'): user_obj = user elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: raise Exception('You have to provide user object or username') if hasattr(repo, 'repo_id'): repo_obj = Repository.get(repo.repo_id) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip('/') repo_obj = Repository.get_by_repo_name(repo_name) else: raise Exception('You have to provide repository to action logger') user_log = UserLog() user_log.user_id = user_obj.user_id user_log.action = safe_unicode(action) user_log.repository_id = repo_obj.repo_id user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) log.info( 'Adding user %s, action %s on %s' % (user_obj, action, safe_unicode(repo)) ) if commit: sa.commit() except: log.error(traceback.format_exc()) raise
def action_logger(user, action, repo, ipaddr="", sa=None): """ Action logger for various actions made by users :param user: user that made this action, can be a unique username string or object containing user_id attribute :param action: action to log, should be on of predefined unique actions for easy translations :param repo: string name of repository or object containing repo_id, that action was made on :param ipaddr: optional ip address from what the action was made :param sa: optional sqlalchemy session """ if not sa: sa = meta.Session() try: if hasattr(user, "user_id"): user_obj = user elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: raise Exception("You have to provide user object or username") rm = RepoModel() if hasattr(repo, "repo_id"): repo_obj = rm.get(repo.repo_id, cache=False) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip("/") repo_obj = rm.get_by_repo_name(repo_name, cache=False) else: raise Exception("You have to provide repository to action logger") user_log = UserLog() user_log.user_id = user_obj.user_id user_log.action = action user_log.repository_id = repo_obj.repo_id user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) sa.commit() log.info("Adding user %s, action %s on %s", user_obj, action, repo) except: log.error(traceback.format_exc()) sa.rollback()
def test_api_merge_pull_request(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() pull_request_2 = PullRequestModel().create( created_by=pull_request.author, source_repo=pull_request.source_repo, source_ref=pull_request.source_ref, target_repo=pull_request.target_repo, target_ref=pull_request.target_ref, revisions=pull_request.revisions, reviewers=(), title=pull_request.title, description=pull_request.description, ) author = pull_request.user_id repo = pull_request_2.target_repo.repo_id pull_request_2_id = pull_request_2.pull_request_id pull_request_2_repo = pull_request_2.target_repo.repo_name Session().commit() id_, params = build_data(self.apikey, 'merge_pull_request', repoid=pull_request_2_repo, pullrequestid=pull_request_2_id) response = api_call(self.app, params) expected = {'executed': True, 'failure_reason': 0, 'possible': True} response_json = response.json['result'] assert response_json['merge_commit_id'] response_json.pop('merge_commit_id') assert response_json == expected action = 'user_merged_pull_request:%d' % (pull_request_2_id, ) journal = UserLog.query()\ .filter(UserLog.user_id == author)\ .filter(UserLog.repository_id == repo)\ .filter(UserLog.action == action)\ .all() assert len(journal) == 1 id_, params = build_data(self.apikey, 'merge_pull_request', repoid=pull_request_2_repo, pullrequestid=pull_request_2_id) response = api_call(self.app, params) expected = 'pull request `%s` merge failed, pull request is closed' % ( pull_request_2_id) assert_error(id_, expected, given=response.body)
def index(self): users_log = ( UserLog.query() .options(joinedload(UserLog.user)) .options(joinedload(UserLog.repository)) .order_by(UserLog.action_date.desc()) ) p = safe_int(request.params.get("page", 1), 1) c.users_log = Page(users_log, page=p, items_per_page=10) c.log_data = render("admin/admin_log.html") if request.environ.get("HTTP_X_PARTIAL_XHR"): return c.log_data return render("admin/admin.html")
def test_merge_pull_request_enabled(self, pr_util, csrf_token): # Clear any previous calls to rcextensions rhodecode.EXTENSIONS.calls.clear() pull_request = pr_util.create_pull_request( approved=True, mergeable=True) pull_request_id = pull_request.pull_request_id repo_name = pull_request.target_repo.scm_instance().name, response = self.app.post( url(controller='pullrequests', action='merge', repo_name=str(repo_name[0]), pull_request_id=str(pull_request_id)), params={'csrf_token': csrf_token}).follow() pull_request = PullRequest.get(pull_request_id) assert response.status_int == 200 assert pull_request.is_closed() assert_pull_request_status( pull_request, ChangesetStatus.STATUS_APPROVED) # Check the relevant log entries were added user_logs = UserLog.query().order_by('-user_log_id').limit(4) actions = [log.action for log in user_logs] pr_commit_ids = PullRequestModel()._get_commit_ids(pull_request) expected_actions = [ u'user_closed_pull_request:%d' % pull_request_id, u'user_merged_pull_request:%d' % pull_request_id, # The action below reflect that the post push actions were executed u'user_commented_pull_request:%d' % pull_request_id, u'push:%s' % ','.join(pr_commit_ids), ] assert actions == expected_actions # Check post_push rcextension was really executed push_calls = rhodecode.EXTENSIONS.calls['post_push'] assert len(push_calls) == 1 unused_last_call_args, last_call_kwargs = push_calls[0] assert last_call_kwargs['action'] == 'push' assert last_call_kwargs['pushed_revs'] == pr_commit_ids
def test_api_close_pull_request(self, pr_util): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id author = pull_request.user_id repo = pull_request.target_repo.repo_id id_, params = build_data( self.apikey, 'close_pull_request', repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id) response = api_call(self.app, params) expected = { 'pull_request_id': pull_request_id, 'closed': True, } assert_ok(id_, expected, response.body) action = 'user_closed_pull_request:%d' % pull_request_id journal = UserLog.query()\ .filter(UserLog.user_id == author)\ .filter(UserLog.repository_id == repo)\ .filter(UserLog.action == action)\ .all() assert len(journal) == 1
def cleanup(): UserLog.query().delete() Session().commit()
def teardown_class(cls): UserLog.query().delete() Session().commit()
def test_action_map_pr_values(pylonsapp, pr_key): parser = ActionParser(UserLog(action="test:test")) assert pr_key in parser.action_map
def get_logs(): return UserLog.query().all()
def test_logs(initial): logs = UserLog.query().all() operations = 4 if len(initial) + operations != len(logs): raise Exception("missing number of logs initial:%s vs current:%s" % \ (len(initial), len(logs)))