move to jwt tokens

This commit is contained in:
2023-04-08 20:18:56 -05:00
parent 3d0579c82e
commit 0a15180b53
6 changed files with 160 additions and 129 deletions

View File

@@ -12,6 +12,7 @@ type Controller struct {
openaiClient *openai.Client
unraidAPIKey string
unraidURI string
jwtToken string
config *configStruct
}
@@ -29,6 +30,7 @@ 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())
@@ -38,6 +40,7 @@ func NewController() *Controller {
openaiClient: openaiClient,
unraidAPIKey: unraidAPIKey,
unraidURI: unraidURI,
jwtToken: jwtToken,
}
}

42
controller/token.go Normal file
View File

@@ -0,0 +1,42 @@
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

@@ -89,6 +89,38 @@ 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",
@@ -115,50 +147,9 @@ const docTemplate = `{
},
"securityDefinitions": {
"ApiKeyAuth": {
"description": "Description for what is this security definition being used",
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
"BasicAuth": {
"type": "basic"
},
"OAuth2AccessCode": {
"type": "oauth2",
"flow": "accessCode",
"authorizationUrl": "https://example.com/oauth/authorize",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information"
}
},
"OAuth2Application": {
"type": "oauth2",
"flow": "application",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information",
"write": "\t\t\t\t\t\t\tGrants write access"
}
},
"OAuth2Implicit": {
"type": "oauth2",
"flow": "implicit",
"authorizationUrl": "https://example.com/oauth/authorize",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information",
"write": "\t\t\t\t\t\t\tGrants write access"
}
},
"OAuth2Password": {
"type": "oauth2",
"flow": "password",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information",
"read": "\t\t\t\t\t\t\t\tGrants read access",
"write": "\t\t\t\t\t\t\tGrants write access"
}
}
}
}`

View File

@@ -82,6 +82,38 @@
}
}
},
"/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",
@@ -108,50 +140,9 @@
},
"securityDefinitions": {
"ApiKeyAuth": {
"description": "Description for what is this security definition being used",
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
"BasicAuth": {
"type": "basic"
},
"OAuth2AccessCode": {
"type": "oauth2",
"flow": "accessCode",
"authorizationUrl": "https://example.com/oauth/authorize",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information"
}
},
"OAuth2Application": {
"type": "oauth2",
"flow": "application",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information",
"write": "\t\t\t\t\t\t\tGrants write access"
}
},
"OAuth2Implicit": {
"type": "oauth2",
"flow": "implicit",
"authorizationUrl": "https://example.com/oauth/authorize",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information",
"write": "\t\t\t\t\t\t\tGrants write access"
}
},
"OAuth2Password": {
"type": "oauth2",
"flow": "password",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"admin": "\t\t\t\t\t\t\tGrants read and write access to administrative information",
"read": "\t\t\t\t\t\t\t\tGrants read access",
"write": "\t\t\t\t\t\t\tGrants write access"
}
}
}
}

View File

@@ -55,6 +55,27 @@ 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:
@@ -72,39 +93,7 @@ paths:
- unraid
securityDefinitions:
ApiKeyAuth:
description: Description for what is this security definition being used
in: header
name: Authorization
type: apiKey
BasicAuth:
type: basic
OAuth2AccessCode:
authorizationUrl: https://example.com/oauth/authorize
flow: accessCode
scopes:
admin: "\t\t\t\t\t\t\tGrants read and write access to administrative information"
tokenUrl: https://example.com/oauth/token
type: oauth2
OAuth2Application:
flow: application
scopes:
admin: "\t\t\t\t\t\t\tGrants read and write access to administrative information"
write: "\t\t\t\t\t\t\tGrants write access"
tokenUrl: https://example.com/oauth/token
type: oauth2
OAuth2Implicit:
authorizationUrl: https://example.com/oauth/authorize
flow: implicit
scopes:
admin: "\t\t\t\t\t\t\tGrants read and write access to administrative information"
write: "\t\t\t\t\t\t\tGrants write access"
type: oauth2
OAuth2Password:
flow: password
scopes:
admin: "\t\t\t\t\t\t\tGrants read and write access to administrative information"
read: "\t\t\t\t\t\t\t\tGrants read access"
write: "\t\t\t\t\t\t\tGrants write access"
tokenUrl: https://example.com/oauth/token
type: oauth2
swagger: "2.0"

45
main.go
View File

@@ -2,9 +2,12 @@ package main
import (
"net/http"
"os"
"strings"
"github.com/DeveloperDurp/DurpAPI/controller"
_ "github.com/DeveloperDurp/DurpAPI/docs"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
@@ -25,16 +28,21 @@ import (
// @host durpapi.durp.info
// @BasePath /api/v1
// @securityDefinitions.basic BasicAuth
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
func main() {
r := gin.Default()
c := controller.NewController()
v1 := r.Group("/api/v1")
{
token := v1.Group("/token")
{
token.GET("generateTokenHandler", c.GenerateTokenHandler)
}
openai := v1.Group("/openai")
{
openai.Use(authMiddleware())
@@ -53,26 +61,33 @@ func main() {
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Get the username and password from the request header
username, password, ok := c.Request.BasicAuth()
if !ok {
c.Header("WWW-Authenticate", "Basic realm=Restricted")
c.AbortWithStatus(http.StatusUnauthorized)
// Get the authorization header from the request
authHeader := c.GetHeader("Authorization")
// Check if the authorization header is missing or doesn't start with "Bearer"
if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "Unauthorized access"})
return
}
// Check if the username and password are valid
if username != "user" || password != "password" {
c.Header("WWW-Authenticate", "Basic realm=Restricted")
c.AbortWithStatus(http.StatusUnauthorized)
// Extract the token from the authorization header
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
// Parse the token and validate its signature
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("jwtToken")), nil
})
// Check if there was an error parsing the token or if it is not valid
if err != nil || !token.Valid {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "Unauthorized access"})
return
}
// Set the user ID in the context for later use
userID := "user"
c.Set("userID", userID)
// Add the token to the request context
c.Set("token", token)
// Call the next middleware or handler function
// Call the next handler
c.Next()
}
}