updates
This commit is contained in:
@@ -12,7 +12,6 @@ type Controller struct {
|
|||||||
openaiClient *openai.Client
|
openaiClient *openai.Client
|
||||||
unraidAPIKey string
|
unraidAPIKey string
|
||||||
unraidURI string
|
unraidURI string
|
||||||
jwtToken string
|
|
||||||
|
|
||||||
config *configStruct
|
config *configStruct
|
||||||
}
|
}
|
||||||
@@ -30,7 +29,6 @@ func NewController() *Controller {
|
|||||||
openaiClient := openai.NewClient(openaiApiKey)
|
openaiClient := openai.NewClient(openaiApiKey)
|
||||||
unraidAPIKey := os.Getenv("UNRAID_API_KEY")
|
unraidAPIKey := os.Getenv("UNRAID_API_KEY")
|
||||||
unraidURI := os.Getenv("UNRAID_URI")
|
unraidURI := os.Getenv("UNRAID_URI")
|
||||||
jwtToken := os.Getenv("jwtToken")
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
@@ -40,7 +38,6 @@ func NewController() *Controller {
|
|||||||
openaiClient: openaiClient,
|
openaiClient: openaiClient,
|
||||||
unraidAPIKey: unraidAPIKey,
|
unraidAPIKey: unraidAPIKey,
|
||||||
unraidURI: unraidURI,
|
unraidURI: unraidURI,
|
||||||
jwtToken: jwtToken,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
controller/health.go
Normal file
21
controller/health.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getHealth godoc
|
||||||
|
//
|
||||||
|
// @Summary Generate Health status
|
||||||
|
// @Description Get the health of the API
|
||||||
|
// @Tags health
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {string} json "response"
|
||||||
|
// @Router /health/getHealth [get]
|
||||||
|
func (c *Controller) GetHealth(ctx *gin.Context) {
|
||||||
|
// Return the health in the response body
|
||||||
|
ctx.JSON(http.StatusOK, gin.H{"health": "OK"})
|
||||||
|
}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// generateTokenHandler godoc
|
|
||||||
//
|
|
||||||
// @Summary Generate JWT Token
|
|
||||||
// @Description Gets the PSU Data from unraid
|
|
||||||
// @Tags token
|
|
||||||
// @Accept json
|
|
||||||
// @Produce plain
|
|
||||||
// @Param token query string true "Secret Token"
|
|
||||||
// @Success 200 {string} string "response"
|
|
||||||
// @Router /token/generateTokenHandler [get]
|
|
||||||
func (c *Controller) GenerateTokenHandler(ctx *gin.Context) {
|
|
||||||
// Define the token claims
|
|
||||||
claims := jwt.MapClaims{
|
|
||||||
"exp": time.Now().Add(time.Hour * 24).Unix(),
|
|
||||||
"iat": time.Now().Unix(),
|
|
||||||
// Add any additional claims here...
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a new token with the claims
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
||||||
|
|
||||||
// Sign the token with your secret key
|
|
||||||
// TODO: Replace "my-secret-key" with your own secret key
|
|
||||||
tokenString, err := token.SignedString([]byte(ctx.Query("token")))
|
|
||||||
if err != nil {
|
|
||||||
ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"message": "Failed to generate token"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the token in the response body
|
|
||||||
ctx.JSON(http.StatusOK, gin.H{"token": tokenString})
|
|
||||||
}
|
|
||||||
59
docs/docs.go
59
docs/docs.go
@@ -25,6 +25,29 @@ const docTemplate = `{
|
|||||||
"host": "{{.Host}}",
|
"host": "{{.Host}}",
|
||||||
"basePath": "{{.BasePath}}",
|
"basePath": "{{.BasePath}}",
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"/health/getHealth": {
|
||||||
|
"get": {
|
||||||
|
"description": "Get the health of the API",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"health"
|
||||||
|
],
|
||||||
|
"summary": "Generate Health status",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "response",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/openai/general": {
|
"/openai/general": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Ask ChatGPT a general question",
|
"description": "Ask ChatGPT a general question",
|
||||||
@@ -89,38 +112,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/token/generateTokenHandler": {
|
|
||||||
"get": {
|
|
||||||
"description": "Gets the PSU Data from unraid",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"text/plain"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"token"
|
|
||||||
],
|
|
||||||
"summary": "Generate JWT Token",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Secret Token",
|
|
||||||
"name": "token",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "response",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/unraid/powerusage": {
|
"/unraid/powerusage": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Gets the PSU Data from unraid",
|
"description": "Gets the PSU Data from unraid",
|
||||||
@@ -157,11 +148,11 @@ const docTemplate = `{
|
|||||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||||
var SwaggerInfo = &swag.Spec{
|
var SwaggerInfo = &swag.Spec{
|
||||||
Version: "1.0",
|
Version: "1.0",
|
||||||
Host: "localhost:8080",
|
Host: "durpapi.durp.info",
|
||||||
BasePath: "/api/v1",
|
BasePath: "/api/v1",
|
||||||
Schemes: []string{},
|
Schemes: []string{},
|
||||||
Title: "DurpAPI",
|
Title: "DurpAPI",
|
||||||
Description: "This is a sample server celler server.",
|
Description: "API for Durp's needs",
|
||||||
InfoInstanceName: "swagger",
|
InfoInstanceName: "swagger",
|
||||||
SwaggerTemplate: docTemplate,
|
SwaggerTemplate: docTemplate,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"swagger": "2.0",
|
"swagger": "2.0",
|
||||||
"info": {
|
"info": {
|
||||||
"description": "This is a sample server celler server.",
|
"description": "API for Durp's needs",
|
||||||
"title": "DurpAPI",
|
"title": "DurpAPI",
|
||||||
"termsOfService": "http://swagger.io/terms/",
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
"contact": {
|
"contact": {
|
||||||
@@ -15,9 +15,32 @@
|
|||||||
},
|
},
|
||||||
"version": "1.0"
|
"version": "1.0"
|
||||||
},
|
},
|
||||||
"host": "localhost:8080",
|
"host": "durpapi.durp.info",
|
||||||
"basePath": "/api/v1",
|
"basePath": "/api/v1",
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"/health/getHealth": {
|
||||||
|
"get": {
|
||||||
|
"description": "Get the health of the API",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"health"
|
||||||
|
],
|
||||||
|
"summary": "Generate Health status",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "response",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/openai/general": {
|
"/openai/general": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Ask ChatGPT a general question",
|
"description": "Ask ChatGPT a general question",
|
||||||
@@ -82,38 +105,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/token/generateTokenHandler": {
|
|
||||||
"get": {
|
|
||||||
"description": "Gets the PSU Data from unraid",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"text/plain"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"token"
|
|
||||||
],
|
|
||||||
"summary": "Generate JWT Token",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Secret Token",
|
|
||||||
"name": "token",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "response",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/unraid/powerusage": {
|
"/unraid/powerusage": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Gets the PSU Data from unraid",
|
"description": "Gets the PSU Data from unraid",
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
basePath: /api/v1
|
basePath: /api/v1
|
||||||
host: localhost:8080
|
host: durpapi.durp.info
|
||||||
info:
|
info:
|
||||||
contact:
|
contact:
|
||||||
email: support@swagger.io
|
email: support@swagger.io
|
||||||
name: API Support
|
name: API Support
|
||||||
url: http://www.swagger.io/support
|
url: http://www.swagger.io/support
|
||||||
description: This is a sample server celler server.
|
description: API for Durp's needs
|
||||||
license:
|
license:
|
||||||
name: Apache 2.0
|
name: Apache 2.0
|
||||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
@@ -13,6 +13,21 @@ info:
|
|||||||
title: DurpAPI
|
title: DurpAPI
|
||||||
version: "1.0"
|
version: "1.0"
|
||||||
paths:
|
paths:
|
||||||
|
/health/getHealth:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Get the health of the API
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: response
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
summary: Generate Health status
|
||||||
|
tags:
|
||||||
|
- health
|
||||||
/openai/general:
|
/openai/general:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -55,27 +70,6 @@ paths:
|
|||||||
summary: Travel Agent ChatGPT
|
summary: Travel Agent ChatGPT
|
||||||
tags:
|
tags:
|
||||||
- openai
|
- openai
|
||||||
/token/generateTokenHandler:
|
|
||||||
get:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: Gets the PSU Data from unraid
|
|
||||||
parameters:
|
|
||||||
- description: Secret Token
|
|
||||||
in: query
|
|
||||||
name: token
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
produces:
|
|
||||||
- text/plain
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: response
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
summary: Generate JWT Token
|
|
||||||
tags:
|
|
||||||
- token
|
|
||||||
/unraid/powerusage:
|
/unraid/powerusage:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
|||||||
15
main.go
15
main.go
@@ -34,21 +34,24 @@ func main() {
|
|||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
c := controller.NewController()
|
c := controller.NewController()
|
||||||
|
var groups []string
|
||||||
|
|
||||||
v1 := r.Group("/api/v1")
|
v1 := r.Group("/api/v1")
|
||||||
{
|
{
|
||||||
token := v1.Group("/token")
|
health := v1.Group("/health")
|
||||||
{
|
{
|
||||||
token.GET("generateTokenHandler", c.GenerateTokenHandler)
|
health.GET("getHealth", c.GetHealth)
|
||||||
}
|
}
|
||||||
openai := v1.Group("/openai")
|
openai := v1.Group("/openai")
|
||||||
{
|
{
|
||||||
|
groups = []string{"durpapi"}
|
||||||
|
openai.Use(authMiddleware(groups))
|
||||||
openai.GET("general", c.GeneralOpenAI)
|
openai.GET("general", c.GeneralOpenAI)
|
||||||
openai.GET("travelagent", c.TravelAgentOpenAI)
|
openai.GET("travelagent", c.TravelAgentOpenAI)
|
||||||
}
|
}
|
||||||
unraid := v1.Group("/unraid")
|
unraid := v1.Group("/unraid")
|
||||||
{
|
{
|
||||||
groups := []string{"grafana"}
|
groups = []string{"durpapi"}
|
||||||
unraid.Use(authMiddleware(groups))
|
unraid.Use(authMiddleware(groups))
|
||||||
unraid.GET("powerusage", c.UnraidPowerUsage)
|
unraid.GET("powerusage", c.UnraidPowerUsage)
|
||||||
}
|
}
|
||||||
@@ -60,12 +63,12 @@ func main() {
|
|||||||
func authMiddleware(allowedGroups []string) gin.HandlerFunc {
|
func authMiddleware(allowedGroups []string) gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
// Get the user groups from the request headers
|
// Get the user groups from the request headers
|
||||||
groupsHeader := c.GetHeader("X-authentik-groups")
|
groupsHeader := c.GetHeader("X-Forwarded-Groups")
|
||||||
|
|
||||||
// Split the groups header value into individual groups
|
// Split the groups header value into individual groups
|
||||||
groups := strings.Split(groupsHeader, "|")
|
groups := strings.Split(groupsHeader, ",")
|
||||||
|
|
||||||
// Check if the user belongs to any of the allowed groups
|
// Check if the user belongs to any of the allowed grouzps
|
||||||
isAllowed := false
|
isAllowed := false
|
||||||
for _, allowedGroup := range allowedGroups {
|
for _, allowedGroup := range allowedGroups {
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
|
|||||||
112
model/account.go
112
model/account.go
@@ -1,112 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
uuid "github.com/gofrs/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Account example
|
|
||||||
type Account struct {
|
|
||||||
ID int `json:"id" example:"1" format:"int64"`
|
|
||||||
Name string `json:"name" example:"account name"`
|
|
||||||
UUID uuid.UUID `json:"uuid" example:"550e8400-e29b-41d4-a716-446655440000" format:"uuid"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// example
|
|
||||||
var (
|
|
||||||
ErrNameInvalid = errors.New("name is empty")
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddAccount example
|
|
||||||
type AddAccount struct {
|
|
||||||
Name string `json:"name" example:"account name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validation example
|
|
||||||
func (a AddAccount) Validation() error {
|
|
||||||
switch {
|
|
||||||
case len(a.Name) == 0:
|
|
||||||
return ErrNameInvalid
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateAccount example
|
|
||||||
type UpdateAccount struct {
|
|
||||||
Name string `json:"name" example:"account name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validation example
|
|
||||||
func (a UpdateAccount) Validation() error {
|
|
||||||
switch {
|
|
||||||
case len(a.Name) == 0:
|
|
||||||
return ErrNameInvalid
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AccountsAll example
|
|
||||||
func AccountsAll(q string) ([]Account, error) {
|
|
||||||
if q == "" {
|
|
||||||
return accounts, nil
|
|
||||||
}
|
|
||||||
as := []Account{}
|
|
||||||
for k, v := range accounts {
|
|
||||||
if q == v.Name {
|
|
||||||
as = append(as, accounts[k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return as, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AccountOne example
|
|
||||||
func AccountOne(id int) (Account, error) {
|
|
||||||
for _, v := range accounts {
|
|
||||||
if id == v.ID {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Account{}, ErrNoRow
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert example
|
|
||||||
func (a Account) Insert() (int, error) {
|
|
||||||
accountMaxID++
|
|
||||||
a.ID = accountMaxID
|
|
||||||
a.Name = fmt.Sprintf("account_%d", accountMaxID)
|
|
||||||
accounts = append(accounts, a)
|
|
||||||
return accountMaxID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete example
|
|
||||||
func Delete(id int) error {
|
|
||||||
for k, v := range accounts {
|
|
||||||
if id == v.ID {
|
|
||||||
accounts = append(accounts[:k], accounts[k+1:]...)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("account id=%d is not found", id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update example
|
|
||||||
func (a Account) Update() error {
|
|
||||||
for k, v := range accounts {
|
|
||||||
if a.ID == v.ID {
|
|
||||||
accounts[k].Name = a.Name
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("account id=%d is not found", a.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
var accountMaxID = 3
|
|
||||||
var accounts = []Account{
|
|
||||||
{ID: 1, Name: "account_1"},
|
|
||||||
{ID: 2, Name: "account_2"},
|
|
||||||
{ID: 3, Name: "account_3"},
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
// Bottle example
|
|
||||||
type Bottle struct {
|
|
||||||
ID int `json:"id" example:"1"`
|
|
||||||
Name string `json:"name" example:"bottle_name"`
|
|
||||||
Account Account `json:"account"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// BottlesAll example
|
|
||||||
func BottlesAll() ([]Bottle, error) {
|
|
||||||
return bottles, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BottleOne example
|
|
||||||
func BottleOne(id int) (*Bottle, error) {
|
|
||||||
for _, v := range bottles {
|
|
||||||
if id == v.ID {
|
|
||||||
return &v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, ErrNoRow
|
|
||||||
}
|
|
||||||
|
|
||||||
var bottles = []Bottle{
|
|
||||||
{ID: 1, Name: "bottle_1", Account: Account{ID: 1, Name: "accout_1"}},
|
|
||||||
{ID: 2, Name: "bottle_2", Account: Account{ID: 2, Name: "accout_2"}},
|
|
||||||
{ID: 3, Name: "bottle_3", Account: Account{ID: 3, Name: "accout_3"}},
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user