initial commit

This commit is contained in:
Alireza Ahmadi
2024-02-13 01:17:03 +01:00
commit f40b27fd8b
136 changed files with 16023 additions and 0 deletions
+164
View File
@@ -0,0 +1,164 @@
package api
import (
"fmt"
"s-ui/logger"
"s-ui/service"
"strconv"
"strings"
"github.com/gin-gonic/gin"
)
type APIHandler struct {
service.SettingService
service.UserService
service.ConfigService
service.ClientService
service.PanelService
service.StatsService
service.ServerService
}
func NewAPIHandler(g *gin.RouterGroup) {
a := &APIHandler{}
a.initRouter(g)
}
func (a *APIHandler) initRouter(g *gin.RouterGroup) {
g.Use(func(c *gin.Context) {
if c.Request.URL.Path != "/api/login" && c.Request.URL.Path != "/api/logout" {
checkLogin(c)
}
})
g.POST("/:postAction", a.postHandler)
g.GET("/:getAction", a.getHandler)
}
func (a *APIHandler) postHandler(c *gin.Context) {
var err error
action := c.Param("postAction")
remoteIP := getRemoteIp(c)
switch action {
case "login":
loginUser, err := a.UserService.Login(c.Request.FormValue("user"), c.Request.FormValue("pass"), remoteIP)
if err != nil {
jsonMsg(c, "", err)
return
}
sessionMaxAge, err := a.SettingService.GetSessionMaxAge()
if err != nil {
logger.Infof("Unable to get session's max age from DB")
}
if sessionMaxAge > 0 {
err = SetMaxAge(c, sessionMaxAge*60)
if err != nil {
logger.Infof("Unable to set session's max age")
}
}
err = SetLoginUser(c, loginUser)
logger.Info("user ", loginUser, " login success")
jsonMsg(c, "", nil)
case "save":
loginUser := GetLoginUser(c)
data := map[string]string{}
err = c.ShouldBind(&data)
if err == nil {
err = a.ConfigService.SaveChanges(data, loginUser)
}
jsonMsg(c, "save", err)
case "restartApp":
err = a.PanelService.RestartPanel(3)
jsonMsg(c, "restartApp", err)
default:
jsonMsg(c, "API call", nil)
}
}
func (a *APIHandler) getHandler(c *gin.Context) {
action := c.Param("getAction")
switch action {
case "logout":
loginUser := GetLoginUser(c)
if loginUser != "" {
logger.Infof("user %s logout", loginUser)
}
ClearSession(c)
jsonMsg(c, "", nil)
case "load":
data, err := a.loadData(c)
if err != nil {
jsonMsg(c, "", err)
return
}
jsonObj(c, data, nil)
case "setting":
data, err := a.SettingService.GetAllSetting()
if err != nil {
jsonMsg(c, "", err)
return
}
jsonObj(c, data, err)
case "stats":
resource := c.Query("resource")
tag := c.Query("tag")
limit, err := strconv.Atoi(c.Query("limit"))
if err != nil {
limit = 100
}
data, err := a.StatsService.GetStats(resource, tag, limit)
if err != nil {
jsonMsg(c, "", err)
return
}
jsonObj(c, data, err)
case "status":
request := c.Query("r")
result := a.ServerService.GetStatus(request)
jsonObj(c, result, nil)
case "onlines":
onlines, err := a.StatsService.GetOnlines()
jsonObj(c, onlines, err)
default:
jsonMsg(c, "API call", nil)
}
}
func (a *APIHandler) loadData(c *gin.Context) (string, error) {
var data string
lu := c.Query("lu")
isUpdated, err := a.ConfigService.CheckChnages(lu)
if err != nil {
return "", err
}
onlines, err := a.StatsService.GetOnlines()
if err != nil {
return "", err
}
if isUpdated {
config, err := a.ConfigService.GetConfig()
if err != nil {
return "", err
}
clients, err := a.ClientService.GetAll()
if err != nil {
return "", err
}
subURI, err := a.SettingService.GetFinalSubURI(strings.Split(c.Request.Host, ":")[0])
if err != nil {
return "", err
}
data = fmt.Sprintf(`{"config": %s,"clients": %s,"subURI": "%s", "onlines": %s}`, string(*config), clients, subURI, onlines)
} else {
data = fmt.Sprintf(`{"onlines": %s}`, onlines)
}
return data, nil
}
+59
View File
@@ -0,0 +1,59 @@
package api
import (
"encoding/gob"
"s-ui/database/model"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
const (
loginUser = "LOGIN_USER"
)
func init() {
gob.Register(model.User{})
}
func SetLoginUser(c *gin.Context, userName string) error {
s := sessions.Default(c)
s.Set(loginUser, userName)
return s.Save()
}
func SetMaxAge(c *gin.Context, maxAge int) error {
s := sessions.Default(c)
s.Options(sessions.Options{
Path: "/",
MaxAge: maxAge,
})
return s.Save()
}
func GetLoginUser(c *gin.Context) string {
s := sessions.Default(c)
obj := s.Get(loginUser)
if obj == nil {
return ""
}
objStr, ok := obj.(string)
if !ok {
return ""
}
return objStr
}
func IsLogin(c *gin.Context) bool {
return GetLoginUser(c) != ""
}
func ClearSession(c *gin.Context) {
s := sessions.Default(c)
s.Clear()
s.Options(sessions.Options{
Path: "/",
MaxAge: -1,
})
s.Save()
}
+80
View File
@@ -0,0 +1,80 @@
package api
import (
"net"
"net/http"
"s-ui/logger"
"strings"
"github.com/gin-gonic/gin"
)
type Msg struct {
Success bool `json:"success"`
Msg string `json:"msg"`
Obj interface{} `json:"obj"`
}
func getRemoteIp(c *gin.Context) string {
value := c.GetHeader("X-Forwarded-For")
if value != "" {
ips := strings.Split(value, ",")
return ips[0]
} else {
addr := c.Request.RemoteAddr
ip, _, _ := net.SplitHostPort(addr)
return ip
}
}
func jsonMsg(c *gin.Context, msg string, err error) {
jsonMsgObj(c, msg, nil, err)
}
func jsonObj(c *gin.Context, obj interface{}, err error) {
jsonMsgObj(c, "", obj, err)
}
func jsonMsgObj(c *gin.Context, msg string, obj interface{}, err error) {
m := Msg{
Obj: obj,
}
if err == nil {
m.Success = true
if msg != "" {
m.Msg = msg
}
} else {
m.Success = false
m.Msg = msg + err.Error()
logger.Warning("failed :", err)
}
c.JSON(http.StatusOK, m)
}
func pureJsonMsg(c *gin.Context, success bool, msg string) {
if success {
c.JSON(http.StatusOK, Msg{
Success: true,
Msg: msg,
})
} else {
c.JSON(http.StatusOK, Msg{
Success: false,
Msg: msg,
})
}
}
func checkLogin(c *gin.Context) {
if !IsLogin(c) {
if c.GetHeader("X-Requested-With") == "XMLHttpRequest" {
pureJsonMsg(c, false, "Not authorized")
} else {
c.Redirect(http.StatusTemporaryRedirect, "/login")
}
c.Abort()
} else {
c.Next()
}
}