This commit is contained in:
2023-05-20 10:48:15 -05:00
parent 89648fc631
commit 231f7ec29c
9 changed files with 97 additions and 283 deletions

View File

@@ -12,7 +12,6 @@ type Controller struct {
openaiClient *openai.Client
unraidAPIKey string
unraidURI string
jwtToken string
config *configStruct
}
@@ -30,7 +29,6 @@ func NewController() *Controller {
openaiClient := openai.NewClient(openaiApiKey)
unraidAPIKey := os.Getenv("UNRAID_API_KEY")
unraidURI := os.Getenv("UNRAID_URI")
jwtToken := os.Getenv("jwtToken")
if err != nil {
fmt.Println(err.Error())
@@ -40,7 +38,6 @@ func NewController() *Controller {
openaiClient: openaiClient,
unraidAPIKey: unraidAPIKey,
unraidURI: unraidURI,
jwtToken: jwtToken,
}
}

21
controller/health.go Normal file
View 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"})
}

View File

@@ -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})
}

View File

@@ -25,6 +25,29 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"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": {
"get": {
"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": {
"get": {
"description": "Gets the PSU Data from unraid",
@@ -157,11 +148,11 @@ const docTemplate = `{
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0",
Host: "localhost:8080",
Host: "durpapi.durp.info",
BasePath: "/api/v1",
Schemes: []string{},
Title: "DurpAPI",
Description: "This is a sample server celler server.",
Description: "API for Durp's needs",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
}

View File

@@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server celler server.",
"description": "API for Durp's needs",
"title": "DurpAPI",
"termsOfService": "http://swagger.io/terms/",
"contact": {
@@ -15,9 +15,32 @@
},
"version": "1.0"
},
"host": "localhost:8080",
"host": "durpapi.durp.info",
"basePath": "/api/v1",
"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": {
"get": {
"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": {
"get": {
"description": "Gets the PSU Data from unraid",

View File

@@ -1,11 +1,11 @@
basePath: /api/v1
host: localhost:8080
host: durpapi.durp.info
info:
contact:
email: support@swagger.io
name: API Support
url: http://www.swagger.io/support
description: This is a sample server celler server.
description: API for Durp's needs
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
@@ -13,6 +13,21 @@ info:
title: DurpAPI
version: "1.0"
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:
get:
consumes:
@@ -55,27 +70,6 @@ paths:
summary: Travel Agent ChatGPT
tags:
- 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:
get:
consumes:

15
main.go
View File

@@ -34,21 +34,24 @@ func main() {
r := gin.Default()
c := controller.NewController()
var groups []string
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")
{
groups = []string{"durpapi"}
openai.Use(authMiddleware(groups))
openai.GET("general", c.GeneralOpenAI)
openai.GET("travelagent", c.TravelAgentOpenAI)
}
unraid := v1.Group("/unraid")
{
groups := []string{"grafana"}
groups = []string{"durpapi"}
unraid.Use(authMiddleware(groups))
unraid.GET("powerusage", c.UnraidPowerUsage)
}
@@ -60,12 +63,12 @@ func main() {
func authMiddleware(allowedGroups []string) gin.HandlerFunc {
return func(c *gin.Context) {
// 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
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
for _, allowedGroup := range allowedGroups {
for _, group := range groups {

View File

@@ -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"},
}

View File

@@ -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"}},
}