common-func.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. package locals
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "encoding/base64"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "io/ioutil"
  10. "net/http"
  11. "strings"
  12. "time"
  13. "github.com/dabory/abango-rest"
  14. e "github.com/dabory/abango-rest/etc"
  15. "github.com/go-xorm/xorm"
  16. "github.com/microcosm-cc/bluemonday"
  17. )
  18. const (
  19. // Tpf string = "dbr_" // TablePrefix
  20. //QueryComment
  21. QcWhere string = "-- @where"
  22. QcSubWhere string = "-- @subwhere"
  23. QcHaving string = "-- @having"
  24. QcOrder string = "-- @order"
  25. QcLimitOffset string = "-- @limitoffset"
  26. QcExtract string = "-- @extract:"
  27. QcClosed string = "-- @closed:"
  28. QcDelivery string = "-- @delivery:"
  29. QcBetweenDates string = "-- @between_dates"
  30. QcEnd string = "--" //QueryComment
  31. //QueryKeyword
  32. QkWhere string = "\nwhere true "
  33. // QkWhere string = "\nwhere 1 "
  34. QkHaving string = "\nhaving true "
  35. QkOrder string = "\norder by "
  36. QkLimit string = "\nlimit "
  37. QkOffset string = " offset "
  38. QkTmpOrder string = " order by is_sum desc, t_id asc "
  39. )
  40. type AppApi struct {
  41. ApiUrl string
  42. GateToken string
  43. }
  44. // 0:Sso, 1:Dbu 매우 중요하다.
  45. var gAppApis [2]AppApi
  46. var (
  47. SQL_DEBUG bool
  48. NORMAL_DEBUG bool
  49. )
  50. func (t *PageVars) ChkPageVars(chk string) {
  51. if t.Query == "" {
  52. e.ChkLog(chk, "Query is empty")
  53. }
  54. if t.Fields == "" {
  55. e.ChkLog(chk, "Fields is empty")
  56. }
  57. if t.Asc == "" {
  58. e.ChkLog(chk, "Asc is empty")
  59. }
  60. if t.Desc == "" {
  61. e.ChkLog(chk, "Desc is empty")
  62. }
  63. if t.Limit == 0 {
  64. e.ChkLog(chk, "Limit is zero")
  65. }
  66. if t.Offset == 0 {
  67. e.ChkLog(chk, "Offset is zero")
  68. }
  69. e.ChkLog(chk+", PageVars value is", *t)
  70. return
  71. }
  72. type (
  73. MemoryMap map[string]interface{}
  74. MapStore struct {
  75. store MemoryMap
  76. }
  77. )
  78. func (c *MapStore) Get(key string) interface{} {
  79. return c.store[key]
  80. }
  81. func (c *MapStore) Set(key string, val interface{}) {
  82. if c.store == nil {
  83. c.store = make(MemoryMap)
  84. }
  85. c.store[key] = val
  86. }
  87. func DbrPasswd(password string, salt string) string {
  88. salt16 := DbrSaltBase(salt, 16)
  89. var passwordBytes = []byte(password)
  90. var sha256Hasher = sha256.New()
  91. passwordBytes = append(passwordBytes, salt16...)
  92. sha256Hasher.Write(passwordBytes)
  93. var hashedPasswordBytes = sha256Hasher.Sum(nil)
  94. var base64EncodedPasswordHash = base64.URLEncoding.EncodeToString(hashedPasswordBytes)
  95. return base64EncodedPasswordHash
  96. }
  97. func DbrHashedIndex(target string) string {
  98. //!!중요: salt는 16char에서만 작동된다. hash 값은 44 char나오지만 32char로 잘라서 쓴다.
  99. fmt.Println("hash_full_length:", DbrPasswd(target, "$$hashed_index$$"))
  100. return DbrPasswd(target, "$$hashed_index$$")[0:32]
  101. }
  102. func DbrCompare(hashedPassword, currPassword string, salt string) bool {
  103. // fmt.Println("salt:", salt)
  104. // fmt.Println("currPassword:", currPassword)
  105. var currPasswordHash = DbrPasswd(currPassword, salt)
  106. // fmt.Println("currPasswordHash:", currPasswordHash)
  107. // fmt.Println("hashedPassword:", hashedPassword)
  108. return hashedPassword == currPasswordHash
  109. }
  110. func DbrSaltBase(salt string, saltSize int) []byte { //어떤 사이즈라도 16byte의 Base64로 변경
  111. tmp := []byte(salt)
  112. salt64 := base64.StdEncoding.EncodeToString(tmp)
  113. return []byte(salt64[4 : saltSize+4])
  114. }
  115. func HasPickActPage(uri string, table string) bool {
  116. if table == "member" {
  117. if uri == "/"+table+"-pick" || uri == "/"+table+"-act" || uri == "/"+table+"-page" || uri == "/"+table+"-secured-pick" || uri == "/"+table+"-secured-page" || uri == "/"+table+"-secured-act" {
  118. return true
  119. } else {
  120. return false
  121. }
  122. } else {
  123. if uri == "/"+table+"-pick" || uri == "/"+table+"-act" || uri == "/"+table+"-page" {
  124. return true
  125. } else {
  126. return false
  127. }
  128. }
  129. }
  130. // func ByteIndex(ba *[]byte, bt byte, opt int) int {
  131. // if opt == 0 { //normal
  132. // for i := 0; i < len(*ba); i++ {
  133. // if (*ba)[i] == bt {
  134. // return i
  135. // }
  136. // }
  137. // } else if opt == 1 { //rerverse
  138. // for i := len(*ba) - 1; i > 0; i-- {
  139. // if (*ba)[i] == bt {
  140. // return i
  141. // }
  142. // }
  143. // }
  144. // return -1
  145. // }
  146. func LastQry(qry xorm.Session) string {
  147. ret, _ := qry.LastSQL()
  148. fmt.Println("\n" + ret + "\n")
  149. return ret
  150. }
  151. func ShowQry(qry xorm.Session, qryName string) string {
  152. if SQL_DEBUG {
  153. ret, _ := qry.LastSQL()
  154. return e.LogStr("", "ShowQry===["+qryName+"]==="+"\n[ "+ret+" ]\n")
  155. }
  156. return ""
  157. }
  158. func ShowSql(sqlStr string, qryName string) string {
  159. if SQL_DEBUG {
  160. return e.LogStr("", "ShowSql===["+qryName+"]==="+"\n[ "+sqlStr+" ]\n")
  161. }
  162. return ""
  163. }
  164. // func ShowDebug(debugStr string, index string) string {
  165. // if NORMAL_DEBUG {
  166. // return e.LogStr("", "ShowDebug===["+index+"]==="+"\n[ "+debugStr+" ]\n")
  167. // }
  168. // return ""
  169. // }
  170. func QryDirName(qryName string) (string, string) {
  171. if !strings.Contains(qryName, "::") {
  172. return "queries/", qryName
  173. } else {
  174. q := strings.Split(qryName, "::")
  175. return "queries/themes/" + q[0] + "/", q[1]
  176. }
  177. }
  178. func StripHtml(cont string, max int) string {
  179. p := bluemonday.StripTagsPolicy()
  180. s := p.Sanitize(cont)
  181. if len(s) > max {
  182. return string([]rune(s)[:max])
  183. } else {
  184. return s
  185. }
  186. }
  187. func Sanitize(cont string) string {
  188. p := bluemonday.UGCPolicy()
  189. return p.Sanitize(cont)
  190. }
  191. func AddStrIfNotExist(s *string, target string) {
  192. if !strings.Contains(*s, target) {
  193. *s += target
  194. }
  195. }
  196. func HttpResponseSimplePost(method string, apiurl string, jsBytes []byte) (retbody []byte, retsta int, reterr error) {
  197. response, err := http.Post(apiurl, "application/json", bytes.NewBuffer(jsBytes))
  198. if err != nil {
  199. return nil, 0, errors.New(e.FuncRunErr("65rfg0csdew", "The HTTP request failed with error "+e.CurrFuncName()+err.Error()))
  200. } else {
  201. retbody, err = ioutil.ReadAll(response.Body)
  202. if err != nil {
  203. return nil, 0, errors.New(e.FuncRunErr("kjda89382", "ReadAll error "+e.CurrFuncName()+err.Error()))
  204. }
  205. }
  206. return retbody, response.StatusCode, nil
  207. }
  208. func HttpResponseWithGt(method string, apiurl string, jsBytes []byte, gateToken string) (retbody []byte, retsta int, reterr error) {
  209. reader := bytes.NewBuffer(jsBytes)
  210. req, err := http.NewRequest(method, apiurl, reader)
  211. if err != nil {
  212. return nil, 909, e.ErrLog(e.FuncRun("xcawrq3276fa-http.NewRequest "+apiurl, e.CurrFuncName()), err)
  213. }
  214. req.Header.Add("RemoteIp", "localhost")
  215. req.Header.Add("Referer", "http://localhost")
  216. req.Header.Add("GateToken", gateToken)
  217. req.Body = ioutil.NopCloser(bytes.NewReader(jsBytes))
  218. // Client객체에서 Request 실행
  219. client := &http.Client{
  220. Timeout: time.Second * 20, //Otherwirse, it can cause crash without this line. Must Must.
  221. } // Normal is 10 but extend 20 on 1 Dec 2018
  222. // fmt.Println(reflect.TypeOf(respo))
  223. resp, err := client.Do(req)
  224. if err != nil {
  225. return nil, 909, e.ErrLog(e.FuncRun("wewer2354e-client.Do "+apiurl, e.CurrFuncName()), err)
  226. }
  227. defer resp.Body.Close()
  228. byteRtn, _ := ioutil.ReadAll(resp.Body)
  229. return byteRtn, resp.StatusCode, nil
  230. }
  231. func GuestGateTokenGet(appType int, pivotUrl string, ab64 string) (string, string, error) {
  232. if gAppApis[appType].GateToken == "" {
  233. req := &struct {
  234. AppType string
  235. AppBase64 string
  236. }{
  237. AppType: "Main",
  238. AppBase64: ab64,
  239. }
  240. bodyBytes, _ := json.Marshal(req)
  241. apiUrl := pivotUrl + "/gate-token-get"
  242. msgBytes, staInt, err := HttpResponseSimplePost("POST", apiUrl, bodyBytes)
  243. fmt.Println("apiUrl:", apiUrl)
  244. fmt.Println("bodyBytes:", string(bodyBytes))
  245. if err != nil {
  246. return "", "", e.ErrLog(e.FuncRun("45425fd34sd-The HTTP request "+apiUrl, e.CurrFuncName()), err)
  247. }
  248. if staInt != 200 {
  249. return "", "", errors.New(e.FuncRun("87ty344ra3-Request Fail "+string(msgBytes), e.CurrFuncName()))
  250. }
  251. ret := &struct {
  252. ApiUrl string
  253. GateToken string
  254. }{}
  255. if err := json.Unmarshal(msgBytes, ret); err != nil {
  256. return "", "", e.ErrLog(e.FuncRun("45425fd34sd-Json Format "+apiUrl, e.CurrFuncName()), err)
  257. }
  258. gAppApis[appType].ApiUrl = ret.ApiUrl
  259. gAppApis[appType].GateToken = ret.GateToken
  260. } else {
  261. fmt.Println("GateToken already is in the ARRAY")
  262. }
  263. // fmt.Println("gSsoApiUrl:", gSsoApiUrl)
  264. // fmt.Println("gSsoGateToken:", gSsoGateToken)
  265. return gAppApis[appType].ApiUrl, gAppApis[appType].GateToken, nil
  266. }
  267. func GuestEncryptGet(code string) (string, string, error) {
  268. appType := 1 //Dbupdate
  269. req := &struct {
  270. EncryptCode string
  271. }{
  272. EncryptCode: code,
  273. }
  274. // 0:Sso, 1:Dbu
  275. pivotUrl, gateToken, err := GuestGateTokenGet(appType, abango.XConfig["DbuConnString"], abango.XConfig["DbuAppBase64"])
  276. if err != nil {
  277. return "", "", e.ErrLog(e.FuncRun("23rfsr3qrase", e.CurrFuncName()), err)
  278. }
  279. ret := &struct {
  280. EncrypteKey string
  281. SaltKey string
  282. }{}
  283. bodyBytes, _ := json.Marshal(req)
  284. apiUrl := pivotUrl + "/encrypt-get"
  285. msgBytes, staInt, err := HttpResponseWithGt("POST", apiUrl, bodyBytes, gateToken)
  286. if err != nil {
  287. return "", "", e.ErrLog(e.FuncRun("1eadwrq34dxc-The HTTP request "+apiUrl, e.CurrFuncName()), err)
  288. }
  289. if staInt != 200 {
  290. gAppApis[appType].GateToken = "" // GateToke Expired 경우 Clear 한다.
  291. return "", "", errors.New(e.FuncRun("45faw3rfw-Request Fail "+string(msgBytes), e.CurrFuncName()))
  292. }
  293. if err := json.Unmarshal(msgBytes, ret); err != nil {
  294. return "", "", e.ErrLog(e.FuncRun("6756er345r3", e.CurrFuncName()), err)
  295. }
  296. return ret.EncrypteKey, ret.SaltKey, nil
  297. }
  298. func GuestAvailDbupdateGet(lastno string, isskipup string) ([]byte, error) {
  299. appType := 1 //Dbupdate
  300. req := &struct {
  301. DbupdateNo string
  302. IsSkipUpdate string
  303. }{
  304. DbupdateNo: lastno,
  305. IsSkipUpdate: isskipup,
  306. }
  307. // 0:Sso, 1:Dbu
  308. pivotUrl, gateToken, err := GuestGateTokenGet(appType, abango.XConfig["DbuConnString"], abango.XConfig["DbuAppBase64"])
  309. if err != nil {
  310. return nil, e.ErrLog(e.FuncRun("23rfsr3qrase", e.CurrFuncName()), err)
  311. }
  312. bodyBytes, _ := json.Marshal(req)
  313. apiUrl := pivotUrl + "/avail-dbupdate-get"
  314. msgBytes, staInt, err := HttpResponseWithGt("POST", apiUrl, bodyBytes, gateToken)
  315. if err != nil {
  316. return nil, e.ErrLog(e.FuncRun("1eadwrq34dxc-The HTTP request "+apiUrl, e.CurrFuncName()), err)
  317. }
  318. if staInt != 200 {
  319. gAppApis[appType].GateToken = "" // GateToke Expired 경우 Clear 한다.
  320. return nil, errors.New(e.FuncRun("0asfweijcvs-Request Fail "+string(msgBytes), e.CurrFuncName()))
  321. }
  322. return msgBytes, nil
  323. }
  324. func GuestKeyPairGet(clientId string) (string, error) {
  325. appType := 0 //Dbupdate
  326. req := &struct {
  327. ClientId string
  328. }{
  329. ClientId: clientId,
  330. }
  331. fmt.Println("clientId:", clientId)
  332. // 0:Sso, 1:Dbu
  333. pivotUrl, gateToken, err := GuestGateTokenGet(appType, abango.XConfig["SsoConnString"], abango.XConfig["SsoAppBase64"])
  334. if err != nil {
  335. return "", e.ErrLog(e.FuncRun("23rfsr3qrase", e.CurrFuncName()), err)
  336. }
  337. ret := &struct {
  338. KeyPair string
  339. }{}
  340. bodyBytes, _ := json.Marshal(req)
  341. apiUrl := pivotUrl + "/key-pair-get"
  342. msgBytes, staInt, err := HttpResponseWithGt("POST", apiUrl, bodyBytes, gateToken)
  343. if err != nil {
  344. return "", e.ErrLog(e.FuncRun("1eadwrq34dxc-The HTTP request "+apiUrl, e.CurrFuncName()), err)
  345. }
  346. if staInt != 200 {
  347. gAppApis[appType].GateToken = "" // GateToke Expired 경우 Clear 한다.
  348. return "", errors.New(e.FuncRun("09665gsre3-Request Fail "+string(msgBytes), e.CurrFuncName()))
  349. }
  350. if err := json.Unmarshal(msgBytes, ret); err != nil {
  351. return "", e.ErrLog(e.FuncRun("9074tf32de", e.CurrFuncName()), err)
  352. }
  353. return ret.KeyPair, nil
  354. }
  355. func OneRowQuery(y *abango.Controller, sql string) (c1 string, c2 string, c3 string, err error) {
  356. page, err := y.Db.Query(sql)
  357. if err != nil {
  358. return "", "", "", errors.New(e.FuncRunErr("0hjnboisqow", e.CurrFuncName()+err.Error()))
  359. }
  360. if len(page) > 1 {
  361. return "", "", "", errors.New(e.FuncRunErr("0k1dt6j3d", e.CurrFuncName()+"Row Count > 1 "))
  362. }
  363. for _, row := range page {
  364. c1 = string(row["c1"])
  365. c2 = string(row["c2"])
  366. c3 = string(row["c3"])
  367. }
  368. return
  369. }
  370. func IsFirstOrderGet(y *abango.Controller, buyerId int) string {
  371. qry := fmt.Sprintf("select count(*) as c1 from dbr_sorder where buyer_id = %d ", buyerId)
  372. ordCnt, _, _, _ := OneRowQuery(y, qry)
  373. if ordCnt == "1" {
  374. return "1"
  375. } else {
  376. return "0"
  377. }
  378. }
  379. func TimeFormatGet(format string) string {
  380. rtn := ""
  381. if format == "" {
  382. rtn = "060102"
  383. } else if format == "YYMMDD" {
  384. rtn = "060102"
  385. } else if format == "YYYYMMDD" {
  386. rtn = "20060102"
  387. } else if format == "YY-MM-DD" {
  388. rtn = "06-01-02"
  389. } else if format == "YY.MM.DD" {
  390. rtn = "06.01.02"
  391. } else if format == "YYMM" {
  392. rtn = "0601"
  393. } else if format == "YY" {
  394. rtn = "06"
  395. }
  396. return rtn
  397. }