Esempio n. 1
0
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,
        })
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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,
        })
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 8
0
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,
        })
Esempio n. 9
0
 def test_get_local_timestamp(self):
     TimeUtils.get_local_timestamp()
Esempio n. 10
0
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})