mirror of
https://github.com/Forceu/Gokapi.git
synced 2025-12-30 05:19:34 -06:00
Added /auth/create API endpoint #133, fixed wrong openapi schemes, added examples to openapi
This commit is contained in:
@@ -73,3 +73,8 @@ func (key *ApiKey) HasPermissionApiMod() bool {
|
||||
func (key *ApiKey) HasPermissionEdit() bool {
|
||||
return key.HasPermission(ApiPermEdit)
|
||||
}
|
||||
|
||||
type ApiKeyOutput struct {
|
||||
Result string
|
||||
Id string
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ func showApiAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Handling of /apiNew
|
||||
func newApiKey(w http.ResponseWriter, r *http.Request) {
|
||||
api.NewKey()
|
||||
api.NewKey(true)
|
||||
redirect(w, "apiKeys")
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/forceu/gokapi/internal/configuration"
|
||||
"github.com/forceu/gokapi/internal/configuration/database"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
@@ -39,6 +40,8 @@ func Process(w http.ResponseWriter, r *http.Request, maxMemory int) {
|
||||
duplicateFile(w, request)
|
||||
case "/files/modify":
|
||||
editFile(w, request)
|
||||
case "/auth/create":
|
||||
createApiKey(w, request)
|
||||
case "/auth/friendlyname":
|
||||
changeFriendlyName(w, request)
|
||||
case "/auth/modify":
|
||||
@@ -105,6 +108,8 @@ func getApiPermissionRequired(requestUrl string) (uint8, bool) {
|
||||
return models.ApiPermUpload, true
|
||||
case "/files/modify":
|
||||
return models.ApiPermEdit, true
|
||||
case "/auth/create":
|
||||
return models.ApiPermApiMod, true
|
||||
case "/auth/friendlyname":
|
||||
return models.ApiPermApiMod, true
|
||||
case "/auth/modify":
|
||||
@@ -124,13 +129,16 @@ func DeleteKey(id string) bool {
|
||||
}
|
||||
|
||||
// NewKey generates a new API key
|
||||
func NewKey() string {
|
||||
func NewKey(defaultPermissions bool) string {
|
||||
newKey := models.ApiKey{
|
||||
Id: helper.GenerateRandomString(30),
|
||||
FriendlyName: "Unnamed key",
|
||||
LastUsed: 0,
|
||||
Permissions: models.ApiPermAllNoApiMod,
|
||||
}
|
||||
if !defaultPermissions {
|
||||
newKey.Permissions = models.ApiPermNone
|
||||
}
|
||||
database.SaveApiKey(newKey)
|
||||
return newKey.Id
|
||||
}
|
||||
@@ -167,22 +175,47 @@ func isValidKeyForEditing(w http.ResponseWriter, request apiRequest) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func createApiKey(w http.ResponseWriter, request apiRequest) {
|
||||
key := NewKey(false)
|
||||
output := models.ApiKeyOutput{
|
||||
Result: "OK",
|
||||
Id: key,
|
||||
}
|
||||
if request.apiInfo.friendlyName != "" {
|
||||
err := renameApiKeyFriendlyName(key, request.apiInfo.friendlyName)
|
||||
if err != nil {
|
||||
sendError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
result, err := json.Marshal(output)
|
||||
helper.Check(err)
|
||||
_, _ = w.Write(result)
|
||||
}
|
||||
|
||||
func changeFriendlyName(w http.ResponseWriter, request apiRequest) {
|
||||
if !isValidKeyForEditing(w, request) {
|
||||
return
|
||||
}
|
||||
if request.apiInfo.friendlyName == "" {
|
||||
request.apiInfo.friendlyName = "Unnamed key"
|
||||
err := renameApiKeyFriendlyName(request.apiInfo.apiKeyToModify, request.apiInfo.friendlyName)
|
||||
if err != nil {
|
||||
sendError(w, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
key, ok := database.GetApiKey(request.apiInfo.apiKeyToModify)
|
||||
}
|
||||
|
||||
func renameApiKeyFriendlyName(id string, newName string) error {
|
||||
if newName == "" {
|
||||
newName = "Unnamed key"
|
||||
}
|
||||
key, ok := database.GetApiKey(id)
|
||||
if !ok {
|
||||
sendError(w, http.StatusInternalServerError, "Could not modify API key")
|
||||
return
|
||||
return errors.New("could not modify API key")
|
||||
}
|
||||
if key.FriendlyName != request.apiInfo.friendlyName {
|
||||
key.FriendlyName = request.apiInfo.friendlyName
|
||||
if key.FriendlyName != newName {
|
||||
key.FriendlyName = newName
|
||||
database.SaveApiKey(key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteFile(w http.ResponseWriter, request apiRequest) {
|
||||
|
||||
@@ -39,10 +39,16 @@ const maxMemory = 20
|
||||
var newKeyId string
|
||||
|
||||
func TestNewKey(t *testing.T) {
|
||||
newKeyId = NewKey()
|
||||
newKeyId = NewKey(true)
|
||||
key, ok := database.GetApiKey(newKeyId)
|
||||
test.IsEqualBool(t, ok, true)
|
||||
test.IsEqualString(t, key.FriendlyName, "Unnamed key")
|
||||
test.IsEqualBool(t, key.Permissions == models.ApiPermAllNoApiMod, true)
|
||||
|
||||
newKeyId = NewKey(false)
|
||||
key, ok = database.GetApiKey(newKeyId)
|
||||
test.IsEqualBool(t, ok, true)
|
||||
test.IsEqualBool(t, key.Permissions == models.ApiPermNone, true)
|
||||
}
|
||||
|
||||
func TestDeleteKey(t *testing.T) {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"files"
|
||||
],
|
||||
"summary": "Lists all files",
|
||||
"description": "This API call lists all files that are not expired. Requires permission VIEW",
|
||||
"description": "This API call lists all files that are not expired. Returns null, if no files are stored. Requires permission VIEW",
|
||||
"operationId": "list",
|
||||
"security": [
|
||||
{
|
||||
@@ -51,6 +51,7 @@
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"nullable": true,
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/File"
|
||||
}
|
||||
@@ -237,7 +238,7 @@
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UploadResult"
|
||||
"$ref": "#/components/schemas/File"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,7 +321,7 @@
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UploadResult"
|
||||
"$ref": "#/components/schemas/File"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,6 +377,52 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/create": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"auth"
|
||||
],
|
||||
"summary": "Creates a new API key",
|
||||
"description": "This API call returns a new API key. The new key does not have any permissions. Requires permission API_MOD",
|
||||
"operationId": "create",
|
||||
"security": [
|
||||
{
|
||||
"apikey": ["API_MANAGE"]
|
||||
},
|
||||
{
|
||||
"session": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "friendlyName",
|
||||
"in": "header",
|
||||
"description": "The friendly name of the key",
|
||||
"required": false,
|
||||
"style": "simple",
|
||||
"explode": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Operation successful",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NewApiKey"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Invalid API key provided or not logged in as admin"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/friendlyname": {
|
||||
"put": {
|
||||
"tags": [
|
||||
@@ -502,56 +549,72 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "oNleRD3pUZgaDKn"
|
||||
},
|
||||
"Name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "Test File.jpg"
|
||||
},
|
||||
"Size": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "395.4 kB"
|
||||
},
|
||||
"SizeBytes": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "404843"
|
||||
},
|
||||
"HotlinkId": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "tDMs0U8MvRFwK69PfjagI7F87C13UVeQuOGDvtCG.jpg"
|
||||
},
|
||||
"ContentType": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "image/jpeg"
|
||||
},
|
||||
"ExpireAt": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "1708175321"
|
||||
},
|
||||
"ExpireAtString": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "2024-02-17 14:08"
|
||||
},
|
||||
"DownloadsRemaining": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "4"
|
||||
},
|
||||
"DownloadCount": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "1"
|
||||
},
|
||||
"UnlimitedDownloads": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"UnlimitedTime": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"RequiresClientSideDecryption": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"IsEncrypted": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"IsPasswordProtected": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"IsSavedOnLocalStorage": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "true"
|
||||
}
|
||||
},
|
||||
"description": "File is a struct used for saving information about an uploaded file",
|
||||
@@ -561,7 +624,8 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Result": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
}
|
||||
},
|
||||
"description": "Result after uploading a chunk",
|
||||
@@ -571,24 +635,46 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Result": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
},
|
||||
"FileInfo": {
|
||||
"$ref": "#/components/schemas/File"
|
||||
},
|
||||
"HotlinkUrl": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Always the base URL for all hotlinks",
|
||||
"example": "http://localhost:53842/hotlink/"
|
||||
},
|
||||
"Url": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Always the base URL for all regular downloads",
|
||||
"example": "http://localhost:53842/d?id="
|
||||
},
|
||||
"GenericHotlinkUrl": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Always the base URL for all hotlinks that are no pictures",
|
||||
"example": "http://localhost:53842/downloadFile?id="
|
||||
}
|
||||
},
|
||||
"description": "UploadResult is the struct used for the result after an upload",
|
||||
"x-go-package": "Gokapi/internal/models"
|
||||
},
|
||||
"NewApiKey": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Result": {
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
},
|
||||
"Id": {
|
||||
"type": "string",
|
||||
"example": "ar3iecahghiethiemeeR"
|
||||
}
|
||||
},
|
||||
"description": "NewApiKey is the struct used for the result after creating a new API key",
|
||||
"x-go-package": "Gokapi/internal/models"
|
||||
},
|
||||
"body": {
|
||||
"required": [
|
||||
"file"
|
||||
|
||||
File diff suppressed because one or more lines are too long
134
openapi.json
134
openapi.json
@@ -34,7 +34,7 @@
|
||||
"files"
|
||||
],
|
||||
"summary": "Lists all files",
|
||||
"description": "This API call lists all files that are not expired. Requires permission VIEW",
|
||||
"description": "This API call lists all files that are not expired. Returns null, if no files are stored. Requires permission VIEW",
|
||||
"operationId": "list",
|
||||
"security": [
|
||||
{
|
||||
@@ -51,6 +51,7 @@
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"nullable": true,
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/File"
|
||||
}
|
||||
@@ -237,7 +238,7 @@
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UploadResult"
|
||||
"$ref": "#/components/schemas/File"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,7 +321,7 @@
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UploadResult"
|
||||
"$ref": "#/components/schemas/File"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,6 +377,52 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/create": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"auth"
|
||||
],
|
||||
"summary": "Creates a new API key",
|
||||
"description": "This API call returns a new API key. The new key does not have any permissions. Requires permission API_MOD",
|
||||
"operationId": "create",
|
||||
"security": [
|
||||
{
|
||||
"apikey": ["API_MANAGE"]
|
||||
},
|
||||
{
|
||||
"session": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "friendlyName",
|
||||
"in": "header",
|
||||
"description": "The friendly name of the key",
|
||||
"required": false,
|
||||
"style": "simple",
|
||||
"explode": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Operation successful",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NewApiKey"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Invalid API key provided or not logged in as admin"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/friendlyname": {
|
||||
"put": {
|
||||
"tags": [
|
||||
@@ -502,56 +549,72 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Id": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "oNleRD3pUZgaDKn"
|
||||
},
|
||||
"Name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "Test File.jpg"
|
||||
},
|
||||
"Size": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "395.4 kB"
|
||||
},
|
||||
"SizeBytes": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "404843"
|
||||
},
|
||||
"HotlinkId": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "tDMs0U8MvRFwK69PfjagI7F87C13UVeQuOGDvtCG.jpg"
|
||||
},
|
||||
"ContentType": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "image/jpeg"
|
||||
},
|
||||
"ExpireAt": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "1708175321"
|
||||
},
|
||||
"ExpireAtString": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "2024-02-17 14:08"
|
||||
},
|
||||
"DownloadsRemaining": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "4"
|
||||
},
|
||||
"DownloadCount": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"format": "int64",
|
||||
"example": "1"
|
||||
},
|
||||
"UnlimitedDownloads": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"UnlimitedTime": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"RequiresClientSideDecryption": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"IsEncrypted": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"IsPasswordProtected": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "false"
|
||||
},
|
||||
"IsSavedOnLocalStorage": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"example": "true"
|
||||
}
|
||||
},
|
||||
"description": "File is a struct used for saving information about an uploaded file",
|
||||
@@ -561,7 +624,8 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Result": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
}
|
||||
},
|
||||
"description": "Result after uploading a chunk",
|
||||
@@ -571,24 +635,46 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Result": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
},
|
||||
"FileInfo": {
|
||||
"$ref": "#/components/schemas/File"
|
||||
},
|
||||
"HotlinkUrl": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Always the base URL for all hotlinks",
|
||||
"example": "http://localhost:53842/hotlink/"
|
||||
},
|
||||
"Url": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Always the base URL for all regular downloads",
|
||||
"example": "http://localhost:53842/d?id="
|
||||
},
|
||||
"GenericHotlinkUrl": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Always the base URL for all hotlinks that are no pictures",
|
||||
"example": "http://localhost:53842/downloadFile?id="
|
||||
}
|
||||
},
|
||||
"description": "UploadResult is the struct used for the result after an upload",
|
||||
"x-go-package": "Gokapi/internal/models"
|
||||
},
|
||||
"NewApiKey": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Result": {
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
},
|
||||
"Id": {
|
||||
"type": "string",
|
||||
"example": "ar3iecahghiethiemeeR"
|
||||
}
|
||||
},
|
||||
"description": "NewApiKey is the struct used for the result after creating a new API key",
|
||||
"x-go-package": "Gokapi/internal/models"
|
||||
},
|
||||
"body": {
|
||||
"required": [
|
||||
"file"
|
||||
|
||||
Reference in New Issue
Block a user