auth_test.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. package auth
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "mime/multipart"
  7. "net/http"
  8. "net/url"
  9. "testing"
  10. "time"
  11. "go-common/library/ecode"
  12. "go-common/library/log"
  13. bm "go-common/library/net/http/blademaster"
  14. "go-common/library/net/metadata"
  15. "go-common/library/net/netutil/breaker"
  16. "go-common/library/net/rpc/warden"
  17. xtime "go-common/library/time"
  18. "github.com/stretchr/testify/assert"
  19. )
  20. const (
  21. _testUID = "2231365"
  22. )
  23. type Response struct {
  24. Code int `json:"code"`
  25. Data string `json:"data"`
  26. }
  27. func init() {
  28. log.Init(&log.Config{
  29. Stdout: true,
  30. })
  31. }
  32. func client() *bm.Client {
  33. return bm.NewClient(&bm.ClientConfig{
  34. App: &bm.App{
  35. Key: "53e2fa226f5ad348",
  36. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  37. },
  38. Dial: xtime.Duration(time.Second),
  39. Timeout: xtime.Duration(time.Second),
  40. KeepAlive: xtime.Duration(time.Second * 10),
  41. Breaker: &breaker.Config{
  42. Window: xtime.Duration(time.Second),
  43. Sleep: xtime.Duration(time.Millisecond * 100),
  44. Bucket: 10,
  45. Ratio: 0.5,
  46. Request: 100,
  47. },
  48. })
  49. }
  50. func create() *Auth {
  51. return New(&Config{
  52. Identify: &warden.ClientConfig{},
  53. DisableCSRF: false,
  54. })
  55. }
  56. func engine() *bm.Engine {
  57. e := bm.NewServer(nil)
  58. authn := create()
  59. e.GET("/user", authn.User, func(ctx *bm.Context) {
  60. mid, _ := ctx.Get("mid")
  61. ctx.JSON(fmt.Sprintf("%d", mid), nil)
  62. })
  63. e.GET("/metadata/user", authn.User, func(ctx *bm.Context) {
  64. mid := metadata.Value(ctx, metadata.Mid)
  65. ctx.JSON(fmt.Sprintf("%d", mid.(int64)), nil)
  66. })
  67. e.GET("/mobile", authn.UserMobile, func(ctx *bm.Context) {
  68. mid, _ := ctx.Get("mid")
  69. ctx.JSON(fmt.Sprintf("%d", mid), nil)
  70. })
  71. e.GET("/metadata/mobile", authn.UserMobile, func(ctx *bm.Context) {
  72. mid := metadata.Value(ctx, metadata.Mid)
  73. ctx.JSON(fmt.Sprintf("%d", mid.(int64)), nil)
  74. })
  75. e.GET("/web", authn.UserWeb, func(ctx *bm.Context) {
  76. mid, _ := ctx.Get("mid")
  77. ctx.JSON(fmt.Sprintf("%d", mid), nil)
  78. })
  79. e.GET("/guest", authn.Guest, func(ctx *bm.Context) {
  80. var (
  81. mid int64
  82. )
  83. if _mid, ok := ctx.Get("mid"); ok {
  84. mid, _ = _mid.(int64)
  85. }
  86. ctx.JSON(fmt.Sprintf("%d", mid), nil)
  87. })
  88. e.GET("/guest/web", authn.GuestWeb, func(ctx *bm.Context) {
  89. var (
  90. mid int64
  91. )
  92. if _mid, ok := ctx.Get("mid"); ok {
  93. mid, _ = _mid.(int64)
  94. }
  95. ctx.JSON(fmt.Sprintf("%d", mid), nil)
  96. })
  97. e.GET("/guest/mobile", authn.GuestMobile, func(ctx *bm.Context) {
  98. var (
  99. mid int64
  100. )
  101. if _mid, ok := ctx.Get("mid"); ok {
  102. mid, _ = _mid.(int64)
  103. }
  104. ctx.JSON(fmt.Sprintf("%d", mid), nil)
  105. })
  106. e.POST("/guest/csrf", authn.Guest, func(ctx *bm.Context) {
  107. var (
  108. mid int64
  109. )
  110. if _mid, ok := ctx.Get("mid"); ok {
  111. mid, _ = _mid.(int64)
  112. }
  113. ctx.JSON(fmt.Sprintf("%d", mid), nil)
  114. })
  115. return e
  116. }
  117. func TestFromNilConfig(t *testing.T) {
  118. New(nil)
  119. }
  120. func TestIdentifyHandler(t *testing.T) {
  121. e := engine()
  122. go e.Run(":18080")
  123. time.Sleep(time.Second)
  124. // test cases
  125. testWebUser(t, "/user")
  126. testWebUser(t, "/metadata/user")
  127. testWebUser(t, "/web")
  128. testWebUser(t, "/guest")
  129. testWebUser(t, "/guest/web")
  130. testWebUserFailed(t, "/user")
  131. testWebUserFailed(t, "/web")
  132. testMobileUser(t, "/user")
  133. testMobileUser(t, "/mobile")
  134. testMobileUser(t, "/metadata/mobile")
  135. testMobileUser(t, "/guest")
  136. testMobileUser(t, "/guest/mobile")
  137. testMobileUserFailed(t, "/user")
  138. testMobileUserFailed(t, "/mobile")
  139. testGuest(t, "/guest")
  140. testGuestCSRF(t, "/guest/csrf")
  141. testGuestCSRFFailed(t, "/guest/csrf")
  142. testMultipartCSRF(t, "/guest/csrf")
  143. if err := e.Server().Shutdown(context.TODO()); err != nil {
  144. t.Logf("Failed to shutdown bm engine: %v", err)
  145. }
  146. }
  147. func testWebUser(t *testing.T, path string) {
  148. res := Response{}
  149. query := url.Values{}
  150. cli := client()
  151. req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080/"+path, "", query)
  152. assert.NoError(t, err)
  153. req.AddCookie(&http.Cookie{
  154. Name: "DedeUserID",
  155. Value: _testUID,
  156. })
  157. req.AddCookie(&http.Cookie{
  158. Name: "DedeUserID__ckMd5",
  159. Value: "36976f7a5cb6e4a6",
  160. })
  161. req.AddCookie(&http.Cookie{
  162. Name: "SESSDATA",
  163. Value: "7bf20cf0%2C1540627371%2C8ec39f0c",
  164. })
  165. err = cli.Do(context.TODO(), req, &res)
  166. assert.NoError(t, err)
  167. assert.Equal(t, 0, res.Code)
  168. assert.Equal(t, _testUID, res.Data)
  169. }
  170. func testMobileUser(t *testing.T, path string) {
  171. res := Response{}
  172. query := url.Values{}
  173. query.Set("access_key", "cdbd166be6673a5a4f6fbcdd88569edf")
  174. cli := client()
  175. req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080"+path, "", query)
  176. assert.NoError(t, err)
  177. err = cli.Do(context.TODO(), req, &res)
  178. assert.NoError(t, err)
  179. assert.Equal(t, 0, res.Code)
  180. assert.Equal(t, _testUID, res.Data)
  181. }
  182. func testWebUserFailed(t *testing.T, path string) {
  183. res := Response{}
  184. query := url.Values{}
  185. cli := client()
  186. req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080/"+path, "", query)
  187. assert.NoError(t, err)
  188. req.AddCookie(&http.Cookie{
  189. Name: "DedeUserID",
  190. Value: _testUID,
  191. })
  192. req.AddCookie(&http.Cookie{
  193. Name: "DedeUserID__ckMd5",
  194. Value: "53c4b106fb4462f1",
  195. })
  196. req.AddCookie(&http.Cookie{
  197. Name: "SESSDATA",
  198. Value: "6eeda532%2C1515837495%2C5a6baa4e",
  199. })
  200. err = cli.Do(context.TODO(), req, &res)
  201. assert.NoError(t, err)
  202. assert.Equal(t, ecode.NoLogin.Code(), res.Code)
  203. assert.Empty(t, res.Data)
  204. }
  205. func testMobileUserFailed(t *testing.T, path string) {
  206. res := Response{}
  207. query := url.Values{}
  208. query.Set("access_key", "5dce488c2ff8d62d7b131da40ae18729")
  209. cli := client()
  210. req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080"+path, "", query)
  211. assert.NoError(t, err)
  212. err = cli.Do(context.TODO(), req, &res)
  213. assert.NoError(t, err)
  214. assert.Equal(t, ecode.NoLogin.Code(), res.Code)
  215. assert.Empty(t, res.Data)
  216. }
  217. func testGuest(t *testing.T, path string) {
  218. res := Response{}
  219. cli := client()
  220. req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:18080"+path, nil)
  221. assert.NoError(t, err)
  222. err = cli.Do(context.TODO(), req, &res)
  223. assert.NoError(t, err)
  224. assert.Equal(t, 0, res.Code)
  225. assert.Equal(t, "0", res.Data)
  226. }
  227. func testGuestCSRF(t *testing.T, path string) {
  228. res := Response{}
  229. param := url.Values{}
  230. param.Set("csrf", "c1524bbf3aa5a1996ff7b1f29a09e796")
  231. cli := client()
  232. req, err := cli.NewRequest(http.MethodPost, "http://127.0.0.1:18080"+path, "", param)
  233. assert.NoError(t, err)
  234. req.AddCookie(&http.Cookie{
  235. Name: "DedeUserID",
  236. Value: _testUID,
  237. })
  238. req.AddCookie(&http.Cookie{
  239. Name: "DedeUserID__ckMd5",
  240. Value: "36976f7a5cb6e4a6",
  241. })
  242. req.AddCookie(&http.Cookie{
  243. Name: "SESSDATA",
  244. Value: "7bf20cf0%2C1540627371%2C8ec39f0c",
  245. })
  246. err = cli.Do(context.TODO(), req, &res)
  247. assert.NoError(t, err)
  248. assert.Equal(t, 0, res.Code)
  249. assert.Equal(t, _testUID, res.Data)
  250. }
  251. func testGuestCSRFFailed(t *testing.T, path string) {
  252. res := Response{}
  253. param := url.Values{}
  254. param.Set("csrf", "invalid-csrf-token")
  255. cli := client()
  256. req, err := cli.NewRequest(http.MethodPost, "http://127.0.0.1:18080"+path, "", param)
  257. assert.NoError(t, err)
  258. req.AddCookie(&http.Cookie{
  259. Name: "DedeUserID",
  260. Value: _testUID,
  261. })
  262. req.AddCookie(&http.Cookie{
  263. Name: "DedeUserID__ckMd5",
  264. Value: "36976f7a5cb6e4a6",
  265. })
  266. req.AddCookie(&http.Cookie{
  267. Name: "SESSDATA",
  268. Value: "7bf20cf0%2C1540627371%2C8ec39f0c",
  269. })
  270. err = cli.Do(context.TODO(), req, &res)
  271. assert.NoError(t, err)
  272. assert.Equal(t, ecode.CsrfNotMatchErr.Code(), res.Code)
  273. assert.Empty(t, res.Data)
  274. }
  275. func testMultipartCSRF(t *testing.T, path string) {
  276. res := Response{}
  277. body := &bytes.Buffer{}
  278. writer := multipart.NewWriter(body)
  279. writer.WriteField("csrf", "c1524bbf3aa5a1996ff7b1f29a09e796")
  280. writer.Close()
  281. req, err := http.NewRequest("POST", "http://127.0.0.1:18080"+path, body)
  282. assert.NoError(t, err)
  283. req.Header.Set("Content-Type", writer.FormDataContentType())
  284. cli := client()
  285. req.AddCookie(&http.Cookie{
  286. Name: "DedeUserID",
  287. Value: _testUID,
  288. })
  289. req.AddCookie(&http.Cookie{
  290. Name: "DedeUserID__ckMd5",
  291. Value: "36976f7a5cb6e4a6",
  292. })
  293. req.AddCookie(&http.Cookie{
  294. Name: "SESSDATA",
  295. Value: "7bf20cf0%2C1540627371%2C8ec39f0c",
  296. })
  297. err = cli.Do(context.TODO(), req, &res)
  298. assert.NoError(t, err)
  299. assert.Equal(t, 0, res.Code)
  300. assert.Equal(t, _testUID, res.Data)
  301. }