Skip to content

Commit 31bb9f3

Browse files
authored
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
1 parent a784ed3 commit 31bb9f3

File tree

11 files changed

+45
-42
lines changed

11 files changed

+45
-42
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ ifdef DEPS_PLAYWRIGHT
164164
endif
165165

166166
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
167-
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
168-
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
167+
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape}}/api/v1"|g
168+
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape}}/api/v1"|"basePath": "/api/v1"|g
169169
SWAGGER_EXCLUDE := code.gitea.io/sdk
170170
SWAGGER_NEWLINE_COMMAND := -e '$$a\'
171171

modules/context/context_response.go

+14
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ func (ctx *Context) HTML(status int, name base.TplName) {
9090
}
9191
}
9292

93+
// JSONTemplate renders the template as JSON response
94+
// keep in mind that the template is processed in HTML context, so JSON-things should be handled carefully, eg: by JSEscape
95+
func (ctx *Context) JSONTemplate(tmpl base.TplName) {
96+
t, err := ctx.Render.TemplateLookup(string(tmpl), nil)
97+
if err != nil {
98+
ctx.ServerError("unable to find template", err)
99+
return
100+
}
101+
ctx.Resp.Header().Set("Content-Type", "application/json")
102+
if err = t.Execute(ctx.Resp, ctx.Data); err != nil {
103+
ctx.ServerError("unable to execute template", err)
104+
}
105+
}
106+
93107
// RenderToString renders the template content to a string
94108
func (ctx *Context) RenderToString(name base.TplName, data map[string]any) (string, error) {
95109
var buf strings.Builder

modules/templates/helper.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func NewFuncMap() template.FuncMap {
3838
"Safe": Safe,
3939
"Escape": Escape,
4040
"QueryEscape": url.QueryEscape,
41-
"JSEscape": template.JSEscapeString,
41+
"JSEscape": JSEscapeSafe,
4242
"Str2html": Str2html, // TODO: rename it to SanitizeHTML
4343
"URLJoin": util.URLJoin,
4444
"DotEscape": DotEscape,
@@ -211,6 +211,10 @@ func Escape(s any) template.HTML {
211211
panic(fmt.Sprintf("unexpected type %T", s))
212212
}
213213

214+
func JSEscapeSafe(s string) template.HTML {
215+
return template.HTML(template.JSEscapeString(s))
216+
}
217+
214218
func RenderEmojiPlain(s any) any {
215219
switch v := s.(type) {
216220
case string:

modules/templates/helper_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,7 @@ func TestSubjectBodySeparator(t *testing.T) {
5252
"",
5353
"Insuficient\n--\nSeparators")
5454
}
55+
56+
func TestJSEscapeSafe(t *testing.T) {
57+
assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`))
58+
}

routers/api/v1/api.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
//
77
// This documentation describes the Gitea API.
88
//
9-
// Schemes: http, https
9+
// Schemes: https, http
1010
// BasePath: /api/v1
11-
// Version: {{AppVer | JSEscape | Safe}}
11+
// Version: {{AppVer | JSEscape}}
1212
// License: MIT http://opensource.org/licenses/MIT
1313
//
1414
// Consumes:

routers/web/auth/oauth.go

+1-9
Original file line numberDiff line numberDiff line change
@@ -579,16 +579,8 @@ func GrantApplicationOAuth(ctx *context.Context) {
579579

580580
// OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities
581581
func OIDCWellKnown(ctx *context.Context) {
582-
t, err := ctx.Render.TemplateLookup("user/auth/oidc_wellknown", nil)
583-
if err != nil {
584-
ctx.ServerError("unable to find template", err)
585-
return
586-
}
587-
ctx.Resp.Header().Set("Content-Type", "application/json")
588582
ctx.Data["SigningKey"] = oauth2.DefaultSigningKey
589-
if err = t.Execute(ctx.Resp, ctx.Data); err != nil {
590-
ctx.ServerError("unable to execute template", err)
591-
}
583+
ctx.JSONTemplate("user/auth/oidc_wellknown")
592584
}
593585

594586
// OIDCKeys generates the JSON Web Key Set

routers/web/shared/user/header.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package user
55

66
import (
7+
"net/url"
8+
79
"code.gitea.io/gitea/models/db"
810
"code.gitea.io/gitea/models/organization"
911
access_model "code.gitea.io/gitea/models/perm/access"
@@ -36,7 +38,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
3638

3739
ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
3840
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate
39-
ctx.Data["UserLocationMapURL"] = setting.Service.UserLocationMapURL
41+
ctx.Data["ContextUserLocationMapURL"] = setting.Service.UserLocationMapURL + url.QueryEscape(ctx.ContextUser.Location)
4042

4143
// Show OpenID URIs
4244
openIDs, err := user_model.GetUserOpenIDs(ctx, ctx.ContextUser.ID)

routers/web/swagger_json.go

+1-13
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,10 @@
44
package web
55

66
import (
7-
"code.gitea.io/gitea/modules/base"
87
"code.gitea.io/gitea/modules/context"
98
)
109

11-
// tplSwaggerV1Json swagger v1 json template
12-
const tplSwaggerV1Json base.TplName = "swagger/v1_json"
13-
1410
// SwaggerV1Json render swagger v1 json
1511
func SwaggerV1Json(ctx *context.Context) {
16-
t, err := ctx.Render.TemplateLookup(string(tplSwaggerV1Json), nil)
17-
if err != nil {
18-
ctx.ServerError("unable to find template", err)
19-
return
20-
}
21-
ctx.Resp.Header().Set("Content-Type", "application/json")
22-
if err = t.Execute(ctx.Resp, ctx.Data); err != nil {
23-
ctx.ServerError("unable to execute template", err)
24-
}
12+
ctx.JSONTemplate("swagger/v1_json")
2513
}

templates/shared/user/profile_big_avatar.tmpl

+2-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@
3131
<li>
3232
{{svg "octicon-location"}}
3333
<span class="gt-f1">{{.ContextUser.Location}}</span>
34-
{{if .UserLocationMapURL}}
35-
{{/* We presume that the UserLocationMapURL is safe, as it is provided by the site administrator. */}}
36-
<a href="{{.UserLocationMapURL | Safe}}{{.ContextUser.Location | QueryEscape}}" rel="nofollow noreferrer" data-tooltip-content="{{ctx.Locale.Tr "user.show_on_map"}}">
34+
{{if .ContextUserLocationMapURL}}
35+
<a href="{{.ContextUserLocationMapURL}}" rel="nofollow noreferrer" data-tooltip-content="{{ctx.Locale.Tr "user.show_on_map"}}">
3736
{{svg "octicon-link-external"}}
3837
</a>
3938
{{end}}

templates/swagger/v1_json.tmpl

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/user/auth/oidc_wellknown.tmpl

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
2-
"issuer": "{{AppUrl | JSEscape | Safe}}",
3-
"authorization_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/authorize",
4-
"token_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/access_token",
5-
"jwks_uri": "{{AppUrl | JSEscape | Safe}}login/oauth/keys",
6-
"userinfo_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/userinfo",
7-
"introspection_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/introspect",
2+
"issuer": "{{AppUrl | JSEscape}}",
3+
"authorization_endpoint": "{{AppUrl | JSEscape}}login/oauth/authorize",
4+
"token_endpoint": "{{AppUrl | JSEscape}}login/oauth/access_token",
5+
"jwks_uri": "{{AppUrl | JSEscape}}login/oauth/keys",
6+
"userinfo_endpoint": "{{AppUrl | JSEscape}}login/oauth/userinfo",
7+
"introspection_endpoint": "{{AppUrl | JSEscape}}login/oauth/introspect",
88
"response_types_supported": [
99
"code",
1010
"id_token"
1111
],
1212
"id_token_signing_alg_values_supported": [
13-
"{{.SigningKey.SigningMethod.Alg | JSEscape | Safe}}"
13+
"{{.SigningKey.SigningMethod.Alg | JSEscape}}"
1414
],
1515
"subject_types_supported": [
1616
"public"

0 commit comments

Comments
 (0)