move to jwt tokens
This commit is contained in:
@@ -12,6 +12,7 @@ type Controller struct {
|
|||||||
openaiClient *openai.Client
|
openaiClient *openai.Client
|
||||||
unraidAPIKey string
|
unraidAPIKey string
|
||||||
unraidURI string
|
unraidURI string
|
||||||
|
jwtToken string
|
||||||
|
|
||||||
config *configStruct
|
config *configStruct
|
||||||
}
|
}
|
||||||
@@ -29,6 +30,7 @@ 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())
|
||||||
@@ -38,6 +40,7 @@ func NewController() *Controller {
|
|||||||
openaiClient: openaiClient,
|
openaiClient: openaiClient,
|
||||||
unraidAPIKey: unraidAPIKey,
|
unraidAPIKey: unraidAPIKey,
|
||||||
unraidURI: unraidURI,
|
unraidURI: unraidURI,
|
||||||
|
jwtToken: jwtToken,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
controller/token.go
Normal file
42
controller/token.go
Normal 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})
|
||||||
|
}
|
||||||
73
docs/docs.go
73
docs/docs.go
@@ -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": {
|
"/unraid/powerusage": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Gets the PSU Data from unraid",
|
"description": "Gets the PSU Data from unraid",
|
||||||
@@ -115,50 +147,9 @@ const docTemplate = `{
|
|||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
"ApiKeyAuth": {
|
"ApiKeyAuth": {
|
||||||
"description": "Description for what is this security definition being used",
|
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"name": "Authorization",
|
"name": "Authorization",
|
||||||
"in": "header"
|
"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"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|||||||
@@ -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": {
|
"/unraid/powerusage": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Gets the PSU Data from unraid",
|
"description": "Gets the PSU Data from unraid",
|
||||||
@@ -108,50 +140,9 @@
|
|||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
"ApiKeyAuth": {
|
"ApiKeyAuth": {
|
||||||
"description": "Description for what is this security definition being used",
|
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"name": "Authorization",
|
"name": "Authorization",
|
||||||
"in": "header"
|
"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"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,6 +55,27 @@ 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:
|
||||||
@@ -72,39 +93,7 @@ paths:
|
|||||||
- unraid
|
- unraid
|
||||||
securityDefinitions:
|
securityDefinitions:
|
||||||
ApiKeyAuth:
|
ApiKeyAuth:
|
||||||
description: Description for what is this security definition being used
|
|
||||||
in: header
|
in: header
|
||||||
name: Authorization
|
name: Authorization
|
||||||
type: apiKey
|
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"
|
swagger: "2.0"
|
||||||
|
|||||||
45
main.go
45
main.go
@@ -2,9 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/DeveloperDurp/DurpAPI/controller"
|
"github.com/DeveloperDurp/DurpAPI/controller"
|
||||||
_ "github.com/DeveloperDurp/DurpAPI/docs"
|
_ "github.com/DeveloperDurp/DurpAPI/docs"
|
||||||
|
"github.com/dgrijalva/jwt-go"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
swaggerFiles "github.com/swaggo/files"
|
swaggerFiles "github.com/swaggo/files"
|
||||||
ginSwagger "github.com/swaggo/gin-swagger"
|
ginSwagger "github.com/swaggo/gin-swagger"
|
||||||
@@ -25,16 +28,21 @@ import (
|
|||||||
// @host durpapi.durp.info
|
// @host durpapi.durp.info
|
||||||
// @BasePath /api/v1
|
// @BasePath /api/v1
|
||||||
|
|
||||||
// @securityDefinitions.basic BasicAuth
|
// @securityDefinitions.apikey ApiKeyAuth
|
||||||
|
// @in header
|
||||||
|
// @name Authorization
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
c := controller.NewController()
|
c := controller.NewController()
|
||||||
|
|
||||||
v1 := r.Group("/api/v1")
|
v1 := r.Group("/api/v1")
|
||||||
{
|
{
|
||||||
|
token := v1.Group("/token")
|
||||||
|
{
|
||||||
|
token.GET("generateTokenHandler", c.GenerateTokenHandler)
|
||||||
|
}
|
||||||
openai := v1.Group("/openai")
|
openai := v1.Group("/openai")
|
||||||
{
|
{
|
||||||
openai.Use(authMiddleware())
|
openai.Use(authMiddleware())
|
||||||
@@ -53,26 +61,33 @@ func main() {
|
|||||||
|
|
||||||
func authMiddleware() gin.HandlerFunc {
|
func authMiddleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
// Get the username and password from the request header
|
// Get the authorization header from the request
|
||||||
username, password, ok := c.Request.BasicAuth()
|
authHeader := c.GetHeader("Authorization")
|
||||||
if !ok {
|
|
||||||
c.Header("WWW-Authenticate", "Basic realm=Restricted")
|
// Check if the authorization header is missing or doesn't start with "Bearer"
|
||||||
c.AbortWithStatus(http.StatusUnauthorized)
|
if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
|
||||||
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"message": "Unauthorized access"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the username and password are valid
|
// Extract the token from the authorization header
|
||||||
if username != "user" || password != "password" {
|
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
||||||
c.Header("WWW-Authenticate", "Basic realm=Restricted")
|
|
||||||
c.AbortWithStatus(http.StatusUnauthorized)
|
// 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the user ID in the context for later use
|
// Add the token to the request context
|
||||||
userID := "user"
|
c.Set("token", token)
|
||||||
c.Set("userID", userID)
|
|
||||||
|
|
||||||
// Call the next middleware or handler function
|
// Call the next handler
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user