Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api does not change repository properties #15121

Closed
3 of 6 tasks
philfry opened this issue Mar 23, 2021 · 6 comments
Closed
3 of 6 tasks

api does not change repository properties #15121

philfry opened this issue Mar 23, 2021 · 6 comments
Labels
issue/not-a-bug The reported issue is the intended behavior or the problem is not inside Gitea

Comments

@philfry
Copy link
Contributor

philfry commented Mar 23, 2021

Description

trying to update some repository's attributes like disabling the issue tracker, pull requests, the wiki, converting it to private, doesn't have any effect.

Screenshots

gitea

#!/bin/bash
token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
apiurl="https://try.gitea.io/api/v1"
fullname="philfry/testrepository"

status() {
    curl -s \
        -H "Accept: application/json" -H "Authorization: token ${token}" \
        "${apiurl}/repos/${fullname}" | jq '.|{has_issues,has_projects,has_wiki,private}'
}

setval() {
    echo "set $1 to $2"
    curl -s -X PATCH \
        -H "Accept: application/json" -H "Authorization: token ${token}" \
        "${apiurl}/repos/${fullname}" -d "{\"$1\":$2}" | jq .${1}
}

status
setval has_issues false
setval has_projects false
setval has_wiki false
setval private true
status
@noerw
Copy link
Member

noerw commented Mar 23, 2021

I can only partially reproduce: Changing most of these flags works, private stays false for me.
However the returned response of the PATCH req seems to contain the unmodified repo.
On 1.13.5 all of this works fine.

edit: thanks for the nice reproducer!

@noerw noerw added modifies/api This PR adds API routes or modifies them type/bug labels Mar 23, 2021
@noerw noerw added this to the 1.14.0 milestone Mar 23, 2021
@philfry
Copy link
Contributor Author

philfry commented Mar 24, 2021

That's strange. On my production system I'm running 1.13.5, too, and it behaves the same as the version on try.gitea.io: It does not change anything. It doesn't even matter how many options I try to change at once.

curl -s -X PATCH \
  -H "Accept: application/json" -H "Authorization: token ${token}" \
  "${apiurl}/repos/rpms/ccache" \
  -d '{"private":true,"has_issues":false,"has_pull_requests":false,"has_projects":false,"has_wiki":false}' | \
  jq '.|{has_wiki,has_issues,has_pull_requests,has_projects,private}'
{
  "has_wiki": true,
  "has_issues": true,
  "has_pull_requests": true,
  "has_projects": true,
  "private": false
}

gitea.log:

2021/03/24 09:05:28 ...m.io/xorm/core/db.go:286:afterProcess() [I] [SQL] UPDATE `repository` SET 
`owner_id` = ?, `owner_name` = ?, `lower_name` = ?, `name` = ?, `description` = ?, `website` = ?, 
`original_service_type` = ?, `original_url` = ?, `default_branch` = ?, `num_watches` = ?, 
`num_stars` = ?, `num_forks` = ?, `num_issues` = ?, `num_closed_issues` = ?, `num_pulls` = ?, 
`num_closed_pulls` = ?, `num_milestones` = ?, `num_closed_milestones` = ?, `num_projects` = ?, 
`num_closed_projects` = ?, `is_private` = ?, `is_empty` = ?, `is_archived` = ?, `is_mirror` = ?, 
`status` = ?, `is_fork` = ?, `fork_id` = ?, `is_template` = ?, `template_id` = ?, `size` = ?, 
`is_fsck_enabled` = ?, `close_issues_via_commit_in_any_branch` = ?, `topics` = ?, `trust_model` = 
?, `avatar` = ?, `updated_unix` = ? WHERE `id`=? [3 rpms ccache ccache rpm package source of ccache 
 0  master 1 0 0 0 0 0 0 0 0 0 0 false false false false 0 false 0 false 0 19558 true false null 
default  1616573128 14] - 741.512µs
2021/03/24 09:05:28 ...m.io/xorm/core/db.go:286:afterProcess() [I] [SQL] DELETE FROM `repo_unit`
WHERE (repo_id = ?) AND 0=1 [14] - 463.333µs

which translates to

Execute	UPDATE `repository` SET `owner_id` = 3, `owner_name` = 'rpms', `lower_name` = 'ccache', 
`name` = 'ccache', `description` = 'rpm package source of ccache', `website` = '', 
`original_service_type` = 0, `original_url` = '', `default_branch` = 'master', `num_watches` = 1, 
`num_stars` = 0, `num_forks` = 0, `num_issues` = 0, `num_closed_issues` = 0, `num_pulls` = 0, 
`num_closed_pulls` = 0, `num_milestones` = 0, `num_closed_milestones` = 0, `num_projects` = 0, 
`num_closed_projects` = 0, `is_private` = 0, `is_empty` = 0, `is_archived` = 0, `is_mirror` = 0, 
`status` = 0, `is_fork` = 0, `fork_id` = 0, `is_template` = 0, `template_id` = 0, `size` = 19558, 
`is_fsck_enabled` = 1, `close_issues_via_commit_in_any_branch` = 0, `topics` = 'null', 
`trust_model` = 0, `avatar` = '', `updated_unix` = 1616574014 WHERE `id`=14
  1. is_private is set to the wrong value (false instead of true)
  2. the DELETE FROM repo_unit statement never applies because of AND 0=1.
mysql(root@localhost) [gitea]> select * from repository where name = "ccache"\G
*************************** 1. row ***************************
                                   id: 14
                             owner_id: 3
                           lower_name: ccache
                                 name: ccache
                          description: rpm package source of ccache
                              website: 
                       default_branch: master
                          num_watches: 1
                            num_stars: 0
                            num_forks: 0
                           num_issues: 0
                    num_closed_issues: 0
                            num_pulls: 0
                     num_closed_pulls: 0
                       num_milestones: 0
                num_closed_milestones: 0
                           is_private: 0
                            is_mirror: 0
                          enable_wiki: 1
                 enable_external_wiki: 0
                    external_wiki_url: 
                        enable_issues: 0
              enable_external_tracker: 0
                 external_tracker_url: 
              external_tracker_format: 
               external_tracker_style: 
                         enable_pulls: 0
                              is_fork: 0
                              fork_id: 0
                         created_unix: 1488205778
                         updated_unix: 1616573388
                                 size: 19558
                      is_fsck_enabled: 1
                               topics: null
                             is_empty: 0
close_issues_via_commit_in_any_branch: 0
                          is_archived: 0
                               avatar: 
                         original_url: 
                               status: 0
                original_service_type: 0
                          is_template: 0
                          template_id: 0
                           owner_name: rpms
                         num_projects: 0
                  num_closed_projects: 0
                          trust_model: 0
1 row in set (0.001 sec)

I found out that as I started quite early with gitea and did lots of version upgrades since then, my database schema seems to be fscked up as gitea seemingly no longer uses enable_{wiki,issues,pulls} etc. in the repository table but uses repo_unit instead (at least that's what a fresh gitea installation says).

Offtopic: is it safe to remove the no longer used columns from the tables?

But alas, even the freshly installed gitea does not change anything using the api, probably because of the AND 0=1 condition for updating the repo_unit table.

Take a look at the different queries when changing the repository's settings:

  • using the webinterface:
...m.io/xorm/core/db.go:286:afterProcess() [I] [SQL] DELETE FROM `repo_unit` WHERE (repo_id = ?) AND `type` IN (?,?,?,?,?,?) [2 UnitTypeExternalWiki UnitTypeWiki UnitTypeExternalTracker UnitTypeIssues UnitTypeProjects UnitTypePullRequests] - 2.397183ms
...m.io/xorm/core/db.go:286:afterProcess() [I] [SQL] INSERT INTO `repo_unit` (`repo_id`,`type`,`config`,`created_unix`) VALUES (?, ?, ?, ?),(?, ?, ?, ?),(?, ?, ?, ?) [2 UnitTypeIssues {"EnableTimetracker":true,"AllowOnlyContributorsToTrackTime":true,"EnableDependencies":true} 1616588607 2 UnitTypeProjects <nil> 1616588607 2 UnitTypePullRequests {"IgnoreWhitespaceConflicts":false,"AllowMerge":true,"AllowRebase":true,"AllowRebaseMerge":true,"AllowSquash":true} 1616588607] - 801.272µs
  • using the api:
...m.io/xorm/core/db.go:286:afterProcess() [I] [SQL] DELETE FROM `repo_unit` WHERE (repo_id = ?) AND 0=1 [2] - 150.432µs

@a1012112796
Copy link
Member

I'm sorry, but I hasn't found any bug by test code,I wonder .....

test code

func TestAPIEditRepo(t *testing.T) {
	defer prepareTestEnv(t)()

	user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
	repo1 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)

	session := loginUser(t, user.Name)
	token := getTokenForLoggedInUser(t, session)

	// test edit base repo config

	newDesc := "test new description"
	newWeb := "http://example.com"


	req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", repo1.OwnerName, repo1.Name, token), &api.EditRepoOption{
		Description: &newDesc,
		Website: &newWeb,
	})
	session.MakeRequest(t, req, http.StatusOK)

	repo1 = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
	assert.Equal(t, newDesc, repo1.Description)
	assert.Equal(t, newWeb, repo1.Website)

	optFalse := false
	optTrue := true

	// test edit repo units config
	req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", repo1.OwnerName, repo1.Name, token), &api.EditRepoOption{
		HasIssues: &optFalse,
		HasPullRequests: &optFalse,
		Private: &optTrue,
	})
	session.MakeRequest(t, req, http.StatusOK)

	var repo api.Repository

	req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1?token="+ token)
	resp := MakeRequest(t, req, http.StatusOK)
	DecodeJSON(t, resp, &repo)

	assert.Equal(t, false, repo.HasIssues)
	assert.Equal(t, false, repo.HasPullRequests)
	assert.Equal(t, true, repo.Private)
}

Result:
image

@philfry
Copy link
Contributor Author

philfry commented Mar 27, 2021

So you cannot reproduce it? That's strange. I am able to reproduce it in my production environment, on a freshly installed test vm, on try.gitea.io and even on a docker container podman run --rm -ti -p 3000:3000 docker.io/gitea/gitea, both by either using the script above or hacking directly into /api/swagger#/repository/repoEdit. No matter which database backend (mysql or sqlite3) I use.

As I'm not a native go speaker: do your queries in that test code differ from mine? You're using HasIssues instead of has_issues and HasPullRequests instead of has_pull_requests. Just clutching at any straw…

@noerw
Copy link
Member

noerw commented Mar 29, 2021

I found the issue. Instead of Accept: application/json you need to set Content-Type: application/json.
Then the payload is read properly. The issue remains that the PATCH response contains the unchanged repo.

@philfry
Copy link
Contributor Author

philfry commented Mar 29, 2021

Darn, you're right. Setting the content-type works fine. Sorry for the noise 😞

@lunny lunny closed this as completed Apr 6, 2021
@lunny lunny removed this from the 1.14.0 milestone Apr 6, 2021
@lunny lunny added reviewed/invalid and removed modifies/api This PR adds API routes or modifies them type/bug labels Apr 6, 2021
@go-gitea go-gitea locked and limited conversation to collaborators May 13, 2021
@delvh delvh added issue/not-a-bug The reported issue is the intended behavior or the problem is not inside Gitea and removed reviewed/invalid labels Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
issue/not-a-bug The reported issue is the intended behavior or the problem is not inside Gitea
Projects
None yet
Development

No branches or pull requests

5 participants