Merge remote-tracking branch 'upstream/main' into limit-repo-size

This commit is contained in:
DmitryFrolovTri
2022-12-19 09:53:10 +00:00
13 changed files with 314 additions and 28 deletions
+3
View File
@@ -88,6 +88,7 @@ require (
github.com/unrolled/render v1.5.0
github.com/urfave/cli v1.22.10
github.com/xanzy/go-gitlab v0.73.1
github.com/xeipuuv/gojsonschema v1.2.0
github.com/yohcop/openid-go v1.0.0
github.com/yuin/goldmark v1.5.2
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
@@ -266,6 +267,8 @@ require (
github.com/valyala/fastjson v1.6.3 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.2 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
+6
View File
@@ -1468,6 +1468,12 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
+31 -1
View File
@@ -8,6 +8,7 @@
package charset
import (
"bufio"
"io"
"strings"
@@ -31,7 +32,7 @@ func EscapeControlHTML(text string, locale translation.Locale, allowed ...rune)
return streamer.escaped, sb.String()
}
// EscapeControlReaders escapes the unicode control sequences in a provider reader and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte
// EscapeControlReaders escapes the unicode control sequences in a provided reader of HTML content and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte
func EscapeControlReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) {
outputStream := &HTMLStreamerWriter{Writer: writer}
streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
@@ -43,6 +44,35 @@ func EscapeControlReader(reader io.Reader, writer io.Writer, locale translation.
return streamer.escaped, err
}
// EscapeControlStringReader escapes the unicode control sequences in a provided reader of string content and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte
func EscapeControlStringReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) {
bufRd := bufio.NewReader(reader)
outputStream := &HTMLStreamerWriter{Writer: writer}
streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
for {
line, rdErr := bufRd.ReadString('\n')
if len(line) > 0 {
if err := streamer.Text(line); err != nil {
streamer.escaped.HasError = true
log.Error("Error whilst escaping: %v", err)
return streamer.escaped, err
}
}
if rdErr != nil {
if rdErr != io.EOF {
err = rdErr
}
break
}
if err := streamer.SelfClosingTag("br"); err != nil {
streamer.escaped.HasError = true
return streamer.escaped, err
}
}
return streamer.escaped, err
}
// EscapeControlString escapes the unicode control sequences in a provided string and returns the findings as an EscapeStatus and the escaped string
func EscapeControlString(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) {
sb := &strings.Builder{}
+2 -1
View File
@@ -102,7 +102,8 @@ func (l *LocalStorage) Save(path string, r io.Reader, size int64) (int64, error)
return 0, err
}
// Golang's tmp file (os.CreateTemp) always have 0o600 mode, so we need to change the file to follow the umask (as what Create/MkDir does)
if err := util.ApplyUmask(p, os.ModePerm); err != nil {
// but we don't want to make these files executable - so ensure that we mask out the executable bits
if err := util.ApplyUmask(p, os.ModePerm&0o666); err != nil {
return 0, err
}
+44
View File
@@ -0,0 +1,44 @@
Portions of LOOP are Copyright (c) 1986 by the Massachusetts Institute of Technology.
All Rights Reserved.
Permission to use, copy, modify and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the M.I.T. copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation. The names "M.I.T." and "Massachusetts
Institute of Technology" may not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission. Notice must be given in supporting documentation that
copying distribution is by permission of M.I.T. M.I.T. makes no
representations about the suitability of this software for any purpose.
It is provided "as is" without express or implied warranty.
Massachusetts Institute of Technology
77 Massachusetts Avenue
Cambridge, Massachusetts 02139
United States of America
+1-617-253-1000
Portions of LOOP are Copyright (c) 1989, 1990, 1991, 1992 by Symbolics, Inc.
All Rights Reserved.
Permission to use, copy, modify and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the Symbolics copyright notice appear in all copies and
that both that copyright notice and this permission notice appear in
supporting documentation. The name "Symbolics" may not be used in
advertising or publicity pertaining to distribution of the software
without specific, written prior permission. Notice must be given in
supporting documentation that copying distribution is by permission of
Symbolics. Symbolics makes no representations about the suitability of
this software for any purpose. It is provided "as is" without express
or implied warranty.
Symbolics, CLOE Runtime, and Minima are trademarks, and CLOE, Genera,
and Zetalisp are registered trademarks of Symbolics, Inc.
Symbolics, Inc.
8 New England Executive Park, East
Burlington, Massachusetts 01803
United States of America
+1-617-221-1000
+4 -16
View File
@@ -9,7 +9,6 @@ import (
gocontext "context"
"encoding/base64"
"fmt"
gotemplate "html/template"
"io"
"net/http"
"net/url"
@@ -350,15 +349,13 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
if err != nil {
log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.name, ctx.Repo.Repository, err)
buf := &bytes.Buffer{}
ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf, ctx.Locale)
ctx.Data["FileContent"] = strings.ReplaceAll(
gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
)
ctx.Data["EscapeStatus"], _ = charset.EscapeControlStringReader(rd, buf, ctx.Locale)
ctx.Data["FileContent"] = buf.String()
}
} else {
ctx.Data["IsRenderedHTML"] = true
ctx.Data["IsPlainText"] = true
buf := &bytes.Buffer{}
ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, &charset.BreakWriter{Writer: buf}, ctx.Locale, charset.RuneNBSP)
ctx.Data["EscapeStatus"], err = charset.EscapeControlStringReader(rd, buf, ctx.Locale)
if err != nil {
log.Error("Read failed: %v", err)
}
@@ -492,15 +489,6 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
}
// to prevent iframe load third-party url
ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'")
} else if readmeExist && !shouldRenderSource {
buf := &bytes.Buffer{}
ctx.Data["IsRenderedHTML"] = true
ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf, ctx.Locale)
ctx.Data["FileContent"] = strings.ReplaceAll(
gotemplate.HTMLEscapeString(buf.String()), "\n", `<br>`,
)
} else {
buf, _ := io.ReadAll(rd)
+3 -3
View File
@@ -17,11 +17,11 @@
</h4>
<div class="ui attached table unstackable segment">
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsRenderedHTML}} plain-text{{else if .IsTextFile}} code-view{{end}}">
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextFile}} code-view{{end}}">
{{if .IsMarkup}}
{{if .FileContent}}{{.FileContent | Safe}}{{end}}
{{else if .IsRenderedHTML}}
<pre>{{if .FileContent}}{{.FileContent | Str2html}}{{end}}</pre>
{{else if .IsPlainText}}
<pre>{{if .FileContent}}{{.FileContent | Safe}}{{end}}</pre>
{{else if not .IsTextFile}}
<div class="view-raw ui center">
{{if .IsImageFile}}
+3 -3
View File
@@ -61,11 +61,11 @@
{{if not (or .IsMarkup .IsRenderedHTML)}}
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
{{end}}
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsRenderedHTML}} plain-text{{else if .IsTextSource}} code-view{{end}}">
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextSource}} code-view{{end}}">
{{if .IsMarkup}}
{{if .FileContent}}{{.FileContent | Safe}}{{end}}
{{else if .IsRenderedHTML}}
<pre>{{if .FileContent}}{{.FileContent | Str2html}}{{end}}</pre>
{{else if .IsPlainText}}
<pre>{{if .FileContent}}{{.FileContent | Safe}}{{end}}</pre>
{{else if not .IsTextSource}}
<div class="view-raw ui center">
{{if .IsImageFile}}
+3 -3
View File
@@ -128,9 +128,9 @@
<ul class="repo-owner-name-list">
<li v-for="repo in repos" :class="{'private': repo.private || repo.internal}">
<a class="repo-list-link df ac sb" :href="repo.html_url">
<div class="text truncate item-name f1">
<component v-bind:is="repoIcon(repo)" size="16"></component>
<strong>${repo.full_name}</strong>
<div class="item-name df ac f1 mr-2">
<component v-bind:is="repoIcon(repo)" size="16" class="mr-2"></component>
<div class="text bold truncate ml-1">${repo.full_name}</div>
<span v-if="repo.archived">
{{svg "octicon-archive" 16 "ml-2"}}
</span>
+2
View File
@@ -27,6 +27,8 @@ func TestNodeinfo(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
req := NewRequestf(t, "GET", "/api/v1/nodeinfo")
resp := MakeRequest(t, req, http.StatusOK)
VerifyJSONSchema(t, resp, "nodeinfo_2.1.json")
var nodeinfo api.NodeInfo
DecodeJSON(t, resp, &nodeinfo)
assert.True(t, nodeinfo.OpenRegistrations)
+20
View File
@@ -33,6 +33,7 @@ import (
"github.com/PuerkitoBio/goquery"
"github.com/stretchr/testify/assert"
"github.com/xeipuuv/gojsonschema"
)
var c *web.Route
@@ -398,6 +399,25 @@ func DecodeJSON(t testing.TB, resp *httptest.ResponseRecorder, v interface{}) {
assert.NoError(t, decoder.Decode(v))
}
func VerifyJSONSchema(t testing.TB, resp *httptest.ResponseRecorder, schemaFile string) {
t.Helper()
schemaFilePath := filepath.Join(filepath.Dir(setting.AppPath), "tests", "integration", "schemas", schemaFile)
_, schemaFileErr := os.Stat(schemaFilePath)
assert.Nil(t, schemaFileErr)
schema, schemaFileReadErr := os.ReadFile(schemaFilePath)
assert.Nil(t, schemaFileReadErr)
assert.True(t, len(schema) > 0)
nodeinfoSchema := gojsonschema.NewStringLoader(string(schema))
nodeinfoString := gojsonschema.NewStringLoader(resp.Body.String())
result, schemaValidationErr := gojsonschema.Validate(nodeinfoSchema, nodeinfoString)
assert.Nil(t, schemaValidationErr)
assert.Empty(t, result.Errors())
assert.True(t, result.Valid())
}
func GetCSRF(t testing.TB, session *TestSession, urlStr string) string {
t.Helper()
req := NewRequest(t, "GET", urlStr)
+188
View File
@@ -0,0 +1,188 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://nodeinfo.diaspora.software/ns/schema/2.1#",
"description": "NodeInfo schema version 2.1.",
"type": "object",
"additionalProperties": false,
"required": [
"version",
"software",
"protocols",
"services",
"openRegistrations",
"usage",
"metadata"
],
"properties": {
"version": {
"description": "The schema version, must be 2.1.",
"enum": [
"2.1"
]
},
"software": {
"description": "Metadata about server software in use.",
"type": "object",
"additionalProperties": false,
"required": [
"name",
"version"
],
"properties": {
"name": {
"description": "The canonical name of this server software.",
"type": "string",
"pattern": "^[a-z0-9-]+$"
},
"version": {
"description": "The version of this server software.",
"type": "string"
},
"repository": {
"description": "The url of the source code repository of this server software.",
"type": "string"
},
"homepage": {
"description": "The url of the homepage of this server software.",
"type": "string"
}
}
},
"protocols": {
"description": "The protocols supported on this server.",
"type": "array",
"minItems": 1,
"items": {
"enum": [
"activitypub",
"buddycloud",
"dfrn",
"diaspora",
"libertree",
"ostatus",
"pumpio",
"tent",
"xmpp",
"zot"
]
}
},
"services": {
"description": "The third party sites this server can connect to via their application API.",
"type": "object",
"additionalProperties": false,
"required": [
"inbound",
"outbound"
],
"properties": {
"inbound": {
"description": "The third party sites this server can retrieve messages from for combined display with regular traffic.",
"type": "array",
"minItems": 0,
"items": {
"enum": [
"atom1.0",
"gnusocial",
"imap",
"pnut",
"pop3",
"pumpio",
"rss2.0",
"twitter"
]
}
},
"outbound": {
"description": "The third party sites this server can publish messages to on the behalf of a user.",
"type": "array",
"minItems": 0,
"items": {
"enum": [
"atom1.0",
"blogger",
"buddycloud",
"diaspora",
"dreamwidth",
"drupal",
"facebook",
"friendica",
"gnusocial",
"google",
"insanejournal",
"libertree",
"linkedin",
"livejournal",
"mediagoblin",
"myspace",
"pinterest",
"pnut",
"posterous",
"pumpio",
"redmatrix",
"rss2.0",
"smtp",
"tent",
"tumblr",
"twitter",
"wordpress",
"xmpp"
]
}
}
}
},
"openRegistrations": {
"description": "Whether this server allows open self-registration.",
"type": "boolean"
},
"usage": {
"description": "Usage statistics for this server.",
"type": "object",
"additionalProperties": false,
"required": [
"users"
],
"properties": {
"users": {
"description": "statistics about the users of this server.",
"type": "object",
"additionalProperties": false,
"properties": {
"total": {
"description": "The total amount of on this server registered users.",
"type": "integer",
"minimum": 0
},
"activeHalfyear": {
"description": "The amount of users that signed in at least once in the last 180 days.",
"type": "integer",
"minimum": 0
},
"activeMonth": {
"description": "The amount of users that signed in at least once in the last 30 days.",
"type": "integer",
"minimum": 0
}
}
},
"localPosts": {
"description": "The amount of posts that were made by users that are registered on this server.",
"type": "integer",
"minimum": 0
},
"localComments": {
"description": "The amount of comments that were made by users that are registered on this server.",
"type": "integer",
"minimum": 0
}
}
},
"metadata": {
"description": "Free form key value pairs for software specific values. Clients should not rely on any specific key present.",
"type": "object",
"minProperties": 0,
"additionalProperties": true
}
}
}
+5 -1
View File
@@ -188,7 +188,11 @@
}
.repo-owner-name-list .item-name {
max-width: 70%;
min-width: 0;
}
.repo-owner-name-list .item-name svg {
min-width: 16px;
}
}
}