summaryrefslogtreecommitdiffstats
path: root/public.php
blob: 76fe5ac05706bbd8c630336e172a0a22eea40294 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php

try {

	require_once 'lib/base.php';
	if (\OCP\Util::needUpgrade()) {
		// since the behavior of apps or remotes are unpredictable during
		// an upgrade, return a 503 directly
		OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
		OC_Template::printErrorPage('Service unavailable');
		exit;
	}

	OC::checkMaintenanceMode();
	OC::checkSingleUserMode();
	$request = \OC::$server->getRequest();
	$pathInfo = $request->getPathInfo();

	if (!$pathInfo && $request->getParam('service', '') === '') {
		header('HTTP/1.0 404 Not Found');
		exit;
	} elseif ($request->getParam('service', '')) {
		$service = $request->getParam('service', '');
	} else {
		$pathInfo = trim($pathInfo, '/');
		list($service) = explode('/', $pathInfo);
	}
	$file = OCP\CONFIG::getAppValue('core', 'public_' . strip_tags($service));
	if (is_null($file)) {
		header('HTTP/1.0 404 Not Found');
		exit;
	}

	$parts = explode('/', $file, 2);
	$app = $parts[0];

	// Load all required applications
	\OC::$REQUESTEDAPP = $app;
	OC_App::loadApps(array('authentication'));
	OC_App::loadApps(array('filesystem', 'logging'));

	if (!\OC::$server->getAppManager()->isInstalled($app)) {
		throw new Exception('App not installed: ' . $app);
	}
	OC_App::loadApp($app);
	OC_User::setIncognitoMode(true);

	$baseuri = OC::$WEBROOT . '/public.php/' . $service . '/';

	require_once OC_App::getAppPath($app) . '/' . $parts[1];

} catch (\OC\ServiceUnavailableException $ex) {
	//show the user a detailed error page
	OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
	\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
	OC_Template::printExceptionErrorPage($ex);
} catch (Exception $ex) {
	//show the user a detailed error page
	OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
	\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
	OC_Template::printExceptionErrorPage($ex);
}
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr)) t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffHash, diffLength)) } } func doCreatePRAndSetManuallyMerged(ctx, baseCtx APITestContext, dstPath, baseBranch, headBranch string) func(t *testing.T) { return func(t *testing.T) { defer tests.PrintCurrentTest(t)() var ( pr api.PullRequest err error lastCommitID string ) trueBool := true falseBool := false t.Run("AllowSetManuallyMergedAndSwitchOffAutodetectManualMerge", doAPIEditRepository(baseCtx, &api.EditRepoOption{ HasPullRequests: &trueBool, AllowManualMerge: &trueBool, AutodetectManualMerge: &falseBool, })) t.Run("CreateHeadBranch", doGitCreateBranch(dstPath, headBranch)) t.Run("PushToHeadBranch", doGitPushTestRepository(dstPath, "origin", headBranch)) t.Run("CreateEmptyPullRequest", func(t *testing.T) { pr, err = doAPICreatePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, baseBranch, headBranch)(t) assert.NoError(t, err) }) lastCommitID = pr.Base.Sha t.Run("ManuallyMergePR", doAPIManuallyMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, lastCommitID, pr.Index)) } } func doEnsureCanSeePull(ctx APITestContext, pr api.PullRequest) func(t *testing.T) { return func(t *testing.T) { req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), pr.Index)) ctx.Session.MakeRequest(t, req, http.StatusOK) req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d/files", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), pr.Index)) ctx.Session.MakeRequest(t, req, http.StatusOK) req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d/commits", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), pr.Index)) ctx.Session.MakeRequest(t, req, http.StatusOK) } } func doEnsureDiffNoChange(ctx APITestContext, pr api.PullRequest, diffHash string, diffLength int) func(t *testing.T) { return func(t *testing.T) { req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d.diff", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), pr.Index)) resp := ctx.Session.MakeRequestNilResponseHashSumRecorder(t, req, http.StatusOK) actual := string(resp.Hash.Sum(nil)) actualLength := resp.Length equal := diffHash == actual assert.True(t, equal, "Unexpected change in the diff string: expected hash: %s size: %d but was actually: %s size: %d", hex.EncodeToString([]byte(diffHash)), diffLength, hex.EncodeToString([]byte(actual)), actualLength) } } func doPushCreate(ctx APITestContext, u *url.URL) func(t *testing.T) { return func(t *testing.T) { defer tests.PrintCurrentTest(t)() // create a context for a currently non-existent repository ctx.Reponame = fmt.Sprintf("repo-tmp-push-create-%s", u.Scheme) u.Path = ctx.GitPath() // Create a temporary directory tmpDir := t.TempDir() // Now create local repository to push as our test and set its origin t.Run("InitTestRepository", doGitInitTestRepository(tmpDir)) t.Run("AddRemote", doGitAddRemote(tmpDir, "origin", u)) // Disable "Push To Create" and attempt to push setting.Repository.EnablePushCreateUser = false t.Run("FailToPushAndCreateTestRepository", doGitPushTestRepositoryFail(tmpDir, "origin", "master")) // Enable "Push To Create" setting.Repository.EnablePushCreateUser = true // Assert that cloning from a non-existent repository does not create it and that it definitely wasn't create above t.Run("FailToCloneFromNonExistentRepository", doGitCloneFail(u)) // Then "Push To Create"x t.Run("SuccessfullyPushAndCreateTestRepository", doGitPushTestRepository(tmpDir, "origin", "master")) // Finally, fetch repo from database and ensure the correct repository has been created repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, ctx.Username, ctx.Reponame) assert.NoError(t, err) assert.False(t, repo.IsEmpty) assert.True(t, repo.IsPrivate) // Now add a remote that is invalid to "Push To Create" invalidCtx := ctx invalidCtx.Reponame = fmt.Sprintf("invalid/repo-tmp-push-create-%s", u.Scheme) u.Path = invalidCtx.GitPath() t.Run("AddInvalidRemote", doGitAddRemote(tmpDir, "invalid", u)) // Fail to "Push To Create" the invalid t.Run("FailToPushAndCreateInvalidTestRepository", doGitPushTestRepositoryFail(tmpDir, "invalid", "master")) } } func doBranchDelete(ctx APITestContext, owner, repo, branch string) func(*testing.T) { return func(t *testing.T) { csrf := GetCSRF(t, ctx.Session, fmt.Sprintf("/%s/%s/branches", url.PathEscape(owner), url.PathEscape(repo))) req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/branches/delete?name=%s", url.PathEscape(owner), url.PathEscape(repo), url.QueryEscape(branch)), map[string]string{ "_csrf": csrf, }) ctx.Session.MakeRequest(t, req, http.StatusOK) } } func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) { return func(t *testing.T) { defer tests.PrintCurrentTest(t)() ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeRepo) t.Run("CheckoutProtected", doGitCheckoutBranch(dstPath, "protected")) t.Run("PullProtected", doGitPull(dstPath, "origin", "protected")) t.Run("GenerateCommit", func(t *testing.T) { _, err := generateCommitWithNewData(littleSize, dstPath, "user2@example.com", "User Two", "branch-data-file-") assert.NoError(t, err) }) t.Run("PushToUnprotectedBranch", doGitPushTestRepository(dstPath, "origin", "protected:unprotected3")) var pr api.PullRequest var err error t.Run("CreatePullRequest", func(t *testing.T) { pr, err = doAPICreatePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, "protected", "unprotected3")(t) assert.NoError(t, err) }) // Request repository commits page req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d/commits", baseCtx.Username, baseCtx.Reponame, pr.Index)) resp := ctx.Session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body) // Get first commit URL commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href") assert.True(t, exists) assert.NotEmpty(t, commitURL) commitID := path.Base(commitURL) addCommitStatus := func(status api.CommitStatusState) func(*testing.T) { return doAPICreateCommitStatus(ctx, commitID, api.CreateStatusOption{ State: status, TargetURL: "http://test.ci/", Description: "", Context: "testci", }) } // Call API to add Pending status for commit t.Run("CreateStatus", addCommitStatus(api.CommitStatusPending)) // Cancel not existing auto merge ctx.ExpectedCode = http.StatusNotFound t.Run("CancelAutoMergePR", doAPICancelAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)) // Add auto merge request ctx.ExpectedCode = http.StatusCreated t.Run("AutoMergePR", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)) // Can not create schedule twice ctx.ExpectedCode = http.StatusConflict t.Run("AutoMergePRTwice", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)) // Cancel auto merge request ctx.ExpectedCode = http.StatusNoContent t.Run("CancelAutoMergePR", doAPICancelAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)) // Add auto merge request ctx.ExpectedCode = http.StatusCreated t.Run("AutoMergePR", doAPIAutoMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)) // Check pr status ctx.ExpectedCode = 0 pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t) assert.NoError(t, err) assert.False(t, pr.HasMerged) // Call API to add Failure status for commit t.Run("CreateStatus", addCommitStatus(api.CommitStatusFailure)) // Check pr status pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t) assert.NoError(t, err) assert.False(t, pr.HasMerged) // Call API to add Success status for commit t.Run("CreateStatus", addCommitStatus(api.CommitStatusSuccess)) // wait to let gitea merge stuff time.Sleep(time.Second) // test pr status pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t) assert.NoError(t, err) assert.True(t, pr.HasMerged) } } func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headBranch string) func(t *testing.T) { return func(t *testing.T) { defer tests.PrintCurrentTest(t)() // skip this test if git version is low if git.CheckGitVersionAtLeast("2.29") != nil { return } gitRepo, err := git.OpenRepository(git.DefaultContext, dstPath) if !assert.NoError(t, err) { return } defer gitRepo.Close() var ( pr1, pr2 *issues_model.PullRequest commit string ) repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, ctx.Username, ctx.Reponame) if !assert.NoError(t, err) { return } pullNum := unittest.GetCount(t, &issues_model.PullRequest{}) t.Run("CreateHeadBranch", doGitCreateBranch(dstPath, headBranch)) t.Run("AddCommit", func(t *testing.T) { err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content"), 0o666) if !assert.NoError(t, err) { return } err = git.AddChanges(dstPath, true) assert.NoError(t, err) err = git.CommitChanges(dstPath, git.CommitChangesOptions{ Committer: &git.Signature{ Email: "user2@example.com", Name: "user2", When: time.Now(), }, Author: &git.Signature{ Email: "user2@example.com", Name: "user2", When: time.Now(), }, Message: "Testing commit 1", }) assert.NoError(t, err) commit, err = gitRepo.GetRefCommitID("HEAD") assert.NoError(t, err) }) t.Run("Push", func(t *testing.T) { err := git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic=" + headBranch).Run(&git.RunOpts{Dir: dstPath}) if !assert.NoError(t, err) { return } unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+1) pr1 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo.ID, Flow: issues_model.PullRequestFlowAGit, }) if !assert.NotEmpty(t, pr1) { return } prMsg, err := doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)(t) if !assert.NoError(t, err) { return } assert.Equal(t, "user2/"+headBranch, pr1.HeadBranch) assert.False(t, prMsg.HasMerged) assert.Contains(t, "Testing commit 1", prMsg.Body) assert.Equal(t, commit, prMsg.Head.Sha) _, _, err = git.NewCommand(git.DefaultContext, "push", "origin").AddDynamicArguments("HEAD:refs/for/master/test/" + headBranch).RunStdString(&git.RunOpts{Dir: dstPath}) if !assert.NoError(t, err) { return } unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) pr2 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo.ID, Index: pr1.Index + 1, Flow: issues_model.PullRequestFlowAGit, }) if !assert.NotEmpty(t, pr2) { return } prMsg, err = doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr2.Index)(t) if !assert.NoError(t, err) { return } assert.Equal(t, "user2/test/"+headBranch, pr2.HeadBranch) assert.False(t, prMsg.HasMerged) }) if pr1 == nil || pr2 == nil { return } t.Run("AddCommit2", func(t *testing.T) { err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content \n ## test content 2"), 0o666) if !assert.NoError(t, err) { return } err = git.AddChanges(dstPath, true) assert.NoError(t, err) err = git.CommitChanges(dstPath, git.CommitChangesOptions{ Committer: &git.Signature{ Email: "user2@example.com", Name: "user2", When: time.Now(), }, Author: &git.Signature{ Email: "user2@example.com", Name: "user2", When: time.Now(), }, Message: "Testing commit 2", }) assert.NoError(t, err) commit, err = gitRepo.GetRefCommitID("HEAD") assert.NoError(t, err) }) t.Run("Push2", func(t *testing.T) { err := git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic=" + headBranch).Run(&git.RunOpts{Dir: dstPath}) if !assert.NoError(t, err) { return } unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) prMsg, err := doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)(t) if !assert.NoError(t, err) { return } assert.False(t, prMsg.HasMerged) assert.Equal(t, commit, prMsg.Head.Sha) _, _, err = git.NewCommand(git.DefaultContext, "push", "origin").AddDynamicArguments("HEAD:refs/for/master/test/" + headBranch).RunStdString(&git.RunOpts{Dir: dstPath}) if !assert.NoError(t, err) { return } unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) prMsg, err = doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr2.Index)(t) if !assert.NoError(t, err) { return } assert.False(t, prMsg.HasMerged) assert.Equal(t, commit, prMsg.Head.Sha) }) t.Run("Merge", doAPIMergePullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)) t.Run("CheckoutMasterAgain", doGitCheckoutBranch(dstPath, "master")) } }