| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- package controller
- import (
- "errors"
- "net/http"
- "strconv"
- "github.com/mhsanaei/3x-ui/v2/database/model"
- "github.com/mhsanaei/3x-ui/v2/logger"
- "github.com/mhsanaei/3x-ui/v2/web/entity"
- "github.com/mhsanaei/3x-ui/v2/web/service"
- "github.com/gin-gonic/gin"
- )
- type CustomGeoController struct {
- BaseController
- customGeoService *service.CustomGeoService
- }
- func NewCustomGeoController(g *gin.RouterGroup, customGeo *service.CustomGeoService) *CustomGeoController {
- a := &CustomGeoController{customGeoService: customGeo}
- a.initRouter(g)
- return a
- }
- func (a *CustomGeoController) initRouter(g *gin.RouterGroup) {
- g.GET("/list", a.list)
- g.GET("/aliases", a.aliases)
- g.POST("/add", a.add)
- g.POST("/update/:id", a.update)
- g.POST("/delete/:id", a.delete)
- g.POST("/download/:id", a.download)
- g.POST("/update-all", a.updateAll)
- }
- func mapCustomGeoErr(c *gin.Context, err error) error {
- if err == nil {
- return nil
- }
- switch {
- case errors.Is(err, service.ErrCustomGeoInvalidType):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrInvalidType"))
- case errors.Is(err, service.ErrCustomGeoAliasRequired):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrAliasRequired"))
- case errors.Is(err, service.ErrCustomGeoAliasPattern):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrAliasPattern"))
- case errors.Is(err, service.ErrCustomGeoAliasReserved):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrAliasReserved"))
- case errors.Is(err, service.ErrCustomGeoURLRequired):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrUrlRequired"))
- case errors.Is(err, service.ErrCustomGeoInvalidURL):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrInvalidUrl"))
- case errors.Is(err, service.ErrCustomGeoURLScheme):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrUrlScheme"))
- case errors.Is(err, service.ErrCustomGeoURLHost):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrUrlHost"))
- case errors.Is(err, service.ErrCustomGeoDuplicateAlias):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrDuplicateAlias"))
- case errors.Is(err, service.ErrCustomGeoNotFound):
- return errors.New(I18nWeb(c, "pages.index.customGeoErrNotFound"))
- case errors.Is(err, service.ErrCustomGeoDownload):
- logger.Warning("custom geo download:", err)
- return errors.New(I18nWeb(c, "pages.index.customGeoErrDownload"))
- case errors.Is(err, service.ErrCustomGeoSSRFBlocked):
- logger.Warning("custom geo SSRF blocked:", err)
- return errors.New(I18nWeb(c, "pages.index.customGeoErrUrlHost"))
- case errors.Is(err, service.ErrCustomGeoPathTraversal):
- logger.Warning("custom geo path traversal blocked:", err)
- return errors.New(I18nWeb(c, "pages.index.customGeoErrDownload"))
- default:
- return err
- }
- }
- func (a *CustomGeoController) list(c *gin.Context) {
- list, err := a.customGeoService.GetAll()
- if err != nil {
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastList"), mapCustomGeoErr(c, err))
- return
- }
- jsonObj(c, list, nil)
- }
- func (a *CustomGeoController) aliases(c *gin.Context) {
- out, err := a.customGeoService.GetAliasesForUI()
- if err != nil {
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoAliasesError"), mapCustomGeoErr(c, err))
- return
- }
- jsonObj(c, out, nil)
- }
- type customGeoForm struct {
- Type string `json:"type" form:"type"`
- Alias string `json:"alias" form:"alias"`
- Url string `json:"url" form:"url"`
- }
- func (a *CustomGeoController) add(c *gin.Context) {
- var form customGeoForm
- if err := c.ShouldBind(&form); err != nil {
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastAdd"), err)
- return
- }
- r := &model.CustomGeoResource{
- Type: form.Type,
- Alias: form.Alias,
- Url: form.Url,
- }
- err := a.customGeoService.Create(r)
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastAdd"), mapCustomGeoErr(c, err))
- }
- func parseCustomGeoID(c *gin.Context, idStr string) (int, bool) {
- id, err := strconv.Atoi(idStr)
- if err != nil {
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoInvalidId"), err)
- return 0, false
- }
- if id <= 0 {
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoInvalidId"), errors.New(""))
- return 0, false
- }
- return id, true
- }
- func (a *CustomGeoController) update(c *gin.Context) {
- id, ok := parseCustomGeoID(c, c.Param("id"))
- if !ok {
- return
- }
- var form customGeoForm
- if bindErr := c.ShouldBind(&form); bindErr != nil {
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastUpdate"), bindErr)
- return
- }
- r := &model.CustomGeoResource{
- Type: form.Type,
- Alias: form.Alias,
- Url: form.Url,
- }
- err := a.customGeoService.Update(id, r)
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastUpdate"), mapCustomGeoErr(c, err))
- }
- func (a *CustomGeoController) delete(c *gin.Context) {
- id, ok := parseCustomGeoID(c, c.Param("id"))
- if !ok {
- return
- }
- name, err := a.customGeoService.Delete(id)
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastDelete", "fileName=="+name), mapCustomGeoErr(c, err))
- }
- func (a *CustomGeoController) download(c *gin.Context) {
- id, ok := parseCustomGeoID(c, c.Param("id"))
- if !ok {
- return
- }
- name, err := a.customGeoService.TriggerUpdate(id)
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastDownload", "fileName=="+name), mapCustomGeoErr(c, err))
- }
- func (a *CustomGeoController) updateAll(c *gin.Context) {
- res, err := a.customGeoService.TriggerUpdateAll()
- if err != nil {
- jsonMsg(c, I18nWeb(c, "pages.index.customGeoToastUpdateAll"), mapCustomGeoErr(c, err))
- return
- }
- if len(res.Failed) > 0 {
- c.JSON(http.StatusOK, entity.Msg{
- Success: false,
- Msg: I18nWeb(c, "pages.index.customGeoErrUpdateAllIncomplete"),
- Obj: res,
- })
- return
- }
- jsonMsgObj(c, I18nWeb(c, "pages.index.customGeoToastUpdateAll"), res, nil)
- }
|