mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	verify nodeinfo response by schema (#22137)
... using [github.com/xeipuuv/gojsonschema](https://github.com/xeipuuv/gojsonschema) Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							@@ -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
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.sum
									
									
									
									
									
								
							@@ -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=
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
								tests/integration/schemas/nodeinfo_2.1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								tests/integration/schemas/nodeinfo_2.1.json
									
									
									
									
									
										Normal 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
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user