aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-02-18 17:52:02 +0800
committerGitHub <noreply@github.com>2024-02-18 10:52:02 +0100
commit31bb9f3247388b993c61a10190cfd512408ce57e (patch)
tree6a4c777d5507b8e92cebd1786750c6a4db9367c8
parenta784ed3d6c6946fd9bf95f2e910f52f549326fe2 (diff)
downloadgitea-31bb9f3247388b993c61a10190cfd512408ce57e.tar.gz
gitea-31bb9f3247388b993c61a10190cfd512408ce57e.zip
Refactor more code in templates (#29236)
Follow #29165. * Introduce JSONTemplate to help to render JSON templates * Introduce JSEscapeSafe for templates. Now only use `{{ ... | JSEscape}}` instead of `{{ ... | JSEscape | Safe}}` * Simplify "UserLocationMapURL" useage
-rw-r--r--Makefile4
-rw-r--r--modules/context/context_response.go14
-rw-r--r--modules/templates/helper.go6
-rw-r--r--modules/templates/helper_test.go4
-rw-r--r--routers/api/v1/api.go4
-rw-r--r--routers/web/auth/oauth.go10
-rw-r--r--routers/web/shared/user/header.go4
-rw-r--r--routers/web/swagger_json.go14
-rw-r--r--templates/shared/user/profile_big_avatar.tmpl5
-rw-r--r--templates/swagger/v1_json.tmpl8
-rw-r--r--templates/user/auth/oidc_wellknown.tmpl14
11 files changed, 45 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 3065d9e683..925fdcb946 100644
--- a/Makefile
+++ b/Makefile
@@ -164,8 +164,8 @@ ifdef DEPS_PLAYWRIGHT
endif
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
-SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
-SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
+SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape}}/api/v1"|g
+SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape}}/api/v1"|"basePath": "/api/v1"|g
SWAGGER_EXCLUDE := code.gitea.io/sdk
SWAGGER_NEWLINE_COMMAND := -e '$$a\'
diff --git a/modules/context/context_response.go b/modules/context/context_response.go
index d9102b77bd..829bca1f59 100644
--- a/modules/context/context_response.go
+++ b/modules/context/context_response.go
@@ -90,6 +90,20 @@ func (ctx *Context) HTML(status int, name base.TplName) {
}
}
+// JSONTemplate renders the template as JSON response
+// keep in mind that the template is processed in HTML context, so JSON-things should be handled carefully, eg: by JSEscape
+func (ctx *Context) JSONTemplate(tmpl base.TplName) {
+ t, err := ctx.Render.TemplateLookup(string(tmpl), nil)
+ if err != nil {
+ ctx.ServerError("unable to find template", err)
+ return
+ }
+ ctx.Resp.Header().Set("Content-Type", "application/json")
+ if err = t.Execute(ctx.Resp, ctx.Data); err != nil {
+ ctx.ServerError("unable to execute template", err)
+ }
+}
+
// RenderToString renders the template content to a string
func (ctx *Context) RenderToString(name base.TplName, data map[string]any) (string, error) {
var buf strings.Builder
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 9ff5d8927f..6e42594b0b 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -38,7 +38,7 @@ func NewFuncMap() template.FuncMap {
"Safe": Safe,
"Escape": Escape,
"QueryEscape": url.QueryEscape,
- "JSEscape": template.JSEscapeString,
+ "JSEscape": JSEscapeSafe,
"Str2html": Str2html, // TODO: rename it to SanitizeHTML
"URLJoin": util.URLJoin,
"DotEscape": DotEscape,
@@ -211,6 +211,10 @@ func Escape(s any) template.HTML {
panic(fmt.Sprintf("unexpected type %T", s))
}
+func JSEscapeSafe(s string) template.HTML {
+ return template.HTML(template.JSEscapeString(s))
+}
+
func RenderEmojiPlain(s any) any {
switch v := s.(type) {
case string:
diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go
index ec83e9ac33..739a92f34f 100644
--- a/modules/templates/helper_test.go
+++ b/modules/templates/helper_test.go
@@ -52,3 +52,7 @@ func TestSubjectBodySeparator(t *testing.T) {
"",
"Insuficient\n--\nSeparators")
}
+
+func TestJSEscapeSafe(t *testing.T) {
+ assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`))
+}
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index f3082e4fa0..3fafb96b8e 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -6,9 +6,9 @@
//
// This documentation describes the Gitea API.
//
-// Schemes: http, https
+// Schemes: https, http
// BasePath: /api/v1
-// Version: {{AppVer | JSEscape | Safe}}
+// Version: {{AppVer | JSEscape}}
// License: MIT http://opensource.org/licenses/MIT
//
// Consumes:
diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go
index 07140b6674..660fa8fe4e 100644
--- a/routers/web/auth/oauth.go
+++ b/routers/web/auth/oauth.go
@@ -579,16 +579,8 @@ func GrantApplicationOAuth(ctx *context.Context) {
// OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities
func OIDCWellKnown(ctx *context.Context) {
- t, err := ctx.Render.TemplateLookup("user/auth/oidc_wellknown", nil)
- if err != nil {
- ctx.ServerError("unable to find template", err)
- return
- }
- ctx.Resp.Header().Set("Content-Type", "application/json")
ctx.Data["SigningKey"] = oauth2.DefaultSigningKey
- if err = t.Execute(ctx.Resp, ctx.Data); err != nil {
- ctx.ServerError("unable to execute template", err)
- }
+ ctx.JSONTemplate("user/auth/oidc_wellknown")
}
// OIDCKeys generates the JSON Web Key Set
diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go
index a2c0abb47e..a6c66a2c70 100644
--- a/routers/web/shared/user/header.go
+++ b/routers/web/shared/user/header.go
@@ -4,6 +4,8 @@
package user
import (
+ "net/url"
+
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
access_model "code.gitea.io/gitea/models/perm/access"
@@ -36,7 +38,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
- ctx.Data["UserLocationMapURL"] = setting.Service.UserLocationMapURL
+ ctx.Data["ContextUserLocationMapURL"] = setting.Service.UserLocationMapURL + url.QueryEscape(ctx.ContextUser.Location)
// Show OpenID URIs
openIDs, err := user_model.GetUserOpenIDs(ctx, ctx.ContextUser.ID)
diff --git a/routers/web/swagger_json.go b/routers/web/swagger_json.go
index 493c97aa67..42e9dbe967 100644
--- a/routers/web/swagger_json.go
+++ b/routers/web/swagger_json.go
@@ -4,22 +4,10 @@
package web
import (
- "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
)
-// tplSwaggerV1Json swagger v1 json template
-const tplSwaggerV1Json base.TplName = "swagger/v1_json"
-
// SwaggerV1Json render swagger v1 json
func SwaggerV1Json(ctx *context.Context) {
- t, err := ctx.Render.TemplateLookup(string(tplSwaggerV1Json), nil)
- if err != nil {
- ctx.ServerError("unable to find template", err)
- return
- }
- ctx.Resp.Header().Set("Content-Type", "application/json")
- if err = t.Execute(ctx.Resp, ctx.Data); err != nil {
- ctx.ServerError("unable to execute template", err)
- }
+ ctx.JSONTemplate("swagger/v1_json")
}
diff --git a/templates/shared/user/profile_big_avatar.tmpl b/templates/shared/user/profile_big_avatar.tmpl
index 4fbc43f541..9ea8334881 100644
--- a/templates/shared/user/profile_big_avatar.tmpl
+++ b/templates/shared/user/profile_big_avatar.tmpl
@@ -31,9 +31,8 @@
<li>
{{svg "octicon-location"}}
<span class="gt-f1">{{.ContextUser.Location}}</span>
- {{if .UserLocationMapURL}}
- {{/* We presume that the UserLocationMapURL is safe, as it is provided by the site administrator. */}}
- <a href="{{.UserLocationMapURL | Safe}}{{.ContextUser.Location | QueryEscape}}" rel="nofollow noreferrer" data-tooltip-content="{{ctx.Locale.Tr "user.show_on_map"}}">
+ {{if .ContextUserLocationMapURL}}
+ <a href="{{.ContextUserLocationMapURL}}" rel="nofollow noreferrer" data-tooltip-content="{{ctx.Locale.Tr "user.show_on_map"}}">
{{svg "octicon-link-external"}}
</a>
{{end}}
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index a881afaf0e..d26bed53aa 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -8,8 +8,8 @@
"text/html"
],
"schemes": [
- "http",
- "https"
+ "https",
+ "http"
],
"swagger": "2.0",
"info": {
@@ -19,9 +19,9 @@
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
},
- "version": "{{AppVer | JSEscape | Safe}}"
+ "version": "{{AppVer | JSEscape}}"
},
- "basePath": "{{AppSubUrl | JSEscape | Safe}}/api/v1",
+ "basePath": "{{AppSubUrl | JSEscape}}/api/v1",
"paths": {
"/activitypub/user-id/{user-id}": {
"get": {
diff --git a/templates/user/auth/oidc_wellknown.tmpl b/templates/user/auth/oidc_wellknown.tmpl
index 38e6900c38..54bb4a763d 100644
--- a/templates/user/auth/oidc_wellknown.tmpl
+++ b/templates/user/auth/oidc_wellknown.tmpl
@@ -1,16 +1,16 @@
{
- "issuer": "{{AppUrl | JSEscape | Safe}}",
- "authorization_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/authorize",
- "token_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/access_token",
- "jwks_uri": "{{AppUrl | JSEscape | Safe}}login/oauth/keys",
- "userinfo_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/userinfo",
- "introspection_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/introspect",
+ "issuer": "{{AppUrl | JSEscape}}",
+ "authorization_endpoint": "{{AppUrl | JSEscape}}login/oauth/authorize",
+ "token_endpoint": "{{AppUrl | JSEscape}}login/oauth/access_token",
+ "jwks_uri": "{{AppUrl | JSEscape}}login/oauth/keys",
+ "userinfo_endpoint": "{{AppUrl | JSEscape}}login/oauth/userinfo",
+ "introspection_endpoint": "{{AppUrl | JSEscape}}login/oauth/introspect",
"response_types_supported": [
"code",
"id_token"
],
"id_token_signing_alg_values_supported": [
- "{{.SigningKey.SigningMethod.Alg | JSEscape | Safe}}"
+ "{{.SigningKey.SigningMethod.Alg | JSEscape}}"
],
"subject_types_supported": [
"public"