You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
8.0 KiB
341 lines
8.0 KiB
package auth |
|
|
|
import ( |
|
"bytes" |
|
"context" |
|
"fmt" |
|
"mime/multipart" |
|
"net/http" |
|
"net/url" |
|
"testing" |
|
"time" |
|
|
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
bm "go-common/library/net/http/blademaster" |
|
"go-common/library/net/metadata" |
|
"go-common/library/net/netutil/breaker" |
|
"go-common/library/net/rpc/warden" |
|
xtime "go-common/library/time" |
|
|
|
"github.com/stretchr/testify/assert" |
|
) |
|
|
|
const ( |
|
_testUID = "2231365" |
|
) |
|
|
|
type Response struct { |
|
Code int `json:"code"` |
|
Data string `json:"data"` |
|
} |
|
|
|
func init() { |
|
log.Init(&log.Config{ |
|
Stdout: true, |
|
}) |
|
} |
|
|
|
func client() *bm.Client { |
|
return bm.NewClient(&bm.ClientConfig{ |
|
App: &bm.App{ |
|
Key: "53e2fa226f5ad348", |
|
Secret: "3cf6bd1b0ff671021da5f424fea4b04a", |
|
}, |
|
Dial: xtime.Duration(time.Second), |
|
Timeout: xtime.Duration(time.Second), |
|
KeepAlive: xtime.Duration(time.Second * 10), |
|
Breaker: &breaker.Config{ |
|
Window: xtime.Duration(time.Second), |
|
Sleep: xtime.Duration(time.Millisecond * 100), |
|
Bucket: 10, |
|
Ratio: 0.5, |
|
Request: 100, |
|
}, |
|
}) |
|
} |
|
|
|
func create() *Auth { |
|
return New(&Config{ |
|
Identify: &warden.ClientConfig{}, |
|
DisableCSRF: false, |
|
}) |
|
} |
|
|
|
func engine() *bm.Engine { |
|
e := bm.NewServer(nil) |
|
authn := create() |
|
e.GET("/user", authn.User, func(ctx *bm.Context) { |
|
mid, _ := ctx.Get("mid") |
|
ctx.JSON(fmt.Sprintf("%d", mid), nil) |
|
}) |
|
e.GET("/metadata/user", authn.User, func(ctx *bm.Context) { |
|
mid := metadata.Value(ctx, metadata.Mid) |
|
ctx.JSON(fmt.Sprintf("%d", mid.(int64)), nil) |
|
}) |
|
e.GET("/mobile", authn.UserMobile, func(ctx *bm.Context) { |
|
mid, _ := ctx.Get("mid") |
|
ctx.JSON(fmt.Sprintf("%d", mid), nil) |
|
}) |
|
e.GET("/metadata/mobile", authn.UserMobile, func(ctx *bm.Context) { |
|
mid := metadata.Value(ctx, metadata.Mid) |
|
ctx.JSON(fmt.Sprintf("%d", mid.(int64)), nil) |
|
}) |
|
e.GET("/web", authn.UserWeb, func(ctx *bm.Context) { |
|
mid, _ := ctx.Get("mid") |
|
ctx.JSON(fmt.Sprintf("%d", mid), nil) |
|
}) |
|
e.GET("/guest", authn.Guest, func(ctx *bm.Context) { |
|
var ( |
|
mid int64 |
|
) |
|
if _mid, ok := ctx.Get("mid"); ok { |
|
mid, _ = _mid.(int64) |
|
} |
|
ctx.JSON(fmt.Sprintf("%d", mid), nil) |
|
}) |
|
e.GET("/guest/web", authn.GuestWeb, func(ctx *bm.Context) { |
|
var ( |
|
mid int64 |
|
) |
|
if _mid, ok := ctx.Get("mid"); ok { |
|
mid, _ = _mid.(int64) |
|
} |
|
ctx.JSON(fmt.Sprintf("%d", mid), nil) |
|
}) |
|
e.GET("/guest/mobile", authn.GuestMobile, func(ctx *bm.Context) { |
|
var ( |
|
mid int64 |
|
) |
|
if _mid, ok := ctx.Get("mid"); ok { |
|
mid, _ = _mid.(int64) |
|
} |
|
ctx.JSON(fmt.Sprintf("%d", mid), nil) |
|
}) |
|
e.POST("/guest/csrf", authn.Guest, func(ctx *bm.Context) { |
|
var ( |
|
mid int64 |
|
) |
|
if _mid, ok := ctx.Get("mid"); ok { |
|
mid, _ = _mid.(int64) |
|
} |
|
ctx.JSON(fmt.Sprintf("%d", mid), nil) |
|
}) |
|
return e |
|
} |
|
|
|
func TestFromNilConfig(t *testing.T) { |
|
New(nil) |
|
} |
|
|
|
func TestIdentifyHandler(t *testing.T) { |
|
e := engine() |
|
go e.Run(":18080") |
|
|
|
time.Sleep(time.Second) |
|
|
|
// test cases |
|
testWebUser(t, "/user") |
|
testWebUser(t, "/metadata/user") |
|
testWebUser(t, "/web") |
|
testWebUser(t, "/guest") |
|
testWebUser(t, "/guest/web") |
|
testWebUserFailed(t, "/user") |
|
testWebUserFailed(t, "/web") |
|
|
|
testMobileUser(t, "/user") |
|
testMobileUser(t, "/mobile") |
|
testMobileUser(t, "/metadata/mobile") |
|
testMobileUser(t, "/guest") |
|
testMobileUser(t, "/guest/mobile") |
|
testMobileUserFailed(t, "/user") |
|
testMobileUserFailed(t, "/mobile") |
|
|
|
testGuest(t, "/guest") |
|
testGuestCSRF(t, "/guest/csrf") |
|
testGuestCSRFFailed(t, "/guest/csrf") |
|
testMultipartCSRF(t, "/guest/csrf") |
|
|
|
if err := e.Server().Shutdown(context.TODO()); err != nil { |
|
t.Logf("Failed to shutdown bm engine: %v", err) |
|
} |
|
} |
|
|
|
func testWebUser(t *testing.T, path string) { |
|
res := Response{} |
|
query := url.Values{} |
|
cli := client() |
|
req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080/"+path, "", query) |
|
assert.NoError(t, err) |
|
|
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID", |
|
Value: _testUID, |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID__ckMd5", |
|
Value: "36976f7a5cb6e4a6", |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "SESSDATA", |
|
Value: "7bf20cf0%2C1540627371%2C8ec39f0c", |
|
}) |
|
|
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
|
|
assert.Equal(t, 0, res.Code) |
|
assert.Equal(t, _testUID, res.Data) |
|
} |
|
|
|
func testMobileUser(t *testing.T, path string) { |
|
res := Response{} |
|
query := url.Values{} |
|
query.Set("access_key", "cdbd166be6673a5a4f6fbcdd88569edf") |
|
cli := client() |
|
req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080"+path, "", query) |
|
assert.NoError(t, err) |
|
|
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
|
|
assert.Equal(t, 0, res.Code) |
|
assert.Equal(t, _testUID, res.Data) |
|
} |
|
|
|
func testWebUserFailed(t *testing.T, path string) { |
|
res := Response{} |
|
query := url.Values{} |
|
cli := client() |
|
req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080/"+path, "", query) |
|
assert.NoError(t, err) |
|
|
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID", |
|
Value: _testUID, |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID__ckMd5", |
|
Value: "53c4b106fb4462f1", |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "SESSDATA", |
|
Value: "6eeda532%2C1515837495%2C5a6baa4e", |
|
}) |
|
|
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
|
|
assert.Equal(t, ecode.NoLogin.Code(), res.Code) |
|
assert.Empty(t, res.Data) |
|
} |
|
|
|
func testMobileUserFailed(t *testing.T, path string) { |
|
res := Response{} |
|
query := url.Values{} |
|
query.Set("access_key", "5dce488c2ff8d62d7b131da40ae18729") |
|
cli := client() |
|
req, err := cli.NewRequest(http.MethodGet, "http://127.0.0.1:18080"+path, "", query) |
|
assert.NoError(t, err) |
|
|
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
|
|
assert.Equal(t, ecode.NoLogin.Code(), res.Code) |
|
assert.Empty(t, res.Data) |
|
} |
|
|
|
func testGuest(t *testing.T, path string) { |
|
res := Response{} |
|
cli := client() |
|
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:18080"+path, nil) |
|
assert.NoError(t, err) |
|
|
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
|
|
assert.Equal(t, 0, res.Code) |
|
assert.Equal(t, "0", res.Data) |
|
} |
|
|
|
func testGuestCSRF(t *testing.T, path string) { |
|
res := Response{} |
|
param := url.Values{} |
|
param.Set("csrf", "c1524bbf3aa5a1996ff7b1f29a09e796") |
|
cli := client() |
|
req, err := cli.NewRequest(http.MethodPost, "http://127.0.0.1:18080"+path, "", param) |
|
assert.NoError(t, err) |
|
|
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID", |
|
Value: _testUID, |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID__ckMd5", |
|
Value: "36976f7a5cb6e4a6", |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "SESSDATA", |
|
Value: "7bf20cf0%2C1540627371%2C8ec39f0c", |
|
}) |
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
|
|
assert.Equal(t, 0, res.Code) |
|
assert.Equal(t, _testUID, res.Data) |
|
} |
|
|
|
func testGuestCSRFFailed(t *testing.T, path string) { |
|
res := Response{} |
|
param := url.Values{} |
|
param.Set("csrf", "invalid-csrf-token") |
|
cli := client() |
|
req, err := cli.NewRequest(http.MethodPost, "http://127.0.0.1:18080"+path, "", param) |
|
assert.NoError(t, err) |
|
|
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID", |
|
Value: _testUID, |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID__ckMd5", |
|
Value: "36976f7a5cb6e4a6", |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "SESSDATA", |
|
Value: "7bf20cf0%2C1540627371%2C8ec39f0c", |
|
}) |
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
|
|
assert.Equal(t, ecode.CsrfNotMatchErr.Code(), res.Code) |
|
assert.Empty(t, res.Data) |
|
} |
|
|
|
func testMultipartCSRF(t *testing.T, path string) { |
|
res := Response{} |
|
body := &bytes.Buffer{} |
|
writer := multipart.NewWriter(body) |
|
writer.WriteField("csrf", "c1524bbf3aa5a1996ff7b1f29a09e796") |
|
writer.Close() |
|
req, err := http.NewRequest("POST", "http://127.0.0.1:18080"+path, body) |
|
assert.NoError(t, err) |
|
req.Header.Set("Content-Type", writer.FormDataContentType()) |
|
cli := client() |
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID", |
|
Value: _testUID, |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "DedeUserID__ckMd5", |
|
Value: "36976f7a5cb6e4a6", |
|
}) |
|
req.AddCookie(&http.Cookie{ |
|
Name: "SESSDATA", |
|
Value: "7bf20cf0%2C1540627371%2C8ec39f0c", |
|
}) |
|
err = cli.Do(context.TODO(), req, &res) |
|
assert.NoError(t, err) |
|
assert.Equal(t, 0, res.Code) |
|
assert.Equal(t, _testUID, res.Data) |
|
}
|
|
|