package routers import ( "bytes" "encoding/json" "errors" "io/ioutil" controllers_func "kkscrap-go/controllers/func" controllers_scraper "kkscrap-go/controllers/scraper" "kkscrap-go/locals" models_table "kkscrap-go/models/table" "github.com/dabory/abango-rest" e "github.com/dabory/abango-rest/etc" "github.com/labstack/echo" "github.com/labstack/echo/middleware" ) type Route struct { Method []string Path string Handler echo.HandlerFunc } var routes []Route func AddRoute(route Route) { routes = append(routes, route) } func RestRouterInit(ask *abango.AbangoAsk) { //main.go 에서는 XConfig 값을 받아 올수 없으므로 여기서 모든걸 세팅한다. c := echo.New() // c.Pre(middleware.BodyDump(func(c echo.Context, reqBody, resBody []byte) { c.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"*"}, // AllowOrigins: []string{"http://single.daboryhost.com", "http://fit-vac.com", AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept}, })) c.Pre(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { r := c.Request() uri := r.URL.Path var l models_table.DbtLogAccess //변수재사용을 위하여, 실제 로그 기록은 소스 맨 아래에서 AddaRow함. l.CreatedOn = e.GetNowUnix() l.FrontIp = c.RealIP() l.Url = uri l.FrontHost = r.Header.Get("FrontendHost") l.RemoteIp = r.Header.Get("RemoteIp") l.Referer = r.Header.Get("Referer") e.OkLog(".") e.OkLog("Start >> " + l.Url + " FROM (" + l.FrontIp + ") " + l.FrontHost + " <- " + l.RemoteIp) bodyBytes, err := ioutil.ReadAll(r.Body) if err == nil { // Remove when production completes e.OkLog("Requested Json: " + string(bodyBytes)) r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) // This leads ReadCloser rewinded } // 미들웨어에서 receiver 받은 것을 echo.Context 로 넘겨줌. var abg abango.Controller // var err error if uri != "/gate-token-get" { // 미리 GateToken이 있는지 확인함. abg.GateToken = r.Header.Get("GateToken") if status, msg := abg.Init(); status != 200 { return c.String(status, msg) } if err := CheckAppPerm(&abg, uri); err != nil { //SsoSubId로 들어온 App 계정체크 return c.String(508, "App Permission Denied: "+err.Error()) } } if uri == "/gate-token-get" { // gate-token-test 는 아웃풋없는 test 이므로 여기 없음. var v controllers_func.GateTokenGetReq err = json.NewDecoder(r.Body).Decode(&v) c.Set("receiver", v) } else if uri == "/gate-token-test" { var v controllers_func.GateTokenTestReq err = json.NewDecoder(r.Body).Decode(&v) c.Set("receiver", v) } else if uri == "/item-url-scrap" { var v controllers_scraper.ItemUrlScrapReq err = json.NewDecoder(r.Body).Decode(&v) c.Set("receiver", v) } else { //!!주의 긴 string이 먼저나오게 지정할 것 if locals.HasPickActPage(uri, "dummydummy") { } else { return c.String(709, e.LogStr("ewgvdafewwa", "Request Function Not Found in Middleware for "+uri)) } } if err != nil { // error 처리를 반복하지 않고 하나로 처리 return c.String(800, e.JsonFormatErr("wevzxdfarfawe", uri)+" "+err.Error()) } // if uri[len(uri)-4:] == "-act" { // var mapped map[string]interface{} // // id 번호 구함. // inxId := bytes.Index(bodyBytes, []byte("\"Id\"")) // inxIdStart := 1 + inxId + bytes.Index(bodyBytes[inxId:], []byte(":")) // inxIdEnd := inxIdStart + bytes.Index(bodyBytes[inxIdStart:], []byte(",")) // if inxIdStart > inxIdEnd { //Delete 는 { "Id": -152 } 형태이므로 , 가 없다. // inxIdEnd = inxIdStart + bytes.Index(bodyBytes[inxIdStart:], []byte("}")) // } // // fmt.Println("inxIdStart2:", inxIdStart) // // fmt.Println("inxIdEnd2", inxIdEnd) // idChar := string(bodyBytes[inxIdStart:inxIdEnd]) // if idChar[len(idChar)-1:] == "}" { //{"Id": -1541}, 다중 레코드의 경우도 처리 // idChar = idChar[:len(idChar)-1] // } // strId := strings.TrimSpace(idChar) // intId, err := strconv.Atoi(strId) // // fmt.Println("strId=", strId) // if err != nil { // Id 가 정수가 아니면 치명적에러 이다. // ** 입력,수정,삭제를 복합적으로 한번에 request하는 것은 처리 안됨. // return c.String(800, e.JsonFormatErr("0qjhoysaee", "Id value is not a integer "+err.Error())) // } // if intId > 0 { //id > 0 경우는 update인 경우만 처리한다. // inxPage := bytes.Index(bodyBytes, []byte("\"Page\"")) // inxCoreStart := inxPage + bytes.Index(bodyBytes[inxPage:], []byte("{")) // //Json 필드를 찾기 Skip 하기 위한 부분인데 만약 Json Field가 2개이상이면 For문으로 업그레이드 필요. // // 현재는 setup-act 와 eyetest-act의 경우를 처리함. // inxCoreJson := bytes.Index(bodyBytes, []byte("}\"")) //Json필드의 마지막은 이렇게 저장된다. // inxCoreEnd := 0 // if inxCoreJson <= inxCoreStart { //Json 필드 없는 경우 // inxCoreEnd = 1 + bytes.Index(bodyBytes, []byte("}")) // } else { //Json 필드 있는 경우 // inxCoreJson = 1 + inxCoreJson // inxCoreEnd = 1 + inxCoreJson + bytes.Index(bodyBytes[inxCoreJson:], []byte("}")) // } // // fmt.Println("core:", string(bodyBytes[inxCoreStart:inxCoreEnd])) // if err := json.Unmarshal(bodyBytes[inxCoreStart:inxCoreEnd], &mapped); err != nil { // return c.String(800, e.JsonFormatErr("903uous09ur", uri)) // } // update := "" // for fld := range mapped { // update += e.SnakeString(fld) + "," // } // abg.UpdateFieldList = update[0 : len(update)-1] //마지막 , 하니떼고 // // fmt.Println("UpdateFieldList:", abg.UpdateFieldList) // } // } // } // c.Set("abango", abg) // 미들웨어에서 y.Db를 접속한 후 echo.Context 로 넘겨줌. //Log 기록 _setup반영요 // if abg.GateToken != "" { //GateToken 이 있는 경우,유효 Request만 로그를 TargetDB에 쓸수가 있슴 // l.MemberId = abg.Gtb.MemberId // l.UserId = abg.Gtb.UserId // if err := l.AddaRow(&abg); err != nil { // return c.String(603, err.Error()) // } // } err1 := next(c) // fmt.Println("Pre 2번 미들웨어 종료") return err1 } }) c.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ Format: "Finish >> method=${method}, uri=${uri}, status=${status} \n", })) for _, r := range routes { c.Match(r.Method, r.Path, r.Handler) } // c.Static("/.well-known/acme-challenge", "/home/.well-known/acme-challenge") xc := abango.XConfig if xc["SslMode"] == "Yes" { e.OkLog("SSL(HTTPS) Mode Started !!") //API Server 포트가 443: "https://api.dabory.com", 40443 포트: "https://api.dabory.com" c.Logger.Fatal(c.StartTLS(xc["SslConnect"], xc["SslFullChain"], xc["SslPrivate"])) } else { e.OkLog("PLAIN(HTTP) Mode Started !!") c.Logger.Fatal(c.Start(abango.XConfig["RestConnect"])) } } func CheckAppPerm(y *abango.Controller, uri string) error { if y.Gtb.SsoSubId == 0 { return nil } var qName string //이쿼리 queries 필드에거 가져와서 진행할 수 있도록 할 것. sql := `select mx.id from pro_member_app as mx inner join pro_app_perm as prm on mx.app_perm_id = prm.id inner join pro_app_perm_bd as bdy on prm.id = bdy.app_perm_id inner join pro_app_api as api on api.id = bdy.app_api_id where mx.sso_sub_id = ? and api.api_uri = ?` // qName = "kkk" //나중에 "QueryName 찾는 로직도 넣을 것 if qName != "" { sql += " and api.query_name = '" + qName + "'" } // fmt.Println("y.Gtb.SsoSubId,", y.Gtb.SsoSubId) // fmt.Println("uri: ", uri) // fmt.Println("sql: ", sql) arr, err := y.Db.Query(sql, y.Gtb.SsoSubId, uri) if err != nil { return e.LogErr("3f0oijhbfre", "Query issue. ", err) } if len(arr) == 1 { return nil } else { return e.LogErr("34445ef34r", "App Api Record Issue ", errors.New("")) } }