mirror of
https://github.com/cubixle/vault.git
synced 2026-04-30 15:48:41 +01:00
expiry time functionality & request validation
This commit is contained in:
@@ -9,61 +9,54 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/gin-gonic/gin.v1"
|
"gopkg.in/gin-gonic/gin.v1"
|
||||||
|
"gopkg.in/gin-gonic/gin.v1/binding"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Item holds the data.
|
// Item holds the data.
|
||||||
type Item struct {
|
type Item struct {
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
Expiry time.Time `json:"expiryData"`
|
Expiry time.Time `json:"expiryDate"`
|
||||||
TTL int32 `json:"ttl"`
|
TTL int `json:"ttl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vault holds the vault data and key.
|
// Vault holds the vault data and key.
|
||||||
type Vault struct {
|
type Vault struct {
|
||||||
Vault string `json:"vault"`
|
Vault string `json:"vault" binding:"required"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
binding.Validator = new(DefaultValidator)
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
router.Use(CORS(os.Getenv("VAULT_APP_URL")))
|
|
||||||
|
appURL := os.Getenv("VAULT_APP_URL")
|
||||||
|
if appURL == "" {
|
||||||
|
appURL = "*"
|
||||||
|
}
|
||||||
|
|
||||||
|
router.Use(CORS(appURL))
|
||||||
|
router.Use(Logger())
|
||||||
|
|
||||||
router.POST("/", createAction)
|
router.POST("/", createAction)
|
||||||
router.POST("/decrypt", decryptAction)
|
router.POST("/decrypt", decryptAction)
|
||||||
router.Run(":7014")
|
router.Run(":7014")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CORS handles setting up the CORS security headers.
|
|
||||||
func CORS(allowOrigin string) gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
|
|
||||||
c.Writer.Header().Set("Access-Control-Max-Age", "86400")
|
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PATCH, DELETE, UPDATE")
|
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
|
|
||||||
c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
|
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
|
||||||
|
|
||||||
if c.Request.Method == "OPTIONS" {
|
|
||||||
fmt.Println("OPTIONS")
|
|
||||||
c.AbortWithStatus(200)
|
|
||||||
} else {
|
|
||||||
c.Next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func show(c *gin.Context) {
|
|
||||||
log.Println("asdasdsa")
|
|
||||||
}
|
|
||||||
|
|
||||||
func createAction(c *gin.Context) {
|
func createAction(c *gin.Context) {
|
||||||
var item Item
|
var item Item
|
||||||
c.BindJSON(&item)
|
c.BindJSON(&item)
|
||||||
|
|
||||||
|
if item.TTL > 0 {
|
||||||
|
currentTime := time.Now()
|
||||||
|
item.Expiry = currentTime.Add(-time.Duration(item.TTL) * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
key := generateUniqueID(16)
|
key := generateUniqueID(16)
|
||||||
json, _ := json.Marshal(&item)
|
json, _ := json.Marshal(&item)
|
||||||
data := encrypt([]byte(key), string(json))
|
data := encrypt([]byte(key), string(json))
|
||||||
@@ -79,7 +72,8 @@ func decryptAction(c *gin.Context) {
|
|||||||
var vault Vault
|
var vault Vault
|
||||||
err := c.BindJSON(&vault)
|
err := c.BindJSON(&vault)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := decrypt([]byte(vault.Key), vault.Vault)
|
data := decrypt([]byte(vault.Key), vault.Vault)
|
||||||
@@ -87,7 +81,16 @@ func decryptAction(c *gin.Context) {
|
|||||||
var item Item
|
var item Item
|
||||||
err = json.Unmarshal([]byte(data), &item)
|
err = json.Unmarshal([]byte(data), &item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
log.Println("tete")
|
||||||
|
log.Fatal(err)
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTime := time.Now()
|
||||||
|
if currentTime.Unix() > item.Expiry.Unix() {
|
||||||
|
c.AbortWithStatus(404)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(200, item)
|
c.JSON(200, item)
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gopkg.in/gin-gonic/gin.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CORS handles setting up the CORS security headers.
|
||||||
|
func CORS(allowOrigin string) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
|
||||||
|
c.Writer.Header().Set("Access-Control-Max-Age", "86400")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PATCH, DELETE, UPDATE")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
|
||||||
|
c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||||
|
|
||||||
|
if c.Request.Method == "OPTIONS" {
|
||||||
|
fmt.Println("OPTIONS")
|
||||||
|
c.AbortWithStatus(200)
|
||||||
|
} else {
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger handles some logging.
|
||||||
|
func Logger() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.Header("Content-Type", "application/json")
|
||||||
|
c.Next()
|
||||||
|
|
||||||
|
errors := c.Errors.ByType(gin.ErrorTypeAny)
|
||||||
|
if len(errors) > 0 {
|
||||||
|
c.JSON(-1, errors.JSON())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"gopkg.in/gin-gonic/gin.v1/binding"
|
||||||
|
"gopkg.in/go-playground/validator.v9"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultValidator override.
|
||||||
|
type DefaultValidator struct {
|
||||||
|
once sync.Once
|
||||||
|
validate *validator.Validate
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ binding.StructValidator = &DefaultValidator{}
|
||||||
|
|
||||||
|
// ValidateStruct override.
|
||||||
|
func (v *DefaultValidator) ValidateStruct(obj interface{}) error {
|
||||||
|
if kindOfData(obj) == reflect.Struct {
|
||||||
|
v.lazyinit()
|
||||||
|
|
||||||
|
if err := v.validate.Struct(obj); err != nil {
|
||||||
|
return error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *DefaultValidator) lazyinit() {
|
||||||
|
v.once.Do(func() {
|
||||||
|
v.validate = validator.New()
|
||||||
|
v.validate.SetTagName("binding")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func kindOfData(data interface{}) reflect.Kind {
|
||||||
|
|
||||||
|
value := reflect.ValueOf(data)
|
||||||
|
valueType := value.Kind()
|
||||||
|
|
||||||
|
if valueType == reflect.Ptr {
|
||||||
|
valueType = value.Elem().Kind()
|
||||||
|
}
|
||||||
|
return valueType
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user