|
|
@@ -5,429 +5,361 @@ import (
|
|
|
"os"
|
|
|
"testing"
|
|
|
|
|
|
+ "github.com/google/uuid"
|
|
|
"github.com/mkaminski/goaim/oscar"
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
)
|
|
|
|
|
|
-func TestReceiveAndSendAuthChallenge_OK(t *testing.T) {
|
|
|
- cfg := Config{}
|
|
|
-
|
|
|
- const testFile string = "aim_test.db"
|
|
|
- defer func() {
|
|
|
- if err := os.Remove(testFile); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- fs, err := NewFeedbagStore(testFile)
|
|
|
- if err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- newUser := User{
|
|
|
- ScreenName: "the_screen_name",
|
|
|
- AuthKey: "the_auth_key",
|
|
|
- }
|
|
|
- if err := newUser.HashPassword("the_password"); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- if err := fs.UpsertUser(newUser); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- input := &bytes.Buffer{}
|
|
|
-
|
|
|
- snacPayloadOut := oscar.SNAC_0x17_0x06_BUCPChallengeRequest{}
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVScreenName, Val: newUser.ScreenName})
|
|
|
-
|
|
|
- var seq uint32
|
|
|
- writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, snacPayloadOut, &seq, input)
|
|
|
-
|
|
|
- output := &bytes.Buffer{}
|
|
|
-
|
|
|
- if err := ReceiveAndSendAuthChallenge(cfg, fs, input, output, &seq); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- flap := oscar.FlapFrame{}
|
|
|
- if err := oscar.Unmarshal(&flap, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- snac := oscar.SnacFrame{}
|
|
|
- if err := oscar.Unmarshal(&snac, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- expectSnacFrame := oscar.SnacFrame{
|
|
|
- FoodGroup: BUCP,
|
|
|
- SubGroup: BUCPChallengeResponse,
|
|
|
- }
|
|
|
- assert.Equal(t, expectSnacFrame, snac)
|
|
|
-
|
|
|
- snacPayload := oscar.SNAC_0x17_0x07_BUCPChallengeResponse{}
|
|
|
- if err := oscar.Unmarshal(&snacPayload, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- assert.Equal(t, newUser.AuthKey, snacPayload.AuthKey)
|
|
|
-}
|
|
|
-
|
|
|
-func TestReceiveAndSendAuthChallenge_BadUser_DisableAuth(t *testing.T) {
|
|
|
- cfg := Config{
|
|
|
- DisableAuth: true,
|
|
|
- }
|
|
|
-
|
|
|
- const testFile string = "aim_test.db"
|
|
|
- defer func() {
|
|
|
- if err := os.Remove(testFile); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- fs, err := NewFeedbagStore(testFile)
|
|
|
- if err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- input := &bytes.Buffer{}
|
|
|
-
|
|
|
- snacPayloadOut := oscar.SNAC_0x17_0x06_BUCPChallengeRequest{}
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVScreenName, Val: "bad-user"})
|
|
|
-
|
|
|
- var seq uint32
|
|
|
- writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, snacPayloadOut, &seq, input)
|
|
|
-
|
|
|
- output := &bytes.Buffer{}
|
|
|
-
|
|
|
- if err := ReceiveAndSendAuthChallenge(cfg, fs, input, output, &seq); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- flap := oscar.FlapFrame{}
|
|
|
- if err := oscar.Unmarshal(&flap, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- snac := oscar.SnacFrame{}
|
|
|
- if err := oscar.Unmarshal(&snac, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- expectSnacFrame := oscar.SnacFrame{
|
|
|
- FoodGroup: BUCP,
|
|
|
- SubGroup: BUCPChallengeResponse,
|
|
|
- }
|
|
|
- assert.Equal(t, expectSnacFrame, snac)
|
|
|
-
|
|
|
- snacPayload := oscar.SNAC_0x17_0x07_BUCPChallengeResponse{}
|
|
|
- if err := oscar.Unmarshal(&snacPayload, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- assert.NotEmpty(t, snacPayload.AuthKey)
|
|
|
-}
|
|
|
-
|
|
|
-func TestReceiveAndSendAuthChallenge_BadUser_EnableAuth(t *testing.T) {
|
|
|
- cfg := Config{}
|
|
|
-
|
|
|
- const testFile string = "aim_test.db"
|
|
|
- defer func() {
|
|
|
- if err := os.Remove(testFile); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- fs, err := NewFeedbagStore(testFile)
|
|
|
- if err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- input := &bytes.Buffer{}
|
|
|
-
|
|
|
- snacPayloadOut := oscar.SNAC_0x17_0x06_BUCPChallengeRequest{}
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVScreenName, Val: "bad-user"})
|
|
|
-
|
|
|
- var seq uint32
|
|
|
- writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, snacPayloadOut, &seq, input)
|
|
|
-
|
|
|
- output := &bytes.Buffer{}
|
|
|
-
|
|
|
- if err := ReceiveAndSendAuthChallenge(cfg, fs, input, output, &seq); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- flap := oscar.FlapFrame{}
|
|
|
- if err := oscar.Unmarshal(&flap, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- snac := oscar.SnacFrame{}
|
|
|
- if err := oscar.Unmarshal(&snac, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- expectSnacFrame := oscar.SnacFrame{
|
|
|
- FoodGroup: BUCP,
|
|
|
- SubGroup: BUCPLoginResponse,
|
|
|
- }
|
|
|
- assert.Equal(t, expectSnacFrame, snac)
|
|
|
-
|
|
|
- snacPayload := oscar.SNAC_0x17_0x03_BUCPLoginResponse{}
|
|
|
- if err := oscar.Unmarshal(&snacPayload, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- _, hasError := snacPayload.GetTLV(TLVErrorSubcode)
|
|
|
- assert.True(t, hasError)
|
|
|
-}
|
|
|
-
|
|
|
-func TestReceiveAndSendBUCPLoginRequest_OK(t *testing.T) {
|
|
|
- cfg := Config{}
|
|
|
- sm := NewSessionManager()
|
|
|
-
|
|
|
- const testFile string = "aim_test.db"
|
|
|
- defer func() {
|
|
|
- if err := os.Remove(testFile); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- fs, err := NewFeedbagStore(testFile)
|
|
|
- if err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- newUser := User{
|
|
|
- ScreenName: "the_screen_name",
|
|
|
- AuthKey: "the_auth_key",
|
|
|
- }
|
|
|
- if err := newUser.HashPassword("the_password"); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- if err := fs.UpsertUser(newUser); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- input := &bytes.Buffer{}
|
|
|
-
|
|
|
- snacPayloadOut := oscar.SNAC_0x17_0x02_BUCPLoginRequest{}
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVPasswordHash, Val: newUser.PassHash})
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVScreenName, Val: newUser.ScreenName})
|
|
|
-
|
|
|
- var seq uint32
|
|
|
- writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, snacPayloadOut, &seq, input)
|
|
|
-
|
|
|
- output := &bytes.Buffer{}
|
|
|
-
|
|
|
- if err := ReceiveAndSendBUCPLoginRequest(cfg, sm, fs, input, output, &seq); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
+func TestReceiveAndSendBUCPLoginRequest(t *testing.T) {
|
|
|
+ userGoodPwd := User{
|
|
|
+ ScreenName: "sn_user_a",
|
|
|
+ AuthKey: "auth_key_user",
|
|
|
+ }
|
|
|
+ assert.NoError(t, userGoodPwd.HashPassword("good_pwd"))
|
|
|
+ userBadPwd := userGoodPwd
|
|
|
+ assert.NoError(t, userBadPwd.HashPassword("bad_pwd"))
|
|
|
+
|
|
|
+ cases := []struct {
|
|
|
+ name string
|
|
|
+ cfg Config
|
|
|
+ userInDB User
|
|
|
+ sessionUUID uuid.UUID
|
|
|
+ inputSNAC oscar.SNAC_0x17_0x02_BUCPLoginRequest
|
|
|
+ expectSnacFrame oscar.SnacFrame
|
|
|
+ expectSNACBody oscar.SNAC_0x17_0x03_BUCPLoginResponse
|
|
|
+ }{
|
|
|
+ {
|
|
|
+ name: "login with valid password, expect OK login response",
|
|
|
+ cfg: Config{
|
|
|
+ OSCARHost: "127.0.0.1",
|
|
|
+ BOSPort: 1234,
|
|
|
+ },
|
|
|
+ userInDB: userGoodPwd,
|
|
|
+ sessionUUID: uuid.UUID{1, 2, 3},
|
|
|
+ inputSNAC: oscar.SNAC_0x17_0x02_BUCPLoginRequest{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVPasswordHash, Val: userGoodPwd.PassHash,
|
|
|
+ },
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVScreenName, Val: userGoodPwd.ScreenName,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ expectSnacFrame: oscar.SnacFrame{
|
|
|
+ FoodGroup: BUCP,
|
|
|
+ SubGroup: BUCPLoginResponse,
|
|
|
+ },
|
|
|
+ expectSNACBody: oscar.SNAC_0x17_0x03_BUCPLoginResponse{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ {
|
|
|
+ TType: oscar.TLVScreenName,
|
|
|
+ Val: userGoodPwd.ScreenName,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ TType: oscar.TLVReconnectHere,
|
|
|
+ Val: "127.0.0.1:1234",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ TType: oscar.TLVAuthorizationCookie,
|
|
|
+ Val: uuid.UUID{1, 2, 3}.String(),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "login with bad password, expect OK login response (cfg.DisableAuth=true)",
|
|
|
+ cfg: Config{
|
|
|
+ OSCARHost: "127.0.0.1",
|
|
|
+ BOSPort: 1234,
|
|
|
+ DisableAuth: true,
|
|
|
+ },
|
|
|
+ userInDB: userGoodPwd,
|
|
|
+ sessionUUID: uuid.UUID{1, 2, 3},
|
|
|
+ inputSNAC: oscar.SNAC_0x17_0x02_BUCPLoginRequest{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVPasswordHash, Val: userBadPwd.PassHash,
|
|
|
+ },
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVScreenName, Val: userBadPwd.ScreenName,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ expectSnacFrame: oscar.SnacFrame{
|
|
|
+ FoodGroup: BUCP,
|
|
|
+ SubGroup: BUCPLoginResponse,
|
|
|
+ },
|
|
|
+ expectSNACBody: oscar.SNAC_0x17_0x03_BUCPLoginResponse{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ {
|
|
|
+ TType: oscar.TLVScreenName,
|
|
|
+ Val: userBadPwd.ScreenName,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ TType: oscar.TLVReconnectHere,
|
|
|
+ Val: "127.0.0.1:1234",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ TType: oscar.TLVAuthorizationCookie,
|
|
|
+ Val: uuid.UUID{1, 2, 3}.String(),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "login with bad password, expect failed login response (cfg.DisableAuth=false)",
|
|
|
+ cfg: Config{
|
|
|
+ OSCARHost: "127.0.0.1",
|
|
|
+ BOSPort: 1234,
|
|
|
+ },
|
|
|
+ userInDB: userGoodPwd,
|
|
|
+ sessionUUID: uuid.UUID{1, 2, 3},
|
|
|
+ inputSNAC: oscar.SNAC_0x17_0x02_BUCPLoginRequest{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVPasswordHash, Val: userBadPwd.PassHash,
|
|
|
+ },
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVScreenName, Val: userBadPwd.ScreenName,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ expectSnacFrame: oscar.SnacFrame{
|
|
|
+ FoodGroup: BUCP,
|
|
|
+ SubGroup: BUCPLoginResponse,
|
|
|
+ },
|
|
|
+ expectSNACBody: oscar.SNAC_0x17_0x03_BUCPLoginResponse{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ {
|
|
|
+ TType: oscar.TLVScreenName,
|
|
|
+ Val: userBadPwd.ScreenName,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ TType: oscar.TLVErrorSubcode,
|
|
|
+ Val: uint16(0x01),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, tc := range cases {
|
|
|
+ t.Run(tc.name, func(t *testing.T) {
|
|
|
+ //
|
|
|
+ // initialize dependencies
|
|
|
+ //
|
|
|
+ const testFile string = "aim_test.db"
|
|
|
+ defer func() {
|
|
|
+ assert.NoError(t, os.Remove(testFile))
|
|
|
+ }()
|
|
|
+ fs, err := NewFeedbagStore(testFile)
|
|
|
+ if err != nil {
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ assert.NoError(t, fs.InsertUser(tc.userInDB))
|
|
|
+ sm := NewSessionManager()
|
|
|
+ //
|
|
|
+ // send input SNAC
|
|
|
+ //
|
|
|
+ input := &bytes.Buffer{}
|
|
|
+ var seq uint32
|
|
|
+ assert.NoError(t, writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, tc.inputSNAC, &seq, input))
|
|
|
+ //
|
|
|
+ // receive response
|
|
|
+ //
|
|
|
+ output := &bytes.Buffer{}
|
|
|
+ fnNewUUID := func() uuid.UUID {
|
|
|
+ return tc.sessionUUID
|
|
|
+ }
|
|
|
+ assert.NoError(t, ReceiveAndSendBUCPLoginRequest(tc.cfg, sm, fs, input, output, &seq, fnNewUUID))
|
|
|
+ flap := oscar.FlapFrame{}
|
|
|
+ assert.NoError(t, oscar.Unmarshal(&flap, output))
|
|
|
+ //
|
|
|
+ // verify output SNAC frame
|
|
|
+ //
|
|
|
+ SnacFrame := oscar.SnacFrame{}
|
|
|
+ assert.NoError(t, oscar.Unmarshal(&SnacFrame, output))
|
|
|
+ assert.Equal(t, tc.expectSnacFrame, SnacFrame)
|
|
|
+ //
|
|
|
+ // verify output SNAC body
|
|
|
+ //
|
|
|
+ assert.NoError(t, tc.expectSNACBody.SerializeInPlace())
|
|
|
+ actual := oscar.SNAC_0x17_0x03_BUCPLoginResponse{}
|
|
|
+ assert.NoError(t, oscar.Unmarshal(&actual, output))
|
|
|
+ assert.Equal(t, tc.expectSNACBody, actual)
|
|
|
+ })
|
|
|
}
|
|
|
-
|
|
|
- flap := oscar.FlapFrame{}
|
|
|
- if err := oscar.Unmarshal(&flap, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- snac := oscar.SnacFrame{}
|
|
|
- if err := oscar.Unmarshal(&snac, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- expectSnacFrame := oscar.SnacFrame{
|
|
|
- FoodGroup: BUCP,
|
|
|
- SubGroup: BUCPLoginResponse,
|
|
|
- }
|
|
|
- assert.Equal(t, expectSnacFrame, snac)
|
|
|
-
|
|
|
- snacPayload := oscar.SNAC_0x17_0x03_BUCPLoginResponse{}
|
|
|
- if err := oscar.Unmarshal(&snacPayload, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- _, hasError := snacPayload.GetTLV(TLVErrorSubcode)
|
|
|
- assert.False(t, hasError)
|
|
|
-}
|
|
|
-
|
|
|
-func TestReceiveAndSendBUCPLoginRequest_BadUser_EnableAuth(t *testing.T) {
|
|
|
- cfg := Config{}
|
|
|
- sm := NewSessionManager()
|
|
|
-
|
|
|
- const testFile string = "aim_test.db"
|
|
|
- defer func() {
|
|
|
- if err := os.Remove(testFile); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- fs, err := NewFeedbagStore(testFile)
|
|
|
- if err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- newUser := User{
|
|
|
- ScreenName: "the_screen_name",
|
|
|
- AuthKey: "the_auth_key",
|
|
|
- }
|
|
|
- if err := newUser.HashPassword("the_password"); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- if err := fs.UpsertUser(newUser); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- input := &bytes.Buffer{}
|
|
|
-
|
|
|
- snacPayloadOut := oscar.SNAC_0x17_0x02_BUCPLoginRequest{}
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVPasswordHash, Val: newUser.PassHash})
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVScreenName, Val: "bad-screen-name"})
|
|
|
-
|
|
|
- var seq uint32
|
|
|
- writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, snacPayloadOut, &seq, input)
|
|
|
-
|
|
|
- output := &bytes.Buffer{}
|
|
|
-
|
|
|
- if err := ReceiveAndSendBUCPLoginRequest(cfg, sm, fs, input, output, &seq); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- flap := oscar.FlapFrame{}
|
|
|
- if err := oscar.Unmarshal(&flap, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- snac := oscar.SnacFrame{}
|
|
|
- if err := oscar.Unmarshal(&snac, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- expectSnacFrame := oscar.SnacFrame{
|
|
|
- FoodGroup: BUCP,
|
|
|
- SubGroup: BUCPLoginResponse,
|
|
|
- }
|
|
|
- assert.Equal(t, expectSnacFrame, snac)
|
|
|
-
|
|
|
- snacPayload := oscar.SNAC_0x17_0x02_BUCPLoginRequest{}
|
|
|
- if err := oscar.Unmarshal(&snacPayload, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- _, hasError := snacPayload.GetTLV(TLVErrorSubcode)
|
|
|
- assert.True(t, hasError)
|
|
|
-}
|
|
|
-
|
|
|
-func TestReceiveAndSendBUCPLoginRequest_BadUser_DisableAuth(t *testing.T) {
|
|
|
- cfg := Config{
|
|
|
- DisableAuth: true,
|
|
|
- }
|
|
|
- sm := NewSessionManager()
|
|
|
-
|
|
|
- const testFile string = "aim_test.db"
|
|
|
- defer func() {
|
|
|
- if err := os.Remove(testFile); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- fs, err := NewFeedbagStore(testFile)
|
|
|
- if err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- newUser := User{
|
|
|
- ScreenName: "the_screen_name",
|
|
|
- AuthKey: "the_auth_key",
|
|
|
- }
|
|
|
- if err := newUser.HashPassword("the_password"); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- if err := fs.UpsertUser(newUser); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- input := &bytes.Buffer{}
|
|
|
-
|
|
|
- snacPayloadOut := oscar.SNAC_0x17_0x02_BUCPLoginRequest{}
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVPasswordHash, Val: newUser.PassHash})
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVScreenName, Val: "bad-screen-name"})
|
|
|
-
|
|
|
- var seq uint32
|
|
|
- writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, snacPayloadOut, &seq, input)
|
|
|
-
|
|
|
- output := &bytes.Buffer{}
|
|
|
-
|
|
|
- if err := ReceiveAndSendBUCPLoginRequest(cfg, sm, fs, input, output, &seq); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- flap := oscar.FlapFrame{}
|
|
|
- if err := oscar.Unmarshal(&flap, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- snac := oscar.SnacFrame{}
|
|
|
- if err := oscar.Unmarshal(&snac, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- expectSnacFrame := oscar.SnacFrame{
|
|
|
- FoodGroup: BUCP,
|
|
|
- SubGroup: BUCPLoginResponse,
|
|
|
- }
|
|
|
- assert.Equal(t, expectSnacFrame, snac)
|
|
|
-
|
|
|
- snacPayload := oscar.SNAC_0x17_0x02_BUCPLoginRequest{}
|
|
|
- if err := oscar.Unmarshal(&snacPayload, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- _, hasError := snacPayload.GetTLV(TLVErrorSubcode)
|
|
|
- assert.False(t, hasError)
|
|
|
}
|
|
|
|
|
|
-func TestReceiveAndSendBUCPLoginRequest_BadPassword(t *testing.T) {
|
|
|
- cfg := Config{}
|
|
|
- sm := NewSessionManager()
|
|
|
-
|
|
|
- const testFile string = "aim_test.db"
|
|
|
- defer func() {
|
|
|
- if err := os.Remove(testFile); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- fs, err := NewFeedbagStore(testFile)
|
|
|
- if err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- newUser := User{
|
|
|
- ScreenName: "the_screen_name",
|
|
|
- AuthKey: "the_auth_key",
|
|
|
- }
|
|
|
- if err := newUser.HashPassword("the_password"); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- if err := fs.UpsertUser(newUser); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- input := &bytes.Buffer{}
|
|
|
-
|
|
|
- snacPayloadOut := oscar.SNAC_0x17_0x02_BUCPLoginRequest{}
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVPasswordHash, Val: []byte("bad_password")})
|
|
|
- snacPayloadOut.AddTLV(oscar.TLV{TType: TLVScreenName, Val: newUser.ScreenName})
|
|
|
-
|
|
|
- var seq uint32
|
|
|
- writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, snacPayloadOut, &seq, input)
|
|
|
-
|
|
|
- output := &bytes.Buffer{}
|
|
|
-
|
|
|
- if err := ReceiveAndSendBUCPLoginRequest(cfg, sm, fs, input, output, &seq); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- flap := oscar.FlapFrame{}
|
|
|
- if err := oscar.Unmarshal(&flap, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
-
|
|
|
- snac := oscar.SnacFrame{}
|
|
|
- if err := oscar.Unmarshal(&snac, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
- }
|
|
|
- expectSnacFrame := oscar.SnacFrame{
|
|
|
- FoodGroup: BUCP,
|
|
|
- SubGroup: BUCPLoginResponse,
|
|
|
- }
|
|
|
- assert.Equal(t, expectSnacFrame, snac)
|
|
|
-
|
|
|
- snacPayload := oscar.SNAC_0x17_0x02_BUCPLoginRequest{}
|
|
|
- if err := oscar.Unmarshal(&snacPayload, output); err != nil {
|
|
|
- assert.NoError(t, err)
|
|
|
+func TestReceiveAndSendAuthChallenge(t *testing.T) {
|
|
|
+ cases := []struct {
|
|
|
+ name string
|
|
|
+ cfg Config
|
|
|
+ userInDB User
|
|
|
+ fnNewUUID uuid.UUID
|
|
|
+ inputSNAC oscar.SNAC_0x17_0x06_BUCPChallengeRequest
|
|
|
+ expectSnacFrame oscar.SnacFrame
|
|
|
+ expectSNACBody any
|
|
|
+ }{
|
|
|
+ {
|
|
|
+ name: "login with valid username, expect OK login response",
|
|
|
+ cfg: Config{
|
|
|
+ OSCARHost: "127.0.0.1",
|
|
|
+ BOSPort: 1234,
|
|
|
+ },
|
|
|
+ userInDB: User{
|
|
|
+ ScreenName: "sn_user_a",
|
|
|
+ AuthKey: "auth_key_user_a",
|
|
|
+ },
|
|
|
+ fnNewUUID: uuid.UUID{1, 2, 3},
|
|
|
+ inputSNAC: oscar.SNAC_0x17_0x06_BUCPChallengeRequest{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVScreenName, Val: "sn_user_a",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ expectSnacFrame: oscar.SnacFrame{
|
|
|
+ FoodGroup: BUCP,
|
|
|
+ SubGroup: BUCPChallengeResponse,
|
|
|
+ },
|
|
|
+ expectSNACBody: oscar.SNAC_0x17_0x07_BUCPChallengeResponse{
|
|
|
+ AuthKey: "auth_key_user_a",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "login with invalid username, expect OK login response (cfg.DisableAuth=true)",
|
|
|
+ cfg: Config{
|
|
|
+ OSCARHost: "127.0.0.1",
|
|
|
+ BOSPort: 1234,
|
|
|
+ DisableAuth: true,
|
|
|
+ },
|
|
|
+ userInDB: User{
|
|
|
+ ScreenName: "sn_user_a",
|
|
|
+ AuthKey: "auth_key_user_a",
|
|
|
+ },
|
|
|
+ fnNewUUID: uuid.UUID{1, 2, 3},
|
|
|
+ inputSNAC: oscar.SNAC_0x17_0x06_BUCPChallengeRequest{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVScreenName, Val: "sn_user_b",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ expectSnacFrame: oscar.SnacFrame{
|
|
|
+ FoodGroup: BUCP,
|
|
|
+ SubGroup: BUCPChallengeResponse,
|
|
|
+ },
|
|
|
+ expectSNACBody: oscar.SNAC_0x17_0x07_BUCPChallengeResponse{
|
|
|
+ AuthKey: uuid.UUID{1, 2, 3}.String(),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "login with invalid username, expect failed login response (cfg.DisableAuth=false)",
|
|
|
+ cfg: Config{
|
|
|
+ OSCARHost: "127.0.0.1",
|
|
|
+ BOSPort: 1234,
|
|
|
+ },
|
|
|
+ userInDB: User{
|
|
|
+ ScreenName: "sn_user_a",
|
|
|
+ AuthKey: "auth_key_user_a",
|
|
|
+ },
|
|
|
+ fnNewUUID: uuid.UUID{1, 2, 3},
|
|
|
+ inputSNAC: oscar.SNAC_0x17_0x06_BUCPChallengeRequest{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ oscar.TLV{
|
|
|
+ TType: oscar.TLVScreenName, Val: "sn_user_b",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ expectSnacFrame: oscar.SnacFrame{
|
|
|
+ FoodGroup: BUCP,
|
|
|
+ SubGroup: BUCPLoginResponse,
|
|
|
+ },
|
|
|
+ expectSNACBody: oscar.SNAC_0x17_0x03_BUCPLoginResponse{
|
|
|
+ TLVRestBlock: oscar.TLVRestBlock{
|
|
|
+ TLVList: oscar.TLVList{
|
|
|
+ {
|
|
|
+ TType: oscar.TLVErrorSubcode,
|
|
|
+ Val: uint16(0x01),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, tc := range cases {
|
|
|
+ t.Run(tc.name, func(t *testing.T) {
|
|
|
+ //
|
|
|
+ // initialize dependencies
|
|
|
+ //
|
|
|
+ const testFile string = "aim_test.db"
|
|
|
+ defer func() {
|
|
|
+ assert.NoError(t, os.Remove(testFile))
|
|
|
+ }()
|
|
|
+ fs, err := NewFeedbagStore(testFile)
|
|
|
+ if err != nil {
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ assert.NoError(t, fs.InsertUser(tc.userInDB))
|
|
|
+ //
|
|
|
+ // send input SNAC
|
|
|
+ //
|
|
|
+ input := &bytes.Buffer{}
|
|
|
+ var seq uint32
|
|
|
+ assert.NoError(t, writeOutSNAC(oscar.SnacFrame{}, oscar.SnacFrame{}, tc.inputSNAC, &seq, input))
|
|
|
+ //
|
|
|
+ // receive response
|
|
|
+ //
|
|
|
+ output := &bytes.Buffer{}
|
|
|
+ fnNewUUID := func() uuid.UUID {
|
|
|
+ return tc.fnNewUUID
|
|
|
+ }
|
|
|
+ assert.NoError(t, ReceiveAndSendAuthChallenge(tc.cfg, fs, input, output, &seq, fnNewUUID))
|
|
|
+ flap := oscar.FlapFrame{}
|
|
|
+ assert.NoError(t, oscar.Unmarshal(&flap, output))
|
|
|
+ //
|
|
|
+ // verify output SNAC frame
|
|
|
+ //
|
|
|
+ SnacFrame := oscar.SnacFrame{}
|
|
|
+ assert.NoError(t, oscar.Unmarshal(&SnacFrame, output))
|
|
|
+ assert.Equal(t, tc.expectSnacFrame, SnacFrame)
|
|
|
+ //
|
|
|
+ // verify output SNAC body
|
|
|
+ //
|
|
|
+ switch v := tc.expectSNACBody.(type) {
|
|
|
+ case oscar.SNAC_0x17_0x07_BUCPChallengeResponse:
|
|
|
+ actual := oscar.SNAC_0x17_0x07_BUCPChallengeResponse{}
|
|
|
+ assert.NoError(t, oscar.Unmarshal(&actual, output))
|
|
|
+ assert.Equal(t, v, actual)
|
|
|
+ case oscar.SNAC_0x17_0x03_BUCPLoginResponse:
|
|
|
+ assert.NoError(t, v.SerializeInPlace())
|
|
|
+ actual := oscar.SNAC_0x17_0x03_BUCPLoginResponse{}
|
|
|
+ assert.NoError(t, oscar.Unmarshal(&actual, output))
|
|
|
+ assert.Equal(t, v, actual)
|
|
|
+ default:
|
|
|
+ t.Fatalf("unexpected output SNAC type")
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
- _, hasError := snacPayload.GetTLV(TLVErrorSubcode)
|
|
|
- assert.True(t, hasError)
|
|
|
}
|