Remove dependent on session auth for api/v1 routers (#19321)
* Remove dependent on session auth for api/v1 routers * Remove unnecessary session on API context * remove missed header * fix test * fix missed api/v1
This commit is contained in:
		
							parent
							
								
									75f8534c3a
								
							
						
					
					
						commit
						3c3d49899f
					
				| @ -168,12 +168,11 @@ func TestAPIEditIssue(t *testing.T) { | ||||
| func TestAPISearchIssues(t *testing.T) { | ||||
| 	defer prepareTestEnv(t)() | ||||
| 
 | ||||
| 	session := loginUser(t, "user2") | ||||
| 	token := getTokenForLoggedInUser(t, session) | ||||
| 	token := getUserToken(t, "user2") | ||||
| 
 | ||||
| 	link, _ := url.Parse("/api/v1/repos/issues/search") | ||||
| 	req := NewRequest(t, "GET", link.String()) | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	req := NewRequest(t, "GET", link.String()+"?token="+token) | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	var apiIssues []*api.Issue | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 10) | ||||
| @ -181,7 +180,7 @@ func TestAPISearchIssues(t *testing.T) { | ||||
| 	query := url.Values{"token": {token}} | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 10) | ||||
| 
 | ||||
| @ -189,9 +188,10 @@ func TestAPISearchIssues(t *testing.T) { | ||||
| 	before := time.Unix(999307200, 0).Format(time.RFC3339) | ||||
| 	query.Add("since", since) | ||||
| 	query.Add("before", before) | ||||
| 	query.Add("token", token) | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 8) | ||||
| 	query.Del("since") | ||||
| @ -200,14 +200,14 @@ func TestAPISearchIssues(t *testing.T) { | ||||
| 	query.Add("state", "closed") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| 	query.Set("state", "all") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.EqualValues(t, "15", resp.Header().Get("X-Total-Count")) | ||||
| 	assert.Len(t, apiIssues, 10) // there are more but 10 is page item limit
 | ||||
| @ -215,49 +215,49 @@ func TestAPISearchIssues(t *testing.T) { | ||||
| 	query.Add("limit", "20") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 15) | ||||
| 
 | ||||
| 	query = url.Values{"assigned": {"true"}, "state": {"all"}} | ||||
| 	query = url.Values{"assigned": {"true"}, "state": {"all"}, "token": {token}} | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 1) | ||||
| 
 | ||||
| 	query = url.Values{"milestones": {"milestone1"}, "state": {"all"}} | ||||
| 	query = url.Values{"milestones": {"milestone1"}, "state": {"all"}, "token": {token}} | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 1) | ||||
| 
 | ||||
| 	query = url.Values{"milestones": {"milestone1,milestone3"}, "state": {"all"}} | ||||
| 	query = url.Values{"milestones": {"milestone1,milestone3"}, "state": {"all"}, "token": {token}} | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| 	query = url.Values{"owner": {"user2"}} // user
 | ||||
| 	query = url.Values{"owner": {"user2"}, "token": {token}} // user
 | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 6) | ||||
| 
 | ||||
| 	query = url.Values{"owner": {"user3"}} // organization
 | ||||
| 	query = url.Values{"owner": {"user3"}, "token": {token}} // organization
 | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 3) | ||||
| 
 | ||||
| 	query = url.Values{"owner": {"user3"}, "team": {"team1"}} // organization + team
 | ||||
| 	query = url.Values{"owner": {"user3"}, "team": {"team1"}, "token": {token}} // organization + team
 | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| } | ||||
| @ -265,12 +265,11 @@ func TestAPISearchIssues(t *testing.T) { | ||||
| func TestAPISearchIssuesWithLabels(t *testing.T) { | ||||
| 	defer prepareTestEnv(t)() | ||||
| 
 | ||||
| 	session := loginUser(t, "user1") | ||||
| 	token := getTokenForLoggedInUser(t, session) | ||||
| 	token := getUserToken(t, "user1") | ||||
| 
 | ||||
| 	link, _ := url.Parse("/api/v1/repos/issues/search") | ||||
| 	req := NewRequest(t, "GET", link.String()) | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	req := NewRequest(t, "GET", link.String()+"?token="+token) | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	var apiIssues []*api.Issue | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 
 | ||||
| @ -280,14 +279,14 @@ func TestAPISearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Add("token", token) | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 10) | ||||
| 
 | ||||
| 	query.Add("labels", "label1") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| @ -295,7 +294,7 @@ func TestAPISearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Set("labels", "label1,label2") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| @ -303,7 +302,7 @@ func TestAPISearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Set("labels", "orglabel4") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 1) | ||||
| 
 | ||||
| @ -312,7 +311,7 @@ func TestAPISearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Add("state", "all") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| @ -320,7 +319,7 @@ func TestAPISearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Set("labels", "label1,orglabel4") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| } | ||||
|  | ||||
| @ -20,9 +20,8 @@ import ( | ||||
| 
 | ||||
| func TestAPIOrgCreate(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		session := loginUser(t, "user1") | ||||
| 		token := getUserToken(t, "user1") | ||||
| 
 | ||||
| 		token := getTokenForLoggedInUser(t, session) | ||||
| 		org := api.CreateOrgOption{ | ||||
| 			UserName:    "user1_org", | ||||
| 			FullName:    "User1's organization", | ||||
| @ -32,7 +31,7 @@ func TestAPIOrgCreate(t *testing.T) { | ||||
| 			Visibility:  "limited", | ||||
| 		} | ||||
| 		req := NewRequestWithJSON(t, "POST", "/api/v1/orgs?token="+token, &org) | ||||
| 		resp := session.MakeRequest(t, req, http.StatusCreated) | ||||
| 		resp := MakeRequest(t, req, http.StatusCreated) | ||||
| 
 | ||||
| 		var apiOrg api.Organization | ||||
| 		DecodeJSON(t, resp, &apiOrg) | ||||
| @ -50,13 +49,13 @@ func TestAPIOrgCreate(t *testing.T) { | ||||
| 			FullName:  org.FullName, | ||||
| 		}) | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s", org.UserName) | ||||
| 		resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s?token=%s", org.UserName, token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 		DecodeJSON(t, resp, &apiOrg) | ||||
| 		assert.EqualValues(t, org.UserName, apiOrg.UserName) | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", org.UserName) | ||||
| 		resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos?token=%s", org.UserName, token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		var repos []*api.Repository | ||||
| 		DecodeJSON(t, resp, &repos) | ||||
| @ -64,8 +63,8 @@ func TestAPIOrgCreate(t *testing.T) { | ||||
| 			assert.False(t, repo.Private) | ||||
| 		} | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", org.UserName) | ||||
| 		resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members?token=%s", org.UserName, token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		// user1 on this org is public
 | ||||
| 		var users []*api.User | ||||
|  | ||||
| @ -25,12 +25,11 @@ func TestAPIListReleases(t *testing.T) { | ||||
| 
 | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) | ||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | ||||
| 	session := loginUser(t, user2.LowerName) | ||||
| 	token := getTokenForLoggedInUser(t, session) | ||||
| 	token := getUserToken(t, user2.LowerName) | ||||
| 
 | ||||
| 	link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/releases", user2.Name, repo.Name)) | ||||
| 	link.RawQuery = url.Values{"token": {token}}.Encode() | ||||
| 	resp := session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) | ||||
| 	resp := MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) | ||||
| 	var apiReleases []*api.Release | ||||
| 	DecodeJSON(t, resp, &apiReleases) | ||||
| 	if assert.Len(t, apiReleases, 3) { | ||||
| @ -53,13 +52,11 @@ func TestAPIListReleases(t *testing.T) { | ||||
| 
 | ||||
| 	// test filter
 | ||||
| 	testFilterByLen := func(auth bool, query url.Values, expectedLength int, msgAndArgs ...string) { | ||||
| 		link.RawQuery = query.Encode() | ||||
| 		if auth { | ||||
| 			query.Set("token", token) | ||||
| 			resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) | ||||
| 		} else { | ||||
| 			resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) | ||||
| 		} | ||||
| 		link.RawQuery = query.Encode() | ||||
| 		resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) | ||||
| 		DecodeJSON(t, resp, &apiReleases) | ||||
| 		assert.Len(t, apiReleases, expectedLength, msgAndArgs) | ||||
| 	} | ||||
|  | ||||
| @ -59,36 +59,34 @@ func TestAPIRepoTopic(t *testing.T) { | ||||
| 	repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | ||||
| 
 | ||||
| 	// Get user2's token
 | ||||
| 	session := loginUser(t, user2.Name) | ||||
| 	token2 := getTokenForLoggedInUser(t, session) | ||||
| 	token2 := getUserToken(t, user2.Name) | ||||
| 
 | ||||
| 	// Test read topics using login
 | ||||
| 	url := fmt.Sprintf("/api/v1/repos/%s/%s/topics", user2.Name, repo2.Name) | ||||
| 	req := NewRequest(t, "GET", url) | ||||
| 	res := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	req := NewRequest(t, "GET", url+"?token="+token2) | ||||
| 	res := MakeRequest(t, req, http.StatusOK) | ||||
| 	var topics *api.TopicName | ||||
| 	DecodeJSON(t, res, &topics) | ||||
| 	assert.ElementsMatch(t, []string{"topicname1", "topicname2"}, topics.TopicNames) | ||||
| 
 | ||||
| 	// Log out user2
 | ||||
| 	session = emptyTestSession(t) | ||||
| 	url = fmt.Sprintf("/api/v1/repos/%s/%s/topics?token=%s", user2.Name, repo2.Name, token2) | ||||
| 
 | ||||
| 	// Test delete a topic
 | ||||
| 	req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "Topicname1", token2) | ||||
| 	session.MakeRequest(t, req, http.StatusNoContent) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| 
 | ||||
| 	// Test add an existing topic
 | ||||
| 	req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "Golang", token2) | ||||
| 	session.MakeRequest(t, req, http.StatusNoContent) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| 
 | ||||
| 	// Test add a topic
 | ||||
| 	req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "topicName3", token2) | ||||
| 	session.MakeRequest(t, req, http.StatusNoContent) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| 
 | ||||
| 	// Test read topics using token
 | ||||
| 	req = NewRequest(t, "GET", url) | ||||
| 	res = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	res = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, res, &topics) | ||||
| 	assert.ElementsMatch(t, []string{"topicname2", "golang", "topicname3"}, topics.TopicNames) | ||||
| 
 | ||||
| @ -97,9 +95,9 @@ func TestAPIRepoTopic(t *testing.T) { | ||||
| 	req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ | ||||
| 		Topics: newTopics, | ||||
| 	}) | ||||
| 	session.MakeRequest(t, req, http.StatusNoContent) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| 	req = NewRequest(t, "GET", url) | ||||
| 	res = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	res = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, res, &topics) | ||||
| 	assert.ElementsMatch(t, []string{"windows", "mac"}, topics.TopicNames) | ||||
| 
 | ||||
| @ -108,9 +106,9 @@ func TestAPIRepoTopic(t *testing.T) { | ||||
| 	req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ | ||||
| 		Topics: newTopics, | ||||
| 	}) | ||||
| 	session.MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 	MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 	req = NewRequest(t, "GET", url) | ||||
| 	res = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	res = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, res, &topics) | ||||
| 	assert.ElementsMatch(t, []string{"windows", "mac"}, topics.TopicNames) | ||||
| 
 | ||||
| @ -119,9 +117,9 @@ func TestAPIRepoTopic(t *testing.T) { | ||||
| 	req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ | ||||
| 		Topics: newTopics, | ||||
| 	}) | ||||
| 	session.MakeRequest(t, req, http.StatusNoContent) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| 	req = NewRequest(t, "GET", url) | ||||
| 	res = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	res = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, res, &topics) | ||||
| 	assert.Len(t, topics.TopicNames, 25) | ||||
| 
 | ||||
| @ -130,29 +128,27 @@ func TestAPIRepoTopic(t *testing.T) { | ||||
| 	req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ | ||||
| 		Topics: newTopics, | ||||
| 	}) | ||||
| 	session.MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 	MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 
 | ||||
| 	// Test add a topic when there is already maximum
 | ||||
| 	req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "t26", token2) | ||||
| 	session.MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 	MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 
 | ||||
| 	// Test delete a topic that repo doesn't have
 | ||||
| 	req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "Topicname1", token2) | ||||
| 	session.MakeRequest(t, req, http.StatusNotFound) | ||||
| 	MakeRequest(t, req, http.StatusNotFound) | ||||
| 
 | ||||
| 	// Get user4's token
 | ||||
| 	session = loginUser(t, user4.Name) | ||||
| 	token4 := getTokenForLoggedInUser(t, session) | ||||
| 	session = emptyTestSession(t) | ||||
| 	token4 := getUserToken(t, user4.Name) | ||||
| 
 | ||||
| 	// Test read topics with write access
 | ||||
| 	url = fmt.Sprintf("/api/v1/repos/%s/%s/topics?token=%s", user3.Name, repo3.Name, token4) | ||||
| 	req = NewRequest(t, "GET", url) | ||||
| 	res = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	res = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, res, &topics) | ||||
| 	assert.Empty(t, topics.TopicNames) | ||||
| 
 | ||||
| 	// Test add a topic to repo with write access (requires repo admin access)
 | ||||
| 	req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", user3.Name, repo3.Name, "topicName", token4) | ||||
| 	session.MakeRequest(t, req, http.StatusForbidden) | ||||
| 	MakeRequest(t, req, http.StatusForbidden) | ||||
| } | ||||
|  | ||||
| @ -224,11 +224,9 @@ func TestAPITeamSearch(t *testing.T) { | ||||
| 
 | ||||
| 	var results TeamSearchResults | ||||
| 
 | ||||
| 	session := loginUser(t, user.Name) | ||||
| 	csrf := GetCSRF(t, session, "/"+org.Name) | ||||
| 	req := NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s", org.Name, "_team") | ||||
| 	req.Header.Add("X-Csrf-Token", csrf) | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	token := getUserToken(t, user.Name) | ||||
| 	req := NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "_team", token) | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &results) | ||||
| 	assert.NotEmpty(t, results.Data) | ||||
| 	assert.Len(t, results.Data, 1) | ||||
| @ -236,9 +234,8 @@ func TestAPITeamSearch(t *testing.T) { | ||||
| 
 | ||||
| 	// no access if not organization member
 | ||||
| 	user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) | ||||
| 	session = loginUser(t, user5.Name) | ||||
| 	csrf = GetCSRF(t, session, "/"+org.Name) | ||||
| 	req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s", org.Name, "team") | ||||
| 	req.Header.Add("X-Csrf-Token", csrf) | ||||
| 	session.MakeRequest(t, req, http.StatusForbidden) | ||||
| 	token5 := getUserToken(t, user5.Name) | ||||
| 
 | ||||
| 	req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5) | ||||
| 	MakeRequest(t, req, http.StatusForbidden) | ||||
| } | ||||
|  | ||||
| @ -20,15 +20,15 @@ func TestUserHeatmap(t *testing.T) { | ||||
| 	defer prepareTestEnv(t)() | ||||
| 	adminUsername := "user1" | ||||
| 	normalUsername := "user2" | ||||
| 	session := loginUser(t, adminUsername) | ||||
| 	token := getUserToken(t, adminUsername) | ||||
| 
 | ||||
| 	fakeNow := time.Date(2011, 10, 20, 0, 0, 0, 0, time.Local) | ||||
| 	timeutil.Set(fakeNow) | ||||
| 	defer timeutil.Unset() | ||||
| 
 | ||||
| 	urlStr := fmt.Sprintf("/api/v1/users/%s/heatmap", normalUsername) | ||||
| 	urlStr := fmt.Sprintf("/api/v1/users/%s/heatmap?token=%s", normalUsername, token) | ||||
| 	req := NewRequest(t, "GET", urlStr) | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	var heatmap []*models.UserHeatmapData | ||||
| 	DecodeJSON(t, resp, &heatmap) | ||||
| 	var dummyheatmap []*models.UserHeatmapData | ||||
|  | ||||
| @ -359,6 +359,10 @@ func emptyTestSession(t testing.TB) *TestSession { | ||||
| 	return &TestSession{jar: jar} | ||||
| } | ||||
| 
 | ||||
| func getUserToken(t testing.TB, userName string) string { | ||||
| 	return getTokenForLoggedInUser(t, loginUser(t, userName)) | ||||
| } | ||||
| 
 | ||||
| func loginUser(t testing.TB, userName string) *TestSession { | ||||
| 	t.Helper() | ||||
| 	if session, ok := loginSessionCache[userName]; ok { | ||||
|  | ||||
| @ -448,27 +448,29 @@ func TestSearchIssues(t *testing.T) { | ||||
| func TestSearchIssuesWithLabels(t *testing.T) { | ||||
| 	defer prepareTestEnv(t)() | ||||
| 
 | ||||
| 	session := loginUser(t, "user1") | ||||
| 	token := getUserToken(t, "user1") | ||||
| 
 | ||||
| 	link, _ := url.Parse("/api/v1/repos/issues/search") | ||||
| 	link, _ := url.Parse("/api/v1/repos/issues/search?token=" + token) | ||||
| 	req := NewRequest(t, "GET", link.String()) | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	var apiIssues []*api.Issue | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 
 | ||||
| 	assert.Len(t, apiIssues, 10) | ||||
| 
 | ||||
| 	query := url.Values{} | ||||
| 	query := url.Values{ | ||||
| 		"token": []string{token}, | ||||
| 	} | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 10) | ||||
| 
 | ||||
| 	query.Add("labels", "label1") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| @ -476,7 +478,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Set("labels", "label1,label2") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| @ -484,7 +486,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Set("labels", "orglabel4") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 1) | ||||
| 
 | ||||
| @ -493,7 +495,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Add("state", "all") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| 
 | ||||
| @ -501,7 +503,7 @@ func TestSearchIssuesWithLabels(t *testing.T) { | ||||
| 	query.Set("labels", "label1,orglabel4") | ||||
| 	link.RawQuery = query.Encode() | ||||
| 	req = NewRequest(t, "GET", link.String()) | ||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiIssues) | ||||
| 	assert.Len(t, apiIssues, 2) | ||||
| } | ||||
|  | ||||
| @ -8,7 +8,6 @@ package context | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"html" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| @ -20,8 +19,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| 	auth_service "code.gitea.io/gitea/services/auth" | ||||
| 
 | ||||
| 	"gitea.com/go-chi/session" | ||||
| ) | ||||
| 
 | ||||
| // APIContext is a specific context for API service
 | ||||
| @ -191,17 +188,6 @@ func (ctx *APIContext) SetLinkHeader(total, pageSize int) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // RequireCSRF requires a validated a CSRF token
 | ||||
| func (ctx *APIContext) RequireCSRF() { | ||||
| 	headerToken := ctx.Req.Header.Get(ctx.csrf.GetHeaderName()) | ||||
| 	formValueToken := ctx.Req.FormValue(ctx.csrf.GetFormName()) | ||||
| 	if len(headerToken) > 0 || len(formValueToken) > 0 { | ||||
| 		Validate(ctx.Context, ctx.csrf) | ||||
| 	} else { | ||||
| 		ctx.Context.Error(http.StatusUnauthorized, "Missing CSRF token.") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // CheckForOTP validates OTP
 | ||||
| func (ctx *APIContext) CheckForOTP() { | ||||
| 	if skip, ok := ctx.Data["SkipLocalTwoFA"]; ok && skip.(bool) { | ||||
| @ -253,8 +239,6 @@ func APIAuth(authMethod auth_service.Method) func(*APIContext) { | ||||
| 
 | ||||
| // APIContexter returns apicontext as middleware
 | ||||
| func APIContexter() func(http.Handler) http.Handler { | ||||
| 	csrfOpts := getCsrfOpts() | ||||
| 
 | ||||
| 	return func(next http.Handler) http.Handler { | ||||
| 		return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { | ||||
| 			locale := middleware.Locale(w, req) | ||||
| @ -263,7 +247,6 @@ func APIContexter() func(http.Handler) http.Handler { | ||||
| 					Resp:   NewResponse(w), | ||||
| 					Data:   map[string]interface{}{}, | ||||
| 					Locale: locale, | ||||
| 					Session: session.GetSession(req), | ||||
| 					Repo: &Repository{ | ||||
| 						PullRequest: &PullRequest{}, | ||||
| 					}, | ||||
| @ -273,7 +256,6 @@ func APIContexter() func(http.Handler) http.Handler { | ||||
| 			} | ||||
| 
 | ||||
| 			ctx.Req = WithAPIContext(WithContext(req, ctx.Context), &ctx) | ||||
| 			ctx.csrf = Csrfer(csrfOpts, ctx.Context) | ||||
| 
 | ||||
| 			// If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.
 | ||||
| 			if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { | ||||
| @ -285,7 +267,6 @@ func APIContexter() func(http.Handler) http.Handler { | ||||
| 
 | ||||
| 			ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) | ||||
| 
 | ||||
| 			ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken()) | ||||
| 			ctx.Data["Context"] = &ctx | ||||
| 
 | ||||
| 			next.ServeHTTP(ctx.Resp, ctx.Req) | ||||
|  | ||||
| @ -216,7 +216,6 @@ func reqToken() func(ctx *context.APIContext) { | ||||
| 			return | ||||
| 		} | ||||
| 		if ctx.IsSigned { | ||||
| 			ctx.RequireCSRF() | ||||
| 			return | ||||
| 		} | ||||
| 		ctx.Error(http.StatusUnauthorized, "reqToken", "token is required") | ||||
| @ -585,7 +584,6 @@ func buildAuthGroup() *auth.Group { | ||||
| 	group := auth.NewGroup( | ||||
| 		&auth.OAuth2{}, | ||||
| 		&auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API
 | ||||
| 		auth.SharedSession, // FIXME: this should be removed once all UI don't reference API/v1, see https://github.com/go-gitea/gitea/pull/16052
 | ||||
| 	) | ||||
| 	if setting.Service.EnableReverseProxyAuth { | ||||
| 		group.Add(&auth.ReverseProxy{}) | ||||
| @ -596,11 +594,9 @@ func buildAuthGroup() *auth.Group { | ||||
| } | ||||
| 
 | ||||
| // Routes registers all v1 APIs routes to web application.
 | ||||
| func Routes(sessioner func(http.Handler) http.Handler) *web.Route { | ||||
| func Routes() *web.Route { | ||||
| 	m := web.NewRoute() | ||||
| 
 | ||||
| 	m.Use(sessioner) | ||||
| 
 | ||||
| 	m.Use(securityHeaders()) | ||||
| 	if setting.CORSConfig.Enabled { | ||||
| 		m.Use(cors.Handler(cors.Options{ | ||||
| @ -609,7 +605,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route { | ||||
| 			// setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option
 | ||||
| 			AllowedMethods:   setting.CORSConfig.Methods, | ||||
| 			AllowCredentials: setting.CORSConfig.AllowCredentials, | ||||
| 			AllowedHeaders:   []string{"Authorization", "X-CSRFToken", "X-Gitea-OTP"}, | ||||
| 			AllowedHeaders:   []string{"Authorization", "X-Gitea-OTP"}, | ||||
| 			MaxAge:           int(setting.CORSConfig.MaxAge.Seconds()), | ||||
| 		})) | ||||
| 	} | ||||
|  | ||||
| @ -48,8 +48,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/services/repository/archiver" | ||||
| 	"code.gitea.io/gitea/services/task" | ||||
| 	"code.gitea.io/gitea/services/webhook" | ||||
| 
 | ||||
| 	"gitea.com/go-chi/session" | ||||
| ) | ||||
| 
 | ||||
| func mustInit(fn func() error) { | ||||
| @ -174,20 +172,8 @@ func NormalRoutes() *web.Route { | ||||
| 		r.Use(middle) | ||||
| 	} | ||||
| 
 | ||||
| 	sessioner := session.Sessioner(session.Options{ | ||||
| 		Provider:       setting.SessionConfig.Provider, | ||||
| 		ProviderConfig: setting.SessionConfig.ProviderConfig, | ||||
| 		CookieName:     setting.SessionConfig.CookieName, | ||||
| 		CookiePath:     setting.SessionConfig.CookiePath, | ||||
| 		Gclifetime:     setting.SessionConfig.Gclifetime, | ||||
| 		Maxlifetime:    setting.SessionConfig.Maxlifetime, | ||||
| 		Secure:         setting.SessionConfig.Secure, | ||||
| 		SameSite:       setting.SessionConfig.SameSite, | ||||
| 		Domain:         setting.SessionConfig.Domain, | ||||
| 	}) | ||||
| 
 | ||||
| 	r.Mount("/", web_routers.Routes(sessioner)) | ||||
| 	r.Mount("/api/v1", apiv1.Routes(sessioner)) | ||||
| 	r.Mount("/", web_routers.Routes()) | ||||
| 	r.Mount("/api/v1", apiv1.Routes()) | ||||
| 	r.Mount("/api/internal", private.Routes()) | ||||
| 	if setting.Packages.Enabled { | ||||
| 		r.Mount("/api/packages", packages_router.Routes()) | ||||
|  | ||||
							
								
								
									
										98
									
								
								routers/web/misc/markdown.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								routers/web/misc/markdown.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | ||||
| // Copyright 2014 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2022 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package misc | ||||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"mvdan.cc/xurls/v2" | ||||
| ) | ||||
| 
 | ||||
| // Markdown render markdown document to HTML
 | ||||
| func Markdown(ctx *context.Context) { | ||||
| 	// swagger:operation POST /markdown miscellaneous renderMarkdown
 | ||||
| 	// ---
 | ||||
| 	// summary: Render a markdown document as HTML
 | ||||
| 	// parameters:
 | ||||
| 	// - name: body
 | ||||
| 	//   in: body
 | ||||
| 	//   schema:
 | ||||
| 	//     "$ref": "#/definitions/MarkdownOption"
 | ||||
| 	// consumes:
 | ||||
| 	// - application/json
 | ||||
| 	// produces:
 | ||||
| 	//     - text/html
 | ||||
| 	// responses:
 | ||||
| 	//   "200":
 | ||||
| 	//     "$ref": "#/responses/MarkdownRender"
 | ||||
| 	//   "422":
 | ||||
| 	//     "$ref": "#/responses/validationError"
 | ||||
| 
 | ||||
| 	form := web.GetForm(ctx).(*api.MarkdownOption) | ||||
| 
 | ||||
| 	if ctx.HasAPIError() { | ||||
| 		ctx.Error(http.StatusUnprocessableEntity, "", ctx.GetErrMsg()) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if len(form.Text) == 0 { | ||||
| 		_, _ = ctx.Write([]byte("")) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	switch form.Mode { | ||||
| 	case "comment": | ||||
| 		fallthrough | ||||
| 	case "gfm": | ||||
| 		urlPrefix := form.Context | ||||
| 		meta := map[string]string{} | ||||
| 		if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) { | ||||
| 			// check if urlPrefix is already set to a URL
 | ||||
| 			linkRegex, _ := xurls.StrictMatchingScheme("https?://") | ||||
| 			m := linkRegex.FindStringIndex(urlPrefix) | ||||
| 			if m == nil { | ||||
| 				urlPrefix = util.URLJoin(setting.AppURL, form.Context) | ||||
| 			} | ||||
| 		} | ||||
| 		if ctx.Repo != nil && ctx.Repo.Repository != nil { | ||||
| 			// "gfm" = Github Flavored Markdown - set this to render as a document
 | ||||
| 			if form.Mode == "gfm" { | ||||
| 				meta = ctx.Repo.Repository.ComposeDocumentMetas() | ||||
| 			} else { | ||||
| 				meta = ctx.Repo.Repository.ComposeMetas() | ||||
| 			} | ||||
| 		} | ||||
| 		if form.Mode == "gfm" { | ||||
| 			meta["mode"] = "document" | ||||
| 		} | ||||
| 
 | ||||
| 		if err := markdown.Render(&markup.RenderContext{ | ||||
| 			Ctx:       ctx, | ||||
| 			URLPrefix: urlPrefix, | ||||
| 			Metas:     meta, | ||||
| 			IsWiki:    form.Wiki, | ||||
| 		}, strings.NewReader(form.Text), ctx.Resp); err != nil { | ||||
| 			ctx.Error(http.StatusInternalServerError, err.Error()) | ||||
| 			return | ||||
| 		} | ||||
| 	default: | ||||
| 		if err := markdown.RenderRaw(&markup.RenderContext{ | ||||
| 			Ctx:       ctx, | ||||
| 			URLPrefix: form.Context, | ||||
| 		}, strings.NewReader(form.Text), ctx.Resp); err != nil { | ||||
| 			ctx.Error(http.StatusInternalServerError, err.Error()) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @ -25,13 +25,13 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/validation" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/modules/web/routing" | ||||
| 	"code.gitea.io/gitea/routers/api/v1/misc" | ||||
| 	"code.gitea.io/gitea/routers/web/admin" | ||||
| 	"code.gitea.io/gitea/routers/web/auth" | ||||
| 	"code.gitea.io/gitea/routers/web/dev" | ||||
| 	"code.gitea.io/gitea/routers/web/events" | ||||
| 	"code.gitea.io/gitea/routers/web/explore" | ||||
| 	"code.gitea.io/gitea/routers/web/feed" | ||||
| 	"code.gitea.io/gitea/routers/web/misc" | ||||
| 	"code.gitea.io/gitea/routers/web/org" | ||||
| 	"code.gitea.io/gitea/routers/web/repo" | ||||
| 	"code.gitea.io/gitea/routers/web/user" | ||||
| @ -46,6 +46,7 @@ import ( | ||||
| 	_ "code.gitea.io/gitea/modules/session" // to registers all internal adapters
 | ||||
| 
 | ||||
| 	"gitea.com/go-chi/captcha" | ||||
| 	"gitea.com/go-chi/session" | ||||
| 	"github.com/NYTimes/gziphandler" | ||||
| 	"github.com/go-chi/chi/v5/middleware" | ||||
| 	"github.com/go-chi/cors" | ||||
| @ -85,7 +86,7 @@ func buildAuthGroup() *auth_service.Group { | ||||
| 	group := auth_service.NewGroup( | ||||
| 		&auth_service.OAuth2{}, // FIXME: this should be removed and only applied in download and oauth realted routers
 | ||||
| 		&auth_service.Basic{},  // FIXME: this should be removed and only applied in download and git/lfs routers
 | ||||
| 		auth_service.SharedSession, | ||||
| 		&auth_service.Session{}, | ||||
| 	) | ||||
| 	if setting.Service.EnableReverseProxyAuth { | ||||
| 		group.Add(&auth_service.ReverseProxy{}) | ||||
| @ -96,7 +97,7 @@ func buildAuthGroup() *auth_service.Group { | ||||
| } | ||||
| 
 | ||||
| // Routes returns all web routes
 | ||||
| func Routes(sessioner func(http.Handler) http.Handler) *web.Route { | ||||
| func Routes() *web.Route { | ||||
| 	routes := web.NewRoute() | ||||
| 
 | ||||
| 	routes.Use(web.WrapWithPrefix(public.AssetsURLPathPrefix, public.AssetsHandlerFunc(&public.Options{ | ||||
| @ -105,6 +106,17 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route { | ||||
| 		CorsHandler: CorsHandler(), | ||||
| 	}), "AssetsHandler")) | ||||
| 
 | ||||
| 	sessioner := session.Sessioner(session.Options{ | ||||
| 		Provider:       setting.SessionConfig.Provider, | ||||
| 		ProviderConfig: setting.SessionConfig.ProviderConfig, | ||||
| 		CookieName:     setting.SessionConfig.CookieName, | ||||
| 		CookiePath:     setting.SessionConfig.CookiePath, | ||||
| 		Gclifetime:     setting.SessionConfig.Gclifetime, | ||||
| 		Maxlifetime:    setting.SessionConfig.Maxlifetime, | ||||
| 		Secure:         setting.SessionConfig.Secure, | ||||
| 		SameSite:       setting.SessionConfig.SameSite, | ||||
| 		Domain:         setting.SessionConfig.Domain, | ||||
| 	}) | ||||
| 	routes.Use(sessioner) | ||||
| 
 | ||||
| 	routes.Use(Recovery()) | ||||
| @ -878,6 +890,7 @@ func RegisterRoutes(m *web.Route) { | ||||
| 		m.Group("/comments/{id}", func() { | ||||
| 			m.Get("/attachments", repo.GetCommentAttachments) | ||||
| 		}) | ||||
| 		m.Post("/markdown", bindIgnErr(structs.MarkdownOption{}), misc.Markdown) | ||||
| 		m.Group("/labels", func() { | ||||
| 			m.Post("/new", bindIgnErr(forms.CreateLabelForm{}), repo.NewLabel) | ||||
| 			m.Post("/edit", bindIgnErr(forms.CreateLabelForm{}), repo.UpdateLabel) | ||||
|  | ||||
| @ -20,16 +20,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| ) | ||||
| 
 | ||||
| // The purpose of the following three function variables is to let the linter know that
 | ||||
| // those functions are not dead code and are actually being used
 | ||||
| var ( | ||||
| 	_ = handleSignIn | ||||
| 
 | ||||
| 	// SharedSession the session auth should only be used by web, but now both web and API/v1
 | ||||
| 	// will use it. We can remove this after Web removed dependent API/v1
 | ||||
| 	SharedSession = &Session{} | ||||
| ) | ||||
| 
 | ||||
| // Init should be called exactly once when the application starts to allow plugins
 | ||||
| // to allocate necessary resources
 | ||||
| func Init() { | ||||
|  | ||||
| @ -162,7 +162,7 @@ | ||||
| 				<div class="ui comment form"> | ||||
| 					<div class="ui top attached tabular menu"> | ||||
| 						<a class="active write item">{{$.i18n.Tr "write"}}</a> | ||||
| 						<a class="preview item" data-url="{{$.Repository.APIURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 						<a class="preview item" data-url="{{$.Repository.HTMLURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 					</div> | ||||
| 					<div class="ui bottom attached active write tab segment"> | ||||
| 						<textarea class="review-textarea" tabindex="1" name="content"></textarea> | ||||
|  | ||||
| @ -11,7 +11,7 @@ | ||||
| 		<input type="hidden" name="diff_base_cid"> | ||||
| 		<div class="ui top tabular menu" data-write="write" data-preview="preview"> | ||||
| 			<a class="active item" data-tab="write">{{$.root.i18n.Tr "write"}}</a> | ||||
| 			<a class="item" data-tab="preview" data-url="{{$.root.Repository.APIURL}}/markdown" data-context="{{$.root.RepoLink}}">{{$.root.i18n.Tr "preview"}}</a> | ||||
| 			<a class="item" data-tab="preview" data-url="{{$.root.Repository.HTMLURL}}/markdown" data-context="{{$.root.RepoLink}}">{{$.root.i18n.Tr "preview"}}</a> | ||||
| 		</div> | ||||
| 		<div class="field"> | ||||
| 			<div class="ui active tab" data-tab="write"> | ||||
|  | ||||
| @ -31,13 +31,13 @@ | ||||
| 				<div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff"> | ||||
| 					<a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{.i18n.Tr "repo.editor.new_file"}}{{else}}{{.i18n.Tr "repo.editor.edit_file"}}{{end}}</a> | ||||
| 					{{if not .IsNewFile}} | ||||
| 					<a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL}}" data-preview-file-modes="{{.PreviewableFileModes}}" data-markdown-mode="gfm">{{svg "octicon-eye"}} {{.i18n.Tr "preview"}}</a> | ||||
| 					<a class="item" data-tab="preview" data-url="{{.Repository.HTMLURL}}/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL}}" data-preview-file-modes="{{.PreviewableFileModes}}" data-markdown-mode="gfm">{{svg "octicon-eye"}} {{.i18n.Tr "preview"}}</a> | ||||
| 					<a class="item" data-tab="diff" data-url="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}" data-context="{{.BranchLink}}">{{svg "octicon-diff"}} {{.i18n.Tr "repo.editor.preview_changes"}}</a> | ||||
| 					{{end}} | ||||
| 				</div> | ||||
| 				<div class="ui bottom attached active tab segment" data-tab="write"> | ||||
| 					<textarea id="edit_area" name="content" class="hide" data-id="repo-{{.Repository.Name}}-{{.TreePath}}" | ||||
| 						data-url="{{.Repository.APIURL}}/markdown" | ||||
| 						data-url="{{.Repository.HTMLURL}}/markdown" | ||||
| 						data-context="{{.RepoLink}}" | ||||
| 						data-markdown-file-exts="{{.MarkdownFileExts}}" | ||||
| 						data-line-wrap-extensions="{{.LineWrapExtensions}}"> | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| <div class="ui top tabular menu" data-write="write" data-preview="preview"> | ||||
| 	<a class="active item" data-tab="write">{{.i18n.Tr "write"}}</a> | ||||
| 	<a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "preview"}}</a> | ||||
| 	<a class="item" data-tab="preview" data-url="{{.Repository.HTMLURL}}/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "preview"}}</a> | ||||
| </div> | ||||
| <div class="field"> | ||||
| 	<div class="ui bottom active tab" data-tab="write"> | ||||
| 		<textarea id="content" class="edit_area js-quick-submit" name="content" tabindex="4" data-id="issue-{{.RepoName}}" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.Repo.RepoLink}}"> | ||||
| 		<textarea id="content" class="edit_area js-quick-submit" name="content" tabindex="4" data-id="issue-{{.RepoName}}" data-url="{{.Repository.HTMLURL}}/markdown" data-context="{{.Repo.RepoLink}}"> | ||||
| 			{{- if .BodyQuery}}{{.BodyQuery}}{{else if .IssueTemplate}}{{.IssueTemplate}}{{else if .PullRequestTemplate}}{{.PullRequestTemplate}}{{else}}{{.content}}{{end -}} | ||||
| 		</textarea> | ||||
| 	</div> | ||||
|  | ||||
| @ -195,7 +195,7 @@ | ||||
| 	<div class="ui comment form"> | ||||
| 		<div class="ui top tabular menu"> | ||||
| 			<a class="active write item">{{$.i18n.Tr "write"}}</a> | ||||
| 			<a class="preview item" data-url="{{$.Repository.APIURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 			<a class="preview item" data-url="{{$.Repository.HTMLURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 		</div> | ||||
| 		<div class="field"> | ||||
| 			<div class="ui bottom active tab write"> | ||||
|  | ||||
| @ -48,7 +48,7 @@ | ||||
| 					<label>{{.i18n.Tr "repo.release.content"}}</label> | ||||
| 					<div class="ui top tabular menu" data-write="write" data-preview="preview"> | ||||
| 						<a class="active write item" data-tab="write">{{$.i18n.Tr "write"}}</a> | ||||
| 						<a class="preview item" data-tab="preview" data-url="{{$.Repository.APIURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 						<a class="preview item" data-tab="preview" data-url="{{$.Repository.HTMLURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 					</div> | ||||
| 					<div class="ui bottom active tab" data-tab="write"> | ||||
| 						<textarea name="content">{{.content}}</textarea> | ||||
|  | ||||
| @ -21,11 +21,11 @@ | ||||
| 			</div> | ||||
| 			<div class="ui top attached tabular menu previewtabs" data-write="write" data-preview="preview"> | ||||
| 				<a class="active item" data-tab="write">{{.i18n.Tr "write"}}</a> | ||||
| 				<a class="item" data-tab="preview" data-url="{{$.Repository.APIURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 				<a class="item" data-tab="preview" data-url="{{$.Repository.HTMLURL}}/markdown" data-context="{{$.RepoLink}}">{{$.i18n.Tr "preview"}}</a> | ||||
| 			</div> | ||||
| 			<div class="field content" data-loading="{{.i18n.Tr "loading"}}"> | ||||
| 				<div class="ui bottom active tab" data-tab="write"> | ||||
| 					<textarea class="js-quick-submit" id="edit_area" name="content" data-id="wiki-{{.title}}" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}">{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea> | ||||
| 					<textarea class="js-quick-submit" id="edit_area" name="content" data-id="wiki-{{.title}}" data-url="{{.Repository.HTMLURL}}/markdown" data-context="{{.RepoLink}}">{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div class="field"> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user