]> source.dussan.org Git - gitea.git/commitdiff
Add API for License templates (#23009)
authorJakobDev <jakobdev@gmx.de>
Wed, 26 Apr 2023 06:08:28 +0000 (08:08 +0200)
committerGitHub <noreply@github.com>
Wed, 26 Apr 2023 06:08:28 +0000 (02:08 -0400)
This adds a API for getting License templates. This tries to be as close
to the [GitHub
API](https://docs.github.com/en/rest/licenses?apiVersion=2022-11-28) as
possible, but Gitea does not support all features that GitHub has. I
think they should been added, but this out f the scope of this PR. You
should merge #23006 before this PR for security reasons.

modules/structs/miscellaneous.go
routers/api/v1/api.go
routers/api/v1/misc/licenses.go [new file with mode: 0644]
routers/api/v1/swagger/misc.go
templates/swagger/v1_json.tmpl
tests/integration/api_license_templates_test.go [new file with mode: 0644]

index 8acea84d6cc175ebc22be4e84912f5d83beb1c1d..53d10a990788ffab11be044ef18d65eb48a4be05 100644 (file)
@@ -72,6 +72,22 @@ type ServerVersion struct {
        Version string `json:"version"`
 }
 
+// LicensesListEntry is used for the API
+type LicensesTemplateListEntry struct {
+       Key  string `json:"key"`
+       Name string `json:"name"`
+       URL  string `json:"url"`
+}
+
+// LicensesInfo contains information about a License
+type LicenseTemplateInfo struct {
+       Key            string `json:"key"`
+       Name           string `json:"name"`
+       URL            string `json:"url"`
+       Implementation string `json:"implementation"`
+       Body           string `json:"body"`
+}
+
 // APIError is an api error with a message
 type APIError struct {
        Message string `json:"message"`
index ad68a33d6be1125b9bd6b600ba93deb37faf8ce9..0af095b2bb6032a779233c02ce1aa4e51d06099d 100644 (file)
@@ -719,6 +719,8 @@ func Routes(ctx gocontext.Context) *web.Route {
                m.Post("/markup", bind(api.MarkupOption{}), misc.Markup)
                m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown)
                m.Post("/markdown/raw", misc.MarkdownRaw)
+               m.Get("/licenses", misc.ListLicenseTemplates)
+               m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo)
                m.Group("/settings", func() {
                        m.Get("/ui", settings.GetGeneralUISettings)
                        m.Get("/api", settings.GetGeneralAPISettings)
diff --git a/routers/api/v1/misc/licenses.go b/routers/api/v1/misc/licenses.go
new file mode 100644 (file)
index 0000000..65f6346
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package misc
+
+import (
+       "fmt"
+       "net/http"
+       "net/url"
+
+       "code.gitea.io/gitea/modules/context"
+       "code.gitea.io/gitea/modules/options"
+       repo_module "code.gitea.io/gitea/modules/repository"
+       "code.gitea.io/gitea/modules/setting"
+       api "code.gitea.io/gitea/modules/structs"
+       "code.gitea.io/gitea/modules/util"
+)
+
+// Returns a list of all License templates
+func ListLicenseTemplates(ctx *context.APIContext) {
+       // swagger:operation GET /licenses miscellaneous listLicenseTemplates
+       // ---
+       // summary: Returns a list of all license templates
+       // produces:
+       // - application/json
+       // responses:
+       //   "200":
+       //     "$ref": "#/responses/LicenseTemplateList"
+       response := make([]api.LicensesTemplateListEntry, len(repo_module.Licenses))
+       for i, license := range repo_module.Licenses {
+               response[i] = api.LicensesTemplateListEntry{
+                       Key:  license,
+                       Name: license,
+                       URL:  fmt.Sprintf("%sapi/v1/licenses/%s", setting.AppURL, url.PathEscape(license)),
+               }
+       }
+       ctx.JSON(http.StatusOK, response)
+}
+
+// Returns information about a gitignore template
+func GetLicenseTemplateInfo(ctx *context.APIContext) {
+       // swagger:operation GET /licenses/{name} miscellaneous getLicenseTemplateInfo
+       // ---
+       // summary: Returns information about a license template
+       // produces:
+       // - application/json
+       // parameters:
+       // - name: name
+       //   in: path
+       //   description: name of the license
+       //   type: string
+       //   required: true
+       // responses:
+       //   "200":
+       //     "$ref": "#/responses/LicenseTemplateInfo"
+       //   "404":
+       //     "$ref": "#/responses/notFound"
+       name := util.PathJoinRelX(ctx.Params("name"))
+
+       text, err := options.License(name)
+       if err != nil {
+               ctx.NotFound()
+               return
+       }
+
+       response := api.LicenseTemplateInfo{
+               Key:  name,
+               Name: name,
+               URL:  fmt.Sprintf("%sapi/v1/licenses/%s", setting.AppURL, url.PathEscape(name)),
+               Body: string(text),
+               // This is for combatibilty with the GitHub API. This Text is for some reason added to each License response.
+               Implementation: "Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file",
+       }
+
+       ctx.JSON(http.StatusOK, response)
+}
index a4052a6a763ed261556612125bf9ad7e8cf9d1ca..322bad0c1c5e115be6f06b437c804030e4d69656 100644 (file)
@@ -14,6 +14,20 @@ type swaggerResponseServerVersion struct {
        Body api.ServerVersion `json:"body"`
 }
 
+// LicenseTemplateList
+// swagger:response LicenseTemplateList
+type swaggerResponseLicensesTemplateList struct {
+       // in:body
+       Body []api.LicensesTemplateListEntry `json:"body"`
+}
+
+// LicenseTemplateInfo
+// swagger:response LicenseTemplateInfo
+type swaggerResponseLicenseTemplateInfo struct {
+       // in:body
+       Body api.LicenseTemplateInfo `json:"body"`
+}
+
 // StringSlice
 // swagger:response StringSlice
 type swaggerResponseStringSlice struct {
index e3f87d703e4f4540a8df308af08e69dc11d66239..bc403be4468af9fa633481c8f7fe628ece8443d3 100644 (file)
         }
       }
     },
+    "/licenses": {
+      "get": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "miscellaneous"
+        ],
+        "summary": "Returns a list of all license templates",
+        "operationId": "listLicenseTemplates",
+        "responses": {
+          "200": {
+            "$ref": "#/responses/LicenseTemplateList"
+          }
+        }
+      }
+    },
+    "/licenses/{name}": {
+      "get": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "miscellaneous"
+        ],
+        "summary": "Returns information about a license template",
+        "operationId": "getLicenseTemplateInfo",
+        "parameters": [
+          {
+            "type": "string",
+            "description": "name of the license",
+            "name": "name",
+            "in": "path",
+            "required": true
+          }
+        ],
+        "responses": {
+          "200": {
+            "$ref": "#/responses/LicenseTemplateInfo"
+          },
+          "404": {
+            "$ref": "#/responses/notFound"
+          }
+        }
+      }
+    },
     "/markdown": {
       "post": {
         "consumes": [
       },
       "x-go-package": "code.gitea.io/gitea/modules/structs"
     },
+    "LicenseTemplateInfo": {
+      "description": "LicensesInfo contains information about a License",
+      "type": "object",
+      "properties": {
+        "body": {
+          "type": "string",
+          "x-go-name": "Body"
+        },
+        "implementation": {
+          "type": "string",
+          "x-go-name": "Implementation"
+        },
+        "key": {
+          "type": "string",
+          "x-go-name": "Key"
+        },
+        "name": {
+          "type": "string",
+          "x-go-name": "Name"
+        },
+        "url": {
+          "type": "string",
+          "x-go-name": "URL"
+        }
+      },
+      "x-go-package": "code.gitea.io/gitea/modules/structs"
+    },
+    "LicensesTemplateListEntry": {
+      "description": "LicensesListEntry is used for the API",
+      "type": "object",
+      "properties": {
+        "key": {
+          "type": "string",
+          "x-go-name": "Key"
+        },
+        "name": {
+          "type": "string",
+          "x-go-name": "Name"
+        },
+        "url": {
+          "type": "string",
+          "x-go-name": "URL"
+        }
+      },
+      "x-go-package": "code.gitea.io/gitea/modules/structs"
+    },
     "MarkdownOption": {
       "description": "MarkdownOption markdown options",
       "type": "object",
         }
       }
     },
+    "LicenseTemplateInfo": {
+      "description": "LicenseTemplateInfo",
+      "schema": {
+        "$ref": "#/definitions/LicenseTemplateInfo"
+      }
+    },
+    "LicenseTemplateList": {
+      "description": "LicenseTemplateList",
+      "schema": {
+        "type": "array",
+        "items": {
+          "$ref": "#/definitions/LicensesTemplateListEntry"
+        }
+      }
+    },
     "MarkdownRender": {
       "description": "MarkdownRender is a rendered markdown document",
       "schema": {
diff --git a/tests/integration/api_license_templates_test.go b/tests/integration/api_license_templates_test.go
new file mode 100644 (file)
index 0000000..e12aab7
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+       "fmt"
+       "net/http"
+       "net/url"
+       "testing"
+
+       "code.gitea.io/gitea/modules/options"
+       repo_module "code.gitea.io/gitea/modules/repository"
+       api "code.gitea.io/gitea/modules/structs"
+       "code.gitea.io/gitea/tests"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestAPIListLicenseTemplates(t *testing.T) {
+       defer tests.PrepareTestEnv(t)()
+
+       req := NewRequest(t, "GET", "/api/v1/licenses")
+       resp := MakeRequest(t, req, http.StatusOK)
+
+       // This tests if the API returns a list of strings
+       var licenseList []api.LicensesTemplateListEntry
+       DecodeJSON(t, resp, &licenseList)
+}
+
+func TestAPIGetLicenseTemplateInfo(t *testing.T) {
+       defer tests.PrepareTestEnv(t)()
+
+       // If Gitea has for some reason no License templates, we need to skip this test
+       if len(repo_module.Licenses) == 0 {
+               return
+       }
+
+       // Use the first template for the test
+       licenseName := repo_module.Licenses[0]
+
+       urlStr := fmt.Sprintf("/api/v1/licenses/%s", url.PathEscape(licenseName))
+       req := NewRequest(t, "GET", urlStr)
+       resp := MakeRequest(t, req, http.StatusOK)
+
+       var licenseInfo api.LicenseTemplateInfo
+       DecodeJSON(t, resp, &licenseInfo)
+
+       // We get the text of the template here
+       text, _ := options.License(licenseName)
+
+       assert.Equal(t, licenseInfo.Key, licenseName)
+       assert.Equal(t, licenseInfo.Name, licenseName)
+       assert.Equal(t, licenseInfo.Body, string(text))
+}