Blame tests/test_pagure_flask_ui_clone.py

Patrick Uiterwijk a50651
# -*- coding: utf-8 -*-
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
"""
Patrick Uiterwijk a50651
 (c) 2015-2018 - Copyright Red Hat Inc
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
 Authors:
Patrick Uiterwijk a50651
   Patrick Uiterwijk <puiterwijk@redhat.com></puiterwijk@redhat.com>
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
"""
Patrick Uiterwijk a50651
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
import datetime
Patrick Uiterwijk a50651
import unittest
Patrick Uiterwijk a50651
import shutil
Patrick Uiterwijk a50651
import sys
Patrick Uiterwijk a50651
import tempfile
Patrick Uiterwijk a50651
import os
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
import six
Patrick Uiterwijk a50651
import json
Patrick Uiterwijk a50651
import pygit2
Patrick Uiterwijk a50651
from mock import patch, MagicMock
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
sys.path.insert(
Pierre-Yves Chibon 73d120
    0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
Pierre-Yves Chibon 73d120
)
Patrick Uiterwijk a50651
Pierre-Yves Chibon 930073
import pagure.lib.query
Patrick Uiterwijk a50651
import tests
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
class PagureFlaskAppClonetests(tests.Modeltests):
Patrick Uiterwijk a50651
    """ Tests for the clone bridging. """
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
    def setUp(self):
Patrick Uiterwijk a50651
        super(PagureFlaskAppClonetests, self).setUp()
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
        tests.create_projects(self.session)
Patrick Uiterwijk a50651
        tests.create_tokens(self.session)
Patrick Uiterwijk a50651
        tests.create_tokens_acl(self.session)
Pierre-Yves Chibon 73d120
        self.create_project_full("clonetest", {"create_readme": "y"})
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
    @patch.dict("pagure.config.config", {"ALLOW_HTTP_PULL_PUSH": False})
Patrick Uiterwijk a50651
    def test_http_clone_disabled(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP clone endpoint gets correctly closed. """
Pierre-Yves Chibon 73d120
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-upload-pack"
Pierre-Yves Chibon 73d120
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 73d120
        self.assertIn("not allowed", output.get_data(as_text=True))
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
    @patch.dict("pagure.config.config", {"ALLOW_HTTP_PULL_PUSH": True})
Patrick Uiterwijk a50651
    def test_http_clone_invalid_service(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP endpoint refuses invalid services. """
Pierre-Yves Chibon 73d120
        output = self.app.get("/clonetest.git/info/refs?service=myservice")
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 400)
Pierre-Yves Chibon 73d120
        self.assertIn("Unknown service", output.get_data(as_text=True))
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
    @patch.dict("pagure.config.config", {"ALLOW_HTTP_PULL_PUSH": True})
Patrick Uiterwijk a50651
    def test_http_clone_invalid_project(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP endpoint refuses invalid projects. """
Pierre-Yves Chibon 73d120
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/nosuchrepo.git/info/refs?service=git-upload-pack"
Pierre-Yves Chibon 73d120
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 73d120
        self.assertIn("Project not found", output.get_data(as_text=True))
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
    @patch.dict("pagure.config.config", {"ALLOW_HTTP_PULL_PUSH": True})
Patrick Uiterwijk a50651
    def test_http_clone_dumb(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP endpoint refuses dumb service request. """
Pierre-Yves Chibon 73d120
        output = self.app.get("/clonetest.git/info/refs")
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 400)
Pierre-Yves Chibon 73d120
        self.assertIn("Please switch", output.get_data(as_text=True))
Pierre-Yves Chibon 73d120
Pierre-Yves Chibon 73d120
    @patch.dict(
Pierre-Yves Chibon 73d120
        "pagure.config.config",
Pierre-Yves Chibon 73d120
        {
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PULL_PUSH": True,
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PUSH": False,
Pierre-Yves Chibon 73d120
            "HTTP_REPO_ACCESS_GITOLITE": None,
Pierre-Yves Chibon 73d120
        },
Pierre-Yves Chibon 73d120
    )
Patrick Uiterwijk a50651
    def test_http_push_disabled(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP push gets refused. """
Pierre-Yves Chibon 73d120
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-receive-pack"
Pierre-Yves Chibon 73d120
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 73d120
        self.assertIn("pushing disabled", output.get_data(as_text=True))
Pierre-Yves Chibon 73d120
        output = self.app.post("/clonetest.git/git-receive-pack")
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 73d120
        self.assertIn("pushing disabled", output.get_data(as_text=True))
Pierre-Yves Chibon 73d120
Pierre-Yves Chibon 73d120
    @patch.dict(
Pierre-Yves Chibon 73d120
        "pagure.config.config",
Pierre-Yves Chibon 73d120
        {
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PULL_PUSH": True,
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PUSH": True,
Pierre-Yves Chibon 73d120
            "HTTP_REPO_ACCESS_GITOLITE": None,
Pierre-Yves Chibon 73d120
        },
Pierre-Yves Chibon 73d120
    )
Patrick Uiterwijk a50651
    def test_http_push_unauthed(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP push gets refused unauthed. """
Pierre-Yves Chibon 73d120
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-receive-pack"
Pierre-Yves Chibon 73d120
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 73d120
        self.assertIn("Unauthenticated push", output.get_data(as_text=True))
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
    @patch.dict("pagure.config.config", {"ALLOW_HTTP_PULL_PUSH": True})
Patrick Uiterwijk a50651
    def test_http_clone_private_project_unauthed(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP endpoint enforced project.private. """
Pierre-Yves Chibon 73d120
        project = pagure.lib.query._get_project(self.session, "clonetest")
Patrick Uiterwijk a50651
        project.private = True
Patrick Uiterwijk a50651
        self.session.add(project)
Patrick Uiterwijk a50651
        self.session.commit()
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-upload-pack"
Pierre-Yves Chibon 73d120
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 73d120
        self.assertIn("Project not found", output.get_data(as_text=True))
Pierre-Yves Chibon 73d120
Pierre-Yves Chibon 73d120
    @patch.dict(
Pierre-Yves Chibon 73d120
        "pagure.config.config",
Pierre-Yves Chibon 73d120
        {
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PULL_PUSH": True,
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PUSH": False,
Pierre-Yves Chibon 73d120
            "HTTP_REPO_ACCESS_GITOLITE": None,
Pierre-Yves Chibon 73d120
        },
Pierre-Yves Chibon 73d120
    )
Patrick Uiterwijk a50651
    def test_http_clone(self):
Patrick Uiterwijk a50651
        """ Test that HTTP cloning gives reasonable output. """
Patrick Uiterwijk a50651
        # Unfortunately, actually testing a git clone would need the app to
Patrick Uiterwijk a50651
        # run on a TCP port, which the test environment doesn't do.
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-upload-pack"
Pierre-Yves Chibon 73d120
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 200)
Patrick Uiterwijk a50651
        output_text = output.get_data(as_text=True)
Patrick Uiterwijk a50651
        self.assertIn("# service=git-upload-pack", output_text)
Patrick Uiterwijk a50651
        self.assertIn(" refs/heads/master\n0000", output_text)
Patrick Uiterwijk a50651
Patrick Uiterwijk 802c7e
        output = self.app.post(
Pierre-Yves Chibon 73d120
            "/clonetest.git/git-upload-pack",
Pierre-Yves Chibon 73d120
            headers={"Content-Type": "application/x-git-upload-pack-request"},
Patrick Uiterwijk 802c7e
        )
Patrick Uiterwijk f607ef
        # Git 2.17 returns 415, older return 200
Patrick Uiterwijk f607ef
        # Either means we didn't fully crash when returning the response
Patrick Uiterwijk f607ef
        self.assertIn(output.status_code, (200, 415))
Patrick Uiterwijk 802c7e
Pierre-Yves Chibon 73d120
    @patch.dict(
Pierre-Yves Chibon 73d120
        "pagure.config.config",
Pierre-Yves Chibon 73d120
        {
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PULL_PUSH": True,
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PUSH": False,
Pierre-Yves Chibon 73d120
            "HTTP_REPO_ACCESS_GITOLITE": None,
Pierre-Yves Chibon 73d120
        },
Pierre-Yves Chibon 73d120
    )
Patrick Uiterwijk a50651
    def test_http_clone_private(self):
Patrick Uiterwijk a50651
        """ Test that HTTP cloning gives reasonable output with project.private. """
Patrick Uiterwijk a50651
        # Unfortunately, actually testing a git clone would need the app to
Patrick Uiterwijk a50651
        # run on a TCP port, which the test environment doesn't do.
Pierre-Yves Chibon 73d120
        project = pagure.lib.query._get_project(self.session, "clonetest")
Patrick Uiterwijk a50651
        project.private = True
Patrick Uiterwijk a50651
        self.session.add(project)
Patrick Uiterwijk a50651
        self.session.commit()
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-upload-pack"
Pierre-Yves Chibon 73d120
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 73d120
        self.assertIn("Project not found", output.get_data(as_text=True))
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-upload-pack",
Pierre-Yves Chibon 73d120
            environ_overrides={"REMOTE_USER": "pingou"},
Patrick Uiterwijk a50651
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 200)
Patrick Uiterwijk a50651
        output_text = output.get_data(as_text=True)
Patrick Uiterwijk a50651
        self.assertIn("# service=git-upload-pack", output_text)
Patrick Uiterwijk a50651
        self.assertIn(" refs/heads/master\n0000", output_text)
Patrick Uiterwijk a50651
Pierre-Yves Chibon 73d120
    @patch.dict(
Pierre-Yves Chibon 73d120
        "pagure.config.config",
Pierre-Yves Chibon 73d120
        {
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PULL_PUSH": True,
Pierre-Yves Chibon 73d120
            "ALLOW_HTTP_PUSH": True,
Pierre-Yves Chibon 73d120
            "HTTP_REPO_ACCESS_GITOLITE": None,
Pierre-Yves Chibon 73d120
        },
Pierre-Yves Chibon 73d120
    )
Patrick Uiterwijk a50651
    def test_http_push(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP push gets accepted. """
Patrick Uiterwijk a50651
        output = self.app.get(
Pierre-Yves Chibon 73d120
            "/clonetest.git/info/refs?service=git-receive-pack",
Pierre-Yves Chibon 73d120
            environ_overrides={"REMOTE_USER": "pingou"},
Patrick Uiterwijk a50651
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 200)
Patrick Uiterwijk a50651
        output_text = output.get_data(as_text=True)
Patrick Uiterwijk a50651
        self.assertIn("# service=git-receive-pack", output_text)
Patrick Uiterwijk a50651
        self.assertIn(" refs/heads/master\x00", output_text)