Initial commit
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"config": "charset=utf8mb4\u0026parseTime=True\u0026loc=Local",
|
||||
"db-name": "iris-admin",
|
||||
"log-mode": false,
|
||||
"log-zap": "error",
|
||||
"max-idle-conns": 0,
|
||||
"max-open-conns": 0,
|
||||
"password": "",
|
||||
"path": "127.0.0.1:3306",
|
||||
"username": "root"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"captcha": {
|
||||
"img-height": 80,
|
||||
"img-width": 240,
|
||||
"key-long": 4
|
||||
},
|
||||
"cors": {
|
||||
"access-credentials": "true",
|
||||
"access-expose-headers": "Content-Length,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Content-Type",
|
||||
"access-headers": "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-U-Id",
|
||||
"access-methods": "POST,GET",
|
||||
"access-origin": "*"
|
||||
},
|
||||
"except": {
|
||||
"method": "",
|
||||
"uri": ""
|
||||
},
|
||||
"file-max-size": 1024,
|
||||
"limit": {
|
||||
"burst": 5,
|
||||
"disable": true,
|
||||
"limit": 0
|
||||
},
|
||||
"menu": {
|
||||
"method": "",
|
||||
"uri": ""
|
||||
},
|
||||
"session-timeout": 60,
|
||||
"system": {
|
||||
"addr": "127.0.0.1:8085",
|
||||
"db-type": "mysql",
|
||||
"level": "debug",
|
||||
"time-format": "2006-01-02 15:04:05",
|
||||
"tls": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"director": "logs",
|
||||
"encode-level": "LowercaseColorLevelEncoder",
|
||||
"format": "console",
|
||||
"level": "debug",
|
||||
"link-name": "latest_log",
|
||||
"log-in-console": false,
|
||||
"prefix": "[IRIS-ADMIN]",
|
||||
"show-line": true,
|
||||
"stacktrace-key": "stacktrace"
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package web_iris
|
||||
|
||||
import (
|
||||
stdContext "context"
|
||||
"errors"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12/middleware/recover"
|
||||
"pet-house.com/core/helper/arr"
|
||||
"pet-house.com/core/helper/str"
|
||||
"pet-house.com/core/server/web"
|
||||
"pet-house.com/core/server/web/web_iris/middleware"
|
||||
)
|
||||
|
||||
var ErrAuthDriverEmpty = errors.New("auth driver initialize fail")
|
||||
|
||||
// WebServer
|
||||
// - app iris application
|
||||
// - idleConnsClosed
|
||||
// - addr
|
||||
// - timeFormat
|
||||
// - staticPrefix
|
||||
|
||||
type WebServer struct {
|
||||
app *iris.Application
|
||||
idleConnsClosed chan struct{}
|
||||
parties []Party
|
||||
addr string
|
||||
timeFormat string
|
||||
}
|
||||
|
||||
// Party
|
||||
// - perfix
|
||||
// - partyFunc
|
||||
type Party struct {
|
||||
Perfix string
|
||||
PartyFunc func(index iris.Party)
|
||||
}
|
||||
|
||||
func Init() *WebServer {
|
||||
app := iris.New()
|
||||
if web.CONFIG.System.Tls {
|
||||
app.Use(middleware.LoadTls())
|
||||
}
|
||||
app.Use(recover.New())
|
||||
app.Validator = validator.New()
|
||||
app.Logger().SetLevel(web.CONFIG.System.Level)
|
||||
idleConnsClosed := make(chan struct{})
|
||||
iris.RegisterOnInterrupt(func() {
|
||||
timeout := 10 * time.Second
|
||||
ctx, cancel := stdContext.WithTimeout(stdContext.Background(), timeout)
|
||||
defer cancel()
|
||||
app.Shutdown(ctx) // close all hosts
|
||||
close(idleConnsClosed)
|
||||
})
|
||||
// 自定义应用程序配置
|
||||
_ = iris.Configuration{
|
||||
DisablePathCorrection: true,
|
||||
DisableBodyConsumptionOnUnmarshal: true,
|
||||
Charset: "UTF-8",
|
||||
}
|
||||
app.Configure(iris.WithCharset("UTF-8"), iris.WithOptimizations)
|
||||
web.SetDefaultAddrAndTimeFormat()
|
||||
|
||||
return &WebServer{
|
||||
app: app,
|
||||
addr: web.CONFIG.System.Addr,
|
||||
timeFormat: web.CONFIG.System.TimeFormat,
|
||||
idleConnsClosed: idleConnsClosed,
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) GetEngine() *iris.Application {
|
||||
return ws.app
|
||||
}
|
||||
|
||||
func (ws *WebServer) AddModule(parties ...Party) {
|
||||
ws.parties = append(ws.parties, parties...)
|
||||
}
|
||||
|
||||
func (ws *WebServer) AddFrontFunc(f func(ctx *context.Context)) {
|
||||
ws.app.Use(f)
|
||||
}
|
||||
|
||||
func (ws *WebServer) AddWebStatic(staticAbsPath, webPrefix string, paths ...string) {
|
||||
webPrefixs := strings.Split(web.CONFIG.System.WebPrefix, ",")
|
||||
wp := arr.NewCheckArrayType(2)
|
||||
for _, webPrefix := range webPrefixs {
|
||||
wp.Add(webPrefix)
|
||||
}
|
||||
if wp.Check(webPrefix) {
|
||||
return
|
||||
}
|
||||
|
||||
fsOrDir := iris.Dir(staticAbsPath)
|
||||
opt := iris.DirOptions{
|
||||
IndexName: "index.html",
|
||||
SPA: true,
|
||||
}
|
||||
ws.app.HandleDir(webPrefix, fsOrDir, opt)
|
||||
web.CONFIG.System.WebPrefix = str.Join(web.CONFIG.System.WebPrefix, ",", webPrefix)
|
||||
}
|
||||
|
||||
func (ws *WebServer) AddUploadStatic(webPrefix, staticAbsPath string) {
|
||||
fsOrDir := iris.Dir(staticAbsPath)
|
||||
ws.app.HandleDir(webPrefix, fsOrDir)
|
||||
web.CONFIG.System.StaticPrefix = webPrefix
|
||||
}
|
||||
|
||||
func (ws *WebServer) Run() {
|
||||
ws.app.Listen(
|
||||
ws.addr,
|
||||
iris.WithoutInterruptHandler,
|
||||
iris.WithoutServerError(iris.ErrServerClosed),
|
||||
iris.WithOptimizations,
|
||||
iris.WithTimeFormat(ws.timeFormat),
|
||||
)
|
||||
<-ws.idleConnsClosed
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package web_iris
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"pet-house.com/core/server/database"
|
||||
"pet-house.com/core/server/web"
|
||||
"pet-house.com/core/server/zap_server"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
defer zap_server.Remove()
|
||||
defer web.Remove()
|
||||
defer database.Remove()
|
||||
web.CONFIG.System.Addr = "127.0.0.1:18085"
|
||||
go func() {
|
||||
web.Start(Init())
|
||||
}()
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
t.Run("test web run", func(t *testing.T) {
|
||||
resp, err := http.Get("http://127.0.0.1:18085/v0/version")
|
||||
if err != nil {
|
||||
t.Errorf("test web start get %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
s, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Errorf("test web start get %v", err)
|
||||
}
|
||||
if string(s) != "IRIS-ADMIN is running!!!" {
|
||||
t.Errorf("test web start want %s but get %s", "Not Found", string(s))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/iris-contrib/middleware/cors"
|
||||
"github.com/kataras/iris/v12/context"
|
||||
)
|
||||
|
||||
// CrsAuth
|
||||
func CrsAuth() context.Handler {
|
||||
return cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"*"}, // allows everything, use that to change the hosts.
|
||||
AllowedMethods: []string{"POST", "GET"},
|
||||
AllowedHeaders: []string{"*"},
|
||||
ExposedHeaders: []string{"Accept", "Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization"},
|
||||
AllowCredentials: true,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/iris-contrib/middleware/secure"
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
// LoadTls
|
||||
func LoadTls() iris.Handler {
|
||||
middleware := secure.New(secure.Options{
|
||||
SSLRedirect: true,
|
||||
SSLHost: "127.0.0.1:443",
|
||||
})
|
||||
return middleware.Handler
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package web_iris
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12/middleware/pprof"
|
||||
"github.com/kataras/iris/v12/middleware/rate"
|
||||
"github.com/kataras/iris/v12/middleware/recover"
|
||||
"pet-house.com/core/helper/arr"
|
||||
"pet-house.com/core/server/web"
|
||||
"pet-house.com/core/server/web/web_iris/middleware"
|
||||
)
|
||||
|
||||
// InitRouter
|
||||
func (ws *WebServer) InitRouter() error {
|
||||
app := ws.app.Party("/").AllowMethods(iris.MethodOptions)
|
||||
{
|
||||
app.Get("/v0/version", func(ctx iris.Context) {
|
||||
ctx.WriteString("IRIS-ADMIN is running!!!")
|
||||
})
|
||||
|
||||
app.UseRouter(middleware.CrsAuth())
|
||||
app.UseRouter(recover.New())
|
||||
if !web.CONFIG.Limit.Disable {
|
||||
limitV1 := rate.Limit(web.CONFIG.Limit.Limit, web.CONFIG.Limit.Burst, rate.PurgeEvery(time.Minute, 5*time.Minute))
|
||||
app.Use(limitV1)
|
||||
}
|
||||
if web.CONFIG.System.Level == "debug" {
|
||||
debug := func(index iris.Party) {
|
||||
index.Get("/", func(ctx iris.Context) {
|
||||
ctx.HTML("<h1>请点击<a href='/debug/pprof'>这里</a>打开调试页面")
|
||||
})
|
||||
index.Any("/pprof", pprof.New())
|
||||
index.Any("/pprof/{action:path}", pprof.New())
|
||||
}
|
||||
app.PartyFunc("/debug", debug)
|
||||
}
|
||||
|
||||
for _, party := range ws.parties {
|
||||
app.PartyFunc(party.Perfix, party.PartyFunc)
|
||||
}
|
||||
}
|
||||
|
||||
// http test must build
|
||||
if err := ws.app.Build(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSources
|
||||
// - PermRoutes
|
||||
// - NoPermRoutes
|
||||
func (ws *WebServer) GetSources() ([]map[string]string, []map[string]string) {
|
||||
methodExcepts := strings.Split(web.CONFIG.Except.Method, ";")
|
||||
uris := strings.Split(web.CONFIG.Except.Uri, ";")
|
||||
|
||||
methodMenus := strings.Split(web.CONFIG.Menu.Method, ";")
|
||||
uriMenus := strings.Split(web.CONFIG.Menu.Uri, ";")
|
||||
|
||||
routeLen := len(ws.app.GetRoutes())
|
||||
permRoutes := make([]map[string]string, 0, routeLen)
|
||||
noPermRoutes := make([]map[string]string, 0, routeLen)
|
||||
|
||||
for _, r := range ws.app.GetRoutes() {
|
||||
route := map[string]string{
|
||||
"path": r.Path,
|
||||
"name": r.Name,
|
||||
"act": r.Method,
|
||||
}
|
||||
if len(methodMenus) > 0 && len(uriMenus) > 0 && len(methodMenus) == len(uriMenus) {
|
||||
for i := 0; i < len(methodMenus); i++ {
|
||||
if strings.EqualFold(r.Method, strings.ToLower(methodMenus[i])) && strings.EqualFold(r.Path, strings.ToLower(uriMenus[i])) {
|
||||
route["is_menu"] = "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
httpStatusType := arr.NewCheckArrayType(4)
|
||||
httpStatusType.AddMutil(http.MethodGet, http.MethodPost)
|
||||
if !httpStatusType.Check(r.Method) {
|
||||
noPermRoutes = append(noPermRoutes, route)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(methodExcepts) > 0 && len(uris) > 0 && len(methodExcepts) == len(uris) {
|
||||
for i := 0; i < len(methodExcepts); i++ {
|
||||
if strings.EqualFold(r.Method, strings.ToLower(methodExcepts[i])) && strings.EqualFold(r.Path, strings.ToLower(uris[i])) {
|
||||
noPermRoutes = append(noPermRoutes, route)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
permRoutes = append(permRoutes, route)
|
||||
}
|
||||
return permRoutes, noPermRoutes
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package validate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
// ValidRequest
|
||||
func ValidRequest(err interface{}) []string {
|
||||
var errs []string
|
||||
if err == nil {
|
||||
return errs
|
||||
}
|
||||
if validateErrs, ok := err.(validator.ValidationErrors); ok {
|
||||
for _, e := range validateErrs {
|
||||
e := e
|
||||
sErr := fmt.Errorf("%s param error: %v", e.Namespace(), e.Value())
|
||||
errs = append(errs, sErr.Error())
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
Reference in New Issue
Block a user