def repo_update(request): """ Get the updates for the repo page. """ if 'last_request' not in request.GET or 'limit' not in request.GET or 'repo_id' not in request.GET: return HttpResponseBadRequest('Missing parameters') this_request = TimeUtils.get_local_timestamp() repo_id = int(request.GET['repo_id']) limit = int(request.GET['limit']) last_request = int(float(request.GET['last_request'])) # in case it has decimals dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request))) repo = get_object_or_404(models.Repository, pk=repo_id) repos_status = RepositoryStatus.filter_repos_status([repo.pk], last_modified=dt) event_q = EventsStatus.get_default_events_query() event_q = event_q.filter(base__branch__repository=repo)[:limit] events_info = EventsStatus.multiline_events_info(event_q, last_modified=dt) # we also need to check if a PR closed recently closed = [] for pr in models.PullRequest.objects.filter(repository=repo, closed=True, last_modified__gte=dt).values('id').all(): closed.append({'id': pr['id']}) return JsonResponse({'repo_status': repos_status, 'closed': closed, 'last_request': this_request, 'events': events_info, 'limit': limit, })
def is_team_member(session, api, team, user): """ Checks to see if a user is a team member and caches the results """ teams = session.get("teams", {}) # Check to see if their permissions are still valid if teams and team in teams and TimeUtils.get_local_timestamp( ) < teams[team][1]: return teams[team][0] is_member = api.is_member(team, user) logger.info("User '%s' member status of '%s': %s" % (user, team, is_member)) teams[team] = (is_member, TimeUtils.get_local_timestamp() + settings.COLLABORATOR_CACHE_TIMEOUT) session["teams"] = teams return is_member
def is_allowed_to_see_clients(session): """ Check to see if the signed in user can see client information. We do this by checking the "authorized_users" "authorized_users" can contain orgs and teams """ val = session.get("allowed_to_see_clients") # Check to see if their permissions are still valid if val and TimeUtils.get_local_timestamp() < val[1]: return val[0] user = None for server in settings.INSTALLED_GITSERVERS: gitserver = models.GitServer.objects.get(host_type=server["type"], name=server["hostname"]) auth = gitserver.auth() user = auth.signed_in_user(gitserver, session) if not user: continue api = user.api() for authed_user in server.get("authorized_users", []): if user.name == authed_user or is_team_member( session, api, authed_user, user): logger.info( "'%s' is a member of '%s' and is allowed to see clients" % (user, authed_user)) session["allowed_to_see_clients"] = ( True, TimeUtils.get_local_timestamp() + settings.COLLABORATOR_CACHE_TIMEOUT) return True logger.info("%s is NOT allowed to see clients on %s" % (user, gitserver)) session["allowed_to_see_clients"] = (False, TimeUtils.get_local_timestamp() + settings.COLLABORATOR_CACHE_TIMEOUT) return False
def is_collaborator(request_session, build_user, repo, user=None): """ Checks to see if the signed in user is a collaborator on a repo. This will cache the value for a time specified by settings.COLLABORATOR_CACHE_TIMEOUT Input: request_session: A session from HttpRequest.session build_user: models.GitUser who has access to check collaborators repo: models.Repository to check against user: models.GitUser: User to check for. If None then the user will be pulled from the request_session Return: (bool, models.GitUser) tuple: bool is whether the user is a collaborator GitUser is the user from the request_session or None if not signed in """ server = repo.server() if not user: user = server.signed_in_user(request_session) if not user: return False auth = server.auth() if auth._collaborators_key in request_session: collab_dict = request_session[auth._collaborators_key] val = collab_dict.get(str(repo)) timestamp = TimeUtils.get_local_timestamp() # Check to see if their permissions are still valid if val and timestamp < val[1]: return val[0] api = build_user.api() collab_dict = request_session.get(auth._collaborators_key, {}) val = api.is_collaborator(user, repo) collab_dict[str(repo)] = (val, TimeUtils.get_local_timestamp() + settings.COLLABORATOR_CACHE_TIMEOUT) request_session[auth._collaborators_key] = collab_dict logger.info("Is collaborator for user '%s' on %s: %s" % (user, repo, val)) return val
def main(request): """ Main view. Just shows the status of repos, with open prs, as well as a short list of recent jobs. Input: request: django.http.HttpRequest Return: django.http.HttpResponse based object """ limit = 30 repos, evs_info, default = get_user_repos_info(request, limit=limit) return render(request, 'ci/main.html', {'repos': repos, 'recent_events': evs_info, 'last_request': TimeUtils.get_local_timestamp(), 'event_limit': limit, 'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL, 'default_view': default, })
def do_repo_page(request, repo): """ Render the repo page. This has the same layout as the main page but only for single repository. Input: request[django.http.HttpRequest] repo[models.Repository] """ limit = 30 repos_status = RepositoryStatus.filter_repos_status([repo.pk]) events_info = EventsStatus.events_filter_by_repo([repo.pk], limit=limit) params = { 'repo': repo, 'repos_status': repos_status, 'events_info': events_info, 'event_limit': limit, 'last_request': TimeUtils.get_local_timestamp(), 'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL } return render(request, 'ci/repo.html', params)
def user_open_prs(request, username): """ Get the updates for the main page. """ users = models.GitUser.objects.filter(name=username) if users.count() == 0: return HttpResponseBadRequest('Bad username') if 'last_request' not in request.GET: return HttpResponseBadRequest('Missing parameters') this_request = TimeUtils.get_local_timestamp() last_request = int(float(request.GET['last_request'])) # in case it has decimals dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request))) repos = RepositoryStatus.get_user_repos_with_open_prs_status(username) repo_ids = [] pr_ids = [] for r in repos: repo_ids.append(r["id"]) for pr in r["prs"]: pr_ids.append(pr["id"]) event_list = EventsStatus.get_single_event_for_open_prs(pr_ids) evs_info = EventsStatus.multiline_events_info(event_list) ev_ids = [] for e in evs_info: ev_ids.append(e["id"]) # Now get the changed ones repos = RepositoryStatus.get_user_repos_with_open_prs_status(username, dt) evs_info = EventsStatus.multiline_events_info(event_list, dt) data = {'repos': repo_ids, 'prs': pr_ids, 'events': ev_ids, 'repo_status': repos, 'closed': [], 'last_request': this_request, 'changed_events': evs_info, } return JsonResponse(data)
def main_update(request): """ Get the updates for the main page. """ if 'last_request' not in request.GET or 'limit' not in request.GET: return HttpResponseBadRequest('Missing parameters') this_request = TimeUtils.get_local_timestamp() limit = int(request.GET['limit']) last_request = int(float(request.GET['last_request'])) # in case it has decimals dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request))) repos_data, einfo, default = views.get_user_repos_info(request, limit=limit, last_modified=dt) # we also need to check if a PR closed recently closed = [] for pr in models.PullRequest.objects.filter(closed=True, last_modified__gte=dt).values('id').all(): closed.append({'id': pr['id']}) return JsonResponse({'repo_status': repos_data, 'closed': closed, 'last_request': this_request, 'events': einfo, 'limit': limit, })
def test_get_local_timestamp(self): TimeUtils.get_local_timestamp()
def job_results(request): """ Returns the job results and job info in JSON. GET parameters: job_id: The pk of the job last_request: A timestamp of when client last requested this information. If the job hasn't been updated since that time we don't have to send as much information. """ if 'last_request' not in request.GET or 'job_id' not in request.GET: return HttpResponseBadRequest('Missing parameters') this_request = TimeUtils.get_local_timestamp() job_id = int(request.GET['job_id']) last_request = int(float(request.GET['last_request'])) # in case it has decimals dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request))) job = get_object_or_404(models.Job.objects.select_related("recipe", "client").prefetch_related("step_results"), pk=job_id) if not Permissions.can_see_results(request.session, job.recipe): return HttpResponseForbidden("Can't see results") job_info = { 'id': job.pk, 'complete': job.complete, 'status': job.status_slug(), 'runtime': str(job.seconds), 'ready': job.ready, 'invalidated': job.invalidated, 'active': job.active, 'last_modified': TimeUtils.display_time_str(job.last_modified), 'created': TimeUtils.display_time_str(job.created), 'client_name': '', 'client_url': '', 'recipe_repo_sha': job.recipe_repo_sha[:6], 'recipe_sha': job.recipe.filename_sha[:6], } if job.last_modified < dt: # always return the basic info since we need to update the # "natural" time return JsonResponse({'job_info': job_info, 'results': [], 'last_request': this_request}) if job.client: can_see_client = Permissions.is_allowed_to_see_clients(request.session) if can_see_client: job_info['client_name'] = job.client.name job_info['client_url'] = reverse('ci:view_client', args=[job.client.pk,]) result_info = [] for result in job.step_results.all(): if dt > result.last_modified: continue exit_status = '' if result.complete: exit_status = result.exit_status info = {'id': result.id, 'name': result.name, 'runtime': str(result.seconds), 'exit_status': exit_status, 'output': result.clean_output(), 'status': result.status_slug(), 'running': result.status != models.JobStatus.NOT_STARTED, 'complete': result.complete, 'output_size': result.output_size(), } result_info.append(info) return JsonResponse({'job_info': job_info, 'results': result_info, 'last_request': this_request})