refactor: completely restructure validation. split request and respond structs to their own package
This commit is contained in:
parent
bfbf13a57d
commit
2f7c31d53c
|
@ -1,15 +1,11 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ed25519"
|
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"git.lumeweb.com/LumeWeb/portal/controller/request"
|
||||||
"git.lumeweb.com/LumeWeb/portal/db"
|
"git.lumeweb.com/LumeWeb/portal/db"
|
||||||
"git.lumeweb.com/LumeWeb/portal/logger"
|
"git.lumeweb.com/LumeWeb/portal/logger"
|
||||||
"git.lumeweb.com/LumeWeb/portal/model"
|
"git.lumeweb.com/LumeWeb/portal/model"
|
||||||
"github.com/go-ozzo/ozzo-validation/v4"
|
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
@ -21,34 +17,6 @@ type AccountController struct {
|
||||||
Ctx iris.Context
|
Ctx iris.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegisterRequest struct {
|
|
||||||
Email string `json:"email"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Pubkey string `json:"pubkey"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckPubkeyValidator(value interface{}) error {
|
|
||||||
p, _ := value.(string)
|
|
||||||
pubkeyBytes, err := hex.DecodeString(p)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pubkeyBytes) != ed25519.PublicKeySize {
|
|
||||||
return errors.New(fmt.Sprintf("pubkey must be %d bytes in hexadecimal format", ed25519.PublicKeySize))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r RegisterRequest) Validate() error {
|
|
||||||
return validation.ValidateStruct(&r,
|
|
||||||
validation.Field(&r.Email, validation.Required, is.EmailFormat),
|
|
||||||
validation.Field(&r.Pubkey, validation.When(len(r.Password) == 0, validation.Required, validation.By(CheckPubkeyValidator))),
|
|
||||||
validation.Field(&r.Password, validation.When(len(r.Pubkey) == 0, validation.Required)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func hashPassword(password string) (string, error) {
|
func hashPassword(password string) (string, error) {
|
||||||
// Generate a new bcrypt hash from the provided password.
|
// Generate a new bcrypt hash from the provided password.
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
|
@ -62,12 +30,13 @@ func hashPassword(password string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AccountController) PostRegister() {
|
func (a *AccountController) PostRegister() {
|
||||||
var r RegisterRequest
|
ri, success := tryParseRequest(request.RegisterRequest{}, a.Ctx)
|
||||||
|
if !success {
|
||||||
if !tryParseRequest(r, a.Ctx) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r, _ := ri.(*request.RegisterRequest)
|
||||||
|
|
||||||
// Check if an account with the same email address already exists.
|
// Check if an account with the same email address already exists.
|
||||||
existingAccount := model.Account{}
|
existingAccount := model.Account{}
|
||||||
err := db.Get().Where("email = ?", r.Email).First(&existingAccount).Error
|
err := db.Get().Where("email = ?", r.Email).First(&existingAccount).Error
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/request"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/response"
|
||||||
"git.lumeweb.com/LumeWeb/portal/db"
|
"git.lumeweb.com/LumeWeb/portal/db"
|
||||||
"git.lumeweb.com/LumeWeb/portal/logger"
|
"git.lumeweb.com/LumeWeb/portal/logger"
|
||||||
"git.lumeweb.com/LumeWeb/portal/model"
|
"git.lumeweb.com/LumeWeb/portal/model"
|
||||||
validation "github.com/go-ozzo/ozzo-validation"
|
|
||||||
"github.com/go-ozzo/ozzo-validation/v4/is"
|
|
||||||
"github.com/joomcode/errorx"
|
"github.com/joomcode/errorx"
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
"github.com/kataras/jwt"
|
"github.com/kataras/jwt"
|
||||||
|
@ -31,54 +31,6 @@ type AuthController struct {
|
||||||
Ctx iris.Context
|
Ctx iris.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginRequest struct {
|
|
||||||
Email string `json:"email"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r LoginRequest) Validate() error {
|
|
||||||
return validation.ValidateStruct(&r,
|
|
||||||
validation.Field(&r.Email, is.EmailFormat, validation.Required),
|
|
||||||
validation.Field(&r.Password, validation.Required),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoginResponse struct {
|
|
||||||
Token string `json:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type LogoutRequest struct {
|
|
||||||
Token string `json:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChallengeRequest struct {
|
|
||||||
Pubkey string `json:"pubkey"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ChallengeRequest) Validate() error {
|
|
||||||
return validation.ValidateStruct(&r,
|
|
||||||
validation.Field(&r.Pubkey, validation.Required, validation.By(CheckPubkeyValidator)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChallengeResponse struct {
|
|
||||||
Challenge string `json:"challenge"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PubkeyLoginRequest struct {
|
|
||||||
Pubkey string `json:"pubkey"`
|
|
||||||
Challenge string `json:"challenge"`
|
|
||||||
Signature string `json:"signature"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r PubkeyLoginRequest) Validate() error {
|
|
||||||
return validation.ValidateStruct(&r,
|
|
||||||
validation.Field(&r.Pubkey, validation.Required, validation.By(CheckPubkeyValidator)),
|
|
||||||
validation.Field(&r.Challenge, validation.Required),
|
|
||||||
validation.Field(&r.Signature, validation.Required, validation.Length(128, 128)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifyPassword compares the provided plaintext password with a hashed password and returns an error if they don't match.
|
// verifyPassword compares the provided plaintext password with a hashed password and returns an error if they don't match.
|
||||||
func verifyPassword(hashedPassword, password string) error {
|
func verifyPassword(hashedPassword, password string) error {
|
||||||
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
||||||
|
@ -166,12 +118,13 @@ func generateAndSaveChallengeToken(accountID uint, maxAge time.Duration) (string
|
||||||
|
|
||||||
// PostLogin handles the POST /api/auth/login request to authenticate a user and return a JWT token.
|
// PostLogin handles the POST /api/auth/login request to authenticate a user and return a JWT token.
|
||||||
func (a *AuthController) PostLogin() {
|
func (a *AuthController) PostLogin() {
|
||||||
var r LoginRequest
|
ri, success := tryParseRequest(request.LoginRequest{}, a.Ctx)
|
||||||
|
if !success {
|
||||||
if !tryParseRequest(r, a.Ctx) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r, _ := ri.(*request.LoginRequest)
|
||||||
|
|
||||||
// Retrieve the account for the given email.
|
// Retrieve the account for the given email.
|
||||||
account := model.Account{}
|
account := model.Account{}
|
||||||
if err := db.Get().Where("email = ?", r.Email).First(&account).Error; err != nil {
|
if err := db.Get().Where("email = ?", r.Email).First(&account).Error; err != nil {
|
||||||
|
@ -205,7 +158,7 @@ func (a *AuthController) PostLogin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the JWT token to the client.
|
// Return the JWT token to the client.
|
||||||
err = a.Ctx.JSON(&LoginResponse{Token: token})
|
err = a.Ctx.JSON(&response.LoginResponse{Token: token})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Get().Error("failed to generate response", zap.Error(err))
|
logger.Get().Error("failed to generate response", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
@ -213,12 +166,13 @@ func (a *AuthController) PostLogin() {
|
||||||
|
|
||||||
// PostChallenge handles the POST /api/auth/pubkey/challenge request to generate a challenge for a user's public key.
|
// PostChallenge handles the POST /api/auth/pubkey/challenge request to generate a challenge for a user's public key.
|
||||||
func (a *AuthController) PostPubkeyChallenge() {
|
func (a *AuthController) PostPubkeyChallenge() {
|
||||||
var r ChallengeRequest
|
ri, success := tryParseRequest(request.PubkeyChallengeRequest{}, a.Ctx)
|
||||||
|
if !success {
|
||||||
if !tryParseRequest(r, a.Ctx) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r, _ := (ri).(*request.PubkeyChallengeRequest)
|
||||||
|
|
||||||
r.Pubkey = strings.ToLower(r.Pubkey)
|
r.Pubkey = strings.ToLower(r.Pubkey)
|
||||||
|
|
||||||
// Retrieve the account for the given email.
|
// Retrieve the account for the given email.
|
||||||
|
@ -236,20 +190,21 @@ func (a *AuthController) PostPubkeyChallenge() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the challenge to the client.
|
// Return the challenge to the client.
|
||||||
err = a.Ctx.JSON(&ChallengeResponse{Challenge: challenge})
|
err = a.Ctx.JSON(&response.ChallengeResponse{Challenge: challenge})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("Error with challenge request: %s \n", err))
|
logger.Get().Error("failed to create response", zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostKeyLogin handles the POST /api/auth/pubkey/login request to authenticate a user using a public key challenge and return a JWT token.
|
// PostKeyLogin handles the POST /api/auth/pubkey/login request to authenticate a user using a public key challenge and return a JWT token.
|
||||||
func (a *AuthController) PostPubkeyLogin() {
|
func (a *AuthController) PostPubkeyLogin() {
|
||||||
var r PubkeyLoginRequest
|
ri, success := tryParseRequest(request.PubkeyLoginRequest{}, a.Ctx)
|
||||||
|
if !success {
|
||||||
if !tryParseRequest(r, a.Ctx) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r, _ := ri.(*request.PubkeyLoginRequest)
|
||||||
|
|
||||||
r.Pubkey = strings.ToLower(r.Pubkey)
|
r.Pubkey = strings.ToLower(r.Pubkey)
|
||||||
r.Signature = strings.ToLower(r.Signature)
|
r.Signature = strings.ToLower(r.Signature)
|
||||||
|
|
||||||
|
@ -318,7 +273,7 @@ func (a *AuthController) PostPubkeyLogin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the JWT token to the client.
|
// Return the JWT token to the client.
|
||||||
err = a.Ctx.JSON(&LoginResponse{Token: token})
|
err = a.Ctx.JSON(&response.LoginResponse{Token: token})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Get().Error("failed to create response", zap.Error(err))
|
logger.Get().Error("failed to create response", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
@ -327,12 +282,13 @@ func (a *AuthController) PostPubkeyLogin() {
|
||||||
|
|
||||||
// PostLogout handles the POST /api/auth/logout request to invalidate a JWT token.
|
// PostLogout handles the POST /api/auth/logout request to invalidate a JWT token.
|
||||||
func (a *AuthController) PostLogout() {
|
func (a *AuthController) PostLogout() {
|
||||||
var r LogoutRequest
|
ri, success := tryParseRequest(request.LogoutRequest{}, a.Ctx)
|
||||||
|
if !success {
|
||||||
if !tryParseRequest(r, a.Ctx) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r, _ := ri.(*request.LogoutRequest)
|
||||||
|
|
||||||
// Verify the provided token.
|
// Verify the provided token.
|
||||||
claims, err := jwt.Verify(jwt.HS256, sharedKey, []byte(r.Token), blocklist)
|
claims, err := jwt.Verify(jwt.HS256, sharedKey, []byte(r.Token), blocklist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/validators"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/logger"
|
||||||
|
"github.com/kataras/iris/v12"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func tryParseRequest(r interface{}, ctx iris.Context) (interface{}, bool) {
|
||||||
|
v, ok := r.(validators.Validatable)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return r, true
|
||||||
|
}
|
||||||
|
|
||||||
|
var d map[string]interface{}
|
||||||
|
|
||||||
|
// Read the logout request from the client.
|
||||||
|
if err := ctx.ReadJSON(&d); err != nil {
|
||||||
|
logger.Get().Debug("failed to parse request", zap.Error(err))
|
||||||
|
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := v.Import(d)
|
||||||
|
if err != nil {
|
||||||
|
logger.Get().Debug("failed to parse request", zap.Error(err))
|
||||||
|
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := data.Validate(); err != nil {
|
||||||
|
logger.Get().Debug("failed to parse request", zap.Error(err))
|
||||||
|
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, true
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/validators"
|
||||||
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
|
"github.com/go-ozzo/ozzo-validation/v4/is"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LoginRequest struct {
|
||||||
|
validatable validators.ValidatableImpl
|
||||||
|
Email string `json:"email"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r LoginRequest) Validate() error {
|
||||||
|
return validation.ValidateStruct(&r,
|
||||||
|
validation.Field(&r.Email, is.EmailFormat, validation.Required),
|
||||||
|
validation.Field(&r.Password, validation.Required),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (r LoginRequest) Import(d map[string]interface{}) (validators.Validatable, error) {
|
||||||
|
return r.validatable.Import(d, r)
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/validators"
|
||||||
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LogoutRequest struct {
|
||||||
|
validatable validators.ValidatableImpl
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r LogoutRequest) Validate() error {
|
||||||
|
return validation.ValidateStruct(&r, validation.Field(&r.Token, validation.Required))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r LogoutRequest) Import(d map[string]interface{}) (validators.Validatable, error) {
|
||||||
|
return r.validatable.Import(d, r)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/validators"
|
||||||
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PubkeyChallengeRequest struct {
|
||||||
|
validatable validators.ValidatableImpl
|
||||||
|
Pubkey string `json:"pubkey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r PubkeyChallengeRequest) Validate() error {
|
||||||
|
return validation.ValidateStruct(&r,
|
||||||
|
validation.Field(&r.Pubkey, validation.Required, validation.By(validators.CheckPubkeyValidator)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r PubkeyChallengeRequest) Import(d map[string]interface{}) (validators.Validatable, error) {
|
||||||
|
return r.validatable.Import(d, r)
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/validators"
|
||||||
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PubkeyLoginRequest struct {
|
||||||
|
validatable validators.ValidatableImpl
|
||||||
|
Pubkey string `json:"pubkey"`
|
||||||
|
Challenge string `json:"challenge"`
|
||||||
|
Signature string `json:"signature"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r PubkeyLoginRequest) Validate() error {
|
||||||
|
return validation.ValidateStruct(&r,
|
||||||
|
validation.Field(&r.Pubkey, validation.Required, validation.By(validators.CheckPubkeyValidator)),
|
||||||
|
validation.Field(&r.Challenge, validation.Required),
|
||||||
|
validation.Field(&r.Signature, validation.Required, validation.Length(128, 128)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r PubkeyLoginRequest) Import(d map[string]interface{}) (validators.Validatable, error) {
|
||||||
|
return r.validatable.Import(d, r)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller/validators"
|
||||||
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
|
"github.com/go-ozzo/ozzo-validation/v4/is"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RegisterRequest struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Pubkey string `json:"pubkey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RegisterRequest) Validate() error {
|
||||||
|
return validation.ValidateStruct(&r,
|
||||||
|
validation.Field(&r.Email, validation.Required, is.EmailFormat),
|
||||||
|
validation.Field(&r.Pubkey, validation.When(len(r.Password) == 0, validation.Required, validation.By(validators.CheckPubkeyValidator))),
|
||||||
|
validation.Field(&r.Password, validation.When(len(r.Pubkey) == 0, validation.Required)),
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package response
|
||||||
|
|
||||||
|
type ChallengeResponse struct {
|
||||||
|
Challenge string `json:"challenge"`
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package response
|
||||||
|
|
||||||
|
type LoginResponse struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package validators
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
|
"github.com/imdario/mergo"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckPubkeyValidator(value interface{}) error {
|
||||||
|
p, _ := value.(string)
|
||||||
|
pubkeyBytes, err := hex.DecodeString(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pubkeyBytes) != ed25519.PublicKeySize {
|
||||||
|
return errors.New(fmt.Sprintf("pubkey must be %d bytes in hexadecimal format", ed25519.PublicKeySize))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Validatable interface {
|
||||||
|
validation.Validatable
|
||||||
|
Import(d map[string]interface{}) (Validatable, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidatableImpl struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValidatableImpl) Import(d map[string]interface{}, destType Validatable) (Validatable, error) {
|
||||||
|
instance := reflect.New(reflect.TypeOf(destType)).Interface().(Validatable)
|
||||||
|
// Perform the import logic
|
||||||
|
if err := mergo.Map(instance, d, mergo.WithOverride); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance, nil
|
||||||
|
}
|
1
go.mod
1
go.mod
|
@ -55,6 +55,7 @@ require (
|
||||||
github.com/gorilla/css v1.0.0 // indirect
|
github.com/gorilla/css v1.0.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.0 // indirect
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.16 // indirect
|
||||||
github.com/iris-contrib/go.uuid v2.0.0+incompatible // indirect
|
github.com/iris-contrib/go.uuid v2.0.0+incompatible // indirect
|
||||||
github.com/iris-contrib/schema v0.0.6 // indirect
|
github.com/iris-contrib/schema v0.0.6 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -810,6 +810,8 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
|
||||||
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
|
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||||
|
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||||
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
||||||
github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE=
|
github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE=
|
||||||
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
|
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
|
||||||
|
|
15
main.go
15
main.go
|
@ -9,7 +9,6 @@ import (
|
||||||
"git.lumeweb.com/LumeWeb/portal/logger"
|
"git.lumeweb.com/LumeWeb/portal/logger"
|
||||||
"git.lumeweb.com/LumeWeb/portal/service/files"
|
"git.lumeweb.com/LumeWeb/portal/service/files"
|
||||||
"git.lumeweb.com/LumeWeb/portal/tus"
|
"git.lumeweb.com/LumeWeb/portal/tus"
|
||||||
validation "github.com/go-ozzo/ozzo-validation"
|
|
||||||
"github.com/iris-contrib/swagger"
|
"github.com/iris-contrib/swagger"
|
||||||
"github.com/iris-contrib/swagger/swaggerFiles"
|
"github.com/iris-contrib/swagger/swaggerFiles"
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
|
@ -49,8 +48,6 @@ func main() {
|
||||||
|
|
||||||
// Create a new Iris app instance
|
// Create a new Iris app instance
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
|
||||||
app.Validator = ozzValidator{}
|
|
||||||
// Enable Gzip compression for responses
|
// Enable Gzip compression for responses
|
||||||
app.Use(iris.Compression)
|
app.Use(iris.Compression)
|
||||||
|
|
||||||
|
@ -105,15 +102,3 @@ func main() {
|
||||||
logger.Get().Error("Failed starting webserver proof", zap.Error(err))
|
logger.Get().Error("Failed starting webserver proof", zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ozzValidator struct{}
|
|
||||||
|
|
||||||
func (o ozzValidator) Struct(d interface{}) error {
|
|
||||||
v, ok := d.(validation.Validatable)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.Validate()
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue