Skip to content

Commit f3370ee

Browse files
verify nodeinfo response by schema (#22137)
... using [github.com/xeipuuv/gojsonschema](https://github.com/xeipuuv/gojsonschema) Co-authored-by: techknowlogick <[email protected]>
1 parent c4c4151 commit f3370ee

File tree

5 files changed

+219
-0
lines changed

5 files changed

+219
-0
lines changed

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ require (
8888
github.com/unrolled/render v1.5.0
8989
github.com/urfave/cli v1.22.10
9090
github.com/xanzy/go-gitlab v0.73.1
91+
github.com/xeipuuv/gojsonschema v1.2.0
9192
github.com/yohcop/openid-go v1.0.0
9293
github.com/yuin/goldmark v1.5.2
9394
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
@@ -266,6 +267,8 @@ require (
266267
github.com/valyala/fastjson v1.6.3 // indirect
267268
github.com/x448/float16 v0.8.4 // indirect
268269
github.com/xanzy/ssh-agent v0.3.2 // indirect
270+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
271+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
269272
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
270273
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
271274
go.etcd.io/bbolt v1.3.6 // indirect

go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -1468,6 +1468,12 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+
14681468
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
14691469
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
14701470
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
1471+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
1472+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
1473+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
1474+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
1475+
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
1476+
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
14711477
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
14721478
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
14731479
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=

tests/integration/api_nodeinfo_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ func TestNodeinfo(t *testing.T) {
2727
onGiteaRun(t, func(*testing.T, *url.URL) {
2828
req := NewRequestf(t, "GET", "/api/v1/nodeinfo")
2929
resp := MakeRequest(t, req, http.StatusOK)
30+
VerifyJSONSchema(t, resp, "nodeinfo_2.1.json")
31+
3032
var nodeinfo api.NodeInfo
3133
DecodeJSON(t, resp, &nodeinfo)
3234
assert.True(t, nodeinfo.OpenRegistrations)

tests/integration/integration_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333

3434
"github.com/PuerkitoBio/goquery"
3535
"github.com/stretchr/testify/assert"
36+
"github.com/xeipuuv/gojsonschema"
3637
)
3738

3839
var c *web.Route
@@ -398,6 +399,25 @@ func DecodeJSON(t testing.TB, resp *httptest.ResponseRecorder, v interface{}) {
398399
assert.NoError(t, decoder.Decode(v))
399400
}
400401

402+
func VerifyJSONSchema(t testing.TB, resp *httptest.ResponseRecorder, schemaFile string) {
403+
t.Helper()
404+
405+
schemaFilePath := filepath.Join(filepath.Dir(setting.AppPath), "tests", "integration", "schemas", schemaFile)
406+
_, schemaFileErr := os.Stat(schemaFilePath)
407+
assert.Nil(t, schemaFileErr)
408+
409+
schema, schemaFileReadErr := os.ReadFile(schemaFilePath)
410+
assert.Nil(t, schemaFileReadErr)
411+
assert.True(t, len(schema) > 0)
412+
413+
nodeinfoSchema := gojsonschema.NewStringLoader(string(schema))
414+
nodeinfoString := gojsonschema.NewStringLoader(resp.Body.String())
415+
result, schemaValidationErr := gojsonschema.Validate(nodeinfoSchema, nodeinfoString)
416+
assert.Nil(t, schemaValidationErr)
417+
assert.Empty(t, result.Errors())
418+
assert.True(t, result.Valid())
419+
}
420+
401421
func GetCSRF(t testing.TB, session *TestSession, urlStr string) string {
402422
t.Helper()
403423
req := NewRequest(t, "GET", urlStr)
+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"id": "http://nodeinfo.diaspora.software/ns/schema/2.1#",
4+
"description": "NodeInfo schema version 2.1.",
5+
"type": "object",
6+
"additionalProperties": false,
7+
"required": [
8+
"version",
9+
"software",
10+
"protocols",
11+
"services",
12+
"openRegistrations",
13+
"usage",
14+
"metadata"
15+
],
16+
"properties": {
17+
"version": {
18+
"description": "The schema version, must be 2.1.",
19+
"enum": [
20+
"2.1"
21+
]
22+
},
23+
"software": {
24+
"description": "Metadata about server software in use.",
25+
"type": "object",
26+
"additionalProperties": false,
27+
"required": [
28+
"name",
29+
"version"
30+
],
31+
"properties": {
32+
"name": {
33+
"description": "The canonical name of this server software.",
34+
"type": "string",
35+
"pattern": "^[a-z0-9-]+$"
36+
},
37+
"version": {
38+
"description": "The version of this server software.",
39+
"type": "string"
40+
},
41+
"repository": {
42+
"description": "The url of the source code repository of this server software.",
43+
"type": "string"
44+
},
45+
"homepage": {
46+
"description": "The url of the homepage of this server software.",
47+
"type": "string"
48+
}
49+
}
50+
},
51+
"protocols": {
52+
"description": "The protocols supported on this server.",
53+
"type": "array",
54+
"minItems": 1,
55+
"items": {
56+
"enum": [
57+
"activitypub",
58+
"buddycloud",
59+
"dfrn",
60+
"diaspora",
61+
"libertree",
62+
"ostatus",
63+
"pumpio",
64+
"tent",
65+
"xmpp",
66+
"zot"
67+
]
68+
}
69+
},
70+
"services": {
71+
"description": "The third party sites this server can connect to via their application API.",
72+
"type": "object",
73+
"additionalProperties": false,
74+
"required": [
75+
"inbound",
76+
"outbound"
77+
],
78+
"properties": {
79+
"inbound": {
80+
"description": "The third party sites this server can retrieve messages from for combined display with regular traffic.",
81+
"type": "array",
82+
"minItems": 0,
83+
"items": {
84+
"enum": [
85+
"atom1.0",
86+
"gnusocial",
87+
"imap",
88+
"pnut",
89+
"pop3",
90+
"pumpio",
91+
"rss2.0",
92+
"twitter"
93+
]
94+
}
95+
},
96+
"outbound": {
97+
"description": "The third party sites this server can publish messages to on the behalf of a user.",
98+
"type": "array",
99+
"minItems": 0,
100+
"items": {
101+
"enum": [
102+
"atom1.0",
103+
"blogger",
104+
"buddycloud",
105+
"diaspora",
106+
"dreamwidth",
107+
"drupal",
108+
"facebook",
109+
"friendica",
110+
"gnusocial",
111+
"google",
112+
"insanejournal",
113+
"libertree",
114+
"linkedin",
115+
"livejournal",
116+
"mediagoblin",
117+
"myspace",
118+
"pinterest",
119+
"pnut",
120+
"posterous",
121+
"pumpio",
122+
"redmatrix",
123+
"rss2.0",
124+
"smtp",
125+
"tent",
126+
"tumblr",
127+
"twitter",
128+
"wordpress",
129+
"xmpp"
130+
]
131+
}
132+
}
133+
}
134+
},
135+
"openRegistrations": {
136+
"description": "Whether this server allows open self-registration.",
137+
"type": "boolean"
138+
},
139+
"usage": {
140+
"description": "Usage statistics for this server.",
141+
"type": "object",
142+
"additionalProperties": false,
143+
"required": [
144+
"users"
145+
],
146+
"properties": {
147+
"users": {
148+
"description": "statistics about the users of this server.",
149+
"type": "object",
150+
"additionalProperties": false,
151+
"properties": {
152+
"total": {
153+
"description": "The total amount of on this server registered users.",
154+
"type": "integer",
155+
"minimum": 0
156+
},
157+
"activeHalfyear": {
158+
"description": "The amount of users that signed in at least once in the last 180 days.",
159+
"type": "integer",
160+
"minimum": 0
161+
},
162+
"activeMonth": {
163+
"description": "The amount of users that signed in at least once in the last 30 days.",
164+
"type": "integer",
165+
"minimum": 0
166+
}
167+
}
168+
},
169+
"localPosts": {
170+
"description": "The amount of posts that were made by users that are registered on this server.",
171+
"type": "integer",
172+
"minimum": 0
173+
},
174+
"localComments": {
175+
"description": "The amount of comments that were made by users that are registered on this server.",
176+
"type": "integer",
177+
"minimum": 0
178+
}
179+
}
180+
},
181+
"metadata": {
182+
"description": "Free form key value pairs for software specific values. Clients should not rely on any specific key present.",
183+
"type": "object",
184+
"minProperties": 0,
185+
"additionalProperties": true
186+
}
187+
}
188+
}

0 commit comments

Comments
 (0)