mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-04-29 22:51:42 +02:00
Merge hotfix changes
This commit is contained in:
commit
8dfa1957f4
@ -15,9 +15,8 @@
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"host": "localhost:8080",
|
||||
"basePath": "/api",
|
||||
"paths": {
|
||||
"/clusters/": {
|
||||
"/api/clusters/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -74,7 +73,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/": {
|
||||
"/api/jobs/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -169,7 +168,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/delete_job/": {
|
||||
"/api/jobs/delete_job/": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
@ -244,7 +243,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/delete_job/{id}": {
|
||||
"/api/jobs/delete_job/{id}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
@ -314,7 +313,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/delete_job_before/{ts}": {
|
||||
"/api/jobs/delete_job_before/{ts}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
@ -384,7 +383,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/edit_meta/{id}": {
|
||||
"/api/jobs/edit_meta/{id}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -454,7 +453,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/start_job/": {
|
||||
"/api/jobs/start_job/": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -523,7 +522,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/stop_job/": {
|
||||
"/api/jobs/stop_job/": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -595,7 +594,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/tag_job/{id}": {
|
||||
"/api/jobs/tag_job/{id}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -668,7 +667,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/{id}": {
|
||||
"/api/jobs/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -827,7 +826,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/notice/": {
|
||||
"/config/notice/": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -893,7 +892,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/{id}": {
|
||||
"/config/user/{id}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -998,7 +997,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/": {
|
||||
"/config/users/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
|
@ -1,4 +1,3 @@
|
||||
basePath: /api
|
||||
definitions:
|
||||
api.ApiReturnedUser:
|
||||
properties:
|
||||
@ -671,7 +670,7 @@ info:
|
||||
title: ClusterCockpit REST API
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/clusters/:
|
||||
/api/clusters/:
|
||||
get:
|
||||
description: Get a list of all cluster configs. Specific cluster can be requested
|
||||
using query parameter.
|
||||
@ -708,7 +707,7 @@ paths:
|
||||
summary: Lists all cluster configs
|
||||
tags:
|
||||
- Cluster query
|
||||
/jobs/:
|
||||
/api/jobs/:
|
||||
get:
|
||||
description: |-
|
||||
Get a list of all jobs. Filters can be applied using query parameters.
|
||||
@ -773,7 +772,7 @@ paths:
|
||||
summary: Lists all jobs
|
||||
tags:
|
||||
- Job query
|
||||
/jobs/{id}:
|
||||
/api/jobs/{id}:
|
||||
get:
|
||||
description: |-
|
||||
Job to get is specified by database ID
|
||||
@ -882,7 +881,7 @@ paths:
|
||||
summary: Get job meta and configurable metric data
|
||||
tags:
|
||||
- Job query
|
||||
/jobs/delete_job/:
|
||||
/api/jobs/delete_job/:
|
||||
delete:
|
||||
consumes:
|
||||
- application/json
|
||||
@ -932,7 +931,7 @@ paths:
|
||||
summary: Remove a job from the sql database
|
||||
tags:
|
||||
- Job remove
|
||||
/jobs/delete_job/{id}:
|
||||
/api/jobs/delete_job/{id}:
|
||||
delete:
|
||||
description: Job to remove is specified by database ID. This will not remove
|
||||
the job from the job archive.
|
||||
@ -979,7 +978,7 @@ paths:
|
||||
summary: Remove a job from the sql database
|
||||
tags:
|
||||
- Job remove
|
||||
/jobs/delete_job_before/{ts}:
|
||||
/api/jobs/delete_job_before/{ts}:
|
||||
delete:
|
||||
description: Remove all jobs with start time before timestamp. The jobs will
|
||||
not be removed from the job archive.
|
||||
@ -1026,7 +1025,7 @@ paths:
|
||||
summary: Remove a job from the sql database
|
||||
tags:
|
||||
- Job remove
|
||||
/jobs/edit_meta/{id}:
|
||||
/api/jobs/edit_meta/{id}:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
@ -1073,7 +1072,7 @@ paths:
|
||||
summary: Edit meta-data json
|
||||
tags:
|
||||
- Job add and modify
|
||||
/jobs/start_job/:
|
||||
/api/jobs/start_job/:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
@ -1120,7 +1119,7 @@ paths:
|
||||
summary: Adds a new job as "running"
|
||||
tags:
|
||||
- Job add and modify
|
||||
/jobs/stop_job/:
|
||||
/api/jobs/stop_job/:
|
||||
post:
|
||||
description: |-
|
||||
Job to stop is specified by request body. All fields are required in this case.
|
||||
@ -1168,7 +1167,7 @@ paths:
|
||||
summary: Marks job as completed and triggers archiving
|
||||
tags:
|
||||
- Job add and modify
|
||||
/jobs/tag_job/{id}:
|
||||
/api/jobs/tag_job/{id}:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
@ -1218,7 +1217,7 @@ paths:
|
||||
summary: Adds one or more tags to a job
|
||||
tags:
|
||||
- Job add and modify
|
||||
/notice/:
|
||||
/config/notice/:
|
||||
post:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
@ -1263,7 +1262,7 @@ paths:
|
||||
summary: Updates or empties the notice box content
|
||||
tags:
|
||||
- User
|
||||
/user/{id}:
|
||||
/config/user/{id}:
|
||||
post:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
@ -1337,7 +1336,7 @@ paths:
|
||||
summary: Updates an existing user
|
||||
tags:
|
||||
- User
|
||||
/users/:
|
||||
/config/users/:
|
||||
delete:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/99designs/gqlgen/graphql/handler/transport"
|
||||
"github.com/99designs/gqlgen/graphql/playground"
|
||||
"github.com/ClusterCockpit/cc-backend/internal/api"
|
||||
"github.com/ClusterCockpit/cc-backend/internal/archiver"
|
||||
@ -31,6 +32,7 @@ import (
|
||||
"github.com/ClusterCockpit/cc-backend/web"
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/websocket"
|
||||
httpSwagger "github.com/swaggo/http-swagger"
|
||||
)
|
||||
|
||||
@ -53,13 +55,24 @@ func serverInit() {
|
||||
// Setup the http.Handler/Router used by the server
|
||||
graph.Init()
|
||||
resolver := graph.GetResolverInstance()
|
||||
graphQLEndpoint := handler.NewDefaultServer(
|
||||
graphQLServer := handler.New(
|
||||
generated.NewExecutableSchema(generated.Config{Resolvers: resolver}))
|
||||
|
||||
graphQLServer.AddTransport(transport.SSE{})
|
||||
graphQLServer.AddTransport(transport.POST{})
|
||||
graphQLServer.AddTransport(transport.Websocket{
|
||||
KeepAlivePingInterval: 10 * time.Second,
|
||||
Upgrader: websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if os.Getenv("DEBUG") != "1" {
|
||||
// Having this handler means that a error message is returned via GraphQL instead of the connection simply beeing closed.
|
||||
// The problem with this is that then, no more stacktrace is printed to stderr.
|
||||
graphQLEndpoint.SetRecoverFunc(func(ctx context.Context, err interface{}) error {
|
||||
graphQLServer.SetRecoverFunc(func(ctx context.Context, err any) error {
|
||||
switch e := err.(type) {
|
||||
case string:
|
||||
return fmt.Errorf("MAIN > Panic: %s", e)
|
||||
@ -78,7 +91,7 @@ func serverInit() {
|
||||
router = mux.NewRouter()
|
||||
buildInfo := web.Build{Version: version, Hash: commit, Buildtime: date}
|
||||
|
||||
info := map[string]interface{}{}
|
||||
info := map[string]any{}
|
||||
info["hasOpenIDConnect"] = false
|
||||
|
||||
if config.Keys.OpenIDConfig != nil {
|
||||
@ -208,7 +221,7 @@ func serverInit() {
|
||||
router.PathPrefix("/swagger/").Handler(httpSwagger.Handler(
|
||||
httpSwagger.URL("http://" + config.Keys.Addr + "/swagger/doc.json"))).Methods(http.MethodGet)
|
||||
}
|
||||
secured.Handle("/query", graphQLEndpoint)
|
||||
secured.Handle("/query", graphQLServer)
|
||||
|
||||
// Send a searchId and then reply with a redirect to a user, or directly send query to job table for jobid and project.
|
||||
secured.HandleFunc("/search", func(rw http.ResponseWriter, r *http.Request) {
|
||||
|
@ -23,7 +23,7 @@ const docTemplate = `{
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/clusters/": {
|
||||
"/api/clusters/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -80,7 +80,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/": {
|
||||
"/api/jobs/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -175,7 +175,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/delete_job/": {
|
||||
"/api/jobs/delete_job/": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
@ -250,7 +250,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/delete_job/{id}": {
|
||||
"/api/jobs/delete_job/{id}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
@ -320,7 +320,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/delete_job_before/{ts}": {
|
||||
"/api/jobs/delete_job_before/{ts}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
@ -390,7 +390,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/edit_meta/{id}": {
|
||||
"/api/jobs/edit_meta/{id}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -460,7 +460,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/start_job/": {
|
||||
"/api/jobs/start_job/": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -529,7 +529,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/stop_job/": {
|
||||
"/api/jobs/stop_job/": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -601,7 +601,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/tag_job/{id}": {
|
||||
"/api/jobs/tag_job/{id}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -674,7 +674,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jobs/{id}": {
|
||||
"/api/jobs/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -833,7 +833,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/notice/": {
|
||||
"/config/notice/": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -899,7 +899,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/{id}": {
|
||||
"/config/user/{id}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@ -1004,7 +1004,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/": {
|
||||
"/config/users/": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
@ -2191,7 +2191,7 @@ const docTemplate = `{
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "1.0.0",
|
||||
Host: "localhost:8080",
|
||||
BasePath: "/api",
|
||||
BasePath: "",
|
||||
Schemes: []string{},
|
||||
Title: "ClusterCockpit REST API",
|
||||
Description: "API for batch job control.",
|
||||
|
@ -46,7 +46,6 @@ import (
|
||||
// @license.url https://opensource.org/licenses/MIT
|
||||
|
||||
// @host localhost:8080
|
||||
// @basePath /api
|
||||
|
||||
// @securityDefinitions.apikey ApiKeyAuth
|
||||
// @in header
|
||||
@ -220,7 +219,7 @@ func handleError(err error, statusCode int, rw http.ResponseWriter) {
|
||||
})
|
||||
}
|
||||
|
||||
func decode(r io.Reader, val interface{}) error {
|
||||
func decode(r io.Reader, val any) error {
|
||||
dec := json.NewDecoder(r)
|
||||
dec.DisallowUnknownFields()
|
||||
return dec.Decode(val)
|
||||
@ -238,7 +237,7 @@ func decode(r io.Reader, val interface{}) error {
|
||||
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /clusters/ [get]
|
||||
// @router /api/clusters/ [get]
|
||||
func (api *RestApi) getClusters(rw http.ResponseWriter, r *http.Request) {
|
||||
if user := repository.GetUserFromContext(r.Context()); user != nil &&
|
||||
!user.HasRole(schema.RoleApi) {
|
||||
@ -293,7 +292,7 @@ func (api *RestApi) getClusters(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 403 {object} api.ErrorResponse "Forbidden"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/ [get]
|
||||
// @router /api/jobs/ [get]
|
||||
func (api *RestApi) getJobs(rw http.ResponseWriter, r *http.Request) {
|
||||
withMetadata := false
|
||||
filter := &model.JobFilter{}
|
||||
@ -427,7 +426,7 @@ func (api *RestApi) getJobs(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 422 {object} api.ErrorResponse "Unprocessable Entity: finding job failed: sql: no rows in result set"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/{id} [get]
|
||||
// @router /api/jobs/{id} [get]
|
||||
func (api *RestApi) getCompleteJobById(rw http.ResponseWriter, r *http.Request) {
|
||||
// Fetch job from db
|
||||
id, ok := mux.Vars(r)["id"]
|
||||
@ -520,7 +519,7 @@ func (api *RestApi) getCompleteJobById(rw http.ResponseWriter, r *http.Request)
|
||||
// @failure 422 {object} api.ErrorResponse "Unprocessable Entity: finding job failed: sql: no rows in result set"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/{id} [post]
|
||||
// @router /api/jobs/{id} [post]
|
||||
func (api *RestApi) getJobById(rw http.ResponseWriter, r *http.Request) {
|
||||
// Fetch job from db
|
||||
id, ok := mux.Vars(r)["id"]
|
||||
@ -624,7 +623,7 @@ func (api *RestApi) getJobById(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 404 {object} api.ErrorResponse "Job does not exist"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/edit_meta/{id} [post]
|
||||
// @router /api/jobs/edit_meta/{id} [post]
|
||||
func (api *RestApi) editMeta(rw http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["id"], 10, 64)
|
||||
if err != nil {
|
||||
@ -670,7 +669,7 @@ func (api *RestApi) editMeta(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 404 {object} api.ErrorResponse "Job or tag does not exist"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/tag_job/{id} [post]
|
||||
// @router /api/jobs/tag_job/{id} [post]
|
||||
func (api *RestApi) tagJob(rw http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(mux.Vars(r)["id"], 10, 64)
|
||||
if err != nil {
|
||||
@ -839,7 +838,7 @@ func (api *RestApi) removeTags(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 422 {object} api.ErrorResponse "Unprocessable Entity: The combination of jobId, clusterId and startTime does already exist"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/start_job/ [post]
|
||||
// @router /api/jobs/start_job/ [post]
|
||||
func (api *RestApi) startJob(rw http.ResponseWriter, r *http.Request) {
|
||||
req := schema.JobMeta{BaseJob: schema.JobDefaults}
|
||||
if err := decode(r.Body, &req); err != nil {
|
||||
@ -912,7 +911,7 @@ func (api *RestApi) startJob(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 422 {object} api.ErrorResponse "Unprocessable Entity: job has already been stopped"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/stop_job/ [post]
|
||||
// @router /api/jobs/stop_job/ [post]
|
||||
func (api *RestApi) stopJobByRequest(rw http.ResponseWriter, r *http.Request) {
|
||||
// Parse request body
|
||||
req := StopJobApiRequest{}
|
||||
@ -953,7 +952,7 @@ func (api *RestApi) stopJobByRequest(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 422 {object} api.ErrorResponse "Unprocessable Entity: finding job failed: sql: no rows in result set"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/delete_job/{id} [delete]
|
||||
// @router /api/jobs/delete_job/{id} [delete]
|
||||
func (api *RestApi) deleteJobById(rw http.ResponseWriter, r *http.Request) {
|
||||
// Fetch job (that will be stopped) from db
|
||||
id, ok := mux.Vars(r)["id"]
|
||||
@ -996,7 +995,7 @@ func (api *RestApi) deleteJobById(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 422 {object} api.ErrorResponse "Unprocessable Entity: finding job failed: sql: no rows in result set"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/delete_job/ [delete]
|
||||
// @router /api/jobs/delete_job/ [delete]
|
||||
func (api *RestApi) deleteJobByRequest(rw http.ResponseWriter, r *http.Request) {
|
||||
// Parse request body
|
||||
req := DeleteJobApiRequest{}
|
||||
@ -1046,7 +1045,7 @@ func (api *RestApi) deleteJobByRequest(rw http.ResponseWriter, r *http.Request)
|
||||
// @failure 422 {object} api.ErrorResponse "Unprocessable Entity: finding job failed: sql: no rows in result set"
|
||||
// @failure 500 {object} api.ErrorResponse "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /jobs/delete_job_before/{ts} [delete]
|
||||
// @router /api/jobs/delete_job_before/{ts} [delete]
|
||||
func (api *RestApi) deleteJobBefore(rw http.ResponseWriter, r *http.Request) {
|
||||
var cnt int
|
||||
// Fetch job (that will be stopped) from db
|
||||
@ -1183,7 +1182,7 @@ func (api *RestApi) getJobMetrics(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 422 {string} string "Unprocessable Entity: creating user failed"
|
||||
// @failure 500 {string} string "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /users/ [post]
|
||||
// @router /config/users/ [post]
|
||||
func (api *RestApi) createUser(rw http.ResponseWriter, r *http.Request) {
|
||||
// SecuredCheck() only worked with TokenAuth: Removed
|
||||
|
||||
@ -1258,7 +1257,7 @@ func (api *RestApi) deleteUser(rw http.ResponseWriter, r *http.Request) {
|
||||
// @failure 403 {string} string "Forbidden"
|
||||
// @failure 500 {string} string "Internal Server Error"
|
||||
// @security ApiKeyAuth
|
||||
// @router /users/ [get]
|
||||
// @router /config/users/ [get]
|
||||
func (api *RestApi) getUsers(rw http.ResponseWriter, r *http.Request) {
|
||||
// SecuredCheck() only worked with TokenAuth: Removed
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user