Changes
22 changed files (+219/-161)
-
-
@@ -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 contextimport ( "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,17 +239,14 @@ 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) ctx := APIContext{ Context: &Context{ Resp: NewResponse(w), Data: map[string]interface{}{}, Locale: locale, Session: session.GetSession(req), Resp: NewResponse(w), Data: map[string]interface{}{}, Locale: locale, 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")
-
@@ -584,8 +583,7 @@ func bind(obj interface{}) http.HandlerFunc {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 &auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API ) 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())
-
-
-
@@ -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">
-