From e217539ed13135e6682414108fce8a73cbce74ba Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 10 Jun 2024 22:27:50 -0400 Subject: [PATCH] add support for user-defined screen name formatting This commit introduces two distinct screen name data types: - IdentScreenName: A normalized version of the screen name used as a unique identifier. This is stored in the database and used for login validation, ensuring that users can log in regardless of the format they use. - DisplayScreenName: Maintains the user-defined formatting, including case and spaces, allowing for personalized display. Additionally, a database migration is included, which adds a new field identScreenName, for storing the IdentScreenName. The screenName field is renamed to displayScreenName, which stores the value of DisplayScreenName. These changes allow users to register and log in with any screen name format, as long as the normalized version matches the identifier stored in the database. From the API perspective, users continue to have the "screen_name" field, which is the display screen name. --- README.md | 8 +- foodgroup/auth.go | 37 ++- foodgroup/auth_test.go | 187 ++++++----- foodgroup/bart_test.go | 4 +- foodgroup/buddy.go | 24 +- foodgroup/buddy_test.go | 82 ++--- foodgroup/chat.go | 4 +- foodgroup/chat_nav.go | 2 +- foodgroup/chat_nav_test.go | 3 +- foodgroup/feedbag.go | 24 +- foodgroup/feedbag_test.go | 143 ++++----- foodgroup/icbm.go | 26 +- foodgroup/icbm_test.go | 51 ++- foodgroup/locate.go | 10 +- foodgroup/locate_test.go | 44 +-- foodgroup/mock_chat_message_relayer_test.go | 32 +- foodgroup/mock_feedbag_manager_test.go | 118 +++---- .../mock_legacy_buddy_list_manager_test.go | 75 ++--- foodgroup/mock_message_relayer_test.go | 32 +- foodgroup/mock_profile_manager_test.go | 33 +- foodgroup/mock_session_manager_test.go | 34 +- foodgroup/mock_user_manager_manager_test.go | 16 +- foodgroup/oservice.go | 10 +- foodgroup/oservice_test.go | 66 ++-- foodgroup/test_helpers.go | 74 ++--- foodgroup/types.go | 40 +-- server/http/mgmt_api.go | 92 +++--- server/http/mgmt_api_test.go | 78 +++-- server/http/mock_user_manager_test.go | 28 +- server/oscar/auth.go | 6 +- server/oscar/bos.go | 7 +- server/oscar/bos_test.go | 2 +- server/oscar/chat.go | 2 +- server/oscar/connection_test.go | 2 +- server/oscar/middleware/logger.go | 2 +- server/oscar/mock_auth_test.go | 76 ++--- state/buddy_list_store.go | 20 +- state/buddy_list_store_test.go | 87 +++--- .../0003_formatted_screen_name.down.sql | 16 + .../0003_formatted_screen_name.up.sql | 27 ++ state/session.go | 59 ++-- state/session_manager.go | 38 +-- state/session_manager_test.go | 95 +++--- state/session_test.go | 11 +- state/user.go | 122 ++++++++ state/user_store.go | 191 ++++-------- state/user_store_test.go | 290 +++++++++++++----- 47 files changed, 1373 insertions(+), 1057 deletions(-) create mode 100644 state/migrations/0003_formatted_screen_name.down.sql create mode 100644 state/migrations/0003_formatted_screen_name.up.sql create mode 100644 state/user.go diff --git a/README.md b/README.md index 9dfccf01..e1f879b4 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Invoke-WebRequest -Uri http://localhost:8080/user -Method Get ```powershell Invoke-WebRequest -Uri http://localhost:8080/user ` - -Body '{"screen_name":"myscreenname", "password":"thepassword"}' ` + -Body '{"screen_name":"MyScreenName", "password":"thepassword"}' ` -Method Post ` -ContentType "application/json" ``` @@ -83,7 +83,7 @@ Invoke-WebRequest -Uri http://localhost:8080/user ` ```powershell Invoke-WebRequest -Uri http://localhost:8080/user/password ` - -Body '{"screen_name":"myscreenname", "password":"thenewpassword"}' ` + -Body '{"screen_name":"MyScreenName", "password":"thenewpassword"}' ` -Method Put ` -ContentType "application/json" ``` @@ -107,7 +107,7 @@ curl http://localhost:8080/user #### Create Users ```shell -curl -d'{"screen_name":"myscreenname", "password":"thepassword"}' http://localhost:8080/user +curl -d'{"screen_name":"MyScreenName", "password":"thepassword"}' http://localhost:8080/user ``` #### Delete Users @@ -119,7 +119,7 @@ curl -X DELETE -d '{"screen_name": "user123"}' http://localhost:8080/user #### Change Password ```shell -curl -X PUT -d'{"screen_name":"myscreenname", "password":"thenewpassword"}' http://localhost:8080/user/password +curl -X PUT -d'{"screen_name":"MyScreenName", "password":"thenewpassword"}' http://localhost:8080/user/password ``` #### List Active Sessions diff --git a/foodgroup/auth.go b/foodgroup/auth.go index a910edf5..cbffb855 100644 --- a/foodgroup/auth.go +++ b/foodgroup/auth.go @@ -58,14 +58,28 @@ func (s AuthService) RegisterChatSession(loginCookie []byte) (*state.Session, er if err != nil { return nil, err } - chatSess := chatSessMgr.(SessionManager).AddSession(c.ScreenName) + u, err := s.userManager.User(state.NewIdentScreenName(c.ScreenName)) + if err != nil { + return nil, fmt.Errorf("failed to retrieve user: %w", err) + } + if u == nil { + return nil, fmt.Errorf("user not found") + } + chatSess := chatSessMgr.(SessionManager).AddSession(u.DisplayScreenName) chatSess.SetChatRoomCookie(room.Cookie) return chatSess, nil } // RegisterBOSSession creates and returns a user's session. -func (s AuthService) RegisterBOSSession(sessionID string) (*state.Session, error) { - return s.sessionManager.AddSession(sessionID), nil +func (s AuthService) RegisterBOSSession(screenName state.IdentScreenName) (*state.Session, error) { + u, err := s.userManager.User(screenName) + if err != nil { + return nil, fmt.Errorf("failed to retrieve user: %w", err) + } + if u == nil { + return nil, fmt.Errorf("user not found") + } + return s.sessionManager.AddSession(u.DisplayScreenName), nil } // Signout removes this user's session and notifies users who have this user on @@ -75,7 +89,7 @@ func (s AuthService) Signout(ctx context.Context, sess *state.Session) error { return err } s.sessionManager.RemoveSession(sess) - s.legacyBuddyListManager.DeleteUser(sess.ScreenName()) + s.legacyBuddyListManager.DeleteUser(sess.IdentScreenName()) return nil } @@ -113,7 +127,7 @@ func (s AuthService) BUCPChallenge( var authKey string - user, err := s.userManager.User(screenName) + user, err := s.userManager.User(state.NewIdentScreenName(screenName)) if err != nil { return wire.SNACMessage{}, err } @@ -163,10 +177,7 @@ func (s AuthService) BUCPChallenge( // (wire.LoginTLVTagsReconnectHere) and an authorization cookie // (wire.LoginTLVTagsAuthorizationCookie). Else, an error code is set // (wire.LoginTLVTagsErrorSubcode). -func (s AuthService) BUCPLogin( - bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, - newUserFn func(screenName string) (state.User, error), -) (wire.SNACMessage, error) { +func (s AuthService) BUCPLogin(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, newUserFn func(screenName state.DisplayScreenName) (state.User, error)) (wire.SNACMessage, error) { block, err := s.login(bodyIn.TLVList, newUserFn) if err != nil { @@ -194,7 +205,7 @@ func (s AuthService) BUCPLogin( // (wire.LoginTLVTagsReconnectHere) and an authorization cookie // (wire.LoginTLVTagsAuthorizationCookie). Else, an error code is set // (wire.LoginTLVTagsErrorSubcode). -func (s AuthService) FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func(screenName string) (state.User, error)) (wire.TLVRestBlock, error) { +func (s AuthService) FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func(screenName state.DisplayScreenName) (state.User, error)) (wire.TLVRestBlock, error) { return s.login(frame.TLVList, newUserFn) } @@ -202,7 +213,7 @@ func (s AuthService) FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func(screen // metadata used in both BUCP and FLAP authentication responses. func (s AuthService) login( TLVList wire.TLVList, - newUserFn func(screenName string) (state.User, error), + newUserFn func(screenName state.DisplayScreenName) (state.User, error), ) (wire.TLVRestBlock, error) { screenName, found := TLVList.String(wire.LoginTLVTagsScreenName) @@ -210,7 +221,7 @@ func (s AuthService) login( return wire.TLVRestBlock{}, errors.New("screen name doesn't exist in tlv") } - user, err := s.userManager.User(screenName) + user, err := s.userManager.User(state.NewIdentScreenName(screenName)) if err != nil { return wire.TLVRestBlock{}, err } @@ -230,7 +241,7 @@ func (s AuthService) login( if !loginOK { // make login succeed anyway. create new user if the account // doesn't already exist. - newUser, err := newUserFn(screenName) + newUser, err := newUserFn(state.DisplayScreenName(screenName)) if err != nil { return wire.TLVRestBlock{}, err } diff --git a/foodgroup/auth_test.go b/foodgroup/auth_test.go index 4fed1f42..e6ca8379 100644 --- a/foodgroup/auth_test.go +++ b/foodgroup/auth_test.go @@ -16,8 +16,8 @@ import ( func TestAuthService_BUCPLoginRequest(t *testing.T) { user := state.User{ - ScreenName: "screen_name", - AuthKey: "auth_key", + IdentScreenName: state.NewIdentScreenName("screen_name"), + AuthKey: "auth_key", } assert.NoError(t, user.HashPassword("the_password")) @@ -32,7 +32,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { // method's dependencies mockParams mockParams // newUserFn is the function that registers a new user account - newUserFn func(screenName string) (state.User, error) + newUserFn func(screenName state.DisplayScreenName) (state.User, error) // expectOutput is the SNAC sent from the server to client expectOutput wire.SNACMessage // wantErr is the error we expect from the method @@ -48,7 +48,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, user.StrongMD5Pass), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -56,14 +56,14 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, @@ -76,7 +76,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { Body: wire.SNAC_0x17_0x03_BUCPLoginResponse{ TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -95,7 +95,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, user.StrongMD5Pass), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -103,7 +103,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: nil, }, }, @@ -115,12 +115,12 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, expectOutput: wire.SNACMessage{ @@ -131,7 +131,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { Body: wire.SNAC_0x17_0x03_BUCPLoginResponse{ TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -150,7 +150,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-password-hash")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -158,7 +158,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, @@ -170,12 +170,12 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, expectOutput: wire.SNACMessage{ @@ -186,7 +186,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { Body: wire.SNAC_0x17_0x03_BUCPLoginResponse{ TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -205,7 +205,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-password-hash")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -213,7 +213,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, @@ -226,12 +226,12 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, expectOutput: wire.SNACMessage{ @@ -242,7 +242,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { Body: wire.SNAC_0x17_0x03_BUCPLoginResponse{ TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -259,7 +259,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-password-hash")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -267,13 +267,13 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, io.EOF }, wantErr: io.EOF, @@ -287,7 +287,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-password-hash")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -295,7 +295,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, @@ -307,7 +307,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, wantErr: io.EOF, @@ -322,7 +322,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad_password")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -330,7 +330,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: nil, }, }, @@ -344,7 +344,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { Body: wire.SNAC_0x17_0x03_BUCPLoginResponse{ TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsErrorSubcode, uint16(0x01)), }, }, @@ -357,7 +357,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, user.StrongMD5Pass), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -365,7 +365,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, err: io.EOF, }, }, @@ -411,8 +411,8 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) { func TestAuthService_FLAPLoginResponse(t *testing.T) { user := state.User{ - ScreenName: "screen_name", - AuthKey: "auth_key", + IdentScreenName: state.NewIdentScreenName("screen_name"), + AuthKey: "auth_key", } assert.NoError(t, user.HashPassword("the_password")) @@ -430,7 +430,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { // method's dependencies mockParams mockParams // newUserFn is the function that registers a new user account - newUserFn func(screenName string) (state.User, error) + newUserFn func(screenName state.DisplayScreenName) (state.User, error) // expectOutput is the response sent from the server to client expectOutput wire.TLVRestBlock // wantErr is the error we expect from the method @@ -446,7 +446,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsRoastedPassword, roastedPassword), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -454,21 +454,21 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, }, expectOutput: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -485,7 +485,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsRoastedPassword, roastedPassword), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -493,7 +493,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: nil, }, }, @@ -505,17 +505,17 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, expectOutput: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -532,7 +532,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-roasted-password")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -540,7 +540,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, @@ -552,17 +552,17 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, expectOutput: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -579,7 +579,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-roasted-password")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -587,7 +587,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, @@ -600,17 +600,17 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { }, cookieIssuerParams: cookieIssuerParams{ { - data: []byte(user.ScreenName), + data: []byte(user.IdentScreenName.String()), cookie: []byte("the-cookie"), }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, expectOutput: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsReconnectHere, "127.0.0.1:1234"), wire.NewTLV(wire.LoginTLVTagsAuthorizationCookie, []byte("the-cookie")), }, @@ -625,7 +625,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-roasted-password")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -633,13 +633,13 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, io.EOF }, wantErr: io.EOF, @@ -653,7 +653,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-roasted-password")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -661,7 +661,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: &user, }, }, @@ -673,7 +673,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { }, }, }, - newUserFn: func(screenName string) (state.User, error) { + newUserFn: func(screenName state.DisplayScreenName) (state.User, error) { return user, nil }, wantErr: io.EOF, @@ -688,7 +688,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, []byte("bad-roasted-password")), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -696,7 +696,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, result: nil, }, }, @@ -704,7 +704,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { }, expectOutput: wire.TLVRestBlock{ TLVList: wire.TLVList{ - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), wire.NewTLV(wire.LoginTLVTagsErrorSubcode, uint16(0x01)), }, }, @@ -715,7 +715,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { TLVRestBlock: wire.TLVRestBlock{ TLVList: wire.TLVList{ wire.NewTLV(wire.LoginTLVTagsPasswordHash, user.StrongMD5Pass), - wire.NewTLV(wire.LoginTLVTagsScreenName, user.ScreenName), + wire.NewTLV(wire.LoginTLVTagsScreenName, user.IdentScreenName), }, }, }, @@ -723,7 +723,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: user.ScreenName, + screenName: user.IdentScreenName, err: io.EOF, }, }, @@ -800,10 +800,10 @@ func TestAuthService_BUCPChallengeRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: "sn_user_a", + screenName: state.NewIdentScreenName("sn_user_a"), result: &state.User{ - ScreenName: "sn_user_a", - AuthKey: "auth_key_user_a", + IdentScreenName: state.NewIdentScreenName("sn_user_a"), + AuthKey: "auth_key_user_a", }, }, }, @@ -837,7 +837,7 @@ func TestAuthService_BUCPChallengeRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: "sn_user_b", + screenName: state.NewIdentScreenName("sn_user_b"), result: nil, }, }, @@ -870,7 +870,7 @@ func TestAuthService_BUCPChallengeRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: "sn_user_b", + screenName: state.NewIdentScreenName("sn_user_b"), result: nil, }, }, @@ -903,7 +903,7 @@ func TestAuthService_BUCPChallengeRequest(t *testing.T) { userManagerParams: userManagerParams{ getUserParams: getUserParams{ { - screenName: "sn_user_b", + screenName: state.NewIdentScreenName("sn_user_b"), err: io.EOF, }, }, @@ -941,16 +941,23 @@ func TestAuthService_RegisterChatSession_HappyPath(t *testing.T) { c := chatLoginCookie{ ChatCookie: cookie, - ScreenName: sess.ScreenName(), + ScreenName: sess.IdentScreenName().String(), } buf := &bytes.Buffer{} assert.NoError(t, wire.Marshal(c, buf)) sessionManager := newMockSessionManager(t) sessionManager.EXPECT(). - AddSession(sess.ScreenName()). + AddSession(sess.DisplayScreenName()). Return(sess) + userManager := newMockUserManager(t) + userManager.EXPECT(). + User(sess.IdentScreenName()). + Return(&state.User{ + DisplayScreenName: sess.DisplayScreenName(), + }, nil) + chatRegistry := newMockChatRegistry(t) chatRegistry.EXPECT(). Retrieve(cookie). @@ -958,7 +965,7 @@ func TestAuthService_RegisterChatSession_HappyPath(t *testing.T) { cookieIssuer := newMockCookieIssuer(t) - svc := NewAuthService(config.Config{}, nil, nil, chatRegistry, nil, cookieIssuer, nil) + svc := NewAuthService(config.Config{}, nil, userManager, chatRegistry, nil, cookieIssuer, nil) have, err := svc.RegisterChatSession(buf.Bytes()) assert.NoError(t, err) @@ -971,7 +978,7 @@ func TestAuthService_RegisterBOSSession_ChatNotFound(t *testing.T) { c := chatLoginCookie{ ChatCookie: cookie, - ScreenName: sess.ScreenName(), + ScreenName: sess.IdentScreenName().String(), } loginCookie := &bytes.Buffer{} assert.NoError(t, wire.Marshal(c, loginCookie)) @@ -993,14 +1000,19 @@ func TestAuthService_RegisterBOSSession_HappyPath(t *testing.T) { sessionManager := newMockSessionManager(t) sessionManager.EXPECT(). - AddSession(sess.ScreenName()). + AddSession(sess.DisplayScreenName()). Return(sess) cookieIssuer := newMockCookieIssuer(t) - svc := NewAuthService(config.Config{}, sessionManager, nil, nil, nil, cookieIssuer, nil) + userManager := newMockUserManager(t) + userManager.EXPECT(). + User(sess.IdentScreenName()). + Return(&state.User{DisplayScreenName: sess.DisplayScreenName()}, nil) - have, err := svc.RegisterBOSSession(sess.ScreenName()) + svc := NewAuthService(config.Config{}, sessionManager, userManager, nil, nil, cookieIssuer, nil) + + have, err := svc.RegisterBOSSession(sess.IdentScreenName()) assert.NoError(t, err) assert.Equal(t, sess, have) } @@ -1010,14 +1022,19 @@ func TestAuthService_RegisterBOSSession_SessionNotFound(t *testing.T) { sessionManager := newMockSessionManager(t) sessionManager.EXPECT(). - AddSession(sess.ScreenName()). + AddSession(sess.DisplayScreenName()). Return(nil) cookieIssuer := newMockCookieIssuer(t) - svc := NewAuthService(config.Config{}, sessionManager, nil, nil, nil, cookieIssuer, nil) + userManager := newMockUserManager(t) + userManager.EXPECT(). + User(sess.IdentScreenName()). + Return(&state.User{DisplayScreenName: sess.DisplayScreenName()}, nil) + + svc := NewAuthService(config.Config{}, sessionManager, userManager, nil, nil, cookieIssuer, nil) - have, err := svc.RegisterBOSSession(sess.ScreenName()) + have, err := svc.RegisterBOSSession(sess.IdentScreenName()) assert.NoError(t, err) assert.Nil(t, have) } @@ -1193,14 +1210,14 @@ func TestAuthService_Signout(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ deleteUserParams: deleteUserParams{ { - userScreenName: "user_screen_name", + userScreenName: state.NewIdentScreenName("user_screen_name"), }, }, }, buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyDepartedParams: broadcastBuddyDepartedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -1222,7 +1239,7 @@ func TestAuthService_Signout(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyDeparted(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } diff --git a/foodgroup/bart_test.go b/foodgroup/bart_test.go index 79c84460..9672b06f 100644 --- a/foodgroup/bart_test.go +++ b/foodgroup/bart_test.go @@ -49,7 +49,7 @@ func TestBARTService_UpsertItem(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -87,7 +87,7 @@ func TestBARTService_UpsertItem(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } diff --git a/foodgroup/buddy.go b/foodgroup/buddy.go index 9fa6a847..29114f75 100644 --- a/foodgroup/buddy.go +++ b/foodgroup/buddy.go @@ -57,13 +57,13 @@ func (s BuddyService) RightsQuery(_ context.Context, frameIn wire.SNACFrame) wir func (s BuddyService) AddBuddies(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x03_0x04_BuddyAddBuddies) error { for _, entry := range inBody.Buddies { - s.legacyBuddyListManager.AddBuddy(sess.ScreenName(), entry.ScreenName) + s.legacyBuddyListManager.AddBuddy(sess.IdentScreenName(), state.NewIdentScreenName(entry.ScreenName)) if !sess.SignonComplete() { // client has not completed sign-on sequence, so any arrival // messages sent at this point would be ignored by the client. continue } - buddy := s.messageRelayer.RetrieveByScreenName(entry.ScreenName) + buddy := s.messageRelayer.RetrieveByScreenName(state.NewIdentScreenName(entry.ScreenName)) if buddy == nil || buddy.Invisible() { continue } @@ -77,7 +77,7 @@ func (s BuddyService) AddBuddies(ctx context.Context, sess *state.Session, inBod func (s BuddyService) DelBuddies(_ context.Context, sess *state.Session, inBody wire.SNAC_0x03_0x05_BuddyDelBuddies) { for _, entry := range inBody.Buddies { - s.legacyBuddyListManager.DeleteBuddy(sess.ScreenName(), entry.ScreenName) + s.legacyBuddyListManager.DeleteBuddy(sess.IdentScreenName(), state.NewIdentScreenName(entry.ScreenName)) } } @@ -94,7 +94,7 @@ func (s BuddyService) UnicastBuddyArrived(ctx context.Context, from *state.Sessi case icon != nil: userInfo.Append(wire.NewTLV(wire.OServiceUserInfoBARTInfo, *icon)) } - s.messageRelayer.RelayToScreenName(ctx, to.ScreenName(), wire.SNACMessage{ + s.messageRelayer.RelayToScreenName(ctx, to.IdentScreenName(), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, SubGroup: wire.BuddyArrived, @@ -112,13 +112,13 @@ func (s BuddyService) UnicastBuddyArrived(ctx context.Context, from *state.Sessi // buddy icons, warning levels, invisibility status, etc. func (s BuddyService) BroadcastBuddyArrived(ctx context.Context, sess *state.Session) error { // find users who have this user on their server-side buddy list - recipients, err := s.feedbagManager.AdjacentUsers(sess.ScreenName()) + recipients, err := s.feedbagManager.AdjacentUsers(sess.IdentScreenName()) if err != nil { return err } // find users who have this user on their client-side buddy list - legacyUsers := s.legacyBuddyListManager.WhoAddedUser(sess.ScreenName()) + legacyUsers := s.legacyBuddyListManager.WhoAddedUser(sess.IdentScreenName()) recipients = append(recipients, legacyUsers...) userInfo := sess.TLVUserInfo() @@ -147,7 +147,7 @@ func (s BuddyService) BroadcastBuddyArrived(ctx context.Context, sess *state.Ses // from their feedbag. If it exists, the buddy icon is the feedbag item of // class wire.FeedbagClassIdBart with BART type wire.BARTTypesBuddyIcon. func getBuddyIconRefFromFeedbag(sess *state.Session, feedbagManager FeedbagManager) (*wire.BARTID, error) { - items, err := feedbagManager.Feedbag(sess.ScreenName()) + items, err := feedbagManager.Feedbag(sess.IdentScreenName()) if err != nil { return nil, err } @@ -198,12 +198,12 @@ func extractBARTItemType(item wire.FeedbagItem) (uint16, error) { } func (s BuddyService) BroadcastBuddyDeparted(ctx context.Context, sess *state.Session) error { - recipients, err := s.feedbagManager.AdjacentUsers(sess.ScreenName()) + recipients, err := s.feedbagManager.AdjacentUsers(sess.IdentScreenName()) if err != nil { return err } - legacyUsers := s.legacyBuddyListManager.WhoAddedUser(sess.ScreenName()) + legacyUsers := s.legacyBuddyListManager.WhoAddedUser(sess.IdentScreenName()) recipients = append(recipients, legacyUsers...) s.messageRelayer.RelayToScreenNames(ctx, recipients, wire.SNACMessage{ @@ -215,7 +215,7 @@ func (s BuddyService) BroadcastBuddyDeparted(ctx context.Context, sess *state.Se TLVUserInfo: wire.TLVUserInfo{ // don't include the TLV block, otherwise the AIM client fails // to process the block event - ScreenName: sess.ScreenName(), + ScreenName: string(sess.DisplayScreenName()), WarningLevel: sess.Warning(), }, }, @@ -225,7 +225,7 @@ func (s BuddyService) BroadcastBuddyDeparted(ctx context.Context, sess *state.Se } func (s BuddyService) UnicastBuddyDeparted(ctx context.Context, from *state.Session, to *state.Session) { - s.messageRelayer.RelayToScreenName(ctx, to.ScreenName(), wire.SNACMessage{ + s.messageRelayer.RelayToScreenName(ctx, to.IdentScreenName(), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, SubGroup: wire.BuddyDeparted, @@ -234,7 +234,7 @@ func (s BuddyService) UnicastBuddyDeparted(ctx context.Context, from *state.Sess TLVUserInfo: wire.TLVUserInfo{ // don't include the TLV block, otherwise the AIM client fails // to process the block event - ScreenName: from.ScreenName(), + ScreenName: string(from.DisplayScreenName()), WarningLevel: from.Warning(), }, }, diff --git a/foodgroup/buddy_test.go b/foodgroup/buddy_test.go index d31949c6..a58ecf80 100644 --- a/foodgroup/buddy_test.go +++ b/foodgroup/buddy_test.go @@ -70,29 +70,29 @@ func TestBuddyService_AddBuddies(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ addBuddyParams: addBuddyParams{ { - userScreenName: "user_screen_name", - buddyScreenName: "buddy_1_online", + userScreenName: state.NewIdentScreenName("user_screen_name"), + buddyScreenName: state.NewIdentScreenName("buddy_1_online"), }, { - userScreenName: "user_screen_name", - buddyScreenName: "buddy_2_offline", + userScreenName: state.NewIdentScreenName("user_screen_name"), + buddyScreenName: state.NewIdentScreenName("buddy_2_offline"), }, }, }, messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy_1_online", + screenName: state.NewIdentScreenName("buddy_1_online"), sess: newTestSession("buddy_1_online", sessOptCannedSignonTime), }, { - screenName: "buddy_2_offline", + screenName: state.NewIdentScreenName("buddy_2_offline"), sess: nil, }, }, relayToScreenNameParams: relayToScreenNameParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, @@ -108,7 +108,7 @@ func TestBuddyService_AddBuddies(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "buddy_1_online", + screenName: state.NewIdentScreenName("buddy_1_online"), }, }, }, @@ -133,12 +133,12 @@ func TestBuddyService_AddBuddies(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ addBuddyParams: addBuddyParams{ { - userScreenName: "user_screen_name", - buddyScreenName: "buddy_1_online", + userScreenName: state.NewIdentScreenName("user_screen_name"), + buddyScreenName: state.NewIdentScreenName("buddy_1_online"), }, { - userScreenName: "user_screen_name", - buddyScreenName: "buddy_2_offline", + userScreenName: state.NewIdentScreenName("user_screen_name"), + buddyScreenName: state.NewIdentScreenName("buddy_2_offline"), }, }, }, @@ -212,12 +212,12 @@ func TestBuddyService_DelBuddies(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ deleteBuddyParams: deleteBuddyParams{ { - userScreenName: "user_screen_name", - buddyScreenName: "buddy_1_online", + userScreenName: state.NewIdentScreenName("user_screen_name"), + buddyScreenName: state.NewIdentScreenName("buddy_1_online"), }, { - userScreenName: "user_screen_name", - buddyScreenName: "buddy_2_offline", + userScreenName: state.NewIdentScreenName("user_screen_name"), + buddyScreenName: state.NewIdentScreenName("buddy_2_offline"), }, }, }, @@ -256,13 +256,13 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ adjacentUsersParams: adjacentUsersParams{ { - screenName: "user_screen_name", - users: []string{"friend1"}, + screenName: state.NewIdentScreenName("user_screen_name"), + users: []state.IdentScreenName{state.NewIdentScreenName("friend1")}, }, }, feedbagParams: feedbagParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), results: []wire.FeedbagItem{}, }, }, @@ -270,7 +270,10 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) { messageRelayerParams: messageRelayerParams{ relayToScreenNamesParams: relayToScreenNamesParams{ { - screenNames: []string{"friend1", "friend2"}, + screenNames: []state.IdentScreenName{ + state.NewIdentScreenName("friend1"), + state.NewIdentScreenName("friend2"), + }, message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, @@ -286,8 +289,8 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ whoAddedUserParams: whoAddedUserParams{ { - userScreenName: "user_screen_name", - result: []string{"friend2"}, + userScreenName: state.NewIdentScreenName("user_screen_name"), + result: []state.IdentScreenName{state.NewIdentScreenName("friend2")}, }, }, }, @@ -300,13 +303,13 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ adjacentUsersParams: adjacentUsersParams{ { - screenName: "user_screen_name", - users: []string{"friend1"}, + screenName: state.NewIdentScreenName("user_screen_name"), + users: []state.IdentScreenName{state.NewIdentScreenName("friend1")}, }, }, feedbagParams: feedbagParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), results: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIdBuddy, @@ -334,7 +337,7 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) { messageRelayerParams: messageRelayerParams{ relayToScreenNamesParams: relayToScreenNamesParams{ { - screenNames: []string{"friend1"}, + screenNames: []state.IdentScreenName{state.NewIdentScreenName("friend1")}, message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, @@ -359,8 +362,8 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ whoAddedUserParams: whoAddedUserParams{ { - userScreenName: "user_screen_name", - result: []string{}, + userScreenName: state.NewIdentScreenName("user_screen_name"), + result: []state.IdentScreenName{}, }, }, }, @@ -418,15 +421,18 @@ func TestBuddyService_BroadcastDeparture(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ adjacentUsersParams: adjacentUsersParams{ { - screenName: "user_screen_name", - users: []string{"friend1"}, + screenName: state.NewIdentScreenName("user_screen_name"), + users: []state.IdentScreenName{state.NewIdentScreenName("friend1")}, }, }, }, messageRelayerParams: messageRelayerParams{ relayToScreenNamesParams: relayToScreenNamesParams{ { - screenNames: []string{"friend1", "friend2"}, + screenNames: []state.IdentScreenName{ + state.NewIdentScreenName("friend1"), + state.NewIdentScreenName("friend2"), + }, message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, @@ -445,8 +451,8 @@ func TestBuddyService_BroadcastDeparture(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ whoAddedUserParams: whoAddedUserParams{ { - userScreenName: "user_screen_name", - result: []string{"friend2"}, + userScreenName: state.NewIdentScreenName("user_screen_name"), + result: []state.IdentScreenName{state.NewIdentScreenName("friend2")}, }, }, }, @@ -502,7 +508,7 @@ func TestBuddyService_UnicastBuddyDeparted(t *testing.T) { messageRelayerParams: messageRelayerParams{ relayToScreenNameParams: relayToScreenNameParams{ { - screenName: "dest_screen_name", + screenName: state.NewIdentScreenName("dest_screen_name"), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, @@ -557,7 +563,7 @@ func TestBuddyService_UnicastBuddyArrived(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "src_screen_name", + screenName: state.NewIdentScreenName("src_screen_name"), results: []wire.FeedbagItem{}, }, }, @@ -565,7 +571,7 @@ func TestBuddyService_UnicastBuddyArrived(t *testing.T) { messageRelayerParams: messageRelayerParams{ relayToScreenNameParams: relayToScreenNameParams{ { - screenName: "dest_screen_name", + screenName: state.NewIdentScreenName("dest_screen_name"), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, @@ -588,7 +594,7 @@ func TestBuddyService_UnicastBuddyArrived(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "src_screen_name", + screenName: state.NewIdentScreenName("src_screen_name"), results: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIdBuddy, @@ -616,7 +622,7 @@ func TestBuddyService_UnicastBuddyArrived(t *testing.T) { messageRelayerParams: messageRelayerParams{ relayToScreenNameParams: relayToScreenNameParams{ { - screenName: "dest_screen_name", + screenName: state.NewIdentScreenName("dest_screen_name"), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Buddy, diff --git a/foodgroup/chat.go b/foodgroup/chat.go index f8d0e1ec..42362654 100644 --- a/foodgroup/chat.go +++ b/foodgroup/chat.go @@ -81,7 +81,7 @@ func setOnlineChatUsers(ctx context.Context, sess *state.Session, chatMessageRel snacPayloadOut.Users = append(snacPayloadOut.Users, uSess.TLVUserInfo()) } - chatMessageRelayer.RelayToScreenName(ctx, sess.ScreenName(), wire.SNACMessage{ + chatMessageRelayer.RelayToScreenName(ctx, sess.IdentScreenName(), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Chat, SubGroup: wire.ChatUsersJoined, @@ -119,7 +119,7 @@ func alertUserLeft(ctx context.Context, sess *state.Session, chatMessageRelayer } func sendChatRoomInfoUpdate(ctx context.Context, sess *state.Session, chatMessageRelayer ChatMessageRelayer, room state.ChatRoom) { - chatMessageRelayer.RelayToScreenName(ctx, sess.ScreenName(), wire.SNACMessage{ + chatMessageRelayer.RelayToScreenName(ctx, sess.IdentScreenName(), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Chat, SubGroup: wire.ChatRoomInfoUpdate, diff --git a/foodgroup/chat_nav.go b/foodgroup/chat_nav.go index 6ef0523f..e7ea45c5 100644 --- a/foodgroup/chat_nav.go +++ b/foodgroup/chat_nav.go @@ -87,7 +87,7 @@ func (s ChatNavService) CreateRoom(_ context.Context, sess *state.Session, inFra s.chatRegistry.Register(room, chatSessMgr) // add user to chat room - chatSess := chatSessMgr.AddSession(sess.ScreenName()) + chatSess := chatSessMgr.AddSession(sess.DisplayScreenName()) chatSess.SetChatRoomCookie(room.Cookie) return wire.SNACMessage{ diff --git a/foodgroup/chat_nav_test.go b/foodgroup/chat_nav_test.go index 1618ab7b..8ea6cf35 100644 --- a/foodgroup/chat_nav_test.go +++ b/foodgroup/chat_nav_test.go @@ -18,7 +18,8 @@ func TestChatNavService_CreateRoom(t *testing.T) { chatRegistry := state.NewChatRegistry() sessionManager := newMockSessionManager(t) - sessionManager.EXPECT().AddSession(bosSess.ScreenName()). + sessionManager.EXPECT(). + AddSession(bosSess.DisplayScreenName()). Return(chatSess) newChatRoom := func() state.ChatRoom { diff --git a/foodgroup/feedbag.go b/foodgroup/feedbag.go index 8be71d21..a9162768 100644 --- a/foodgroup/feedbag.go +++ b/foodgroup/feedbag.go @@ -91,7 +91,7 @@ func (s FeedbagService) RightsQuery(_ context.Context, inFrame wire.SNACFrame) w // Query fetches the user's feedbag (aka buddy list). It returns // wire.FeedbagReply, which contains feedbag entries. func (s FeedbagService) Query(_ context.Context, sess *state.Session, inFrame wire.SNACFrame) (wire.SNACMessage, error) { - fb, err := s.feedbagManager.Feedbag(sess.ScreenName()) + fb, err := s.feedbagManager.Feedbag(sess.IdentScreenName()) if err != nil { return wire.SNACMessage{}, err } @@ -99,7 +99,7 @@ func (s FeedbagService) Query(_ context.Context, sess *state.Session, inFrame wi lm := time.UnixMilli(0) if len(fb) > 0 { - lm, err = s.feedbagManager.FeedbagLastModified(sess.ScreenName()) + lm, err = s.feedbagManager.FeedbagLastModified(sess.IdentScreenName()) if err != nil { return wire.SNACMessage{}, err } @@ -124,7 +124,7 @@ func (s FeedbagService) Query(_ context.Context, sess *state.Session, inFrame wi // inBody.LastUpdate, else return wire.FeedbagReply, which contains feedbag // entries. func (s FeedbagService) QueryIfModified(_ context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x13_0x05_FeedbagQueryIfModified) (wire.SNACMessage, error) { - fb, err := s.feedbagManager.Feedbag(sess.ScreenName()) + fb, err := s.feedbagManager.Feedbag(sess.IdentScreenName()) if err != nil { return wire.SNACMessage{}, err } @@ -132,7 +132,7 @@ func (s FeedbagService) QueryIfModified(_ context.Context, sess *state.Session, lm := time.UnixMilli(0) if len(fb) > 0 { - lm, err = s.feedbagManager.FeedbagLastModified(sess.ScreenName()) + lm, err = s.feedbagManager.FeedbagLastModified(sess.IdentScreenName()) if err != nil { return wire.SNACMessage{}, err } @@ -177,7 +177,7 @@ func (s FeedbagService) UpsertItem(ctx context.Context, sess *state.Session, inF for _, item := range items { // don't let users block themselves, it causes the AIM client to go // into a weird state. - if item.ClassID == 3 && item.Name == sess.ScreenName() { + if item.ClassID == 3 && state.NewIdentScreenName(item.Name) == sess.IdentScreenName() { return wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Feedbag, @@ -191,14 +191,14 @@ func (s FeedbagService) UpsertItem(ctx context.Context, sess *state.Session, inF } } - if err := s.feedbagManager.FeedbagUpsert(sess.ScreenName(), items); err != nil { + if err := s.feedbagManager.FeedbagUpsert(sess.IdentScreenName(), items); err != nil { return wire.SNACMessage{}, err } for _, item := range items { switch item.ClassID { case wire.FeedbagClassIdBuddy, wire.FeedbagClassIDPermit: // add new buddy - buddy := s.messageRelayer.RetrieveByScreenName(item.Name) + buddy := s.messageRelayer.RetrieveByScreenName(state.NewIdentScreenName(item.Name)) if buddy == nil || buddy.Invisible() { continue } @@ -209,7 +209,7 @@ func (s FeedbagService) UpsertItem(ctx context.Context, sess *state.Session, inF if sess.Invisible() { continue // user's offline, don't send departure notification } - blockedSess := s.messageRelayer.RetrieveByScreenName(item.Name) + blockedSess := s.messageRelayer.RetrieveByScreenName(state.NewIdentScreenName(item.Name)) if blockedSess == nil { continue // blocked buddy is offline, nothing to do here } @@ -282,7 +282,7 @@ func (s FeedbagService) broadcastIconUpdate(ctx context.Context, sess *state.Ses } } - s.messageRelayer.RelayToScreenName(ctx, sess.ScreenName(), wire.SNACMessage{ + s.messageRelayer.RelayToScreenName(ctx, sess.IdentScreenName(), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.OService, SubGroup: wire.OServiceBartReply, @@ -300,13 +300,13 @@ func (s FeedbagService) broadcastIconUpdate(ctx context.Context, sess *state.Ses // Sends buddy arrival notifications to each unblocked buddy if current user is // visible. It returns wire.FeedbagStatus, which contains update confirmation. func (s FeedbagService) DeleteItem(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x13_0x0A_FeedbagDeleteItem) (wire.SNACMessage, error) { - if err := s.feedbagManager.FeedbagDelete(sess.ScreenName(), inBody.Items); err != nil { + if err := s.feedbagManager.FeedbagDelete(sess.IdentScreenName(), inBody.Items); err != nil { return wire.SNACMessage{}, err } for _, item := range inBody.Items { if item.ClassID == wire.FeedbagClassIDDeny { - unblockedSess := s.messageRelayer.RetrieveByScreenName(item.Name) + unblockedSess := s.messageRelayer.RetrieveByScreenName(state.NewIdentScreenName(item.Name)) if unblockedSess == nil { continue // unblocked user is offline, nothing to do here } @@ -349,7 +349,7 @@ func (s FeedbagService) StartCluster(context.Context, wire.SNACFrame, wire.SNAC_ // by AIM clients that use the feedbag food group for buddy list management (as // opposed to client-side management). func (s FeedbagService) Use(ctx context.Context, sess *state.Session) error { - buddies, err := s.feedbagManager.Buddies(sess.ScreenName()) + buddies, err := s.feedbagManager.Buddies(sess.IdentScreenName()) if err != nil { return err } diff --git a/foodgroup/feedbag_test.go b/foodgroup/feedbag_test.go index 9f341c54..f3f95167 100644 --- a/foodgroup/feedbag_test.go +++ b/foodgroup/feedbag_test.go @@ -38,7 +38,7 @@ func TestFeedbagService_Query(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), results: []wire.FeedbagItem{}, }, }, @@ -68,7 +68,7 @@ func TestFeedbagService_Query(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), results: []wire.FeedbagItem{ { Name: "buddy_1", @@ -81,7 +81,7 @@ func TestFeedbagService_Query(t *testing.T) { }, feedbagLastModifiedParams: feedbagLastModifiedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), result: time.UnixMilli(1696472198082), }, }, @@ -162,7 +162,7 @@ func TestFeedbagService_QueryIfModified(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), results: []wire.FeedbagItem{}, }, }, @@ -194,7 +194,7 @@ func TestFeedbagService_QueryIfModified(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), results: []wire.FeedbagItem{ { Name: "buddy_1", @@ -207,7 +207,7 @@ func TestFeedbagService_QueryIfModified(t *testing.T) { }, feedbagLastModifiedParams: feedbagLastModifiedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), result: time.UnixMilli(200000), }, }, @@ -248,7 +248,7 @@ func TestFeedbagService_QueryIfModified(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagParams: feedbagParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), results: []wire.FeedbagItem{ { Name: "buddy_1", @@ -261,7 +261,7 @@ func TestFeedbagService_QueryIfModified(t *testing.T) { }, feedbagLastModifiedParams: feedbagLastModifiedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), result: time.UnixMilli(100000), }, }, @@ -406,7 +406,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDPermit, @@ -423,11 +423,11 @@ func TestFeedbagService_UpsertItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy_1_online", + screenName: state.NewIdentScreenName("buddy_1_online"), sess: newTestSession("buddy_1_online", sessOptCannedSignonTime), }, { - screenName: "buddy_2_online", + screenName: state.NewIdentScreenName("buddy_2_online"), sess: newTestSession("buddy_2_online", sessOptCannedSignonTime), }, }, @@ -435,12 +435,12 @@ func TestFeedbagService_UpsertItem(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ unicastBuddyArrivedParams: unicastBuddyArrivedParams{ { - from: "buddy_1_online", - to: "user_screen_name", + from: state.NewIdentScreenName("buddy_1_online"), + to: state.NewIdentScreenName("user_screen_name"), }, { - from: "buddy_2_online", - to: "user_screen_name", + from: state.NewIdentScreenName("buddy_2_online"), + to: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -476,7 +476,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDPermit, @@ -489,7 +489,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy_offline", + screenName: state.NewIdentScreenName("buddy_offline"), sess: nil, }, }, @@ -526,7 +526,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDPermit, @@ -539,7 +539,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "invisible_buddy_online", + screenName: state.NewIdentScreenName("invisible_buddy_online"), sess: newTestSession("invisible_buddy_online", sessOptInvisible), }, }, @@ -576,7 +576,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDDeny, @@ -589,7 +589,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy_1", + screenName: state.NewIdentScreenName("buddy_1"), sess: newTestSession("buddy_1"), }, }, @@ -597,12 +597,12 @@ func TestFeedbagService_UpsertItem(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ unicastBuddyDepartedParams: unicastBuddyDepartedParams{ { - from: "user_screen_name", - to: "buddy_1", + from: state.NewIdentScreenName("user_screen_name"), + to: state.NewIdentScreenName("buddy_1"), }, { - from: "buddy_1", - to: "user_screen_name", + from: state.NewIdentScreenName("buddy_1"), + to: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -638,7 +638,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDDeny, @@ -651,7 +651,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy_1", + screenName: state.NewIdentScreenName("buddy_1"), sess: nil, }, }, @@ -688,7 +688,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDDeny, @@ -771,7 +771,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIdBart, @@ -790,7 +790,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ relayToScreenNameParams: relayToScreenNameParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.OService, @@ -855,7 +855,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIdBart, @@ -876,7 +876,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ relayToScreenNameParams: relayToScreenNameParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.OService, @@ -898,7 +898,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -940,7 +940,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagUpsertParams: feedbagUpsertParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIdBart, @@ -959,7 +959,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -1021,7 +1021,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } @@ -1030,10 +1030,10 @@ func TestFeedbagService_UpsertItem(t *testing.T) { buddyUpdateBroadcaster.EXPECT(). UnicastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.from + return s.IdentScreenName() == p.from }), mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.to + return s.IdentScreenName() == p.to })). Return(nil) } @@ -1042,10 +1042,10 @@ func TestFeedbagService_UpsertItem(t *testing.T) { buddyUpdateBroadcaster.EXPECT(). UnicastBuddyDeparted(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.from + return s.IdentScreenName() == p.from }), mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.to + return s.IdentScreenName() == p.to })) } @@ -1092,7 +1092,7 @@ func TestFeedbagService_DeleteItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagDeleteParams: feedbagDeleteParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIdBuddy, @@ -1138,7 +1138,7 @@ func TestFeedbagService_DeleteItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagDeleteParams: feedbagDeleteParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDDeny, @@ -1155,11 +1155,11 @@ func TestFeedbagService_DeleteItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy_1_online", + screenName: state.NewIdentScreenName("buddy_1_online"), sess: newTestSession("buddy_1_online", sessOptCannedSignonTime), }, { - screenName: "buddy_2_online", + screenName: state.NewIdentScreenName("buddy_2_online"), sess: newTestSession("buddy_2_online", sessOptCannedSignonTime), }, }, @@ -1167,20 +1167,20 @@ func TestFeedbagService_DeleteItem(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ unicastBuddyArrivedParams: unicastBuddyArrivedParams{ { - from: "buddy_1_online", - to: "user_screen_name", + from: state.NewIdentScreenName("buddy_1_online"), + to: state.NewIdentScreenName("user_screen_name"), }, { - from: "buddy_2_online", - to: "user_screen_name", + from: state.NewIdentScreenName("buddy_2_online"), + to: state.NewIdentScreenName("user_screen_name"), }, { - from: "user_screen_name", - to: "buddy_1_online", + from: state.NewIdentScreenName("user_screen_name"), + to: state.NewIdentScreenName("buddy_1_online"), }, { - from: "user_screen_name", - to: "buddy_2_online", + from: state.NewIdentScreenName("user_screen_name"), + to: state.NewIdentScreenName("buddy_2_online"), }, }, }, @@ -1216,7 +1216,7 @@ func TestFeedbagService_DeleteItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagDeleteParams: feedbagDeleteParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDDeny, @@ -1229,7 +1229,7 @@ func TestFeedbagService_DeleteItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy_offline", + screenName: state.NewIdentScreenName("buddy_offline"), sess: nil, }, }, @@ -1266,7 +1266,7 @@ func TestFeedbagService_DeleteItem(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ feedbagDeleteParams: feedbagDeleteParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), items: []wire.FeedbagItem{ { ClassID: wire.FeedbagClassIDDeny, @@ -1279,7 +1279,7 @@ func TestFeedbagService_DeleteItem(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "invisible_buddy_online", + screenName: state.NewIdentScreenName("invisible_buddy_online"), sess: newTestSession("invisible_buddy_online", sessOptInvisible), }, }, @@ -1287,8 +1287,8 @@ func TestFeedbagService_DeleteItem(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ unicastBuddyArrivedParams: unicastBuddyArrivedParams{ { - from: "user_screen_name", - to: "invisible_buddy_online", + from: state.NewIdentScreenName("user_screen_name"), + to: state.NewIdentScreenName("invisible_buddy_online"), }, }, }, @@ -1326,10 +1326,10 @@ func TestFeedbagService_DeleteItem(t *testing.T) { buddyUpdateBroadcast.EXPECT(). UnicastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.from + return s.IdentScreenName() == p.from }), mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.to + return s.IdentScreenName() == p.to })). Return(nil) } @@ -1369,19 +1369,22 @@ func TestFeedbagService_Use(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ buddiesParams: buddiesParams{ { - screenName: "test-user", - results: []string{"buddy1", "buddy3"}, + screenName: state.NewIdentScreenName("test-user"), + results: []state.IdentScreenName{ + state.NewIdentScreenName("buddy1"), + state.NewIdentScreenName("buddy3"), + }, }, }, }, messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy1", + screenName: state.NewIdentScreenName("buddy1"), sess: newTestSession("buddy1"), }, { - screenName: "buddy3", + screenName: state.NewIdentScreenName("buddy3"), sess: newTestSession("buddy3"), }, }, @@ -1389,12 +1392,12 @@ func TestFeedbagService_Use(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ unicastBuddyArrivedParams: unicastBuddyArrivedParams{ { - from: "buddy1", - to: "test-user", + from: state.NewIdentScreenName("buddy1"), + to: state.NewIdentScreenName("test-user"), }, { - from: "buddy3", - to: "test-user", + from: state.NewIdentScreenName("buddy3"), + to: state.NewIdentScreenName("test-user"), }, }, }, @@ -1421,10 +1424,10 @@ func TestFeedbagService_Use(t *testing.T) { buddyUpdateBroadcast.EXPECT(). UnicastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.from + return s.IdentScreenName() == p.from }), mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.to + return s.IdentScreenName() == p.to })). Return(nil) } diff --git a/foodgroup/icbm.go b/foodgroup/icbm.go index 5e8caaea..4ca3b408 100644 --- a/foodgroup/icbm.go +++ b/foodgroup/icbm.go @@ -58,7 +58,7 @@ func (s ICBMService) ParameterQuery(_ context.Context, inFrame wire.SNACFrame) w // the wire.ICBMChannelMsgToHost message contains a request acknowledgement // flag. func (s ICBMService) ChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x06_ICBMChannelMsgToHost) (*wire.SNACMessage, error) { - blocked, err := s.feedbagManager.BlockedState(sess.ScreenName(), inBody.ScreenName) + blocked, err := s.feedbagManager.BlockedState(sess.IdentScreenName(), state.NewIdentScreenName(inBody.ScreenName)) if err != nil { return nil, err } @@ -80,7 +80,7 @@ func (s ICBMService) ChannelMsgToHost(ctx context.Context, sess *state.Session, }, nil } - recipSess := s.messageRelayer.RetrieveByScreenName(inBody.ScreenName) + recipSess := s.messageRelayer.RetrieveByScreenName(state.NewIdentScreenName(inBody.ScreenName)) if recipSess == nil { return &wire.SNACMessage{ Frame: wire.SNACFrame{ @@ -98,7 +98,7 @@ func (s ICBMService) ChannelMsgToHost(ctx context.Context, sess *state.Session, Cookie: inBody.Cookie, ChannelID: inBody.ChannelID, TLVUserInfo: wire.TLVUserInfo{ - ScreenName: sess.ScreenName(), + ScreenName: string(sess.DisplayScreenName()), WarningLevel: sess.Warning(), }, TLVRestBlock: wire.TLVRestBlock{ @@ -115,7 +115,7 @@ func (s ICBMService) ChannelMsgToHost(ctx context.Context, sess *state.Session, // far as I can tell. clientIM.AppendList(inBody.TLVRestBlock.TLVList) - s.messageRelayer.RelayToScreenName(ctx, recipSess.ScreenName(), wire.SNACMessage{ + s.messageRelayer.RelayToScreenName(ctx, recipSess.IdentScreenName(), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.ICBM, SubGroup: wire.ICBMChannelMsgToClient, @@ -146,7 +146,7 @@ func (s ICBMService) ChannelMsgToHost(ctx context.Context, sess *state.Session, // ClientEvent relays SNAC wire.ICBMClientEvent typing events from the // sender to the recipient. func (s ICBMService) ClientEvent(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x14_ICBMClientEvent) error { - blocked, err := s.feedbagManager.BlockedState(sess.ScreenName(), inBody.ScreenName) + blocked, err := s.feedbagManager.BlockedState(sess.IdentScreenName(), state.NewIdentScreenName(inBody.ScreenName)) switch { case err != nil: @@ -154,7 +154,7 @@ func (s ICBMService) ClientEvent(ctx context.Context, sess *state.Session, inFra case blocked != state.BlockedNo: return nil default: - s.messageRelayer.RelayToScreenName(ctx, inBody.ScreenName, wire.SNACMessage{ + s.messageRelayer.RelayToScreenName(ctx, state.NewIdentScreenName(inBody.ScreenName), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.ICBM, SubGroup: wire.ICBMClientEvent, @@ -163,7 +163,7 @@ func (s ICBMService) ClientEvent(ctx context.Context, sess *state.Session, inFra Body: wire.SNAC_0x04_0x14_ICBMClientEvent{ Cookie: inBody.Cookie, ChannelID: inBody.ChannelID, - ScreenName: sess.ScreenName(), + ScreenName: string(sess.DisplayScreenName()), Event: inBody.Event, }, }) @@ -179,9 +179,11 @@ func (s ICBMService) ClientEvent(ctx context.Context, sess *state.Session, inFra // warning was sent. Users may not warn themselves or warn users they have // blocked or are blocked by. func (s ICBMService) EvilRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x08_ICBMEvilRequest) (wire.SNACMessage, error) { + identScreenName := state.NewIdentScreenName(inBody.ScreenName) + // don't let users warn themselves, it causes the AIM client to go into a // weird state. - if inBody.ScreenName == sess.ScreenName() { + if identScreenName == sess.IdentScreenName() { return wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.ICBM, @@ -194,7 +196,7 @@ func (s ICBMService) EvilRequest(ctx context.Context, sess *state.Session, inFra }, nil } - blocked, err := s.feedbagManager.BlockedState(sess.ScreenName(), inBody.ScreenName) + blocked, err := s.feedbagManager.BlockedState(sess.IdentScreenName(), identScreenName) if err != nil { return wire.SNACMessage{}, err } @@ -211,7 +213,7 @@ func (s ICBMService) EvilRequest(ctx context.Context, sess *state.Session, inFra }, nil } - recipSess := s.messageRelayer.RetrieveByScreenName(inBody.ScreenName) + recipSess := s.messageRelayer.RetrieveByScreenName(identScreenName) if recipSess == nil { return wire.SNACMessage{ Frame: wire.SNACFrame{ @@ -236,7 +238,7 @@ func (s ICBMService) EvilRequest(ctx context.Context, sess *state.Session, inFra notif = wire.SNAC_0x01_0x10_OServiceEvilNotification{ NewEvil: recipSess.Warning(), TLVUserInfo: wire.TLVUserInfo{ - ScreenName: sess.ScreenName(), + ScreenName: sess.IdentScreenName().String(), WarningLevel: recipSess.Warning(), }, } @@ -246,7 +248,7 @@ func (s ICBMService) EvilRequest(ctx context.Context, sess *state.Session, inFra } } - s.messageRelayer.RelayToScreenName(ctx, recipSess.ScreenName(), wire.SNACMessage{ + s.messageRelayer.RelayToScreenName(ctx, recipSess.IdentScreenName(), wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.OService, SubGroup: wire.OServiceEvilNotification, diff --git a/foodgroup/icbm_test.go b/foodgroup/icbm_test.go index 94dce131..6d56328b 100644 --- a/foodgroup/icbm_test.go +++ b/foodgroup/icbm_test.go @@ -229,18 +229,18 @@ func TestICBMService_ChannelMsgToHost(t *testing.T) { // feedbagManager := newMockFeedbagManager(t) feedbagManager.EXPECT(). - BlockedState(tc.senderSession.ScreenName(), - tc.inputSNAC.Body.(wire.SNAC_0x04_0x06_ICBMChannelMsgToHost).ScreenName). + BlockedState(tc.senderSession.IdentScreenName(), + state.NewIdentScreenName(tc.inputSNAC.Body.(wire.SNAC_0x04_0x06_ICBMChannelMsgToHost).ScreenName)). Return(tc.blockedState, nil). Maybe() messageRelayer := newMockMessageRelayer(t) messageRelayer.EXPECT(). - RetrieveByScreenName(tc.inputSNAC.Body.(wire.SNAC_0x04_0x06_ICBMChannelMsgToHost).ScreenName). + RetrieveByScreenName(state.NewIdentScreenName(tc.inputSNAC.Body.(wire.SNAC_0x04_0x06_ICBMChannelMsgToHost).ScreenName)). Return(tc.recipientSession). Maybe() if tc.recipientSession != nil { messageRelayer.EXPECT(). - RelayToScreenName(mock.Anything, tc.recipientSession.ScreenName(), tc.expectSNACToClient). + RelayToScreenName(mock.Anything, tc.recipientSession.IdentScreenName(), tc.expectSNACToClient). Maybe() } // @@ -265,7 +265,7 @@ func TestICBMService_ClientEvent(t *testing.T) { // blockedState is the response to the sender/recipient block check blockedState state.BlockedState // senderScreenName is the screen name of the user sending the event - senderScreenName string + senderScreenName state.DisplayScreenName // inputSNAC is the SNAC sent by the sender client inputSNAC wire.SNACMessage // expectSNACToClient is the SNAC sent from the server to the @@ -323,13 +323,15 @@ func TestICBMService_ClientEvent(t *testing.T) { // feedbagManager := newMockFeedbagManager(t) feedbagManager.EXPECT(). - BlockedState(tc.senderScreenName, tc.inputSNAC.Body.(wire.SNAC_0x04_0x14_ICBMClientEvent).ScreenName). + BlockedState(tc.senderScreenName.IdentScreenName(), + state.NewIdentScreenName(tc.inputSNAC.Body.(wire.SNAC_0x04_0x14_ICBMClientEvent).ScreenName)). Return(tc.blockedState, nil). Maybe() messageRelayer := newMockMessageRelayer(t) if tc.blockedState == state.BlockedNo { messageRelayer.EXPECT(). - RelayToScreenName(mock.Anything, tc.inputSNAC.Body.(wire.SNAC_0x04_0x14_ICBMClientEvent).ScreenName, + RelayToScreenName(mock.Anything, + state.NewIdentScreenName(tc.inputSNAC.Body.(wire.SNAC_0x04_0x14_ICBMClientEvent).ScreenName), tc.expectSNACToClient) } // @@ -357,10 +359,7 @@ func TestICBMService_EvilRequest(t *testing.T) { // recipientSession is the session of the user receiving the EvilNotification recipientSession *state.Session // recipientScreenName is the screen name of the user receiving the EvilNotification - recipientScreenName string - // recipientBuddies is a list of the recipient's buddies that get - // updated warning level - recipientBuddies []string + recipientScreenName state.IdentScreenName // inputSNAC is the SNAC sent by the sender client inputSNAC wire.SNACMessage // expectSNACToClient is the SNAC sent from the server to the @@ -377,8 +376,7 @@ func TestICBMService_EvilRequest(t *testing.T) { blockedState: state.BlockedNo, senderSession: newTestSession("sender-screen-name"), recipientSession: newTestSession("recipient-screen-name", sessOptCannedSignonTime), - recipientScreenName: "recipient-screen-name", - recipientBuddies: []string{"buddy1", "buddy2"}, + recipientScreenName: state.NewIdentScreenName("recipient-screen-name"), inputSNAC: wire.SNACMessage{ Frame: wire.SNACFrame{ RequestID: 1234, @@ -412,7 +410,7 @@ func TestICBMService_EvilRequest(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "recipient-screen-name", + screenName: state.NewIdentScreenName("recipient-screen-name"), }, }, }, @@ -423,8 +421,7 @@ func TestICBMService_EvilRequest(t *testing.T) { blockedState: state.BlockedNo, senderSession: newTestSession("sender-screen-name"), recipientSession: newTestSession("recipient-screen-name", sessOptCannedSignonTime), - recipientScreenName: "recipient-screen-name", - recipientBuddies: []string{"buddy1", "buddy2"}, + recipientScreenName: state.NewIdentScreenName("recipient-screen-name"), inputSNAC: wire.SNACMessage{ Frame: wire.SNACFrame{ RequestID: 1234, @@ -462,7 +459,7 @@ func TestICBMService_EvilRequest(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "recipient-screen-name", + screenName: state.NewIdentScreenName("recipient-screen-name"), }, }, }, @@ -473,8 +470,7 @@ func TestICBMService_EvilRequest(t *testing.T) { blockedState: state.BlockedA, senderSession: newTestSession("sender-screen-name"), recipientSession: nil, - recipientScreenName: "recipient-screen-name", - recipientBuddies: []string{"buddy1", "buddy2"}, + recipientScreenName: state.NewIdentScreenName("recipient-screen-name"), inputSNAC: wire.SNACMessage{ Frame: wire.SNACFrame{ RequestID: 1234, @@ -500,8 +496,7 @@ func TestICBMService_EvilRequest(t *testing.T) { blockedState: state.BlockedB, senderSession: newTestSession("sender-screen-name"), recipientSession: nil, - recipientScreenName: "recipient-screen-name", - recipientBuddies: []string{"buddy1", "buddy2"}, + recipientScreenName: state.NewIdentScreenName("recipient-screen-name"), inputSNAC: wire.SNACMessage{ Frame: wire.SNACFrame{ RequestID: 1234, @@ -526,7 +521,7 @@ func TestICBMService_EvilRequest(t *testing.T) { name: "don't let users warn themselves", senderSession: newTestSession("sender-screen-name"), recipientSession: nil, - recipientScreenName: "sender-screen-name", + recipientScreenName: state.NewIdentScreenName("sender-screen-name"), inputSNAC: wire.SNACMessage{ Frame: wire.SNACFrame{ RequestID: 1234, @@ -552,8 +547,7 @@ func TestICBMService_EvilRequest(t *testing.T) { blockedState: state.BlockedNo, senderSession: newTestSession("sender-screen-name"), recipientSession: nil, - recipientScreenName: "recipient-screen-name", - recipientBuddies: []string{"buddy1", "buddy2"}, + recipientScreenName: state.NewIdentScreenName("recipient-screen-name"), inputSNAC: wire.SNACMessage{ Frame: wire.SNACFrame{ RequestID: 1234, @@ -579,8 +573,7 @@ func TestICBMService_EvilRequest(t *testing.T) { blockedState: state.BlockedNo, senderSession: newTestSession("sender-screen-name"), recipientSession: nil, - recipientScreenName: "recipient-screen-name", - recipientBuddies: []string{"buddy1", "buddy2"}, + recipientScreenName: state.NewIdentScreenName("recipient-screen-name"), inputSNAC: wire.SNACMessage{ Frame: wire.SNACFrame{ RequestID: 1234, @@ -610,7 +603,7 @@ func TestICBMService_EvilRequest(t *testing.T) { // feedbagManager := newMockFeedbagManager(t) feedbagManager.EXPECT(). - BlockedState(tc.senderSession.ScreenName(), tc.recipientScreenName). + BlockedState(tc.senderSession.IdentScreenName(), tc.recipientScreenName). Return(tc.blockedState, nil). Maybe() messageRelayer := newMockMessageRelayer(t) @@ -626,14 +619,14 @@ func TestICBMService_EvilRequest(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } // // send input SNAC // - senderSession := newTestSession(tc.senderSession.ScreenName()) + senderSession := newTestSession(tc.senderSession.DisplayScreenName()) svc := NewICBMService(messageRelayer, feedbagManager, buddyUpdateBroadcaster) outputSNAC, err := svc.EvilRequest(nil, senderSession, tc.inputSNAC.Frame, tc.inputSNAC.Body.(wire.SNAC_0x04_0x08_ICBMEvilRequest)) diff --git a/foodgroup/locate.go b/foodgroup/locate.go index 0204b09f..78e80edd 100644 --- a/foodgroup/locate.go +++ b/foodgroup/locate.go @@ -73,7 +73,7 @@ func (s LocateService) RightsQuery(_ context.Context, inFrame wire.SNACFrame) wi func (s LocateService) SetInfo(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x02_0x04_LocateSetInfo) error { // update profile if profile, hasProfile := inBody.String(wire.LocateTLVTagsInfoSigData); hasProfile { - if err := s.profileManager.SetProfile(sess.ScreenName(), profile); err != nil { + if err := s.profileManager.SetProfile(sess.IdentScreenName(), profile); err != nil { return err } } @@ -111,7 +111,9 @@ func (s LocateService) SetInfo(ctx context.Context, sess *state.Session, inBody // profile, if requested, and/or the away message, if requested. This is a v2 // of UserInfoQuery. func (s LocateService) UserInfoQuery(_ context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x02_0x05_LocateUserInfoQuery) (wire.SNACMessage, error) { - blocked, err := s.feedbagManager.BlockedState(sess.ScreenName(), inBody.ScreenName) + identScreenName := state.NewIdentScreenName(inBody.ScreenName) + + blocked, err := s.feedbagManager.BlockedState(sess.IdentScreenName(), identScreenName) switch { case err != nil: return wire.SNACMessage{}, err @@ -128,7 +130,7 @@ func (s LocateService) UserInfoQuery(_ context.Context, sess *state.Session, inF }, nil } - buddySess := s.sessionManager.RetrieveByScreenName(inBody.ScreenName) + buddySess := s.sessionManager.RetrieveByScreenName(identScreenName) if buddySess == nil { return wire.SNACMessage{ Frame: wire.SNACFrame{ @@ -145,7 +147,7 @@ func (s LocateService) UserInfoQuery(_ context.Context, sess *state.Session, inF var list wire.TLVList if inBody.RequestProfile() { - profile, err := s.profileManager.Profile(inBody.ScreenName) + profile, err := s.profileManager.Profile(identScreenName) if err != nil { return wire.SNACMessage{}, err } diff --git a/foodgroup/locate_test.go b/foodgroup/locate_test.go index 026737f4..9df5bb87 100644 --- a/foodgroup/locate_test.go +++ b/foodgroup/locate_test.go @@ -31,8 +31,8 @@ func TestLocateService_UserInfoQuery(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ blockedStateParams: blockedStateParams{ { - screenName1: "user_screen_name", - screenName2: "requested-user", + screenName1: state.NewIdentScreenName("user_screen_name"), + screenName2: state.NewIdentScreenName("requested-user"), result: state.BlockedNo, }, }, @@ -40,7 +40,7 @@ func TestLocateService_UserInfoQuery(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "requested-user", + screenName: state.NewIdentScreenName("requested-user"), sess: newTestSession("requested-user", sessOptCannedSignonTime, sessOptCannedAwayMessage), @@ -79,8 +79,8 @@ func TestLocateService_UserInfoQuery(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ blockedStateParams: blockedStateParams{ { - screenName1: "user_screen_name", - screenName2: "requested-user", + screenName1: state.NewIdentScreenName("user_screen_name"), + screenName2: state.NewIdentScreenName("requested-user"), result: state.BlockedNo, }, }, @@ -88,7 +88,7 @@ func TestLocateService_UserInfoQuery(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "requested-user", + screenName: state.NewIdentScreenName("requested-user"), sess: newTestSession("requested-user", sessOptCannedSignonTime, sessOptCannedAwayMessage), @@ -98,7 +98,7 @@ func TestLocateService_UserInfoQuery(t *testing.T) { profileManagerParams: profileManagerParams{ retrieveProfileParams: retrieveProfileParams{ { - screenName: "requested-user", + screenName: state.NewIdentScreenName("requested-user"), result: "this is my profile!", }, }, @@ -141,8 +141,8 @@ func TestLocateService_UserInfoQuery(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ blockedStateParams: blockedStateParams{ { - screenName1: "user_screen_name", - screenName2: "requested-user", + screenName1: state.NewIdentScreenName("user_screen_name"), + screenName2: state.NewIdentScreenName("requested-user"), result: state.BlockedNo, }, }, @@ -150,7 +150,7 @@ func TestLocateService_UserInfoQuery(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "requested-user", + screenName: state.NewIdentScreenName("requested-user"), sess: newTestSession("requested-user", sessOptCannedSignonTime, sessOptCannedAwayMessage), @@ -160,7 +160,7 @@ func TestLocateService_UserInfoQuery(t *testing.T) { profileManagerParams: profileManagerParams{ retrieveProfileParams: retrieveProfileParams{ { - screenName: "requested-user", + screenName: state.NewIdentScreenName("requested-user"), result: "this is my profile!", }, }, @@ -203,8 +203,8 @@ func TestLocateService_UserInfoQuery(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ blockedStateParams: blockedStateParams{ { - screenName1: "user_screen_name", - screenName2: "requested-user", + screenName1: state.NewIdentScreenName("user_screen_name"), + screenName2: state.NewIdentScreenName("requested-user"), result: state.BlockedNo, }, }, @@ -212,7 +212,7 @@ func TestLocateService_UserInfoQuery(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "requested-user", + screenName: state.NewIdentScreenName("requested-user"), sess: newTestSession("requested-user", sessOptCannedSignonTime, sessOptCannedAwayMessage), @@ -257,8 +257,8 @@ func TestLocateService_UserInfoQuery(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ blockedStateParams: blockedStateParams{ { - screenName1: "user_screen_name", - screenName2: "requested-user", + screenName1: state.NewIdentScreenName("user_screen_name"), + screenName2: state.NewIdentScreenName("requested-user"), result: state.BlockedB, }, }, @@ -290,8 +290,8 @@ func TestLocateService_UserInfoQuery(t *testing.T) { feedbagManagerParams: feedbagManagerParams{ blockedStateParams: blockedStateParams{ { - screenName1: "user_screen_name", - screenName2: "non_existent_requested_user", + screenName1: state.NewIdentScreenName("user_screen_name"), + screenName2: state.NewIdentScreenName("non_existent_requested_user"), result: state.BlockedNo, }, }, @@ -299,7 +299,7 @@ func TestLocateService_UserInfoQuery(t *testing.T) { messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "non_existent_requested_user", + screenName: state.NewIdentScreenName("non_existent_requested_user"), sess: nil, }, }, @@ -425,7 +425,7 @@ func TestLocateService_SetInfo(t *testing.T) { profileManagerParams: profileManagerParams{ setProfileParams: setProfileParams{ { - screenName: "test-user", + screenName: state.NewIdentScreenName("test-user"), body: "profile-result", }, }, @@ -446,7 +446,7 @@ func TestLocateService_SetInfo(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -466,7 +466,7 @@ func TestLocateService_SetInfo(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } diff --git a/foodgroup/mock_chat_message_relayer_test.go b/foodgroup/mock_chat_message_relayer_test.go index e2f08595..6d45859c 100644 --- a/foodgroup/mock_chat_message_relayer_test.go +++ b/foodgroup/mock_chat_message_relayer_test.go @@ -107,7 +107,7 @@ func (_c *mockChatMessageRelayer_RelayToAllExcept_Call) RunAndReturn(run func(co } // RelayToScreenName provides a mock function with given fields: ctx, screenName, msg -func (_m *mockChatMessageRelayer) RelayToScreenName(ctx context.Context, screenName string, msg wire.SNACMessage) { +func (_m *mockChatMessageRelayer) RelayToScreenName(ctx context.Context, screenName state.IdentScreenName, msg wire.SNACMessage) { _m.Called(ctx, screenName, msg) } @@ -118,15 +118,15 @@ type mockChatMessageRelayer_RelayToScreenName_Call struct { // RelayToScreenName is a helper method to define mock.On call // - ctx context.Context -// - screenName string +// - screenName state.IdentScreenName // - msg wire.SNACMessage func (_e *mockChatMessageRelayer_Expecter) RelayToScreenName(ctx interface{}, screenName interface{}, msg interface{}) *mockChatMessageRelayer_RelayToScreenName_Call { return &mockChatMessageRelayer_RelayToScreenName_Call{Call: _e.mock.On("RelayToScreenName", ctx, screenName, msg)} } -func (_c *mockChatMessageRelayer_RelayToScreenName_Call) Run(run func(ctx context.Context, screenName string, msg wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenName_Call { +func (_c *mockChatMessageRelayer_RelayToScreenName_Call) Run(run func(ctx context.Context, screenName state.IdentScreenName, msg wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenName_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(wire.SNACMessage)) + run(args[0].(context.Context), args[1].(state.IdentScreenName), args[2].(wire.SNACMessage)) }) return _c } @@ -136,13 +136,13 @@ func (_c *mockChatMessageRelayer_RelayToScreenName_Call) Return() *mockChatMessa return _c } -func (_c *mockChatMessageRelayer_RelayToScreenName_Call) RunAndReturn(run func(context.Context, string, wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenName_Call { +func (_c *mockChatMessageRelayer_RelayToScreenName_Call) RunAndReturn(run func(context.Context, state.IdentScreenName, wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenName_Call { _c.Call.Return(run) return _c } // RelayToScreenNames provides a mock function with given fields: ctx, screenNames, msg -func (_m *mockChatMessageRelayer) RelayToScreenNames(ctx context.Context, screenNames []string, msg wire.SNACMessage) { +func (_m *mockChatMessageRelayer) RelayToScreenNames(ctx context.Context, screenNames []state.IdentScreenName, msg wire.SNACMessage) { _m.Called(ctx, screenNames, msg) } @@ -153,15 +153,15 @@ type mockChatMessageRelayer_RelayToScreenNames_Call struct { // RelayToScreenNames is a helper method to define mock.On call // - ctx context.Context -// - screenNames []string +// - screenNames []state.IdentScreenName // - msg wire.SNACMessage func (_e *mockChatMessageRelayer_Expecter) RelayToScreenNames(ctx interface{}, screenNames interface{}, msg interface{}) *mockChatMessageRelayer_RelayToScreenNames_Call { return &mockChatMessageRelayer_RelayToScreenNames_Call{Call: _e.mock.On("RelayToScreenNames", ctx, screenNames, msg)} } -func (_c *mockChatMessageRelayer_RelayToScreenNames_Call) Run(run func(ctx context.Context, screenNames []string, msg wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenNames_Call { +func (_c *mockChatMessageRelayer_RelayToScreenNames_Call) Run(run func(ctx context.Context, screenNames []state.IdentScreenName, msg wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenNames_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].([]string), args[2].(wire.SNACMessage)) + run(args[0].(context.Context), args[1].([]state.IdentScreenName), args[2].(wire.SNACMessage)) }) return _c } @@ -171,13 +171,13 @@ func (_c *mockChatMessageRelayer_RelayToScreenNames_Call) Return() *mockChatMess return _c } -func (_c *mockChatMessageRelayer_RelayToScreenNames_Call) RunAndReturn(run func(context.Context, []string, wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenNames_Call { +func (_c *mockChatMessageRelayer_RelayToScreenNames_Call) RunAndReturn(run func(context.Context, []state.IdentScreenName, wire.SNACMessage)) *mockChatMessageRelayer_RelayToScreenNames_Call { _c.Call.Return(run) return _c } // RetrieveByScreenName provides a mock function with given fields: screenName -func (_m *mockChatMessageRelayer) RetrieveByScreenName(screenName string) *state.Session { +func (_m *mockChatMessageRelayer) RetrieveByScreenName(screenName state.IdentScreenName) *state.Session { ret := _m.Called(screenName) if len(ret) == 0 { @@ -185,7 +185,7 @@ func (_m *mockChatMessageRelayer) RetrieveByScreenName(screenName string) *state } var r0 *state.Session - if rf, ok := ret.Get(0).(func(string) *state.Session); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.Session); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { @@ -202,14 +202,14 @@ type mockChatMessageRelayer_RetrieveByScreenName_Call struct { } // RetrieveByScreenName is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockChatMessageRelayer_Expecter) RetrieveByScreenName(screenName interface{}) *mockChatMessageRelayer_RetrieveByScreenName_Call { return &mockChatMessageRelayer_RetrieveByScreenName_Call{Call: _e.mock.On("RetrieveByScreenName", screenName)} } -func (_c *mockChatMessageRelayer_RetrieveByScreenName_Call) Run(run func(screenName string)) *mockChatMessageRelayer_RetrieveByScreenName_Call { +func (_c *mockChatMessageRelayer_RetrieveByScreenName_Call) Run(run func(screenName state.IdentScreenName)) *mockChatMessageRelayer_RetrieveByScreenName_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -219,7 +219,7 @@ func (_c *mockChatMessageRelayer_RetrieveByScreenName_Call) Return(_a0 *state.Se return _c } -func (_c *mockChatMessageRelayer_RetrieveByScreenName_Call) RunAndReturn(run func(string) *state.Session) *mockChatMessageRelayer_RetrieveByScreenName_Call { +func (_c *mockChatMessageRelayer_RetrieveByScreenName_Call) RunAndReturn(run func(state.IdentScreenName) *state.Session) *mockChatMessageRelayer_RetrieveByScreenName_Call { _c.Call.Return(run) return _c } diff --git a/foodgroup/mock_feedbag_manager_test.go b/foodgroup/mock_feedbag_manager_test.go index 35a87633..e1b3b438 100644 --- a/foodgroup/mock_feedbag_manager_test.go +++ b/foodgroup/mock_feedbag_manager_test.go @@ -25,27 +25,27 @@ func (_m *mockFeedbagManager) EXPECT() *mockFeedbagManager_Expecter { } // AdjacentUsers provides a mock function with given fields: screenName -func (_m *mockFeedbagManager) AdjacentUsers(screenName string) ([]string, error) { +func (_m *mockFeedbagManager) AdjacentUsers(screenName state.IdentScreenName) ([]state.IdentScreenName, error) { ret := _m.Called(screenName) if len(ret) == 0 { panic("no return value specified for AdjacentUsers") } - var r0 []string + var r0 []state.IdentScreenName var r1 error - if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) ([]state.IdentScreenName, error)); ok { return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) []string); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) []state.IdentScreenName); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) + r0 = ret.Get(0).([]state.IdentScreenName) } } - if rf, ok := ret.Get(1).(func(string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { r1 = rf(screenName) } else { r1 = ret.Error(1) @@ -60,30 +60,30 @@ type mockFeedbagManager_AdjacentUsers_Call struct { } // AdjacentUsers is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockFeedbagManager_Expecter) AdjacentUsers(screenName interface{}) *mockFeedbagManager_AdjacentUsers_Call { return &mockFeedbagManager_AdjacentUsers_Call{Call: _e.mock.On("AdjacentUsers", screenName)} } -func (_c *mockFeedbagManager_AdjacentUsers_Call) Run(run func(screenName string)) *mockFeedbagManager_AdjacentUsers_Call { +func (_c *mockFeedbagManager_AdjacentUsers_Call) Run(run func(screenName state.IdentScreenName)) *mockFeedbagManager_AdjacentUsers_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } -func (_c *mockFeedbagManager_AdjacentUsers_Call) Return(_a0 []string, _a1 error) *mockFeedbagManager_AdjacentUsers_Call { +func (_c *mockFeedbagManager_AdjacentUsers_Call) Return(_a0 []state.IdentScreenName, _a1 error) *mockFeedbagManager_AdjacentUsers_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *mockFeedbagManager_AdjacentUsers_Call) RunAndReturn(run func(string) ([]string, error)) *mockFeedbagManager_AdjacentUsers_Call { +func (_c *mockFeedbagManager_AdjacentUsers_Call) RunAndReturn(run func(state.IdentScreenName) ([]state.IdentScreenName, error)) *mockFeedbagManager_AdjacentUsers_Call { _c.Call.Return(run) return _c } // BlockedState provides a mock function with given fields: screenName1, screenName2 -func (_m *mockFeedbagManager) BlockedState(screenName1 string, screenName2 string) (state.BlockedState, error) { +func (_m *mockFeedbagManager) BlockedState(screenName1 state.IdentScreenName, screenName2 state.IdentScreenName) (state.BlockedState, error) { ret := _m.Called(screenName1, screenName2) if len(ret) == 0 { @@ -92,16 +92,16 @@ func (_m *mockFeedbagManager) BlockedState(screenName1 string, screenName2 strin var r0 state.BlockedState var r1 error - if rf, ok := ret.Get(0).(func(string, string) (state.BlockedState, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName, state.IdentScreenName) (state.BlockedState, error)); ok { return rf(screenName1, screenName2) } - if rf, ok := ret.Get(0).(func(string, string) state.BlockedState); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName, state.IdentScreenName) state.BlockedState); ok { r0 = rf(screenName1, screenName2) } else { r0 = ret.Get(0).(state.BlockedState) } - if rf, ok := ret.Get(1).(func(string, string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName, state.IdentScreenName) error); ok { r1 = rf(screenName1, screenName2) } else { r1 = ret.Error(1) @@ -116,15 +116,15 @@ type mockFeedbagManager_BlockedState_Call struct { } // BlockedState is a helper method to define mock.On call -// - screenName1 string -// - screenName2 string +// - screenName1 state.IdentScreenName +// - screenName2 state.IdentScreenName func (_e *mockFeedbagManager_Expecter) BlockedState(screenName1 interface{}, screenName2 interface{}) *mockFeedbagManager_BlockedState_Call { return &mockFeedbagManager_BlockedState_Call{Call: _e.mock.On("BlockedState", screenName1, screenName2)} } -func (_c *mockFeedbagManager_BlockedState_Call) Run(run func(screenName1 string, screenName2 string)) *mockFeedbagManager_BlockedState_Call { +func (_c *mockFeedbagManager_BlockedState_Call) Run(run func(screenName1 state.IdentScreenName, screenName2 state.IdentScreenName)) *mockFeedbagManager_BlockedState_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + run(args[0].(state.IdentScreenName), args[1].(state.IdentScreenName)) }) return _c } @@ -134,33 +134,33 @@ func (_c *mockFeedbagManager_BlockedState_Call) Return(_a0 state.BlockedState, _ return _c } -func (_c *mockFeedbagManager_BlockedState_Call) RunAndReturn(run func(string, string) (state.BlockedState, error)) *mockFeedbagManager_BlockedState_Call { +func (_c *mockFeedbagManager_BlockedState_Call) RunAndReturn(run func(state.IdentScreenName, state.IdentScreenName) (state.BlockedState, error)) *mockFeedbagManager_BlockedState_Call { _c.Call.Return(run) return _c } // Buddies provides a mock function with given fields: screenName -func (_m *mockFeedbagManager) Buddies(screenName string) ([]string, error) { +func (_m *mockFeedbagManager) Buddies(screenName state.IdentScreenName) ([]state.IdentScreenName, error) { ret := _m.Called(screenName) if len(ret) == 0 { panic("no return value specified for Buddies") } - var r0 []string + var r0 []state.IdentScreenName var r1 error - if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) ([]state.IdentScreenName, error)); ok { return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) []string); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) []state.IdentScreenName); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) + r0 = ret.Get(0).([]state.IdentScreenName) } } - if rf, ok := ret.Get(1).(func(string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { r1 = rf(screenName) } else { r1 = ret.Error(1) @@ -175,30 +175,30 @@ type mockFeedbagManager_Buddies_Call struct { } // Buddies is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockFeedbagManager_Expecter) Buddies(screenName interface{}) *mockFeedbagManager_Buddies_Call { return &mockFeedbagManager_Buddies_Call{Call: _e.mock.On("Buddies", screenName)} } -func (_c *mockFeedbagManager_Buddies_Call) Run(run func(screenName string)) *mockFeedbagManager_Buddies_Call { +func (_c *mockFeedbagManager_Buddies_Call) Run(run func(screenName state.IdentScreenName)) *mockFeedbagManager_Buddies_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } -func (_c *mockFeedbagManager_Buddies_Call) Return(_a0 []string, _a1 error) *mockFeedbagManager_Buddies_Call { +func (_c *mockFeedbagManager_Buddies_Call) Return(_a0 []state.IdentScreenName, _a1 error) *mockFeedbagManager_Buddies_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *mockFeedbagManager_Buddies_Call) RunAndReturn(run func(string) ([]string, error)) *mockFeedbagManager_Buddies_Call { +func (_c *mockFeedbagManager_Buddies_Call) RunAndReturn(run func(state.IdentScreenName) ([]state.IdentScreenName, error)) *mockFeedbagManager_Buddies_Call { _c.Call.Return(run) return _c } // Feedbag provides a mock function with given fields: screenName -func (_m *mockFeedbagManager) Feedbag(screenName string) ([]wire.FeedbagItem, error) { +func (_m *mockFeedbagManager) Feedbag(screenName state.IdentScreenName) ([]wire.FeedbagItem, error) { ret := _m.Called(screenName) if len(ret) == 0 { @@ -207,10 +207,10 @@ func (_m *mockFeedbagManager) Feedbag(screenName string) ([]wire.FeedbagItem, er var r0 []wire.FeedbagItem var r1 error - if rf, ok := ret.Get(0).(func(string) ([]wire.FeedbagItem, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) ([]wire.FeedbagItem, error)); ok { return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) []wire.FeedbagItem); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) []wire.FeedbagItem); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { @@ -218,7 +218,7 @@ func (_m *mockFeedbagManager) Feedbag(screenName string) ([]wire.FeedbagItem, er } } - if rf, ok := ret.Get(1).(func(string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { r1 = rf(screenName) } else { r1 = ret.Error(1) @@ -233,14 +233,14 @@ type mockFeedbagManager_Feedbag_Call struct { } // Feedbag is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockFeedbagManager_Expecter) Feedbag(screenName interface{}) *mockFeedbagManager_Feedbag_Call { return &mockFeedbagManager_Feedbag_Call{Call: _e.mock.On("Feedbag", screenName)} } -func (_c *mockFeedbagManager_Feedbag_Call) Run(run func(screenName string)) *mockFeedbagManager_Feedbag_Call { +func (_c *mockFeedbagManager_Feedbag_Call) Run(run func(screenName state.IdentScreenName)) *mockFeedbagManager_Feedbag_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -250,13 +250,13 @@ func (_c *mockFeedbagManager_Feedbag_Call) Return(_a0 []wire.FeedbagItem, _a1 er return _c } -func (_c *mockFeedbagManager_Feedbag_Call) RunAndReturn(run func(string) ([]wire.FeedbagItem, error)) *mockFeedbagManager_Feedbag_Call { +func (_c *mockFeedbagManager_Feedbag_Call) RunAndReturn(run func(state.IdentScreenName) ([]wire.FeedbagItem, error)) *mockFeedbagManager_Feedbag_Call { _c.Call.Return(run) return _c } // FeedbagDelete provides a mock function with given fields: screenName, items -func (_m *mockFeedbagManager) FeedbagDelete(screenName string, items []wire.FeedbagItem) error { +func (_m *mockFeedbagManager) FeedbagDelete(screenName state.IdentScreenName, items []wire.FeedbagItem) error { ret := _m.Called(screenName, items) if len(ret) == 0 { @@ -264,7 +264,7 @@ func (_m *mockFeedbagManager) FeedbagDelete(screenName string, items []wire.Feed } var r0 error - if rf, ok := ret.Get(0).(func(string, []wire.FeedbagItem) error); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName, []wire.FeedbagItem) error); ok { r0 = rf(screenName, items) } else { r0 = ret.Error(0) @@ -279,15 +279,15 @@ type mockFeedbagManager_FeedbagDelete_Call struct { } // FeedbagDelete is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName // - items []wire.FeedbagItem func (_e *mockFeedbagManager_Expecter) FeedbagDelete(screenName interface{}, items interface{}) *mockFeedbagManager_FeedbagDelete_Call { return &mockFeedbagManager_FeedbagDelete_Call{Call: _e.mock.On("FeedbagDelete", screenName, items)} } -func (_c *mockFeedbagManager_FeedbagDelete_Call) Run(run func(screenName string, items []wire.FeedbagItem)) *mockFeedbagManager_FeedbagDelete_Call { +func (_c *mockFeedbagManager_FeedbagDelete_Call) Run(run func(screenName state.IdentScreenName, items []wire.FeedbagItem)) *mockFeedbagManager_FeedbagDelete_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]wire.FeedbagItem)) + run(args[0].(state.IdentScreenName), args[1].([]wire.FeedbagItem)) }) return _c } @@ -297,13 +297,13 @@ func (_c *mockFeedbagManager_FeedbagDelete_Call) Return(_a0 error) *mockFeedbagM return _c } -func (_c *mockFeedbagManager_FeedbagDelete_Call) RunAndReturn(run func(string, []wire.FeedbagItem) error) *mockFeedbagManager_FeedbagDelete_Call { +func (_c *mockFeedbagManager_FeedbagDelete_Call) RunAndReturn(run func(state.IdentScreenName, []wire.FeedbagItem) error) *mockFeedbagManager_FeedbagDelete_Call { _c.Call.Return(run) return _c } // FeedbagLastModified provides a mock function with given fields: screenName -func (_m *mockFeedbagManager) FeedbagLastModified(screenName string) (time.Time, error) { +func (_m *mockFeedbagManager) FeedbagLastModified(screenName state.IdentScreenName) (time.Time, error) { ret := _m.Called(screenName) if len(ret) == 0 { @@ -312,16 +312,16 @@ func (_m *mockFeedbagManager) FeedbagLastModified(screenName string) (time.Time, var r0 time.Time var r1 error - if rf, ok := ret.Get(0).(func(string) (time.Time, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) (time.Time, error)); ok { return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) time.Time); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) time.Time); ok { r0 = rf(screenName) } else { r0 = ret.Get(0).(time.Time) } - if rf, ok := ret.Get(1).(func(string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { r1 = rf(screenName) } else { r1 = ret.Error(1) @@ -336,14 +336,14 @@ type mockFeedbagManager_FeedbagLastModified_Call struct { } // FeedbagLastModified is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockFeedbagManager_Expecter) FeedbagLastModified(screenName interface{}) *mockFeedbagManager_FeedbagLastModified_Call { return &mockFeedbagManager_FeedbagLastModified_Call{Call: _e.mock.On("FeedbagLastModified", screenName)} } -func (_c *mockFeedbagManager_FeedbagLastModified_Call) Run(run func(screenName string)) *mockFeedbagManager_FeedbagLastModified_Call { +func (_c *mockFeedbagManager_FeedbagLastModified_Call) Run(run func(screenName state.IdentScreenName)) *mockFeedbagManager_FeedbagLastModified_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -353,13 +353,13 @@ func (_c *mockFeedbagManager_FeedbagLastModified_Call) Return(_a0 time.Time, _a1 return _c } -func (_c *mockFeedbagManager_FeedbagLastModified_Call) RunAndReturn(run func(string) (time.Time, error)) *mockFeedbagManager_FeedbagLastModified_Call { +func (_c *mockFeedbagManager_FeedbagLastModified_Call) RunAndReturn(run func(state.IdentScreenName) (time.Time, error)) *mockFeedbagManager_FeedbagLastModified_Call { _c.Call.Return(run) return _c } // FeedbagUpsert provides a mock function with given fields: screenName, items -func (_m *mockFeedbagManager) FeedbagUpsert(screenName string, items []wire.FeedbagItem) error { +func (_m *mockFeedbagManager) FeedbagUpsert(screenName state.IdentScreenName, items []wire.FeedbagItem) error { ret := _m.Called(screenName, items) if len(ret) == 0 { @@ -367,7 +367,7 @@ func (_m *mockFeedbagManager) FeedbagUpsert(screenName string, items []wire.Feed } var r0 error - if rf, ok := ret.Get(0).(func(string, []wire.FeedbagItem) error); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName, []wire.FeedbagItem) error); ok { r0 = rf(screenName, items) } else { r0 = ret.Error(0) @@ -382,15 +382,15 @@ type mockFeedbagManager_FeedbagUpsert_Call struct { } // FeedbagUpsert is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName // - items []wire.FeedbagItem func (_e *mockFeedbagManager_Expecter) FeedbagUpsert(screenName interface{}, items interface{}) *mockFeedbagManager_FeedbagUpsert_Call { return &mockFeedbagManager_FeedbagUpsert_Call{Call: _e.mock.On("FeedbagUpsert", screenName, items)} } -func (_c *mockFeedbagManager_FeedbagUpsert_Call) Run(run func(screenName string, items []wire.FeedbagItem)) *mockFeedbagManager_FeedbagUpsert_Call { +func (_c *mockFeedbagManager_FeedbagUpsert_Call) Run(run func(screenName state.IdentScreenName, items []wire.FeedbagItem)) *mockFeedbagManager_FeedbagUpsert_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]wire.FeedbagItem)) + run(args[0].(state.IdentScreenName), args[1].([]wire.FeedbagItem)) }) return _c } @@ -400,7 +400,7 @@ func (_c *mockFeedbagManager_FeedbagUpsert_Call) Return(_a0 error) *mockFeedbagM return _c } -func (_c *mockFeedbagManager_FeedbagUpsert_Call) RunAndReturn(run func(string, []wire.FeedbagItem) error) *mockFeedbagManager_FeedbagUpsert_Call { +func (_c *mockFeedbagManager_FeedbagUpsert_Call) RunAndReturn(run func(state.IdentScreenName, []wire.FeedbagItem) error) *mockFeedbagManager_FeedbagUpsert_Call { _c.Call.Return(run) return _c } diff --git a/foodgroup/mock_legacy_buddy_list_manager_test.go b/foodgroup/mock_legacy_buddy_list_manager_test.go index aead877a..b8387cc7 100644 --- a/foodgroup/mock_legacy_buddy_list_manager_test.go +++ b/foodgroup/mock_legacy_buddy_list_manager_test.go @@ -2,7 +2,10 @@ package foodgroup -import mock "github.com/stretchr/testify/mock" +import ( + state "github.com/mk6i/retro-aim-server/state" + mock "github.com/stretchr/testify/mock" +) // mockLegacyBuddyListManager is an autogenerated mock type for the LegacyBuddyListManager type type mockLegacyBuddyListManager struct { @@ -18,7 +21,7 @@ func (_m *mockLegacyBuddyListManager) EXPECT() *mockLegacyBuddyListManager_Expec } // AddBuddy provides a mock function with given fields: userScreenName, buddyScreenName -func (_m *mockLegacyBuddyListManager) AddBuddy(userScreenName string, buddyScreenName string) { +func (_m *mockLegacyBuddyListManager) AddBuddy(userScreenName state.IdentScreenName, buddyScreenName state.IdentScreenName) { _m.Called(userScreenName, buddyScreenName) } @@ -28,15 +31,15 @@ type mockLegacyBuddyListManager_AddBuddy_Call struct { } // AddBuddy is a helper method to define mock.On call -// - userScreenName string -// - buddyScreenName string +// - userScreenName state.IdentScreenName +// - buddyScreenName state.IdentScreenName func (_e *mockLegacyBuddyListManager_Expecter) AddBuddy(userScreenName interface{}, buddyScreenName interface{}) *mockLegacyBuddyListManager_AddBuddy_Call { return &mockLegacyBuddyListManager_AddBuddy_Call{Call: _e.mock.On("AddBuddy", userScreenName, buddyScreenName)} } -func (_c *mockLegacyBuddyListManager_AddBuddy_Call) Run(run func(userScreenName string, buddyScreenName string)) *mockLegacyBuddyListManager_AddBuddy_Call { +func (_c *mockLegacyBuddyListManager_AddBuddy_Call) Run(run func(userScreenName state.IdentScreenName, buddyScreenName state.IdentScreenName)) *mockLegacyBuddyListManager_AddBuddy_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + run(args[0].(state.IdentScreenName), args[1].(state.IdentScreenName)) }) return _c } @@ -46,25 +49,25 @@ func (_c *mockLegacyBuddyListManager_AddBuddy_Call) Return() *mockLegacyBuddyLis return _c } -func (_c *mockLegacyBuddyListManager_AddBuddy_Call) RunAndReturn(run func(string, string)) *mockLegacyBuddyListManager_AddBuddy_Call { +func (_c *mockLegacyBuddyListManager_AddBuddy_Call) RunAndReturn(run func(state.IdentScreenName, state.IdentScreenName)) *mockLegacyBuddyListManager_AddBuddy_Call { _c.Call.Return(run) return _c } // Buddies provides a mock function with given fields: userScreenName -func (_m *mockLegacyBuddyListManager) Buddies(userScreenName string) []string { +func (_m *mockLegacyBuddyListManager) Buddies(userScreenName state.IdentScreenName) []state.IdentScreenName { ret := _m.Called(userScreenName) if len(ret) == 0 { panic("no return value specified for Buddies") } - var r0 []string - if rf, ok := ret.Get(0).(func(string) []string); ok { + var r0 []state.IdentScreenName + if rf, ok := ret.Get(0).(func(state.IdentScreenName) []state.IdentScreenName); ok { r0 = rf(userScreenName) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) + r0 = ret.Get(0).([]state.IdentScreenName) } } @@ -77,30 +80,30 @@ type mockLegacyBuddyListManager_Buddies_Call struct { } // Buddies is a helper method to define mock.On call -// - userScreenName string +// - userScreenName state.IdentScreenName func (_e *mockLegacyBuddyListManager_Expecter) Buddies(userScreenName interface{}) *mockLegacyBuddyListManager_Buddies_Call { return &mockLegacyBuddyListManager_Buddies_Call{Call: _e.mock.On("Buddies", userScreenName)} } -func (_c *mockLegacyBuddyListManager_Buddies_Call) Run(run func(userScreenName string)) *mockLegacyBuddyListManager_Buddies_Call { +func (_c *mockLegacyBuddyListManager_Buddies_Call) Run(run func(userScreenName state.IdentScreenName)) *mockLegacyBuddyListManager_Buddies_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } -func (_c *mockLegacyBuddyListManager_Buddies_Call) Return(_a0 []string) *mockLegacyBuddyListManager_Buddies_Call { +func (_c *mockLegacyBuddyListManager_Buddies_Call) Return(_a0 []state.IdentScreenName) *mockLegacyBuddyListManager_Buddies_Call { _c.Call.Return(_a0) return _c } -func (_c *mockLegacyBuddyListManager_Buddies_Call) RunAndReturn(run func(string) []string) *mockLegacyBuddyListManager_Buddies_Call { +func (_c *mockLegacyBuddyListManager_Buddies_Call) RunAndReturn(run func(state.IdentScreenName) []state.IdentScreenName) *mockLegacyBuddyListManager_Buddies_Call { _c.Call.Return(run) return _c } // DeleteBuddy provides a mock function with given fields: userScreenName, buddyScreenName -func (_m *mockLegacyBuddyListManager) DeleteBuddy(userScreenName string, buddyScreenName string) { +func (_m *mockLegacyBuddyListManager) DeleteBuddy(userScreenName state.IdentScreenName, buddyScreenName state.IdentScreenName) { _m.Called(userScreenName, buddyScreenName) } @@ -110,15 +113,15 @@ type mockLegacyBuddyListManager_DeleteBuddy_Call struct { } // DeleteBuddy is a helper method to define mock.On call -// - userScreenName string -// - buddyScreenName string +// - userScreenName state.IdentScreenName +// - buddyScreenName state.IdentScreenName func (_e *mockLegacyBuddyListManager_Expecter) DeleteBuddy(userScreenName interface{}, buddyScreenName interface{}) *mockLegacyBuddyListManager_DeleteBuddy_Call { return &mockLegacyBuddyListManager_DeleteBuddy_Call{Call: _e.mock.On("DeleteBuddy", userScreenName, buddyScreenName)} } -func (_c *mockLegacyBuddyListManager_DeleteBuddy_Call) Run(run func(userScreenName string, buddyScreenName string)) *mockLegacyBuddyListManager_DeleteBuddy_Call { +func (_c *mockLegacyBuddyListManager_DeleteBuddy_Call) Run(run func(userScreenName state.IdentScreenName, buddyScreenName state.IdentScreenName)) *mockLegacyBuddyListManager_DeleteBuddy_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + run(args[0].(state.IdentScreenName), args[1].(state.IdentScreenName)) }) return _c } @@ -128,13 +131,13 @@ func (_c *mockLegacyBuddyListManager_DeleteBuddy_Call) Return() *mockLegacyBuddy return _c } -func (_c *mockLegacyBuddyListManager_DeleteBuddy_Call) RunAndReturn(run func(string, string)) *mockLegacyBuddyListManager_DeleteBuddy_Call { +func (_c *mockLegacyBuddyListManager_DeleteBuddy_Call) RunAndReturn(run func(state.IdentScreenName, state.IdentScreenName)) *mockLegacyBuddyListManager_DeleteBuddy_Call { _c.Call.Return(run) return _c } // DeleteUser provides a mock function with given fields: userScreenName -func (_m *mockLegacyBuddyListManager) DeleteUser(userScreenName string) { +func (_m *mockLegacyBuddyListManager) DeleteUser(userScreenName state.IdentScreenName) { _m.Called(userScreenName) } @@ -144,14 +147,14 @@ type mockLegacyBuddyListManager_DeleteUser_Call struct { } // DeleteUser is a helper method to define mock.On call -// - userScreenName string +// - userScreenName state.IdentScreenName func (_e *mockLegacyBuddyListManager_Expecter) DeleteUser(userScreenName interface{}) *mockLegacyBuddyListManager_DeleteUser_Call { return &mockLegacyBuddyListManager_DeleteUser_Call{Call: _e.mock.On("DeleteUser", userScreenName)} } -func (_c *mockLegacyBuddyListManager_DeleteUser_Call) Run(run func(userScreenName string)) *mockLegacyBuddyListManager_DeleteUser_Call { +func (_c *mockLegacyBuddyListManager_DeleteUser_Call) Run(run func(userScreenName state.IdentScreenName)) *mockLegacyBuddyListManager_DeleteUser_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -161,25 +164,25 @@ func (_c *mockLegacyBuddyListManager_DeleteUser_Call) Return() *mockLegacyBuddyL return _c } -func (_c *mockLegacyBuddyListManager_DeleteUser_Call) RunAndReturn(run func(string)) *mockLegacyBuddyListManager_DeleteUser_Call { +func (_c *mockLegacyBuddyListManager_DeleteUser_Call) RunAndReturn(run func(state.IdentScreenName)) *mockLegacyBuddyListManager_DeleteUser_Call { _c.Call.Return(run) return _c } // WhoAddedUser provides a mock function with given fields: userScreenName -func (_m *mockLegacyBuddyListManager) WhoAddedUser(userScreenName string) []string { +func (_m *mockLegacyBuddyListManager) WhoAddedUser(userScreenName state.IdentScreenName) []state.IdentScreenName { ret := _m.Called(userScreenName) if len(ret) == 0 { panic("no return value specified for WhoAddedUser") } - var r0 []string - if rf, ok := ret.Get(0).(func(string) []string); ok { + var r0 []state.IdentScreenName + if rf, ok := ret.Get(0).(func(state.IdentScreenName) []state.IdentScreenName); ok { r0 = rf(userScreenName) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) + r0 = ret.Get(0).([]state.IdentScreenName) } } @@ -192,24 +195,24 @@ type mockLegacyBuddyListManager_WhoAddedUser_Call struct { } // WhoAddedUser is a helper method to define mock.On call -// - userScreenName string +// - userScreenName state.IdentScreenName func (_e *mockLegacyBuddyListManager_Expecter) WhoAddedUser(userScreenName interface{}) *mockLegacyBuddyListManager_WhoAddedUser_Call { return &mockLegacyBuddyListManager_WhoAddedUser_Call{Call: _e.mock.On("WhoAddedUser", userScreenName)} } -func (_c *mockLegacyBuddyListManager_WhoAddedUser_Call) Run(run func(userScreenName string)) *mockLegacyBuddyListManager_WhoAddedUser_Call { +func (_c *mockLegacyBuddyListManager_WhoAddedUser_Call) Run(run func(userScreenName state.IdentScreenName)) *mockLegacyBuddyListManager_WhoAddedUser_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } -func (_c *mockLegacyBuddyListManager_WhoAddedUser_Call) Return(_a0 []string) *mockLegacyBuddyListManager_WhoAddedUser_Call { +func (_c *mockLegacyBuddyListManager_WhoAddedUser_Call) Return(_a0 []state.IdentScreenName) *mockLegacyBuddyListManager_WhoAddedUser_Call { _c.Call.Return(_a0) return _c } -func (_c *mockLegacyBuddyListManager_WhoAddedUser_Call) RunAndReturn(run func(string) []string) *mockLegacyBuddyListManager_WhoAddedUser_Call { +func (_c *mockLegacyBuddyListManager_WhoAddedUser_Call) RunAndReturn(run func(state.IdentScreenName) []state.IdentScreenName) *mockLegacyBuddyListManager_WhoAddedUser_Call { _c.Call.Return(run) return _c } diff --git a/foodgroup/mock_message_relayer_test.go b/foodgroup/mock_message_relayer_test.go index d2056db1..33f661a4 100644 --- a/foodgroup/mock_message_relayer_test.go +++ b/foodgroup/mock_message_relayer_test.go @@ -25,7 +25,7 @@ func (_m *mockMessageRelayer) EXPECT() *mockMessageRelayer_Expecter { } // RelayToScreenName provides a mock function with given fields: ctx, screenName, msg -func (_m *mockMessageRelayer) RelayToScreenName(ctx context.Context, screenName string, msg wire.SNACMessage) { +func (_m *mockMessageRelayer) RelayToScreenName(ctx context.Context, screenName state.IdentScreenName, msg wire.SNACMessage) { _m.Called(ctx, screenName, msg) } @@ -36,15 +36,15 @@ type mockMessageRelayer_RelayToScreenName_Call struct { // RelayToScreenName is a helper method to define mock.On call // - ctx context.Context -// - screenName string +// - screenName state.IdentScreenName // - msg wire.SNACMessage func (_e *mockMessageRelayer_Expecter) RelayToScreenName(ctx interface{}, screenName interface{}, msg interface{}) *mockMessageRelayer_RelayToScreenName_Call { return &mockMessageRelayer_RelayToScreenName_Call{Call: _e.mock.On("RelayToScreenName", ctx, screenName, msg)} } -func (_c *mockMessageRelayer_RelayToScreenName_Call) Run(run func(ctx context.Context, screenName string, msg wire.SNACMessage)) *mockMessageRelayer_RelayToScreenName_Call { +func (_c *mockMessageRelayer_RelayToScreenName_Call) Run(run func(ctx context.Context, screenName state.IdentScreenName, msg wire.SNACMessage)) *mockMessageRelayer_RelayToScreenName_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(wire.SNACMessage)) + run(args[0].(context.Context), args[1].(state.IdentScreenName), args[2].(wire.SNACMessage)) }) return _c } @@ -54,13 +54,13 @@ func (_c *mockMessageRelayer_RelayToScreenName_Call) Return() *mockMessageRelaye return _c } -func (_c *mockMessageRelayer_RelayToScreenName_Call) RunAndReturn(run func(context.Context, string, wire.SNACMessage)) *mockMessageRelayer_RelayToScreenName_Call { +func (_c *mockMessageRelayer_RelayToScreenName_Call) RunAndReturn(run func(context.Context, state.IdentScreenName, wire.SNACMessage)) *mockMessageRelayer_RelayToScreenName_Call { _c.Call.Return(run) return _c } // RelayToScreenNames provides a mock function with given fields: ctx, screenNames, msg -func (_m *mockMessageRelayer) RelayToScreenNames(ctx context.Context, screenNames []string, msg wire.SNACMessage) { +func (_m *mockMessageRelayer) RelayToScreenNames(ctx context.Context, screenNames []state.IdentScreenName, msg wire.SNACMessage) { _m.Called(ctx, screenNames, msg) } @@ -71,15 +71,15 @@ type mockMessageRelayer_RelayToScreenNames_Call struct { // RelayToScreenNames is a helper method to define mock.On call // - ctx context.Context -// - screenNames []string +// - screenNames []state.IdentScreenName // - msg wire.SNACMessage func (_e *mockMessageRelayer_Expecter) RelayToScreenNames(ctx interface{}, screenNames interface{}, msg interface{}) *mockMessageRelayer_RelayToScreenNames_Call { return &mockMessageRelayer_RelayToScreenNames_Call{Call: _e.mock.On("RelayToScreenNames", ctx, screenNames, msg)} } -func (_c *mockMessageRelayer_RelayToScreenNames_Call) Run(run func(ctx context.Context, screenNames []string, msg wire.SNACMessage)) *mockMessageRelayer_RelayToScreenNames_Call { +func (_c *mockMessageRelayer_RelayToScreenNames_Call) Run(run func(ctx context.Context, screenNames []state.IdentScreenName, msg wire.SNACMessage)) *mockMessageRelayer_RelayToScreenNames_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].([]string), args[2].(wire.SNACMessage)) + run(args[0].(context.Context), args[1].([]state.IdentScreenName), args[2].(wire.SNACMessage)) }) return _c } @@ -89,13 +89,13 @@ func (_c *mockMessageRelayer_RelayToScreenNames_Call) Return() *mockMessageRelay return _c } -func (_c *mockMessageRelayer_RelayToScreenNames_Call) RunAndReturn(run func(context.Context, []string, wire.SNACMessage)) *mockMessageRelayer_RelayToScreenNames_Call { +func (_c *mockMessageRelayer_RelayToScreenNames_Call) RunAndReturn(run func(context.Context, []state.IdentScreenName, wire.SNACMessage)) *mockMessageRelayer_RelayToScreenNames_Call { _c.Call.Return(run) return _c } // RetrieveByScreenName provides a mock function with given fields: screenName -func (_m *mockMessageRelayer) RetrieveByScreenName(screenName string) *state.Session { +func (_m *mockMessageRelayer) RetrieveByScreenName(screenName state.IdentScreenName) *state.Session { ret := _m.Called(screenName) if len(ret) == 0 { @@ -103,7 +103,7 @@ func (_m *mockMessageRelayer) RetrieveByScreenName(screenName string) *state.Ses } var r0 *state.Session - if rf, ok := ret.Get(0).(func(string) *state.Session); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.Session); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { @@ -120,14 +120,14 @@ type mockMessageRelayer_RetrieveByScreenName_Call struct { } // RetrieveByScreenName is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockMessageRelayer_Expecter) RetrieveByScreenName(screenName interface{}) *mockMessageRelayer_RetrieveByScreenName_Call { return &mockMessageRelayer_RetrieveByScreenName_Call{Call: _e.mock.On("RetrieveByScreenName", screenName)} } -func (_c *mockMessageRelayer_RetrieveByScreenName_Call) Run(run func(screenName string)) *mockMessageRelayer_RetrieveByScreenName_Call { +func (_c *mockMessageRelayer_RetrieveByScreenName_Call) Run(run func(screenName state.IdentScreenName)) *mockMessageRelayer_RetrieveByScreenName_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -137,7 +137,7 @@ func (_c *mockMessageRelayer_RetrieveByScreenName_Call) Return(_a0 *state.Sessio return _c } -func (_c *mockMessageRelayer_RetrieveByScreenName_Call) RunAndReturn(run func(string) *state.Session) *mockMessageRelayer_RetrieveByScreenName_Call { +func (_c *mockMessageRelayer_RetrieveByScreenName_Call) RunAndReturn(run func(state.IdentScreenName) *state.Session) *mockMessageRelayer_RetrieveByScreenName_Call { _c.Call.Return(run) return _c } diff --git a/foodgroup/mock_profile_manager_test.go b/foodgroup/mock_profile_manager_test.go index 0c35e438..85addff1 100644 --- a/foodgroup/mock_profile_manager_test.go +++ b/foodgroup/mock_profile_manager_test.go @@ -2,7 +2,10 @@ package foodgroup -import mock "github.com/stretchr/testify/mock" +import ( + state "github.com/mk6i/retro-aim-server/state" + mock "github.com/stretchr/testify/mock" +) // mockProfileManager is an autogenerated mock type for the ProfileManager type type mockProfileManager struct { @@ -18,7 +21,7 @@ func (_m *mockProfileManager) EXPECT() *mockProfileManager_Expecter { } // Profile provides a mock function with given fields: screenName -func (_m *mockProfileManager) Profile(screenName string) (string, error) { +func (_m *mockProfileManager) Profile(screenName state.IdentScreenName) (string, error) { ret := _m.Called(screenName) if len(ret) == 0 { @@ -27,16 +30,16 @@ func (_m *mockProfileManager) Profile(screenName string) (string, error) { var r0 string var r1 error - if rf, ok := ret.Get(0).(func(string) (string, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) (string, error)); ok { return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) string); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) string); ok { r0 = rf(screenName) } else { r0 = ret.Get(0).(string) } - if rf, ok := ret.Get(1).(func(string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { r1 = rf(screenName) } else { r1 = ret.Error(1) @@ -51,14 +54,14 @@ type mockProfileManager_Profile_Call struct { } // Profile is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockProfileManager_Expecter) Profile(screenName interface{}) *mockProfileManager_Profile_Call { return &mockProfileManager_Profile_Call{Call: _e.mock.On("Profile", screenName)} } -func (_c *mockProfileManager_Profile_Call) Run(run func(screenName string)) *mockProfileManager_Profile_Call { +func (_c *mockProfileManager_Profile_Call) Run(run func(screenName state.IdentScreenName)) *mockProfileManager_Profile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -68,13 +71,13 @@ func (_c *mockProfileManager_Profile_Call) Return(_a0 string, _a1 error) *mockPr return _c } -func (_c *mockProfileManager_Profile_Call) RunAndReturn(run func(string) (string, error)) *mockProfileManager_Profile_Call { +func (_c *mockProfileManager_Profile_Call) RunAndReturn(run func(state.IdentScreenName) (string, error)) *mockProfileManager_Profile_Call { _c.Call.Return(run) return _c } // SetProfile provides a mock function with given fields: screenName, body -func (_m *mockProfileManager) SetProfile(screenName string, body string) error { +func (_m *mockProfileManager) SetProfile(screenName state.IdentScreenName, body string) error { ret := _m.Called(screenName, body) if len(ret) == 0 { @@ -82,7 +85,7 @@ func (_m *mockProfileManager) SetProfile(screenName string, body string) error { } var r0 error - if rf, ok := ret.Get(0).(func(string, string) error); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName, string) error); ok { r0 = rf(screenName, body) } else { r0 = ret.Error(0) @@ -97,15 +100,15 @@ type mockProfileManager_SetProfile_Call struct { } // SetProfile is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName // - body string func (_e *mockProfileManager_Expecter) SetProfile(screenName interface{}, body interface{}) *mockProfileManager_SetProfile_Call { return &mockProfileManager_SetProfile_Call{Call: _e.mock.On("SetProfile", screenName, body)} } -func (_c *mockProfileManager_SetProfile_Call) Run(run func(screenName string, body string)) *mockProfileManager_SetProfile_Call { +func (_c *mockProfileManager_SetProfile_Call) Run(run func(screenName state.IdentScreenName, body string)) *mockProfileManager_SetProfile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + run(args[0].(state.IdentScreenName), args[1].(string)) }) return _c } @@ -115,7 +118,7 @@ func (_c *mockProfileManager_SetProfile_Call) Return(_a0 error) *mockProfileMana return _c } -func (_c *mockProfileManager_SetProfile_Call) RunAndReturn(run func(string, string) error) *mockProfileManager_SetProfile_Call { +func (_c *mockProfileManager_SetProfile_Call) RunAndReturn(run func(state.IdentScreenName, string) error) *mockProfileManager_SetProfile_Call { _c.Call.Return(run) return _c } diff --git a/foodgroup/mock_session_manager_test.go b/foodgroup/mock_session_manager_test.go index ba7f325f..a6b1069d 100644 --- a/foodgroup/mock_session_manager_test.go +++ b/foodgroup/mock_session_manager_test.go @@ -21,7 +21,7 @@ func (_m *mockSessionManager) EXPECT() *mockSessionManager_Expecter { } // AddSession provides a mock function with given fields: screenName -func (_m *mockSessionManager) AddSession(screenName string) *state.Session { +func (_m *mockSessionManager) AddSession(screenName state.DisplayScreenName) *state.Session { ret := _m.Called(screenName) if len(ret) == 0 { @@ -29,7 +29,7 @@ func (_m *mockSessionManager) AddSession(screenName string) *state.Session { } var r0 *state.Session - if rf, ok := ret.Get(0).(func(string) *state.Session); ok { + if rf, ok := ret.Get(0).(func(state.DisplayScreenName) *state.Session); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { @@ -46,14 +46,14 @@ type mockSessionManager_AddSession_Call struct { } // AddSession is a helper method to define mock.On call -// - screenName string +// - screenName state.DisplayScreenName func (_e *mockSessionManager_Expecter) AddSession(screenName interface{}) *mockSessionManager_AddSession_Call { return &mockSessionManager_AddSession_Call{Call: _e.mock.On("AddSession", screenName)} } -func (_c *mockSessionManager_AddSession_Call) Run(run func(screenName string)) *mockSessionManager_AddSession_Call { +func (_c *mockSessionManager_AddSession_Call) Run(run func(screenName state.DisplayScreenName)) *mockSessionManager_AddSession_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.DisplayScreenName)) }) return _c } @@ -63,7 +63,7 @@ func (_c *mockSessionManager_AddSession_Call) Return(_a0 *state.Session) *mockSe return _c } -func (_c *mockSessionManager_AddSession_Call) RunAndReturn(run func(string) *state.Session) *mockSessionManager_AddSession_Call { +func (_c *mockSessionManager_AddSession_Call) RunAndReturn(run func(state.DisplayScreenName) *state.Session) *mockSessionManager_AddSession_Call { _c.Call.Return(run) return _c } @@ -146,17 +146,17 @@ func (_c *mockSessionManager_RemoveSession_Call) RunAndReturn(run func(*state.Se return _c } -// RetrieveSession provides a mock function with given fields: ID -func (_m *mockSessionManager) RetrieveSession(ID string) *state.Session { - ret := _m.Called(ID) +// RetrieveSession provides a mock function with given fields: screenName +func (_m *mockSessionManager) RetrieveSession(screenName state.IdentScreenName) *state.Session { + ret := _m.Called(screenName) if len(ret) == 0 { panic("no return value specified for RetrieveSession") } var r0 *state.Session - if rf, ok := ret.Get(0).(func(string) *state.Session); ok { - r0 = rf(ID) + if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.Session); ok { + r0 = rf(screenName) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*state.Session) @@ -172,14 +172,14 @@ type mockSessionManager_RetrieveSession_Call struct { } // RetrieveSession is a helper method to define mock.On call -// - ID string -func (_e *mockSessionManager_Expecter) RetrieveSession(ID interface{}) *mockSessionManager_RetrieveSession_Call { - return &mockSessionManager_RetrieveSession_Call{Call: _e.mock.On("RetrieveSession", ID)} +// - screenName state.IdentScreenName +func (_e *mockSessionManager_Expecter) RetrieveSession(screenName interface{}) *mockSessionManager_RetrieveSession_Call { + return &mockSessionManager_RetrieveSession_Call{Call: _e.mock.On("RetrieveSession", screenName)} } -func (_c *mockSessionManager_RetrieveSession_Call) Run(run func(ID string)) *mockSessionManager_RetrieveSession_Call { +func (_c *mockSessionManager_RetrieveSession_Call) Run(run func(screenName state.IdentScreenName)) *mockSessionManager_RetrieveSession_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -189,7 +189,7 @@ func (_c *mockSessionManager_RetrieveSession_Call) Return(_a0 *state.Session) *m return _c } -func (_c *mockSessionManager_RetrieveSession_Call) RunAndReturn(run func(string) *state.Session) *mockSessionManager_RetrieveSession_Call { +func (_c *mockSessionManager_RetrieveSession_Call) RunAndReturn(run func(state.IdentScreenName) *state.Session) *mockSessionManager_RetrieveSession_Call { _c.Call.Return(run) return _c } diff --git a/foodgroup/mock_user_manager_manager_test.go b/foodgroup/mock_user_manager_manager_test.go index ac18a6ea..20f36407 100644 --- a/foodgroup/mock_user_manager_manager_test.go +++ b/foodgroup/mock_user_manager_manager_test.go @@ -67,7 +67,7 @@ func (_c *mockUserManager_InsertUser_Call) RunAndReturn(run func(state.User) err } // User provides a mock function with given fields: screenName -func (_m *mockUserManager) User(screenName string) (*state.User, error) { +func (_m *mockUserManager) User(screenName state.IdentScreenName) (*state.User, error) { ret := _m.Called(screenName) if len(ret) == 0 { @@ -76,10 +76,10 @@ func (_m *mockUserManager) User(screenName string) (*state.User, error) { var r0 *state.User var r1 error - if rf, ok := ret.Get(0).(func(string) (*state.User, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) (*state.User, error)); ok { return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) *state.User); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.User); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { @@ -87,7 +87,7 @@ func (_m *mockUserManager) User(screenName string) (*state.User, error) { } } - if rf, ok := ret.Get(1).(func(string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { r1 = rf(screenName) } else { r1 = ret.Error(1) @@ -102,14 +102,14 @@ type mockUserManager_User_Call struct { } // User is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockUserManager_Expecter) User(screenName interface{}) *mockUserManager_User_Call { return &mockUserManager_User_Call{Call: _e.mock.On("User", screenName)} } -func (_c *mockUserManager_User_Call) Run(run func(screenName string)) *mockUserManager_User_Call { +func (_c *mockUserManager_User_Call) Run(run func(screenName state.IdentScreenName)) *mockUserManager_User_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -119,7 +119,7 @@ func (_c *mockUserManager_User_Call) Return(_a0 *state.User, _a1 error) *mockUse return _c } -func (_c *mockUserManager_User_Call) RunAndReturn(run func(string) (*state.User, error)) *mockUserManager_User_Call { +func (_c *mockUserManager_User_Call) RunAndReturn(run func(state.IdentScreenName) (*state.User, error)) *mockUserManager_User_Call { _c.Call.Return(run) return _c } diff --git a/foodgroup/oservice.go b/foodgroup/oservice.go index e7921d00..d6440901 100644 --- a/foodgroup/oservice.go +++ b/foodgroup/oservice.go @@ -562,7 +562,7 @@ type chatLoginCookie struct { func (s OServiceServiceForBOS) ServiceRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x01_0x04_OServiceServiceRequest) (wire.SNACMessage, error) { switch inBody.FoodGroup { case wire.Alert: - cookie, err := s.cookieIssuer.Issue([]byte(sess.ScreenName())) + cookie, err := s.cookieIssuer.Issue([]byte(sess.IdentScreenName().String())) if err != nil { return wire.SNACMessage{}, err } @@ -585,7 +585,7 @@ func (s OServiceServiceForBOS) ServiceRequest(ctx context.Context, sess *state.S }, }, nil case wire.BART: - cookie, err := s.cookieIssuer.Issue([]byte(sess.ScreenName())) + cookie, err := s.cookieIssuer.Issue([]byte(sess.IdentScreenName().String())) if err != nil { return wire.SNACMessage{}, err } @@ -608,7 +608,7 @@ func (s OServiceServiceForBOS) ServiceRequest(ctx context.Context, sess *state.S }, }, nil case wire.ChatNav: - cookie, err := s.cookieIssuer.Issue([]byte(sess.ScreenName())) + cookie, err := s.cookieIssuer.Issue([]byte(sess.IdentScreenName().String())) if err != nil { return wire.SNACMessage{}, err } @@ -648,7 +648,7 @@ func (s OServiceServiceForBOS) ServiceRequest(ctx context.Context, sess *state.S loginCookie := chatLoginCookie{ ChatCookie: room.Cookie, - ScreenName: sess.ScreenName(), + ScreenName: sess.IdentScreenName().String(), } buf := &bytes.Buffer{} if err := wire.Marshal(loginCookie, buf); err != nil { @@ -703,7 +703,7 @@ func (s OServiceServiceForBOS) ClientOnline(ctx context.Context, _ wire.SNAC_0x0 } // send buddy arrival events to client-side buddy list - buddies := s.legacyBuddyListManager.Buddies(sess.ScreenName()) + buddies := s.legacyBuddyListManager.Buddies(sess.IdentScreenName()) for _, buddy := range buddies { buddySess := s.messageRelayer.RetrieveByScreenName(buddy) if buddySess == nil || buddySess.Invisible() { diff --git a/foodgroup/oservice_test.go b/foodgroup/oservice_test.go index 94e2a4e1..fe68a43c 100644 --- a/foodgroup/oservice_test.go +++ b/foodgroup/oservice_test.go @@ -245,7 +245,7 @@ func TestOServiceServiceForBOS_ServiceRequest(t *testing.T) { chatSess := &state.Session{} if tc.chatRoom != nil { sessionManager.EXPECT(). - AddSession(tc.userSession.ScreenName()). + AddSession(tc.userSession.IdentScreenName()). Return(chatSess). Maybe() chatRegistry.Register(*tc.chatRoom, sessionManager) @@ -329,7 +329,7 @@ func TestSetUserInfoFields(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -364,7 +364,7 @@ func TestSetUserInfoFields(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyDepartedParams: broadcastBuddyDepartedParams{ { - screenName: "user_screen_name", + screenName: state.NewIdentScreenName("user_screen_name"), }, }, }, @@ -379,7 +379,7 @@ func TestSetUserInfoFields(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } @@ -387,7 +387,7 @@ func TestSetUserInfoFields(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyDeparted(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } @@ -1452,7 +1452,7 @@ func TestOServiceService_IdleNotification(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "test-user", + screenName: state.NewIdentScreenName("test-user"), }, }, }, @@ -1468,7 +1468,7 @@ func TestOServiceService_IdleNotification(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "test-user", + screenName: state.NewIdentScreenName("test-user"), }, }, }, @@ -1482,7 +1482,7 @@ func TestOServiceService_IdleNotification(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } @@ -1522,19 +1522,22 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ legacyBuddiesParams: legacyBuddiesParams{ { - userScreenName: "test-user", - result: []string{"buddy1", "buddy2"}, + userScreenName: state.NewIdentScreenName("test-user"), + result: []state.IdentScreenName{ + state.NewIdentScreenName("buddy1"), + state.NewIdentScreenName("buddy2"), + }, }, }, }, messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy1", + screenName: state.NewIdentScreenName("buddy1"), sess: newTestSession("buddy1", sessOptCannedSignonTime), }, { - screenName: "buddy2", + screenName: state.NewIdentScreenName("buddy2"), sess: newTestSession("buddy2", sessOptCannedSignonTime), }, }, @@ -1542,17 +1545,17 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "test-user", + screenName: state.NewIdentScreenName("test-user"), }, }, unicastBuddyArrivedParams: unicastBuddyArrivedParams{ { - from: "buddy1", - to: "test-user", + from: state.NewIdentScreenName("buddy1"), + to: state.NewIdentScreenName("test-user"), }, { - from: "buddy2", - to: "test-user", + from: state.NewIdentScreenName("buddy2"), + to: state.NewIdentScreenName("test-user"), }, }, }, @@ -1566,19 +1569,22 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) { legacyBuddyListManagerParams: legacyBuddyListManagerParams{ legacyBuddiesParams: legacyBuddiesParams{ { - userScreenName: "test-user", - result: []string{"buddy1", "buddy2"}, + userScreenName: state.NewIdentScreenName("test-user"), + result: []state.IdentScreenName{ + state.NewIdentScreenName("buddy1"), + state.NewIdentScreenName("buddy2"), + }, }, }, }, messageRelayerParams: messageRelayerParams{ retrieveByScreenNameParams: retrieveByScreenNameParams{ { - screenName: "buddy1", + screenName: state.NewIdentScreenName("buddy1"), sess: newTestSession("buddy1", sessOptCannedSignonTime, sessOptInvisible), }, { - screenName: "buddy2", + screenName: state.NewIdentScreenName("buddy2"), sess: newTestSession("buddy2", sessOptCannedSignonTime), }, }, @@ -1586,13 +1592,13 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) { buddyBroadcasterParams: buddyBroadcasterParams{ broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{ { - screenName: "test-user", + screenName: state.NewIdentScreenName("test-user"), }, }, unicastBuddyArrivedParams: unicastBuddyArrivedParams{ { - from: "buddy2", - to: "test-user", + from: state.NewIdentScreenName("buddy2"), + to: state.NewIdentScreenName("test-user"), }, }, }, @@ -1618,7 +1624,7 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) { p := params buddyUpdateBroadcaster.EXPECT(). BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.screenName + return s.IdentScreenName() == p.screenName })). Return(nil) } @@ -1627,10 +1633,10 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) { buddyUpdateBroadcaster.EXPECT(). UnicastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.from + return s.IdentScreenName() == p.from }), mock.MatchedBy(func(s *state.Session) bool { - return s.ScreenName() == p.to + return s.IdentScreenName() == p.to })). Return(p.err) } @@ -1659,7 +1665,7 @@ func TestOServiceServiceForChat_ClientOnline(t *testing.T) { message wire.SNACMessage } type sendToScreenNameParams []struct { - screenName string + screenName state.IdentScreenName message wire.SNACMessage } @@ -1710,7 +1716,7 @@ func TestOServiceServiceForChat_ClientOnline(t *testing.T) { }, sendToScreenNameParams: sendToScreenNameParams{ { - screenName: chatter1.ScreenName(), + screenName: chatter1.IdentScreenName(), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Chat, @@ -1728,7 +1734,7 @@ func TestOServiceServiceForChat_ClientOnline(t *testing.T) { }, }, { - screenName: chatter1.ScreenName(), + screenName: chatter1.IdentScreenName(), message: wire.SNACMessage{ Frame: wire.SNACFrame{ FoodGroup: wire.Chat, diff --git a/foodgroup/test_helpers.go b/foodgroup/test_helpers.go index 5b1b11e8..c6e4f4fe 100644 --- a/foodgroup/test_helpers.go +++ b/foodgroup/test_helpers.go @@ -69,7 +69,7 @@ type userManagerParams struct { // getUserParams is the list of parameters passed at the mock // UserManager.User call site type getUserParams []struct { - screenName string + screenName state.IdentScreenName result *state.User err error } @@ -92,8 +92,7 @@ type sessionManagerParams struct { // addSessionParams is the list of parameters passed at the mock // SessionManager.AddSession call site type addSessionParams []struct { - sessID string - screenName string + screenName state.DisplayScreenName result *state.Session } @@ -124,8 +123,8 @@ type feedbagManagerParams struct { // blockedStateParams is the list of parameters passed at the mock // FeedbagManager.BlockedState call site type blockedStateParams []struct { - screenName1 string - screenName2 string + screenName1 state.IdentScreenName + screenName2 state.IdentScreenName result state.BlockedState err error } @@ -133,43 +132,43 @@ type blockedStateParams []struct { // adjacentUsersParams is the list of parameters passed at the mock // FeedbagManager.AdjacentUsers call site type adjacentUsersParams []struct { - screenName string - users []string + screenName state.IdentScreenName + users []state.IdentScreenName err error } // feedbagUpsertParams is the list of parameters passed at the mock // FeedbagManager.FeedbagUpsert call site type feedbagUpsertParams []struct { - screenName string + screenName state.IdentScreenName items []wire.FeedbagItem } // buddiesParams is the list of parameters passed at the mock // FeedbagManager.Buddies call site type buddiesParams []struct { - screenName string - results []string + screenName state.IdentScreenName + results []state.IdentScreenName } // feedbagParams is the list of parameters passed at the mock // FeedbagManager.Feedbag call site type feedbagParams []struct { - screenName string + screenName state.IdentScreenName results []wire.FeedbagItem } // feedbagLastModifiedParams is the list of parameters passed at the mock // FeedbagManager.FeedbagLastModified call site type feedbagLastModifiedParams []struct { - screenName string + screenName state.IdentScreenName result time.Time } // feedbagDeleteParams is the list of parameters passed at the mock // FeedbagManager.FeedbagDelete call site type feedbagDeleteParams []struct { - screenName string + screenName state.IdentScreenName items []wire.FeedbagItem } @@ -184,21 +183,21 @@ type messageRelayerParams struct { // retrieveByScreenNameParams is the list of parameters passed at the mock // MessageRelayer.RetrieveByScreenName call site type retrieveByScreenNameParams []struct { - screenName string + screenName state.IdentScreenName sess *state.Session } // relayToScreenNamesParams is the list of parameters passed at the mock // MessageRelayer.RelayToScreenNames call site type relayToScreenNamesParams []struct { - screenNames []string + screenNames []state.IdentScreenName message wire.SNACMessage } // relayToScreenNameParams is the list of parameters passed at the mock // MessageRelayer.RelayToScreenName call site type relayToScreenNameParams []struct { - screenName string + screenName state.IdentScreenName message wire.SNACMessage } @@ -210,17 +209,17 @@ type profileManagerParams struct { } // retrieveByScreenNameParams is the list of parameters passed at the mock -// ProfileManager.RetrieveProfile call site +// ProfileManager.Profile call site type retrieveProfileParams []struct { - screenName string + screenName state.IdentScreenName result string err error } // setProfileParams is the list of parameters passed at the mock -// ProfileManager.UpsertProfile call site +// ProfileManager.SetProfile call site type setProfileParams []struct { - screenName string + screenName state.IdentScreenName body any } @@ -250,35 +249,35 @@ type legacyBuddyListManagerParams struct { // legacyBuddiesParams is the list of parameters passed at the mock // LegacyBuddyListManager.AddBuddy call site type addBuddyParams []struct { - userScreenName string - buddyScreenName string + userScreenName state.IdentScreenName + buddyScreenName state.IdentScreenName } // legacyBuddiesParams is the list of parameters passed at the mock // LegacyBuddyListManager.DeleteBuddy call site type deleteBuddyParams []struct { - userScreenName string - buddyScreenName string + userScreenName state.IdentScreenName + buddyScreenName state.IdentScreenName } // deleteUserParams is the list of parameters passed at the mock // LegacyBuddyListManager.DeleteUser call site type deleteUserParams []struct { - userScreenName string + userScreenName state.IdentScreenName } // legacyBuddiesParams is the list of parameters passed at the mock // LegacyBuddyListManager.Buddies call site type legacyBuddiesParams []struct { - userScreenName string - result []string + userScreenName state.IdentScreenName + result []state.IdentScreenName } // whoAddedUserParams is the list of parameters passed at the mock // LegacyBuddyListManager.WhoAddedUser call site type whoAddedUserParams []struct { - userScreenName string - result []string + userScreenName state.IdentScreenName + result []state.IdentScreenName } // cookieIssuerParams is the list of parameters passed at the mock @@ -301,30 +300,30 @@ type buddyBroadcasterParams struct { // broadcastBuddyArrivedParams is the list of parameters passed at the mock // BuddyBroadcaster.BroadcastBuddyArrived call site type broadcastBuddyArrivedParams []struct { - screenName string + screenName state.IdentScreenName err error } // broadcastBuddyDepartedParams is the list of parameters passed at the mock // BuddyBroadcaster.BroadcastBuddyDeparted call site type broadcastBuddyDepartedParams []struct { - screenName string + screenName state.IdentScreenName err error } // unicastBuddyArrivedParams is the list of parameters passed at the mock // BuddyBroadcaster.UnicastBuddyArrived call site type unicastBuddyArrivedParams []struct { - from string - to string + from state.IdentScreenName + to state.IdentScreenName err error } // unicastBuddyDepartedParams is the list of parameters passed at the mock // BuddyBroadcaster.UnicastBuddyDeparted call site type unicastBuddyDepartedParams []struct { - from string - to string + from state.IdentScreenName + to state.IdentScreenName err error } @@ -388,9 +387,10 @@ func sessOptCaps(caps [][16]byte) func(session *state.Session) { // newTestSession creates a session object with 0 or more functional options // applied -func newTestSession(screenName string, options ...func(session *state.Session)) *state.Session { +func newTestSession(screenName state.DisplayScreenName, options ...func(session *state.Session)) *state.Session { s := state.NewSession() - s.SetScreenName(screenName) + s.SetIdentScreenName(screenName.IdentScreenName()) + s.SetDisplayScreenName(screenName) for _, op := range options { op(s) } diff --git a/foodgroup/types.go b/foodgroup/types.go index 0432c1a9..30ed1710 100644 --- a/foodgroup/types.go +++ b/foodgroup/types.go @@ -42,13 +42,13 @@ import ( ) type FeedbagManager interface { - BlockedState(screenName1, screenName2 string) (state.BlockedState, error) - Buddies(screenName string) ([]string, error) - FeedbagDelete(screenName string, items []wire.FeedbagItem) error - AdjacentUsers(screenName string) ([]string, error) - FeedbagLastModified(screenName string) (time.Time, error) - Feedbag(screenName string) ([]wire.FeedbagItem, error) - FeedbagUpsert(screenName string, items []wire.FeedbagItem) error + BlockedState(screenName1, screenName2 state.IdentScreenName) (state.BlockedState, error) + Buddies(screenName state.IdentScreenName) ([]state.IdentScreenName, error) + FeedbagDelete(screenName state.IdentScreenName, items []wire.FeedbagItem) error + AdjacentUsers(screenName state.IdentScreenName) ([]state.IdentScreenName, error) + FeedbagLastModified(screenName state.IdentScreenName) (time.Time, error) + Feedbag(screenName state.IdentScreenName) ([]wire.FeedbagItem, error) + FeedbagUpsert(screenName state.IdentScreenName, items []wire.FeedbagItem) error } // LegacyBuddyListManager defines operations for tracking user relationships @@ -56,44 +56,44 @@ type FeedbagManager interface { // 4.3. type LegacyBuddyListManager interface { // AddBuddy adds buddyScreenName to userScreenName's buddy list. - AddBuddy(userScreenName, buddyScreenName string) + AddBuddy(userScreenName, buddyScreenName state.IdentScreenName) // Buddies returns a list of all buddies associated with the specified // userScreenName. - Buddies(userScreenName string) []string + Buddies(userScreenName state.IdentScreenName) []state.IdentScreenName // DeleteBuddy removes buddyScreenName from userScreenName's buddy list. - DeleteBuddy(userScreenName, buddyScreenName string) + DeleteBuddy(userScreenName, buddyScreenName state.IdentScreenName) // DeleteUser removes userScreenName's buddy list. - DeleteUser(userScreenName string) + DeleteUser(userScreenName state.IdentScreenName) // WhoAddedUser returns a list of screen names who have userScreenName in // their buddy lists. - WhoAddedUser(userScreenName string) []string + WhoAddedUser(userScreenName state.IdentScreenName) []state.IdentScreenName } type UserManager interface { - User(screenName string) (*state.User, error) + User(screenName state.IdentScreenName) (*state.User, error) InsertUser(u state.User) error } type SessionManager interface { Empty() bool - AddSession(screenName string) *state.Session + AddSession(screenName state.DisplayScreenName) *state.Session RemoveSession(sess *state.Session) - RetrieveSession(ID string) *state.Session + RetrieveSession(screenName state.IdentScreenName) *state.Session } type ProfileManager interface { - Profile(screenName string) (string, error) - SetProfile(screenName string, body string) error + Profile(screenName state.IdentScreenName) (string, error) + SetProfile(screenName state.IdentScreenName, body string) error } type MessageRelayer interface { - RelayToScreenNames(ctx context.Context, screenNames []string, msg wire.SNACMessage) - RetrieveByScreenName(screenName string) *state.Session - RelayToScreenName(ctx context.Context, screenName string, msg wire.SNACMessage) + RelayToScreenNames(ctx context.Context, screenNames []state.IdentScreenName, msg wire.SNACMessage) + RetrieveByScreenName(screenName state.IdentScreenName) *state.Session + RelayToScreenName(ctx context.Context, screenName state.IdentScreenName, msg wire.SNACMessage) } type ChatMessageRelayer interface { diff --git a/server/http/mgmt_api.go b/server/http/mgmt_api.go index eb560b20..9c373c1b 100644 --- a/server/http/mgmt_api.go +++ b/server/http/mgmt_api.go @@ -34,10 +34,10 @@ type onlineUsers struct { type UserManager interface { AllUsers() ([]state.User, error) - DeleteUser(screenName string) error + DeleteUser(screenName state.IdentScreenName) error InsertUser(u state.User) error SetUserPassword(u state.User) error - User(screenName string) (*state.User, error) + User(screenName state.IdentScreenName) (*state.User, error) } type SessionRetriever interface { @@ -46,14 +46,11 @@ type SessionRetriever interface { func StartManagementAPI(cfg config.Config, userManager UserManager, sessionRetriever SessionRetriever, logger *slog.Logger) { mux := http.NewServeMux() - newUser := func() state.User { - return state.User{AuthKey: uuid.New().String()} - } mux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) { - userHandler(w, r, userManager, newUser, logger) + userHandler(w, r, userManager, uuid.New, logger) }) mux.HandleFunc("/user/password", func(w http.ResponseWriter, r *http.Request) { - userPasswordHandler(w, r, userManager, newUser, logger) + userPasswordHandler(w, r, userManager, uuid.New, logger) }) mux.HandleFunc("/user/login", func(w http.ResponseWriter, r *http.Request) { loginHandler(w, r, userManager, logger) @@ -70,32 +67,27 @@ func StartManagementAPI(cfg config.Config, userManager UserManager, sessionRetri } } -func userHandler( - w http.ResponseWriter, - r *http.Request, - userManager UserManager, - newUser func() state.User, - logger *slog.Logger, -) { +func userHandler(w http.ResponseWriter, r *http.Request, userManager UserManager, newUUID func() uuid.UUID, logger *slog.Logger) { switch r.Method { case http.MethodDelete: deleteUserHandler(w, r, userManager, logger) case http.MethodGet: getUserHandler(w, r, userManager, logger) case http.MethodPost: - postUserHandler(w, r, userManager, newUser, logger) + postUserHandler(w, r, userManager, newUUID, logger) default: http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } } func deleteUserHandler(w http.ResponseWriter, r *http.Request, manager UserManager, logger *slog.Logger) { - user := state.User{} - if err := json.NewDecoder(r.Body).Decode(&user); err != nil { - http.Error(w, "malformed input", http.StatusBadRequest) + user, err := userFromBody(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) return } - err := manager.DeleteUser(user.ScreenName) + + err = manager.DeleteUser(user.DisplayScreenName.IdentScreenName()) switch { case errors.Is(err, state.ErrNoUser): http.Error(w, "user does not exist", http.StatusNotFound) @@ -110,36 +102,25 @@ func deleteUserHandler(w http.ResponseWriter, r *http.Request, manager UserManag fmt.Fprintln(w, "User account successfully deleted.") } -func userPasswordHandler( - w http.ResponseWriter, - r *http.Request, - userManager UserManager, - userFactory func() state.User, - logger *slog.Logger, -) { +func userPasswordHandler(w http.ResponseWriter, r *http.Request, userManager UserManager, newUUID func() uuid.UUID, logger *slog.Logger) { switch r.Method { case http.MethodPut: - putUserPasswordHandler(w, r, userManager, userFactory, logger) + putUserPasswordHandler(w, r, userManager, newUUID, logger) default: http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } } // putUserPasswordHandler handles the PUT /user/password endpoint. -func putUserPasswordHandler( - w http.ResponseWriter, - r *http.Request, - userManager UserManager, - newUser func() state.User, - logger *slog.Logger, -) { - user := userWithPassword{ - User: newUser(), - } - if err := json.NewDecoder(r.Body).Decode(&user); err != nil { - http.Error(w, "malformed input", http.StatusBadRequest) +func putUserPasswordHandler(w http.ResponseWriter, r *http.Request, userManager UserManager, newUUID func() uuid.UUID, logger *slog.Logger) { + user, err := userFromBody(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) return } + user.AuthKey = newUUID().String() + + user.IdentScreenName = user.DisplayScreenName.IdentScreenName() if err := user.HashPassword(user.Password); err != nil { logger.Error("error hashing user password in PUT /user/password", "err", err.Error()) http.Error(w, "internal server error", http.StatusInternalServerError) @@ -178,7 +159,7 @@ func sessionHandler(w http.ResponseWriter, r *http.Request, sessionRetriever Ses for _, s := range allUsers { ou.Sessions = append(ou.Sessions, userSession{ - ScreenName: s.ScreenName(), + ScreenName: s.DisplayScreenName().String(), }) } @@ -204,27 +185,21 @@ func getUserHandler(w http.ResponseWriter, _ *http.Request, userManager UserMana } // postUserHandler handles the POST /user endpoint. -func postUserHandler( - w http.ResponseWriter, - r *http.Request, - userManager UserManager, - newUser func() state.User, - logger *slog.Logger, -) { - user := userWithPassword{ - User: newUser(), - } - if err := json.NewDecoder(r.Body).Decode(&user); err != nil { - http.Error(w, "malformed input", http.StatusBadRequest) +func postUserHandler(w http.ResponseWriter, r *http.Request, userManager UserManager, newUUID func() uuid.UUID, logger *slog.Logger) { + user, err := userFromBody(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) return } + user.AuthKey = newUUID().String() + if err := user.HashPassword(user.Password); err != nil { logger.Error("error hashing user password in POST /user", "err", err.Error()) http.Error(w, "internal server error", http.StatusInternalServerError) return } - err := userManager.InsertUser(user.User) + err = userManager.InsertUser(user.User) switch { case errors.Is(err, state.ErrDupUser): http.Error(w, "user already exists", http.StatusConflict) @@ -239,6 +214,15 @@ func postUserHandler( fmt.Fprintln(w, "User account created successfully.") } +func userFromBody(r *http.Request) (userWithPassword, error) { + user := userWithPassword{} + if err := json.NewDecoder(r.Body).Decode(&user); err != nil { + return userWithPassword{}, errors.New("malformed input") + } + user.IdentScreenName = user.DisplayScreenName.IdentScreenName() + return user, nil +} + // loginHandler is a temporary endpoint for validating user credentials for // chivanet. do not rely on this endpoint, as it will be eventually removed. func loginHandler(w http.ResponseWriter, r *http.Request, userManager UserManager, logger *slog.Logger) { @@ -272,7 +256,7 @@ func loginHandler(w http.ResponseWriter, r *http.Request, userManager UserManage return } - username, password := pair[0], pair[1] + username, password := state.NewIdentScreenName(pair[0]), pair[1] user, err := userManager.User(username) if err != nil { diff --git a/server/http/mgmt_api_test.go b/server/http/mgmt_api_test.go index afb0a3bf..895518bd 100644 --- a/server/http/mgmt_api_test.go +++ b/server/http/mgmt_api_test.go @@ -8,6 +8,7 @@ import ( "strings" "testing" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/mk6i/retro-aim-server/state" @@ -16,7 +17,8 @@ import ( func TestSessionHandler_GET(t *testing.T) { fnNewSess := func(screenName string) *state.Session { sess := state.NewSession() - sess.SetScreenName(screenName) + sess.SetIdentScreenName(state.NewIdentScreenName(screenName)) + sess.SetDisplayScreenName(state.DisplayScreenName(screenName)) return sess } tt := []struct { @@ -100,8 +102,14 @@ func TestUserHandler_GET(t *testing.T) { { name: "user store containing 2 users", users: []state.User{ - {ScreenName: "userA"}, - {ScreenName: "userB"}, + { + DisplayScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), + }, + { + DisplayScreenName: "userB", + IdentScreenName: state.NewIdentScreenName("userB"), + }, }, want: `[{"screen_name":"userA"},{"screen_name":"userB"}]`, statusCode: http.StatusOK, @@ -142,6 +150,7 @@ func TestUserHandler_POST(t *testing.T) { tt := []struct { name string body string + UUID uuid.UUID user state.User userHandlerErr error want string @@ -150,10 +159,12 @@ func TestUserHandler_POST(t *testing.T) { { name: "with valid user", body: `{"screen_name":"userA", "password":"thepassword"}`, + UUID: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b"), user: func() state.User { user := state.User{ - AuthKey: "theAuthKey", - ScreenName: "userA", + AuthKey: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b").String(), + DisplayScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), } assert.NoError(t, user.HashPassword("thepassword")) return user @@ -171,10 +182,12 @@ func TestUserHandler_POST(t *testing.T) { { name: "user handler error", body: `{"screen_name":"userA", "password":"thepassword"}`, + UUID: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b"), user: func() state.User { user := state.User{ - AuthKey: "theAuthKey", - ScreenName: "userA", + AuthKey: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b").String(), + DisplayScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), } assert.NoError(t, user.HashPassword("thepassword")) return user @@ -186,10 +199,12 @@ func TestUserHandler_POST(t *testing.T) { { name: "duplicate user", body: `{"screen_name":"userA", "password":"thepassword"}`, + UUID: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b"), user: func() state.User { user := state.User{ - AuthKey: "theAuthKey", - ScreenName: "userA", + AuthKey: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b").String(), + DisplayScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), } assert.NoError(t, user.HashPassword("thepassword")) return user @@ -206,16 +221,14 @@ func TestUserHandler_POST(t *testing.T) { responseRecorder := httptest.NewRecorder() userManager := newMockUserManager(t) - if tc.user.ScreenName != "" { + if tc.user.IdentScreenName.String() != "" { userManager.EXPECT(). InsertUser(tc.user). Return(tc.userHandlerErr) } - newUser := func() state.User { - return tc.user - } - userHandler(responseRecorder, request, userManager, newUser, slog.Default()) + newUUID := func() uuid.UUID { return tc.UUID } + userHandler(responseRecorder, request, userManager, newUUID, slog.Default()) if responseRecorder.Code != tc.statusCode { t.Errorf("want status '%d', got '%d'", tc.statusCode, responseRecorder.Code) @@ -241,7 +254,7 @@ func TestUserHandler_DELETE(t *testing.T) { name: "with valid user", body: `{"screen_name":"userA"}`, user: state.User{ - ScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), }, want: `User account successfully deleted.`, statusCode: http.StatusNoContent, @@ -250,7 +263,7 @@ func TestUserHandler_DELETE(t *testing.T) { name: "with non-existent user", body: `{"screen_name":"userA"}`, user: state.User{ - ScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), }, userHandlerErr: state.ErrNoUser, want: `user does not exist`, @@ -267,7 +280,7 @@ func TestUserHandler_DELETE(t *testing.T) { name: "user handler error", body: `{"screen_name":"userA"}`, user: state.User{ - ScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), }, userHandlerErr: io.EOF, want: `internal server error`, @@ -281,9 +294,9 @@ func TestUserHandler_DELETE(t *testing.T) { responseRecorder := httptest.NewRecorder() userManager := newMockUserManager(t) - if tc.user.ScreenName != "" { + if tc.user.IdentScreenName.String() != "" { userManager.EXPECT(). - DeleteUser(tc.user.ScreenName). + DeleteUser(tc.user.IdentScreenName). Return(tc.userHandlerErr) } @@ -305,6 +318,7 @@ func TestUserPasswordHandler_PUT(t *testing.T) { name string body string user state.User + UUID uuid.UUID userHandlerErr error want string statusCode int @@ -312,10 +326,12 @@ func TestUserPasswordHandler_PUT(t *testing.T) { { name: "with valid password", body: `{"screen_name":"userA", "password":"thepassword"}`, + UUID: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b"), user: func() state.User { user := state.User{ - AuthKey: "theAuthKey", - ScreenName: "userA", + AuthKey: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b").String(), + DisplayScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), } assert.NoError(t, user.HashPassword("thepassword")) return user @@ -333,10 +349,12 @@ func TestUserPasswordHandler_PUT(t *testing.T) { { name: "user password handler error", body: `{"screen_name":"userA", "password":"thepassword"}`, + UUID: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b"), user: func() state.User { user := state.User{ - AuthKey: "theAuthKey", - ScreenName: "userA", + AuthKey: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b").String(), + DisplayScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), } assert.NoError(t, user.HashPassword("thepassword")) return user @@ -348,10 +366,12 @@ func TestUserPasswordHandler_PUT(t *testing.T) { { name: "user doesn't exist", body: `{"screen_name":"userA", "password":"thepassword"}`, + UUID: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b"), user: func() state.User { user := state.User{ - AuthKey: "theAuthKey", - ScreenName: "userA", + AuthKey: uuid.MustParse("07c70701-ba68-49a9-9f9b-67a53816e37b").String(), + DisplayScreenName: "userA", + IdentScreenName: state.NewIdentScreenName("userA"), } assert.NoError(t, user.HashPassword("thepassword")) return user @@ -368,16 +388,14 @@ func TestUserPasswordHandler_PUT(t *testing.T) { responseRecorder := httptest.NewRecorder() userManager := newMockUserManager(t) - if tc.user.ScreenName != "" { + if tc.user.IdentScreenName.String() != "" { userManager.EXPECT(). SetUserPassword(tc.user). Return(tc.userHandlerErr) } - uf := func() state.User { - return tc.user - } - userPasswordHandler(responseRecorder, request, userManager, uf, slog.Default()) + newUUID := func() uuid.UUID { return tc.UUID } + userPasswordHandler(responseRecorder, request, userManager, newUUID, slog.Default()) if responseRecorder.Code != tc.statusCode { t.Errorf("want status '%d', got '%d'", tc.statusCode, responseRecorder.Code) diff --git a/server/http/mock_user_manager_test.go b/server/http/mock_user_manager_test.go index 69343aeb..d0f22167 100644 --- a/server/http/mock_user_manager_test.go +++ b/server/http/mock_user_manager_test.go @@ -78,7 +78,7 @@ func (_c *mockUserManager_AllUsers_Call) RunAndReturn(run func() ([]state.User, } // DeleteUser provides a mock function with given fields: screenName -func (_m *mockUserManager) DeleteUser(screenName string) error { +func (_m *mockUserManager) DeleteUser(screenName state.IdentScreenName) error { ret := _m.Called(screenName) if len(ret) == 0 { @@ -86,7 +86,7 @@ func (_m *mockUserManager) DeleteUser(screenName string) error { } var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) error); ok { r0 = rf(screenName) } else { r0 = ret.Error(0) @@ -101,14 +101,14 @@ type mockUserManager_DeleteUser_Call struct { } // DeleteUser is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockUserManager_Expecter) DeleteUser(screenName interface{}) *mockUserManager_DeleteUser_Call { return &mockUserManager_DeleteUser_Call{Call: _e.mock.On("DeleteUser", screenName)} } -func (_c *mockUserManager_DeleteUser_Call) Run(run func(screenName string)) *mockUserManager_DeleteUser_Call { +func (_c *mockUserManager_DeleteUser_Call) Run(run func(screenName state.IdentScreenName)) *mockUserManager_DeleteUser_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -118,7 +118,7 @@ func (_c *mockUserManager_DeleteUser_Call) Return(_a0 error) *mockUserManager_De return _c } -func (_c *mockUserManager_DeleteUser_Call) RunAndReturn(run func(string) error) *mockUserManager_DeleteUser_Call { +func (_c *mockUserManager_DeleteUser_Call) RunAndReturn(run func(state.IdentScreenName) error) *mockUserManager_DeleteUser_Call { _c.Call.Return(run) return _c } @@ -216,7 +216,7 @@ func (_c *mockUserManager_SetUserPassword_Call) RunAndReturn(run func(state.User } // User provides a mock function with given fields: screenName -func (_m *mockUserManager) User(screenName string) (*state.User, error) { +func (_m *mockUserManager) User(screenName state.IdentScreenName) (*state.User, error) { ret := _m.Called(screenName) if len(ret) == 0 { @@ -225,10 +225,10 @@ func (_m *mockUserManager) User(screenName string) (*state.User, error) { var r0 *state.User var r1 error - if rf, ok := ret.Get(0).(func(string) (*state.User, error)); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) (*state.User, error)); ok { return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) *state.User); ok { + if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.User); ok { r0 = rf(screenName) } else { if ret.Get(0) != nil { @@ -236,7 +236,7 @@ func (_m *mockUserManager) User(screenName string) (*state.User, error) { } } - if rf, ok := ret.Get(1).(func(string) error); ok { + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { r1 = rf(screenName) } else { r1 = ret.Error(1) @@ -251,14 +251,14 @@ type mockUserManager_User_Call struct { } // User is a helper method to define mock.On call -// - screenName string +// - screenName state.IdentScreenName func (_e *mockUserManager_Expecter) User(screenName interface{}) *mockUserManager_User_Call { return &mockUserManager_User_Call{Call: _e.mock.On("User", screenName)} } -func (_c *mockUserManager_User_Call) Run(run func(screenName string)) *mockUserManager_User_Call { +func (_c *mockUserManager_User_Call) Run(run func(screenName state.IdentScreenName)) *mockUserManager_User_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -268,7 +268,7 @@ func (_c *mockUserManager_User_Call) Return(_a0 *state.User, _a1 error) *mockUse return _c } -func (_c *mockUserManager_User_Call) RunAndReturn(run func(string) (*state.User, error)) *mockUserManager_User_Call { +func (_c *mockUserManager_User_Call) RunAndReturn(run func(state.IdentScreenName) (*state.User, error)) *mockUserManager_User_Call { _c.Call.Return(run) return _c } diff --git a/server/oscar/auth.go b/server/oscar/auth.go index 87de317f..6ef69b21 100644 --- a/server/oscar/auth.go +++ b/server/oscar/auth.go @@ -16,9 +16,9 @@ import ( type AuthService interface { BUCPChallenge(bodyIn wire.SNAC_0x17_0x06_BUCPChallengeRequest, newUUID func() uuid.UUID) (wire.SNACMessage, error) - BUCPLogin(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, fn func(screenName string) (state.User, error)) (wire.SNACMessage, error) - FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func(screenName string) (state.User, error)) (wire.TLVRestBlock, error) - RegisterBOSSession(sessionID string) (*state.Session, error) + BUCPLogin(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, newUserFn func(screenName state.DisplayScreenName) (state.User, error)) (wire.SNACMessage, error) + FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func(screenName state.DisplayScreenName) (state.User, error)) (wire.TLVRestBlock, error) + RegisterBOSSession(screenName state.IdentScreenName) (*state.Session, error) RegisterChatSession(loginCookie []byte) (*state.Session, error) Signout(ctx context.Context, sess *state.Session) error SignoutChat(ctx context.Context, sess *state.Session) error diff --git a/server/oscar/bos.go b/server/oscar/bos.go index e9e533ef..d334324e 100644 --- a/server/oscar/bos.go +++ b/server/oscar/bos.go @@ -9,6 +9,7 @@ import ( "os" "github.com/mk6i/retro-aim-server/config" + "github.com/mk6i/retro-aim-server/state" "github.com/mk6i/retro-aim-server/wire" ) @@ -77,12 +78,12 @@ func (rt BOSServer) handleNewConnection(ctx context.Context, rwc io.ReadWriteClo return errors.New("unable to get session id from payload") } - token, err := rt.CookieCracker.Crack(authCookie) + screenName, err := rt.CookieCracker.Crack(authCookie) if err != nil { return err } - sess, err := rt.RegisterBOSSession(string(token)) + sess, err := rt.RegisterBOSSession(state.NewIdentScreenName(string(screenName))) if err != nil { return err } @@ -98,7 +99,7 @@ func (rt BOSServer) handleNewConnection(ctx context.Context, rwc io.ReadWriteClo } }() - ctx = context.WithValue(ctx, "screenName", sess.ScreenName()) + ctx = context.WithValue(ctx, "screenName", sess.IdentScreenName()) msg := rt.OnlineNotifier.HostOnline() if err := flapc.SendSNAC(msg.Frame, msg.Body); err != nil { diff --git a/server/oscar/bos_test.go b/server/oscar/bos_test.go index 5366332a..075a88bf 100644 --- a/server/oscar/bos_test.go +++ b/server/oscar/bos_test.go @@ -81,7 +81,7 @@ func TestBOSService_handleNewConnection(t *testing.T) { authService := newMockAuthService(t) authService.EXPECT(). - RegisterBOSSession("user_screen_name"). + RegisterBOSSession(state.NewIdentScreenName("user_screen_name")). Return(sess, nil) authService.EXPECT(). Signout(mock.Anything, sess). diff --git a/server/oscar/chat.go b/server/oscar/chat.go index 323c1cc4..49d195ae 100644 --- a/server/oscar/chat.go +++ b/server/oscar/chat.go @@ -95,6 +95,6 @@ func (rt ChatServer) handleNewConnection(ctx context.Context, rwc io.ReadWriteCl return err } - ctx = context.WithValue(ctx, "screenName", chatSess.ScreenName()) + ctx = context.WithValue(ctx, "screenName", chatSess.IdentScreenName()) return dispatchIncomingMessages(ctx, chatSess, flapc, rwc, rt.Logger, rt.Handler, rt.Config) } diff --git a/server/oscar/connection_test.go b/server/oscar/connection_test.go index 2843ba89..a158bd5a 100644 --- a/server/oscar/connection_test.go +++ b/server/oscar/connection_test.go @@ -60,7 +60,7 @@ func TestHandleChatConnection_MessageRelay(t *testing.T) { // relay messages to user session for _, msg := range inboundMsgs { - sessionManager.RelayToScreenName(context.Background(), "bob", msg) + sessionManager.RelayToScreenName(context.Background(), state.NewIdentScreenName("bob"), msg) } // consume and verify the relayed messages diff --git a/server/oscar/middleware/logger.go b/server/oscar/middleware/logger.go index fb10ec3e..b6b2e71c 100644 --- a/server/oscar/middleware/logger.go +++ b/server/oscar/middleware/logger.go @@ -59,7 +59,7 @@ type handler struct { func (h handler) Handle(ctx context.Context, r slog.Record) error { if sn := ctx.Value("screenName"); sn != nil { - r.AddAttrs(slog.Attr{Key: "screenName", Value: slog.StringValue(sn.(string))}) + //r.AddAttrs(slog.Attr{Key: "screenName", Value: slog.StringValue(sn.(string))}) } if ip := ctx.Value("ip"); ip != nil { r.AddAttrs(slog.Attr{Key: "ip", Value: slog.StringValue(ip.(string))}) diff --git a/server/oscar/mock_auth_test.go b/server/oscar/mock_auth_test.go index 73a2da66..58ec9a20 100644 --- a/server/oscar/mock_auth_test.go +++ b/server/oscar/mock_auth_test.go @@ -83,9 +83,9 @@ func (_c *mockAuthService_BUCPChallenge_Call) RunAndReturn(run func(wire.SNAC_0x return _c } -// BUCPLogin provides a mock function with given fields: bodyIn, fn -func (_m *mockAuthService) BUCPLogin(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, fn func(string) (state.User, error)) (wire.SNACMessage, error) { - ret := _m.Called(bodyIn, fn) +// BUCPLogin provides a mock function with given fields: bodyIn, newUserFn +func (_m *mockAuthService) BUCPLogin(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, newUserFn func(state.DisplayScreenName) (state.User, error)) (wire.SNACMessage, error) { + ret := _m.Called(bodyIn, newUserFn) if len(ret) == 0 { panic("no return value specified for BUCPLogin") @@ -93,17 +93,17 @@ func (_m *mockAuthService) BUCPLogin(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest var r0 wire.SNACMessage var r1 error - if rf, ok := ret.Get(0).(func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(string) (state.User, error)) (wire.SNACMessage, error)); ok { - return rf(bodyIn, fn) + if rf, ok := ret.Get(0).(func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(state.DisplayScreenName) (state.User, error)) (wire.SNACMessage, error)); ok { + return rf(bodyIn, newUserFn) } - if rf, ok := ret.Get(0).(func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(string) (state.User, error)) wire.SNACMessage); ok { - r0 = rf(bodyIn, fn) + if rf, ok := ret.Get(0).(func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(state.DisplayScreenName) (state.User, error)) wire.SNACMessage); ok { + r0 = rf(bodyIn, newUserFn) } else { r0 = ret.Get(0).(wire.SNACMessage) } - if rf, ok := ret.Get(1).(func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(string) (state.User, error)) error); ok { - r1 = rf(bodyIn, fn) + if rf, ok := ret.Get(1).(func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(state.DisplayScreenName) (state.User, error)) error); ok { + r1 = rf(bodyIn, newUserFn) } else { r1 = ret.Error(1) } @@ -118,14 +118,14 @@ type mockAuthService_BUCPLogin_Call struct { // BUCPLogin is a helper method to define mock.On call // - bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest -// - fn func(string)(state.User , error) -func (_e *mockAuthService_Expecter) BUCPLogin(bodyIn interface{}, fn interface{}) *mockAuthService_BUCPLogin_Call { - return &mockAuthService_BUCPLogin_Call{Call: _e.mock.On("BUCPLogin", bodyIn, fn)} +// - newUserFn func(state.DisplayScreenName)(state.User , error) +func (_e *mockAuthService_Expecter) BUCPLogin(bodyIn interface{}, newUserFn interface{}) *mockAuthService_BUCPLogin_Call { + return &mockAuthService_BUCPLogin_Call{Call: _e.mock.On("BUCPLogin", bodyIn, newUserFn)} } -func (_c *mockAuthService_BUCPLogin_Call) Run(run func(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, fn func(string) (state.User, error))) *mockAuthService_BUCPLogin_Call { +func (_c *mockAuthService_BUCPLogin_Call) Run(run func(bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, newUserFn func(state.DisplayScreenName) (state.User, error))) *mockAuthService_BUCPLogin_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(wire.SNAC_0x17_0x02_BUCPLoginRequest), args[1].(func(string) (state.User, error))) + run(args[0].(wire.SNAC_0x17_0x02_BUCPLoginRequest), args[1].(func(state.DisplayScreenName) (state.User, error))) }) return _c } @@ -135,13 +135,13 @@ func (_c *mockAuthService_BUCPLogin_Call) Return(_a0 wire.SNACMessage, _a1 error return _c } -func (_c *mockAuthService_BUCPLogin_Call) RunAndReturn(run func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(string) (state.User, error)) (wire.SNACMessage, error)) *mockAuthService_BUCPLogin_Call { +func (_c *mockAuthService_BUCPLogin_Call) RunAndReturn(run func(wire.SNAC_0x17_0x02_BUCPLoginRequest, func(state.DisplayScreenName) (state.User, error)) (wire.SNACMessage, error)) *mockAuthService_BUCPLogin_Call { _c.Call.Return(run) return _c } // FLAPLogin provides a mock function with given fields: frame, newUserFn -func (_m *mockAuthService) FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func(string) (state.User, error)) (wire.TLVRestBlock, error) { +func (_m *mockAuthService) FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func(state.DisplayScreenName) (state.User, error)) (wire.TLVRestBlock, error) { ret := _m.Called(frame, newUserFn) if len(ret) == 0 { @@ -150,16 +150,16 @@ func (_m *mockAuthService) FLAPLogin(frame wire.FLAPSignonFrame, newUserFn func( var r0 wire.TLVRestBlock var r1 error - if rf, ok := ret.Get(0).(func(wire.FLAPSignonFrame, func(string) (state.User, error)) (wire.TLVRestBlock, error)); ok { + if rf, ok := ret.Get(0).(func(wire.FLAPSignonFrame, func(state.DisplayScreenName) (state.User, error)) (wire.TLVRestBlock, error)); ok { return rf(frame, newUserFn) } - if rf, ok := ret.Get(0).(func(wire.FLAPSignonFrame, func(string) (state.User, error)) wire.TLVRestBlock); ok { + if rf, ok := ret.Get(0).(func(wire.FLAPSignonFrame, func(state.DisplayScreenName) (state.User, error)) wire.TLVRestBlock); ok { r0 = rf(frame, newUserFn) } else { r0 = ret.Get(0).(wire.TLVRestBlock) } - if rf, ok := ret.Get(1).(func(wire.FLAPSignonFrame, func(string) (state.User, error)) error); ok { + if rf, ok := ret.Get(1).(func(wire.FLAPSignonFrame, func(state.DisplayScreenName) (state.User, error)) error); ok { r1 = rf(frame, newUserFn) } else { r1 = ret.Error(1) @@ -175,14 +175,14 @@ type mockAuthService_FLAPLogin_Call struct { // FLAPLogin is a helper method to define mock.On call // - frame wire.FLAPSignonFrame -// - newUserFn func(string)(state.User , error) +// - newUserFn func(state.DisplayScreenName)(state.User , error) func (_e *mockAuthService_Expecter) FLAPLogin(frame interface{}, newUserFn interface{}) *mockAuthService_FLAPLogin_Call { return &mockAuthService_FLAPLogin_Call{Call: _e.mock.On("FLAPLogin", frame, newUserFn)} } -func (_c *mockAuthService_FLAPLogin_Call) Run(run func(frame wire.FLAPSignonFrame, newUserFn func(string) (state.User, error))) *mockAuthService_FLAPLogin_Call { +func (_c *mockAuthService_FLAPLogin_Call) Run(run func(frame wire.FLAPSignonFrame, newUserFn func(state.DisplayScreenName) (state.User, error))) *mockAuthService_FLAPLogin_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(wire.FLAPSignonFrame), args[1].(func(string) (state.User, error))) + run(args[0].(wire.FLAPSignonFrame), args[1].(func(state.DisplayScreenName) (state.User, error))) }) return _c } @@ -192,14 +192,14 @@ func (_c *mockAuthService_FLAPLogin_Call) Return(_a0 wire.TLVRestBlock, _a1 erro return _c } -func (_c *mockAuthService_FLAPLogin_Call) RunAndReturn(run func(wire.FLAPSignonFrame, func(string) (state.User, error)) (wire.TLVRestBlock, error)) *mockAuthService_FLAPLogin_Call { +func (_c *mockAuthService_FLAPLogin_Call) RunAndReturn(run func(wire.FLAPSignonFrame, func(state.DisplayScreenName) (state.User, error)) (wire.TLVRestBlock, error)) *mockAuthService_FLAPLogin_Call { _c.Call.Return(run) return _c } -// RegisterBOSSession provides a mock function with given fields: sessionID -func (_m *mockAuthService) RegisterBOSSession(sessionID string) (*state.Session, error) { - ret := _m.Called(sessionID) +// RegisterBOSSession provides a mock function with given fields: screenName +func (_m *mockAuthService) RegisterBOSSession(screenName state.IdentScreenName) (*state.Session, error) { + ret := _m.Called(screenName) if len(ret) == 0 { panic("no return value specified for RegisterBOSSession") @@ -207,19 +207,19 @@ func (_m *mockAuthService) RegisterBOSSession(sessionID string) (*state.Session, var r0 *state.Session var r1 error - if rf, ok := ret.Get(0).(func(string) (*state.Session, error)); ok { - return rf(sessionID) + if rf, ok := ret.Get(0).(func(state.IdentScreenName) (*state.Session, error)); ok { + return rf(screenName) } - if rf, ok := ret.Get(0).(func(string) *state.Session); ok { - r0 = rf(sessionID) + if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.Session); ok { + r0 = rf(screenName) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*state.Session) } } - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(sessionID) + if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok { + r1 = rf(screenName) } else { r1 = ret.Error(1) } @@ -233,14 +233,14 @@ type mockAuthService_RegisterBOSSession_Call struct { } // RegisterBOSSession is a helper method to define mock.On call -// - sessionID string -func (_e *mockAuthService_Expecter) RegisterBOSSession(sessionID interface{}) *mockAuthService_RegisterBOSSession_Call { - return &mockAuthService_RegisterBOSSession_Call{Call: _e.mock.On("RegisterBOSSession", sessionID)} +// - screenName state.IdentScreenName +func (_e *mockAuthService_Expecter) RegisterBOSSession(screenName interface{}) *mockAuthService_RegisterBOSSession_Call { + return &mockAuthService_RegisterBOSSession_Call{Call: _e.mock.On("RegisterBOSSession", screenName)} } -func (_c *mockAuthService_RegisterBOSSession_Call) Run(run func(sessionID string)) *mockAuthService_RegisterBOSSession_Call { +func (_c *mockAuthService_RegisterBOSSession_Call) Run(run func(screenName state.IdentScreenName)) *mockAuthService_RegisterBOSSession_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(state.IdentScreenName)) }) return _c } @@ -250,7 +250,7 @@ func (_c *mockAuthService_RegisterBOSSession_Call) Return(_a0 *state.Session, _a return _c } -func (_c *mockAuthService_RegisterBOSSession_Call) RunAndReturn(run func(string) (*state.Session, error)) *mockAuthService_RegisterBOSSession_Call { +func (_c *mockAuthService_RegisterBOSSession_Call) RunAndReturn(run func(state.IdentScreenName) (*state.Session, error)) *mockAuthService_RegisterBOSSession_Call { _c.Call.Return(run) return _c } diff --git a/state/buddy_list_store.go b/state/buddy_list_store.go index 3a7f108c..dad32cc4 100644 --- a/state/buddy_list_store.go +++ b/state/buddy_list_store.go @@ -4,34 +4,34 @@ import "sync" // AdjListBuddyListStore implements a buddy list using an adjacency list. type AdjListBuddyListStore struct { - buddies map[string]map[string]bool + buddies map[IdentScreenName]map[IdentScreenName]bool mu sync.RWMutex // ensures thread-safe access } // NewAdjListBuddyListStore initializes a new instance of AdjListBuddyListStore. func NewAdjListBuddyListStore() *AdjListBuddyListStore { return &AdjListBuddyListStore{ - buddies: make(map[string]map[string]bool), + buddies: make(map[IdentScreenName]map[IdentScreenName]bool), } } // AddBuddy adds buddyScreenName to userScreenName's buddy list. -func (store *AdjListBuddyListStore) AddBuddy(userScreenName, buddyScreenName string) { +func (store *AdjListBuddyListStore) AddBuddy(userScreenName, buddyScreenName IdentScreenName) { store.mu.Lock() defer store.mu.Unlock() if _, exists := store.buddies[userScreenName]; !exists { - store.buddies[userScreenName] = make(map[string]bool) + store.buddies[userScreenName] = make(map[IdentScreenName]bool) } store.buddies[userScreenName][buddyScreenName] = true } // WhoAddedUser returns a list of screen names who have userScreenName in their buddy lists. -func (store *AdjListBuddyListStore) WhoAddedUser(userScreenName string) []string { +func (store *AdjListBuddyListStore) WhoAddedUser(userScreenName IdentScreenName) []IdentScreenName { store.mu.RLock() defer store.mu.RUnlock() - var users []string + var users []IdentScreenName for user, buddies := range store.buddies { if buddies[userScreenName] { users = append(users, user) @@ -41,12 +41,12 @@ func (store *AdjListBuddyListStore) WhoAddedUser(userScreenName string) []string } // Buddies returns a list of all buddies associated with the specified userScreenName. -func (store *AdjListBuddyListStore) Buddies(userScreenName string) []string { +func (store *AdjListBuddyListStore) Buddies(userScreenName IdentScreenName) []IdentScreenName { store.mu.RLock() defer store.mu.RUnlock() if buddies, exists := store.buddies[userScreenName]; exists { - users := make([]string, 0, len(buddies)) + users := make([]IdentScreenName, 0, len(buddies)) for buddy := range buddies { users = append(users, buddy) } @@ -56,7 +56,7 @@ func (store *AdjListBuddyListStore) Buddies(userScreenName string) []string { } // DeleteBuddy removes buddyScreenName from userScreenName's buddy list. -func (store *AdjListBuddyListStore) DeleteBuddy(userScreenName, buddyScreenName string) { +func (store *AdjListBuddyListStore) DeleteBuddy(userScreenName, buddyScreenName IdentScreenName) { store.mu.Lock() defer store.mu.Unlock() @@ -69,7 +69,7 @@ func (store *AdjListBuddyListStore) DeleteBuddy(userScreenName, buddyScreenName } // DeleteUser removes userScreenName's buddy list. -func (store *AdjListBuddyListStore) DeleteUser(userScreenName string) { +func (store *AdjListBuddyListStore) DeleteUser(userScreenName IdentScreenName) { store.mu.Lock() defer store.mu.Unlock() diff --git a/state/buddy_list_store_test.go b/state/buddy_list_store_test.go index 6806c5eb..d1debaed 100644 --- a/state/buddy_list_store_test.go +++ b/state/buddy_list_store_test.go @@ -8,68 +8,79 @@ import ( func TestAdjListBuddyListStore_AddBuddy_Buddies(t *testing.T) { store := NewAdjListBuddyListStore() - store.AddBuddy("alice", "bob") - store.AddBuddy("bob", "alice") - store.AddBuddy("alice", "charlie") - store.AddBuddy("alice", "dave") - store.AddBuddy("dave", "bob") + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("bob")) + store.AddBuddy(NewIdentScreenName("bob"), NewIdentScreenName("alice")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("charlie")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("dave")) + store.AddBuddy(NewIdentScreenName("dave"), NewIdentScreenName("bob")) - buddies := store.Buddies("alice") - assert.ElementsMatch(t, []string{"bob", "charlie", "dave"}, buddies) + buddies := store.Buddies(NewIdentScreenName("alice")) + assert.ElementsMatch(t, []IdentScreenName{ + NewIdentScreenName("bob"), + NewIdentScreenName("charlie"), + NewIdentScreenName("dave"), + }, buddies) } func TestAdjListBuddyListStore_DeleteBuddy_OneBuddy(t *testing.T) { store := NewAdjListBuddyListStore() - store.AddBuddy("alice", "bob") - store.AddBuddy("bob", "alice") - store.AddBuddy("alice", "charlie") - store.AddBuddy("alice", "dave") - store.AddBuddy("dave", "bob") + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("bob")) + store.AddBuddy(NewIdentScreenName("bob"), NewIdentScreenName("alice")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("charlie")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("dave")) + store.AddBuddy(NewIdentScreenName("dave"), NewIdentScreenName("bob")) - store.DeleteBuddy("alice", "bob") + store.DeleteBuddy(NewIdentScreenName("alice"), NewIdentScreenName("bob")) - buddies := store.Buddies("alice") - assert.ElementsMatch(t, []string{"charlie", "dave"}, buddies) + buddies := store.Buddies(NewIdentScreenName("alice")) + assert.ElementsMatch(t, []IdentScreenName{ + NewIdentScreenName("charlie"), + NewIdentScreenName("dave"), + }, buddies) } func TestAdjListBuddyListStore_DeleteBuddy_AllBuddies(t *testing.T) { store := NewAdjListBuddyListStore() - store.AddBuddy("alice", "bob") - store.AddBuddy("bob", "alice") - store.AddBuddy("alice", "charlie") - store.AddBuddy("alice", "dave") - store.AddBuddy("dave", "bob") + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("bob")) + store.AddBuddy(NewIdentScreenName("bob"), NewIdentScreenName("alice")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("charlie")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("dave")) + store.AddBuddy(NewIdentScreenName("dave"), NewIdentScreenName("bob")) - store.DeleteBuddy("alice", "bob") - store.DeleteBuddy("alice", "charlie") - store.DeleteBuddy("alice", "dave") + store.DeleteBuddy(NewIdentScreenName("alice"), NewIdentScreenName("bob")) + store.DeleteBuddy(NewIdentScreenName("alice"), NewIdentScreenName("charlie")) + store.DeleteBuddy(NewIdentScreenName("alice"), NewIdentScreenName("dave")) - buddies := store.Buddies("alice") + buddies := store.Buddies(NewIdentScreenName("alice")) assert.Nil(t, buddies) } func TestAdjListBuddyListStore_DeleteUser(t *testing.T) { store := NewAdjListBuddyListStore() - store.AddBuddy("alice", "bob") - store.AddBuddy("bob", "alice") - store.AddBuddy("alice", "charlie") - store.AddBuddy("alice", "dave") - store.AddBuddy("dave", "bob") + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("bob")) + store.AddBuddy(NewIdentScreenName("bob"), NewIdentScreenName("alice")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("charlie")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("dave")) + store.AddBuddy(NewIdentScreenName("dave"), NewIdentScreenName("bob")) - store.DeleteUser("alice") + store.DeleteUser(NewIdentScreenName("alice")) - buddies := store.Buddies("alice") + buddies := store.Buddies(NewIdentScreenName("alice")) assert.Nil(t, buddies) } func TestAdjListBuddyListStore_WhoAddedUser(t *testing.T) { store := NewAdjListBuddyListStore() - store.AddBuddy("alice", "bob") - store.AddBuddy("alice", "charlie") - store.AddBuddy("charlie", "bob") - store.AddBuddy("dave", "bob") - store.AddBuddy("dave", "alive") + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("bob")) + store.AddBuddy(NewIdentScreenName("alice"), NewIdentScreenName("charlie")) + store.AddBuddy(NewIdentScreenName("charlie"), NewIdentScreenName("bob")) + store.AddBuddy(NewIdentScreenName("dave"), NewIdentScreenName("bob")) + store.AddBuddy(NewIdentScreenName("dave"), NewIdentScreenName("alive")) - whoAddedBob := store.WhoAddedUser("bob") - assert.ElementsMatch(t, []string{"alice", "charlie", "dave"}, whoAddedBob) + whoAddedBob := store.WhoAddedUser(NewIdentScreenName("bob")) + assert.ElementsMatch(t, []IdentScreenName{ + NewIdentScreenName("alice"), + NewIdentScreenName("charlie"), + NewIdentScreenName("dave"), + }, whoAddedBob) } diff --git a/state/migrations/0003_formatted_screen_name.down.sql b/state/migrations/0003_formatted_screen_name.down.sql new file mode 100644 index 00000000..2886a765 --- /dev/null +++ b/state/migrations/0003_formatted_screen_name.down.sql @@ -0,0 +1,16 @@ +CREATE TABLE user +( + screenName VARCHAR(16) PRIMARY KEY, + authKey TEXT, + strongMD5Pass TEXT, + weakMD5Pass TEXT +); + +INSERT INTO user +SELECT displayScreenName, + authKey, + strongMD5Pass, + weakMD5Pass +FROM users; + +DROP TABLE users; \ No newline at end of file diff --git a/state/migrations/0003_formatted_screen_name.up.sql b/state/migrations/0003_formatted_screen_name.up.sql new file mode 100644 index 00000000..14fc99ac --- /dev/null +++ b/state/migrations/0003_formatted_screen_name.up.sql @@ -0,0 +1,27 @@ +-- call the new table "users" since it's not a reserved word that we'll need to +-- deal with for postgres in the future. +CREATE TABLE users +( + identScreenName VARCHAR(16) PRIMARY KEY, + displayScreenName TEXT, + authKey TEXT, + strongMD5Pass TEXT, + weakMD5Pass TEXT +); + +INSERT INTO users +SELECT LOWER(REPLACE(screenName, ' ', '')), + screenName, + authKey, + strongMD5Pass, + weakMD5Pass +FROM user; + +DROP TABLE user; + +UPDATE feedbag +SET name = LOWER(REPLACE(name, ' ', '')) +WHERE classID IN (0, 2, 3); + +UPDATE feedbag +SET screenName = LOWER(REPLACE(screenName, ' ', '')); \ No newline at end of file diff --git a/state/session.go b/state/session.go index 3b58dc82..b641b3b5 100644 --- a/state/session.go +++ b/state/session.go @@ -23,21 +23,22 @@ const ( // Session represents a user's current session. Unless stated otherwise, all // methods may be safely accessed by multiple goroutines. type Session struct { - awayMessage string - chatRoomCookie string - closed bool - idle bool - idleTime time.Time - invisible bool - msgCh chan wire.SNACMessage - mutex sync.RWMutex - nowFn func() time.Time - signonComplete bool - screenName string - signonTime time.Time - stopCh chan struct{} - warning uint16 - caps [][16]byte + awayMessage string + caps [][16]byte + chatRoomCookie string + closed bool + displayScreenName DisplayScreenName + identScreenName IdentScreenName + idle bool + idleTime time.Time + invisible bool + msgCh chan wire.SNACMessage + mutex sync.RWMutex + nowFn func() time.Time + signonComplete bool + signonTime time.Time + stopCh chan struct{} + warning uint16 } // NewSession returns a new instance of Session. By default, the user may have @@ -74,18 +75,32 @@ func (s *Session) Invisible() bool { return s.invisible } -// SetScreenName sets the user's screen name. -func (s *Session) SetScreenName(screenName string) { +// SetIdentScreenName sets the user's screen name. +func (s *Session) SetIdentScreenName(screenName IdentScreenName) { s.mutex.Lock() defer s.mutex.Unlock() - s.screenName = screenName + s.identScreenName = screenName } -// ScreenName returns the user's screen name. -func (s *Session) ScreenName() string { +// IdentScreenName returns the user's screen name. +func (s *Session) IdentScreenName() IdentScreenName { s.mutex.RLock() defer s.mutex.RUnlock() - return s.screenName + return s.identScreenName +} + +// SetDisplayScreenName sets the user's screen name. +func (s *Session) SetDisplayScreenName(displayScreenName DisplayScreenName) { + s.mutex.Lock() + defer s.mutex.Unlock() + s.displayScreenName = displayScreenName +} + +// DisplayScreenName returns the user's screen name. +func (s *Session) DisplayScreenName() DisplayScreenName { + s.mutex.RLock() + defer s.mutex.RUnlock() + return s.displayScreenName } // SetSignonTime sets the user's sign-ontime. @@ -159,7 +174,7 @@ func (s *Session) TLVUserInfo() wire.TLVUserInfo { s.mutex.RLock() defer s.mutex.RUnlock() return wire.TLVUserInfo{ - ScreenName: s.screenName, + ScreenName: string(s.displayScreenName), WarningLevel: s.warning, TLVBlock: wire.TLVBlock{ TLVList: s.userInfo(), diff --git a/state/session_manager.go b/state/session_manager.go index 24d75933..e6e93014 100644 --- a/state/session_manager.go +++ b/state/session_manager.go @@ -12,7 +12,7 @@ import ( // synchronized message relay between sessions in the session pool. An // InMemorySessionManager is safe for concurrent use by multiple goroutines. type InMemorySessionManager struct { - store map[string]*Session + store map[IdentScreenName]*Session mapMutex sync.RWMutex logger *slog.Logger } @@ -21,7 +21,7 @@ type InMemorySessionManager struct { func NewInMemorySessionManager(logger *slog.Logger) *InMemorySessionManager { return &InMemorySessionManager{ logger: logger, - store: make(map[string]*Session), + store: make(map[IdentScreenName]*Session), } } @@ -48,7 +48,7 @@ func (s *InMemorySessionManager) RelayToAllExcept(ctx context.Context, except *S } // RelayToScreenName relays a message to a session with a matching screen name. -func (s *InMemorySessionManager) RelayToScreenName(ctx context.Context, screenName string, msg wire.SNACMessage) { +func (s *InMemorySessionManager) RelayToScreenName(ctx context.Context, screenName IdentScreenName, msg wire.SNACMessage) { sess := s.RetrieveByScreenName(screenName) if sess == nil { s.logger.WarnContext(ctx, "can't send notification because user is not online", "recipient", screenName, "message", msg) @@ -58,7 +58,7 @@ func (s *InMemorySessionManager) RelayToScreenName(ctx context.Context, screenNa } // RelayToScreenNames relays a message to sessions with matching screenNames. -func (s *InMemorySessionManager) RelayToScreenNames(ctx context.Context, screenNames []string, msg wire.SNACMessage) { +func (s *InMemorySessionManager) RelayToScreenNames(ctx context.Context, screenNames []IdentScreenName, msg wire.SNACMessage) { for _, sess := range s.retrieveByScreenNames(screenNames) { s.maybeRelayMessage(ctx, msg, sess) } @@ -67,9 +67,9 @@ func (s *InMemorySessionManager) RelayToScreenNames(ctx context.Context, screenN func (s *InMemorySessionManager) maybeRelayMessage(ctx context.Context, msg wire.SNACMessage, sess *Session) { switch sess.RelayMessage(msg) { case SessSendClosed: - s.logger.WarnContext(ctx, "can't send notification because the user's session is closed", "recipient", sess.ScreenName(), "message", msg) + s.logger.WarnContext(ctx, "can't send notification because the user's session is closed", "recipient", sess.IdentScreenName(), "message", msg) case SessQueueFull: - s.logger.WarnContext(ctx, "can't send notification because queue is full", "recipient", sess.ScreenName(), "message", msg) + s.logger.WarnContext(ctx, "can't send notification because queue is full", "recipient", sess.IdentScreenName(), "message", msg) sess.Close() } } @@ -77,26 +77,28 @@ func (s *InMemorySessionManager) maybeRelayMessage(ctx context.Context, msg wire // AddSession adds a new session to the pool. It replaces an existing session // with a matching screen name, ensuring that each screen name is unique in the // pool. -func (s *InMemorySessionManager) AddSession(screenName string) *Session { +func (s *InMemorySessionManager) AddSession(displayScreenName DisplayScreenName) *Session { s.mapMutex.Lock() defer s.mapMutex.Unlock() + identScreenName := NewIdentScreenName(string(displayScreenName)) // Only allow one session at a time per screen name. A session may already // exist because: // 1) the user is signing on using an already logged-on screen name. // 2) the session might be orphaned due to an undetected client // disconnection. for _, sess := range s.store { - if screenName == sess.ScreenName() { + if identScreenName == sess.IdentScreenName() { sess.Close() - delete(s.store, screenName) + delete(s.store, identScreenName) break } } sess := NewSession() - sess.SetScreenName(screenName) - s.store[sess.ScreenName()] = sess + sess.SetIdentScreenName(identScreenName) + sess.SetDisplayScreenName(displayScreenName) + s.store[identScreenName] = sess return sess } @@ -104,37 +106,37 @@ func (s *InMemorySessionManager) AddSession(screenName string) *Session { func (s *InMemorySessionManager) RemoveSession(sess *Session) { s.mapMutex.Lock() defer s.mapMutex.Unlock() - delete(s.store, sess.ScreenName()) + delete(s.store, sess.IdentScreenName()) } // RetrieveSession finds a session with a matching sessionID. Returns nil if // session is not found. -func (s *InMemorySessionManager) RetrieveSession(sessionID string) *Session { +func (s *InMemorySessionManager) RetrieveSession(screenName IdentScreenName) *Session { s.mapMutex.RLock() defer s.mapMutex.RUnlock() - return s.store[sessionID] + return s.store[screenName] } // RetrieveByScreenName find a session with a matching screen name. Returns nil // if session is not found. -func (s *InMemorySessionManager) RetrieveByScreenName(screenName string) *Session { +func (s *InMemorySessionManager) RetrieveByScreenName(screenName IdentScreenName) *Session { s.mapMutex.RLock() defer s.mapMutex.RUnlock() for _, sess := range s.store { - if screenName == sess.ScreenName() { + if screenName == sess.IdentScreenName() { return sess } } return nil } -func (s *InMemorySessionManager) retrieveByScreenNames(screenNames []string) []*Session { +func (s *InMemorySessionManager) retrieveByScreenNames(screenNames []IdentScreenName) []*Session { s.mapMutex.RLock() defer s.mapMutex.RUnlock() var ret []*Session for _, sn := range screenNames { for _, sess := range s.store { - if sn == sess.ScreenName() { + if sn == sess.IdentScreenName() { ret = append(ret, sess) } } diff --git a/state/session_manager_test.go b/state/session_manager_test.go index 09d0f48d..a782c8c5 100644 --- a/state/session_manager_test.go +++ b/state/session_manager_test.go @@ -14,11 +14,11 @@ func TestInMemorySessionManager_AddSession(t *testing.T) { sm := NewInMemorySessionManager(slog.Default()) want1 := sm.AddSession("user-screen-name") - have1 := sm.RetrieveByScreenName("user-screen-name") + have1 := sm.RetrieveByScreenName(NewIdentScreenName("user-screen-name")) assert.Same(t, want1, have1) want2 := sm.AddSession("user-screen-name") - have2 := sm.RetrieveByScreenName("user-screen-name") + have2 := sm.RetrieveByScreenName(NewIdentScreenName("user-screen-name")) assert.Same(t, want2, have2) // ensure that the second session created with the same screen name as the @@ -29,38 +29,34 @@ func TestInMemorySessionManager_AddSession(t *testing.T) { func TestInMemorySessionManager_Remove(t *testing.T) { tests := []struct { name string - given []*Session - remove string - want []string + given []DisplayScreenName + remove IdentScreenName + want []IdentScreenName }{ { name: "remove user that exists", - given: []*Session{ - { - screenName: "user-screen-name-1", - }, - { - screenName: "user-screen-name-2", - }, - }, - remove: "user-screen-name-1", - want: []string{ + given: []DisplayScreenName{ + "user-screen-name-1", "user-screen-name-2", }, + remove: NewIdentScreenName("user-screen-name-1"), + want: []IdentScreenName{ + NewIdentScreenName("user-screen-name-2"), + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sm := NewInMemorySessionManager(slog.Default()) - for _, sess := range tt.given { - sm.AddSession(sess.screenName) + for _, screenName := range tt.given { + sm.AddSession(screenName) } sm.RemoveSession(sm.RetrieveByScreenName(tt.remove)) for i, sess := range sm.AllSessions() { - assert.Equal(t, tt.want[i], sess.screenName) + assert.Equal(t, tt.want[i], sess.identScreenName) } }) } @@ -68,23 +64,20 @@ func TestInMemorySessionManager_Remove(t *testing.T) { func TestInMemorySessionManager_Empty(t *testing.T) { tests := []struct { - name string - given []*Session - remove string - want bool + name string + given []DisplayScreenName + want bool }{ { name: "session manager is not empty", - given: []*Session{ - { - screenName: "user-screen-name-1", - }, + given: []DisplayScreenName{ + "user-screen-name-1", }, want: false, }, { name: "session manager is empty", - given: []*Session{}, + given: []DisplayScreenName{}, want: true, }, } @@ -92,8 +85,8 @@ func TestInMemorySessionManager_Empty(t *testing.T) { t.Run(tt.name, func(t *testing.T) { sm := NewInMemorySessionManager(slog.Default()) - for _, sess := range tt.given { - sm.AddSession(sess.screenName) + for _, screenName := range tt.given { + sm.AddSession(screenName) } have := sm.Empty() @@ -105,44 +98,39 @@ func TestInMemorySessionManager_Empty(t *testing.T) { func TestInMemorySessionManager_Retrieve(t *testing.T) { tests := []struct { name string - given []*Session - lookupScreenName string - remove string - wantScreenName string + given []DisplayScreenName + lookupScreenName IdentScreenName + wantScreenName IdentScreenName }{ { name: "lookup finds match", - given: []*Session{ - { - screenName: "user-screen-name-1", - }, - { - screenName: "user-screen-name-2", - }, + given: []DisplayScreenName{ + "user-screen-name-1", + "user-screen-name-2", }, - lookupScreenName: "user-screen-name-2", - wantScreenName: "user-screen-name-2", + lookupScreenName: NewIdentScreenName("user-screen-name-2"), + wantScreenName: NewIdentScreenName("user-screen-name-2"), }, { name: "lookup does not find match", - given: []*Session{}, - lookupScreenName: "user-screen-name-3", - wantScreenName: "", + given: []DisplayScreenName{}, + lookupScreenName: NewIdentScreenName("user-screen-name-3"), + wantScreenName: NewIdentScreenName(""), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sm := NewInMemorySessionManager(slog.Default()) - for _, sess := range tt.given { - sm.AddSession(sess.screenName) + for _, screenName := range tt.given { + sm.AddSession(screenName) } have := sm.RetrieveSession(tt.lookupScreenName) if have == nil { assert.Empty(t, tt.wantScreenName) } else { - assert.Equal(t, tt.wantScreenName, have.ScreenName()) + assert.Equal(t, tt.wantScreenName, have.IdentScreenName()) } }) } @@ -157,7 +145,10 @@ func TestInMemorySessionManager_RelayToScreenNames(t *testing.T) { want := wire.SNACMessage{Frame: wire.SNACFrame{FoodGroup: wire.ICBM}} - recips := []string{"user-screen-name-1", "user-screen-name-2"} + recips := []IdentScreenName{ + NewIdentScreenName("user-screen-name-1"), + NewIdentScreenName("user-screen-name-2"), + } sm.RelayToScreenNames(context.Background(), recips, want) select { @@ -229,7 +220,7 @@ func TestInMemorySessionManager_RelayToScreenName_SessionExists(t *testing.T) { want := wire.SNACMessage{Frame: wire.SNACFrame{FoodGroup: wire.ICBM}} - recip := "user-screen-name-1" + recip := NewIdentScreenName("user-screen-name-1") sm.RelayToScreenName(context.Background(), recip, want) select { @@ -251,7 +242,7 @@ func TestInMemorySessionManager_RelayToScreenName_SessionNotExist(t *testing.T) want := wire.SNACMessage{Frame: wire.SNACFrame{FoodGroup: wire.ICBM}} - recip := "user-screen-name-2" + recip := NewIdentScreenName("user-screen-name-2") sm.RelayToScreenName(context.Background(), recip, want) select { @@ -275,7 +266,7 @@ func TestInMemorySessionManager_RelayToScreenName_SkipFullSession(t *testing.T) wantCount++ } - recip := "user-screen-name-1" + recip := NewIdentScreenName("user-screen-name-1") sm.RelayToScreenName(context.Background(), recip, msg) haveCount := 0 diff --git a/state/session_test.go b/state/session_test.go index b64adf03..85faf81b 100644 --- a/state/session_test.go +++ b/state/session_test.go @@ -38,10 +38,10 @@ func TestSession_SetAndGetInvisible(t *testing.T) { func TestSession_SetAndGetScreenName(t *testing.T) { s := NewSession() - assert.Empty(t, s.ScreenName()) - sn := "user-screen-name" - s.SetScreenName(sn) - assert.Equal(t, sn, s.ScreenName()) + assert.Empty(t, s.IdentScreenName()) + sn := NewIdentScreenName("user-screen-name") + s.SetIdentScreenName(sn) + assert.Equal(t, sn, s.IdentScreenName()) } func TestSession_SetAndGetChatRoomCookie(t *testing.T) { @@ -63,7 +63,8 @@ func TestSession_TLVUserInfo(t *testing.T) { givenSessionFn: func() *Session { s := NewSession() s.SetSignonTime(time.Unix(1, 0)) - s.SetScreenName("xXAIMUSERXx") + s.SetIdentScreenName(NewIdentScreenName("xXAIMUSERXx")) + s.SetDisplayScreenName("xXAIMUSERXx") s.IncrementWarning(10) return s }, diff --git a/state/user.go b/state/user.go new file mode 100644 index 00000000..abef2a26 --- /dev/null +++ b/state/user.go @@ -0,0 +1,122 @@ +package state + +import ( + "bytes" + "errors" + "strings" + + "github.com/google/uuid" + + "github.com/mk6i/retro-aim-server/wire" +) + +// BlockedState represents the blocked status between two users +type BlockedState int + +var ( + // ErrDupUser indicates that a user already exists. + ErrDupUser = errors.New("user already exists") + // ErrNoUser indicates that a user does not exist. + ErrNoUser = errors.New("user does not exist") +) + +const ( + // BlockedNo indicates that neither user blocks the other. + BlockedNo BlockedState = iota + // BlockedA indicates that user A blocks user B. + BlockedA + // BlockedB indicates that user B blocks user A. + BlockedB +) + +// IdentScreenName struct stores the normalized version of a user's screen name. +// This format is used for uniformity in storage and comparison by removing spaces +// and converting all characters to lowercase. +type IdentScreenName struct { + // screenName contains the identifier screen name value. Do not assign this + // value directly. Rather, set it through NewIdentScreenName. This ensures + // that when an instance of IdentScreenName is present, it's guaranteed to + // have a normalized value. + screenName string +} + +// String returns the string representation of the IdentScreenName. +func (i IdentScreenName) String() string { + return i.screenName +} + +// NewIdentScreenName creates a new IdentScreenName. +func NewIdentScreenName(screenName string) IdentScreenName { + str := strings.ReplaceAll(screenName, " ", "") + str = strings.ToLower(str) + return IdentScreenName{screenName: str} +} + +// DisplayScreenName type represents the screen name in the user-defined format. +// This includes the original casing and spacing as defined by the user. +type DisplayScreenName string + +// IdentScreenName converts the DisplayScreenName to an IdentScreenName by applying +// the normalization process defined in NewIdentScreenName. +func (s DisplayScreenName) IdentScreenName() IdentScreenName { + return NewIdentScreenName(string(s)) +} + +// String returns the original display string of the screen name, preserving the user-defined +// casing and spaces. +func (s DisplayScreenName) String() string { + return string(s) +} + +// NewStubUser creates a new user with canned credentials. The default password +// is "welcome1". This is typically used for development purposes. +func NewStubUser(screenName DisplayScreenName) (User, error) { + uid, err := uuid.NewRandom() + if err != nil { + return User{}, err + } + u := User{ + IdentScreenName: NewIdentScreenName(string(screenName)), + DisplayScreenName: screenName, + AuthKey: uid.String(), + } + err = u.HashPassword("welcome1") + return u, err +} + +// User represents a user account. +type User struct { + // IdentScreenName is the AIM screen name. + IdentScreenName IdentScreenName `json:"-"` + // DisplayScreenName is the formatted screen name. + DisplayScreenName DisplayScreenName `json:"screen_name"` + // AuthKey is the salt for the MD5 password hash. + AuthKey string `json:"-"` + // StrongMD5Pass is the MD5 password hash format used by AIM v4.8-v5.9. + StrongMD5Pass []byte `json:"-"` + // WeakMD5Pass is the MD5 password hash format used by AIM v3.5-v4.7. This + // hash is used to authenticate roasted passwords for AIM v1.0-v3.0. + WeakMD5Pass []byte `json:"-"` +} + +// ValidateHash checks if md5Hash is identical to one of the password hashes. +func (u *User) ValidateHash(md5Hash []byte) bool { + return bytes.Equal(u.StrongMD5Pass, md5Hash) || bytes.Equal(u.WeakMD5Pass, md5Hash) +} + +// ValidateRoastedPass checks if the provided roasted password matches the MD5 +// hash of the user's actual password. A roasted password is a XOR-obfuscated +// form of the real password, intended to add a simple layer of security. +func (u *User) ValidateRoastedPass(roastedPass []byte) bool { + clearPass := wire.RoastPassword(roastedPass) + md5Hash := wire.WeakMD5PasswordHash(string(clearPass), u.AuthKey) // todo remove string conversion + return bytes.Equal(u.WeakMD5Pass, md5Hash) +} + +// HashPassword computes MD5 hashes of the user's password. It computes both +// weak and strong variants and stores them in the struct. +func (u *User) HashPassword(passwd string) error { + u.WeakMD5Pass = wire.WeakMD5PasswordHash(passwd, u.AuthKey) + u.StrongMD5Pass = wire.StrongMD5PasswordHash(passwd, u.AuthKey) + return nil +} diff --git a/state/user_store.go b/state/user_store.go index 4e5c3b97..52caf33f 100644 --- a/state/user_store.go +++ b/state/user_store.go @@ -15,67 +15,12 @@ import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database/sqlite3" "github.com/golang-migrate/migrate/v4/source/httpfs" - "github.com/google/uuid" _ "github.com/mattn/go-sqlite3" ) -// BlockedState represents the blocked status between two users -type BlockedState int - //go:embed migrations/* var migrations embed.FS -var ( - // ErrDupUser indicates that a user already exists. - ErrDupUser = errors.New("user already exists") - // ErrNoUser indicates that a user does not exist. - ErrNoUser = errors.New("user does not exist") -) - -const ( - // BlockedNo indicates that neither user blocks the other. - BlockedNo BlockedState = iota - // BlockedA indicates that user A blocks user B. - BlockedA - // BlockedB indicates that user B blocks user A. - BlockedB -) - -// User represents a user account. -type User struct { - // ScreenName is the AIM screen name. - ScreenName string `json:"screen_name"` - // AuthKey is the salt for the MD5 password hash. - AuthKey string `json:"-"` - // StrongMD5Pass is the MD5 password hash format used by AIM v4.8-v5.9. - StrongMD5Pass []byte `json:"-"` - // WeakMD5Pass is the MD5 password hash format used by AIM v3.5-v4.7. This - // hash is used to authenticate roasted passwords for AIM v1.0-v3.0. - WeakMD5Pass []byte `json:"-"` -} - -// ValidateHash checks if md5Hash is identical to one of the password hashes. -func (u *User) ValidateHash(md5Hash []byte) bool { - return bytes.Equal(u.StrongMD5Pass, md5Hash) || bytes.Equal(u.WeakMD5Pass, md5Hash) -} - -// ValidateRoastedPass checks if the provided roasted password matches the MD5 -// hash of the user's actual password. A roasted password is a XOR-obfuscated -// form of the real password, intended to add a simple layer of security. -func (u *User) ValidateRoastedPass(roastedPass []byte) bool { - clearPass := wire.RoastPassword(roastedPass) - md5Hash := wire.WeakMD5PasswordHash(string(clearPass), u.AuthKey) // todo remove string conversion - return bytes.Equal(u.WeakMD5Pass, md5Hash) -} - -// HashPassword computes MD5 hashes of the user's password. It computes both -// weak and strong variants and stores them in the struct. -func (u *User) HashPassword(passwd string) error { - u.WeakMD5Pass = wire.WeakMD5PasswordHash(passwd, u.AuthKey) - u.StrongMD5Pass = wire.StrongMD5PasswordHash(passwd, u.AuthKey) - return nil -} - // SQLiteUserStore stores user feedbag (buddy list), profile, and // authentication credentials information in a SQLite database. type SQLiteUserStore struct { @@ -122,10 +67,10 @@ func (f SQLiteUserStore) runMigrations() error { return nil } -// AllUsers returns all stored users. It only populates the User.ScreenName field -// populated in the returned slice. +// AllUsers returns all stored users. It only populates the User.IdentScreenName and +// User.DisplayScreenName fields in the return slice. func (f SQLiteUserStore) AllUsers() ([]User, error) { - q := `SELECT screenName FROM user` + q := `SELECT identScreenName, displayScreenName FROM users` rows, err := f.db.Query(q) if err != nil { return nil, err @@ -134,11 +79,14 @@ func (f SQLiteUserStore) AllUsers() ([]User, error) { var users []User for rows.Next() { - u := User{} - if err := rows.Scan(&u.ScreenName); err != nil { + var identSN, displaySN string + if err := rows.Scan(&identSN, &displaySN); err != nil { return nil, err } - users = append(users, u) + users = append(users, User{ + IdentScreenName: NewIdentScreenName(identSN), + DisplayScreenName: DisplayScreenName(displaySN), + }) } if err := rows.Err(); err != nil { @@ -150,18 +98,22 @@ func (f SQLiteUserStore) AllUsers() ([]User, error) { // User looks up a user by screen name. It populates the User record with // credentials that can be used to validate the user's password. -func (f SQLiteUserStore) User(screenName string) (*User, error) { +func (f SQLiteUserStore) User(screenName IdentScreenName) (*User, error) { q := ` SELECT - screenName, - authKey, + displayScreenName, + authKey, weakMD5Pass, strongMD5Pass - FROM user - WHERE screenName = ? + FROM users + WHERE identScreenName = ? ` - u := &User{} - err := f.db.QueryRow(q, screenName).Scan(&u.ScreenName, &u.AuthKey, &u.WeakMD5Pass, &u.StrongMD5Pass) + u := &User{ + IdentScreenName: screenName, + } + err := f.db.QueryRow(q, screenName.String()). + Scan(&u.DisplayScreenName, &u.AuthKey, &u.WeakMD5Pass, &u.StrongMD5Pass) + if errors.Is(err, sql.ErrNoRows) { return nil, nil } @@ -172,11 +124,11 @@ func (f SQLiteUserStore) User(screenName string) (*User, error) { // same screen name already exists. func (f SQLiteUserStore) InsertUser(u User) error { q := ` - INSERT INTO user (screenName, authKey, weakMD5Pass, strongMD5Pass) - VALUES (?, ?, ?, ?) - ON CONFLICT (screenName) DO NOTHING + INSERT INTO users (identScreenName, displayScreenName, authKey, weakMD5Pass, strongMD5Pass) + VALUES (?, ?, ?, ?, ?) + ON CONFLICT (identScreenName) DO NOTHING ` - result, err := f.db.Exec(q, u.ScreenName, u.AuthKey, u.WeakMD5Pass, u.StrongMD5Pass) + result, err := f.db.Exec(q, u.IdentScreenName.String(), u.DisplayScreenName, u.AuthKey, u.WeakMD5Pass, u.StrongMD5Pass) if err != nil { return err } @@ -194,11 +146,11 @@ func (f SQLiteUserStore) InsertUser(u User) error { // DeleteUser deletes a user from the store. Return ErrNoUser if the user did // not exist prior to deletion. -func (f SQLiteUserStore) DeleteUser(screenName string) error { +func (f SQLiteUserStore) DeleteUser(screenName IdentScreenName) error { q := ` - DELETE FROM user WHERE screenName = ? + DELETE FROM users WHERE identScreenName = ? ` - result, err := f.db.Exec(q, screenName) + result, err := f.db.Exec(q, screenName.String()) if err != nil { return err } @@ -215,43 +167,44 @@ func (f SQLiteUserStore) DeleteUser(screenName string) error { } // SetUserPassword sets the user's password hashes and auth key. -func (f SQLiteUserStore) SetUserPassword(u User) error { +func (f SQLiteUserStore) SetUserPassword(u User) (err error) { tx, err := f.db.Begin() if err != nil { - return err + return } defer func() { if err != nil { - tx.Rollback() + err = errors.Join(err, tx.Rollback()) } }() q := ` - UPDATE user + UPDATE users SET authKey = ?, weakMD5Pass = ?, strongMD5Pass = ? - WHERE screenName = ? + WHERE identScreenName = ? ` - result, err := tx.Exec(q, u.AuthKey, u.WeakMD5Pass, u.StrongMD5Pass, u.ScreenName) + result, err := tx.Exec(q, u.AuthKey, u.WeakMD5Pass, u.StrongMD5Pass, u.IdentScreenName.String()) if err != nil { - return err + return } rowsAffected, err := result.RowsAffected() if err != nil { - return err + return } if rowsAffected == 0 { // it's possible the user didn't change OR the user doesn't exist. // check if the user exists. var exists int - err = tx.QueryRow("SELECT COUNT(*) FROM user WHERE screenName = ?", u.ScreenName).Scan(&exists) + err = tx.QueryRow("SELECT COUNT(*) FROM users WHERE identScreenName = ?", u.IdentScreenName.String()).Scan(&exists) if err != nil { - return err // Handle possible SQL errors during the select + return // Handle possible SQL errors during the select } if exists == 0 { - return ErrNoUser // User does not exist + err = ErrNoUser // User does not exist + return } } @@ -259,7 +212,7 @@ func (f SQLiteUserStore) SetUserPassword(u User) error { } // Feedbag fetches the contents of a user's feedbag (buddy list). -func (f SQLiteUserStore) Feedbag(screenName string) ([]wire.FeedbagItem, error) { +func (f SQLiteUserStore) Feedbag(screenName IdentScreenName) ([]wire.FeedbagItem, error) { q := ` SELECT groupID, @@ -271,7 +224,7 @@ func (f SQLiteUserStore) Feedbag(screenName string) ([]wire.FeedbagItem, error) WHERE screenName = ? ` - rows, err := f.db.Query(q, screenName) + rows, err := f.db.Query(q, screenName.String()) if err != nil { return nil, err } @@ -295,20 +248,20 @@ func (f SQLiteUserStore) Feedbag(screenName string) ([]wire.FeedbagItem, error) // FeedbagLastModified returns the last time a user's feedbag (buddy list) was // updated. -func (f SQLiteUserStore) FeedbagLastModified(screenName string) (time.Time, error) { +func (f SQLiteUserStore) FeedbagLastModified(screenName IdentScreenName) (time.Time, error) { var lastModified sql.NullInt64 q := `SELECT MAX(lastModified) FROM feedbag WHERE screenName = ?` - err := f.db.QueryRow(q, screenName).Scan(&lastModified) + err := f.db.QueryRow(q, screenName.String()).Scan(&lastModified) return time.Unix(lastModified.Int64, 0), err } // FeedbagDelete deletes an entry from a user's feedbag (buddy list). -func (f SQLiteUserStore) FeedbagDelete(screenName string, items []wire.FeedbagItem) error { +func (f SQLiteUserStore) FeedbagDelete(screenName IdentScreenName, items []wire.FeedbagItem) error { // todo add transaction q := `DELETE FROM feedbag WHERE screenName = ? AND itemID = ?` for _, item := range items { - if _, err := f.db.Exec(q, screenName, item.ItemID); err != nil { + if _, err := f.db.Exec(q, screenName.String(), item.ItemID); err != nil { return err } } @@ -318,7 +271,7 @@ func (f SQLiteUserStore) FeedbagDelete(screenName string, items []wire.FeedbagIt // FeedbagUpsert upserts an entry to a user's feedbag (buddy list). An entry is // created if it doesn't already exist, or modified if it already exists. -func (f SQLiteUserStore) FeedbagUpsert(screenName string, items []wire.FeedbagItem) error { +func (f SQLiteUserStore) FeedbagUpsert(screenName IdentScreenName, items []wire.FeedbagItem) error { q := ` INSERT INTO feedbag (screenName, groupID, itemID, classID, name, attributes, lastModified) VALUES (?, ?, ?, ?, ?, ?, UNIXEPOCH()) @@ -335,8 +288,15 @@ func (f SQLiteUserStore) FeedbagUpsert(screenName string, items []wire.FeedbagIt return err } + // todo are these all the right items? + if item.ClassID == wire.FeedbagClassIdBuddy || + item.ClassID == wire.FeedbagClassIDPermit || + item.ClassID == wire.FeedbagClassIDDeny { + // insert screen name identifier + item.Name = NewIdentScreenName(item.Name).String() + } _, err := f.db.Exec(q, - screenName, + screenName.String(), item.GroupID, item.ItemID, item.ClassID, @@ -352,7 +312,7 @@ func (f SQLiteUserStore) FeedbagUpsert(screenName string, items []wire.FeedbagIt // AdjacentUsers returns all users who have screenName in their buddy list. // Exclude users who are on screenName's block list. -func (f SQLiteUserStore) AdjacentUsers(screenName string) ([]string, error) { +func (f SQLiteUserStore) AdjacentUsers(screenName IdentScreenName) ([]IdentScreenName, error) { q := ` SELECT f.screenName FROM feedbag f @@ -364,19 +324,19 @@ func (f SQLiteUserStore) AdjacentUsers(screenName string) ([]string, error) { AND NOT EXISTS(SELECT 1 FROM feedbag WHERE screenName = f.screenName AND name = f.name AND classID = 3) ` - rows, err := f.db.Query(q, screenName, screenName, screenName) + rows, err := f.db.Query(q, screenName.String(), screenName.String(), screenName.String()) if err != nil { return nil, err } defer rows.Close() - var items []string + var items []IdentScreenName for rows.Next() { var sn string if err := rows.Scan(&sn); err != nil { return nil, err } - items = append(items, sn) + items = append(items, NewIdentScreenName(sn)) } return items, nil @@ -384,7 +344,7 @@ func (f SQLiteUserStore) AdjacentUsers(screenName string) ([]string, error) { // Buddies returns all user's buddies. Don't return a buddy if the user has // them on their block list. -func (f SQLiteUserStore) Buddies(screenName string) ([]string, error) { +func (f SQLiteUserStore) Buddies(screenName IdentScreenName) ([]IdentScreenName, error) { q := ` SELECT f.name FROM feedbag f @@ -395,26 +355,26 @@ func (f SQLiteUserStore) Buddies(screenName string) ([]string, error) { AND NOT EXISTS(SELECT 1 FROM feedbag WHERE screenName = ? AND name = f.name AND classID = 3) ` - rows, err := f.db.Query(q, screenName, screenName, screenName) + rows, err := f.db.Query(q, screenName.String(), screenName.String(), screenName.String()) if err != nil { return nil, err } defer rows.Close() - var items []string + var items []IdentScreenName for rows.Next() { var sn string if err := rows.Scan(&sn); err != nil { return nil, err } - items = append(items, sn) + items = append(items, NewIdentScreenName(sn)) } return items, nil } // BlockedState returns the BlockedState between two users. -func (f SQLiteUserStore) BlockedState(screenNameA, screenNameB string) (BlockedState, error) { +func (f SQLiteUserStore) BlockedState(screenName1, screenName2 IdentScreenName) (BlockedState, error) { q := ` SELECT EXISTS(SELECT 1 FROM feedbag f @@ -428,7 +388,7 @@ func (f SQLiteUserStore) BlockedState(screenNameA, screenNameB string) (BlockedS AND f.screenName = ? AND f.name = ?) ` - row, err := f.db.Query(q, screenNameA, screenNameB, screenNameB, screenNameA) + row, err := f.db.Query(q, screenName1.String(), screenName2.String(), screenName2.String(), screenName1.String()) if err != nil { return BlockedNo, err } @@ -460,14 +420,14 @@ func (f SQLiteUserStore) BlockedState(screenNameA, screenNameB string) (BlockedS // Profile fetches a user profile. Return empty string if the user // does not exist or has no profile. -func (f SQLiteUserStore) Profile(screenName string) (string, error) { +func (f SQLiteUserStore) Profile(screenName IdentScreenName) (string, error) { q := ` SELECT IFNULL(body, '') FROM profile WHERE screenName = ? ` var profile string - err := f.db.QueryRow(q, screenName).Scan(&profile) + err := f.db.QueryRow(q, screenName.String()).Scan(&profile) if err != nil && !errors.Is(err, sql.ErrNoRows) { return "", err } @@ -475,14 +435,14 @@ func (f SQLiteUserStore) Profile(screenName string) (string, error) { } // SetProfile sets the text contents of a user's profile. -func (f SQLiteUserStore) SetProfile(screenName string, body string) error { +func (f SQLiteUserStore) SetProfile(screenName IdentScreenName, body string) error { q := ` INSERT INTO profile (screenName, body) VALUES (?, ?) ON CONFLICT (screenName) DO UPDATE SET body = excluded.body ` - _, err := f.db.Exec(q, screenName, body) + _, err := f.db.Exec(q, screenName.String(), body) return err } @@ -509,18 +469,3 @@ func (f SQLiteUserStore) BARTRetrieve(hash []byte) ([]byte, error) { } return body, nil } - -// NewStubUser creates a new user with canned credentials. The default password -// is "welcome1". This is typically used for development purposes. -func NewStubUser(screenName string) (User, error) { - uid, err := uuid.NewRandom() - if err != nil { - return User{}, err - } - u := User{ - ScreenName: screenName, - AuthKey: uid.String(), - } - err = u.HashPassword("welcome1") - return u, err -} diff --git a/state/user_store_test.go b/state/user_store_test.go index 8b741ada..896c3d73 100644 --- a/state/user_store_test.go +++ b/state/user_store_test.go @@ -14,7 +14,7 @@ const testFile string = "aim_test.db" func TestUserStore(t *testing.T) { - const screenName = "sn2day" + screenName := NewIdentScreenName("sn2day") defer func() { assert.NoError(t, os.Remove(testFile)) @@ -54,7 +54,7 @@ func TestUserStore(t *testing.T) { func TestFeedbagDelete(t *testing.T) { - const screenName = "sn2day" + screenName := NewIdentScreenName("sn2day") defer func() { assert.NoError(t, os.Remove(testFile)) @@ -111,7 +111,7 @@ func TestFeedbagDelete(t *testing.T) { func TestLastModifiedEmpty(t *testing.T) { - const screenName = "sn2day" + screenName := NewIdentScreenName("sn2day") defer func() { assert.NoError(t, os.Remove(testFile)) @@ -129,7 +129,7 @@ func TestLastModifiedEmpty(t *testing.T) { func TestLastModifiedNotEmpty(t *testing.T) { - const screenName = "sn2day" + screenName := NewIdentScreenName("sn2day") defer func() { assert.NoError(t, os.Remove(testFile)) @@ -159,7 +159,7 @@ func TestLastModifiedNotEmpty(t *testing.T) { func TestProfile(t *testing.T) { - const screenName = "sn2day" + screenName := NewIdentScreenName("sn2day") defer func() { assert.NoError(t, os.Remove(testFile)) @@ -169,7 +169,7 @@ func TestProfile(t *testing.T) { assert.NoError(t, err) u := User{ - ScreenName: screenName, + IdentScreenName: screenName, } if err := f.InsertUser(u); err != nil { t.Fatalf("failed to upsert new user: %s", err.Error()) @@ -215,7 +215,7 @@ func TestProfile(t *testing.T) { func TestProfileNonExistent(t *testing.T) { - const screenName = "sn2day" + screenName := NewIdentScreenName("sn2day") defer func() { assert.NoError(t, os.Remove(testFile)) @@ -242,12 +242,12 @@ func TestAdjacentUsers(t *testing.T) { f.db.Exec(`INSERT INTO "feedbag" VALUES('userA',27631,4016,0,'userB',NULL,1690508233)`) f.db.Exec(`INSERT INTO "feedbag" VALUES('userB',28330,8120,0,'userA',NULL,1691180328)`) - users, err := f.AdjacentUsers("userA") + users, err := f.AdjacentUsers(NewIdentScreenName("userA")) if len(users) != 0 { t.Fatalf("expected no interested users, got %v", users) } - users, err = f.AdjacentUsers("userB") + users, err = f.AdjacentUsers(NewIdentScreenName("userB")) if len(users) != 0 { t.Fatalf("expected no interested users, got %v", users) } @@ -265,12 +265,12 @@ func TestUserStoreBuddiesBlockedUser(t *testing.T) { f.db.Exec(`INSERT INTO "feedbag" VALUES('userA',27631,4016,0,'userB',NULL,1690508233)`) f.db.Exec(`INSERT INTO "feedbag" VALUES('userB',28330,8120,0,'userA',NULL,1691180328)`) - users, err := f.Buddies("userA") + users, err := f.Buddies(NewIdentScreenName("userA")) if len(users) != 0 { t.Fatalf("expected no buddies, got %v", users) } - users, err = f.Buddies("userB") + users, err = f.Buddies(NewIdentScreenName("userB")) if len(users) != 0 { t.Fatalf("expected no buddies, got %v", users) } @@ -285,12 +285,35 @@ func TestUserStoreBlockedA(t *testing.T) { f, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - f.db.Exec(`INSERT INTO "feedbag" VALUES('userA',0,13852,3,'userB',NULL,1691286176)`) - f.db.Exec(`INSERT INTO "feedbag" VALUES('userA',27631,4016,0,'userB',NULL,1690508233)`) - f.db.Exec(`INSERT INTO "feedbag" VALUES('userB',28330,8120,0,'userA',NULL,1691180328)`) + sn1 := NewIdentScreenName("userA") + sn2 := NewIdentScreenName("userB") + + err = f.FeedbagUpsert(sn1, []wire.FeedbagItem{ + { + GroupID: 0, + ItemID: 13852, + ClassID: 3, + Name: "userB", + }, + { + GroupID: 27631, + ItemID: 4016, + ClassID: 0, + Name: "userB", + }, + }) + assert.NoError(t, err) + + err = f.FeedbagUpsert(sn2, []wire.FeedbagItem{ + { + GroupID: 28330, + ItemID: 8120, + ClassID: 0, + Name: "userA", + }, + }) + assert.NoError(t, err) - sn1 := "userA" - sn2 := "userB" blocked, err := f.BlockedState(sn1, sn2) if err != nil { t.Fatalf("db err: %s", err.Error()) @@ -308,12 +331,35 @@ func TestUserStoreBlockedB(t *testing.T) { f, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - f.db.Exec(`INSERT INTO "feedbag" VALUES('userB',0,13852,3,'userA',NULL,1691286176)`) - f.db.Exec(`INSERT INTO "feedbag" VALUES('userA',27631,4016,0,'userB',NULL,1690508233)`) - f.db.Exec(`INSERT INTO "feedbag" VALUES('userB',28330,8120,0,'userA',NULL,1691180328)`) + sn1 := NewIdentScreenName("userA") + sn2 := NewIdentScreenName("userB") + + err = f.FeedbagUpsert(sn1, []wire.FeedbagItem{ + { + GroupID: 27631, + ItemID: 4016, + ClassID: 0, + Name: "userB", + }, + }) + assert.NoError(t, err) + + err = f.FeedbagUpsert(sn2, []wire.FeedbagItem{ + { + GroupID: 0, + ItemID: 13852, + ClassID: 3, + Name: "userA", + }, + { + GroupID: 28330, + ItemID: 8120, + ClassID: 0, + Name: "userA", + }, + }) + assert.NoError(t, err) - sn1 := "userA" - sn2 := "userB" blocked, err := f.BlockedState(sn1, sn2) if err != nil { t.Fatalf("db err: %s", err.Error()) @@ -334,8 +380,8 @@ func TestUserStoreBlockedNoBlocked(t *testing.T) { f.db.Exec(`INSERT INTO "feedbag" VALUES('userA',27631,4016,0,'userB',NULL,1690508233)`) f.db.Exec(`INSERT INTO "feedbag" VALUES('userB',28330,8120,0,'userA',NULL,1691180328)`) - sn1 := "userA" - sn2 := "userB" + sn1 := NewIdentScreenName("userA") + sn2 := NewIdentScreenName("userB") blocked, err := f.BlockedState(sn1, sn2) if err != nil { t.Fatalf("db err: %s", err.Error()) @@ -353,24 +399,24 @@ func TestGetUser(t *testing.T) { f, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - expectUser := &User{ - ScreenName: "testscreenname", - AuthKey: "theauthkey", - StrongMD5Pass: []byte("thepasshash"), - } - _, err = f.db.Exec(`INSERT INTO user (ScreenName, authKey, strongMD5Pass) VALUES(?, ?, ?)`, - expectUser.ScreenName, expectUser.AuthKey, expectUser.StrongMD5Pass) - if err != nil { - t.Fatalf("failed to insert user: %s", err.Error()) + screenName := NewIdentScreenName("testscreenname") + + insertedUser := &User{ + IdentScreenName: screenName, + DisplayScreenName: DisplayScreenName("testscreenname"), + AuthKey: "theauthkey", + StrongMD5Pass: []byte("thepasshash"), } + err = f.InsertUser(*insertedUser) + assert.NoError(t, err) - actualUser, err := f.User(expectUser.ScreenName) + actualUser, err := f.User(screenName) if err != nil { t.Fatalf("failed to get user: %s", err.Error()) } - if !reflect.DeepEqual(expectUser, actualUser) { - t.Fatalf("users are not equal. expect: %v actual: %v", expectUser, actualUser) + if !reflect.DeepEqual(insertedUser, actualUser) { + t.Fatalf("users are not equal. expect: %v actual: %v", insertedUser, actualUser) } } @@ -382,7 +428,7 @@ func TestGetUserNotFound(t *testing.T) { f, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - actualUser, err := f.User("testscreenname") + actualUser, err := f.User(NewIdentScreenName("testscreenname")) if err != nil { t.Fatalf("failed to get user: %s", err.Error()) } @@ -403,9 +449,18 @@ func TestSQLiteUserStore_Users(t *testing.T) { } want := []User{ - {ScreenName: "userA"}, - {ScreenName: "userB"}, - {ScreenName: "userC"}, + { + IdentScreenName: NewIdentScreenName("userA"), + DisplayScreenName: "userA", + }, + { + IdentScreenName: NewIdentScreenName("userB"), + DisplayScreenName: "userB", + }, + { + IdentScreenName: NewIdentScreenName("userC"), + DisplayScreenName: "userC", + }, } for _, u := range want { @@ -427,18 +482,27 @@ func TestSQLiteUserStore_DeleteUser_DeleteExistentUser(t *testing.T) { f, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - err = f.InsertUser(User{ScreenName: "userA"}) + err = f.InsertUser(User{ + IdentScreenName: NewIdentScreenName("userA"), + DisplayScreenName: "userA", + }) assert.NoError(t, err) - err = f.InsertUser(User{ScreenName: "userB"}) + err = f.InsertUser(User{ + IdentScreenName: NewIdentScreenName("userB"), + DisplayScreenName: "userB", + }) assert.NoError(t, err) - err = f.DeleteUser("userA") + err = f.DeleteUser(NewIdentScreenName("userA")) assert.NoError(t, err) have, err := f.AllUsers() assert.NoError(t, err) - want := []User{{ScreenName: "userB"}} + want := []User{{ + IdentScreenName: NewIdentScreenName("userB"), + DisplayScreenName: "userB", + }} assert.Equal(t, want, have) } @@ -450,7 +514,7 @@ func TestSQLiteUserStore_DeleteUser_DeleteNonExistentUser(t *testing.T) { f, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - err = f.DeleteUser("userA") + err = f.DeleteUser(NewIdentScreenName("userA")) assert.ErrorIs(t, ErrNoUser, err) } @@ -462,21 +526,29 @@ func TestSQLiteUserStore_Buddies(t *testing.T) { feedbagStore, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - assert.NoError(t, feedbagStore.FeedbagUpsert("userA", []wire.FeedbagItem{ - {Name: "userB", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, - })) - assert.NoError(t, feedbagStore.FeedbagUpsert("userB", []wire.FeedbagItem{ - {Name: "userA", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, - })) - - want := []string{"userB", "userC", "userD"} - have, err := feedbagStore.Buddies("userA") + assert.NoError(t, feedbagStore.FeedbagUpsert( + NewIdentScreenName("userA"), + []wire.FeedbagItem{ + {Name: "userB", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, + })) + assert.NoError(t, feedbagStore.FeedbagUpsert( + NewIdentScreenName("userB"), + []wire.FeedbagItem{ + {Name: "userA", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, + })) + + have, err := feedbagStore.Buddies(NewIdentScreenName("userA")) assert.NoError(t, err) + want := []IdentScreenName{ + NewIdentScreenName("userB"), + NewIdentScreenName("userC"), + NewIdentScreenName("userD"), + } assert.Equal(t, want, have) } @@ -485,8 +557,9 @@ func TestNewStubUser(t *testing.T) { assert.NoError(t, err) want := User{ - ScreenName: "userA", - AuthKey: have.AuthKey, + IdentScreenName: NewIdentScreenName("userA"), + DisplayScreenName: "userA", + AuthKey: have.AuthKey, } assert.NoError(t, want.HashPassword("welcome1")) @@ -501,24 +574,33 @@ func TestSQLiteUserStore_AdjacentUsers(t *testing.T) { feedbagStore, err := NewSQLiteUserStore(testFile) assert.NoError(t, err) - assert.NoError(t, feedbagStore.FeedbagUpsert("userA", []wire.FeedbagItem{ - {Name: "userB", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, - })) - assert.NoError(t, feedbagStore.FeedbagUpsert("userB", []wire.FeedbagItem{ - {Name: "userA", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, - })) - assert.NoError(t, feedbagStore.FeedbagUpsert("userC", []wire.FeedbagItem{ - {Name: "userA", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userB", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, - {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, - })) - - want := []string{"userB", "userC"} - have, err := feedbagStore.AdjacentUsers("userA") + assert.NoError(t, feedbagStore.FeedbagUpsert( + NewIdentScreenName("userA"), + []wire.FeedbagItem{ + {Name: "userB", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, + })) + assert.NoError(t, feedbagStore.FeedbagUpsert( + NewIdentScreenName("userB"), + []wire.FeedbagItem{ + {Name: "userA", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userC", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, + })) + assert.NoError(t, feedbagStore.FeedbagUpsert( + NewIdentScreenName("userC"), + []wire.FeedbagItem{ + {Name: "userA", ItemID: 1, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userB", ItemID: 2, ClassID: wire.FeedbagClassIdBuddy}, + {Name: "userD", ItemID: 3, ClassID: wire.FeedbagClassIdBuddy}, + })) + + want := []IdentScreenName{ + NewIdentScreenName("userB"), + NewIdentScreenName("userC"), + } + have, err := feedbagStore.AdjacentUsers(NewIdentScreenName("userA")) assert.NoError(t, err) assert.Equal(t, want, have) @@ -546,3 +628,57 @@ func TestSQLiteUserStore_BARTUpsertAndRetrieve(t *testing.T) { assert.NoError(t, err) assert.Equal(t, item, b) } + +func TestSQLiteUserStore_SetUserPassword_UserExists(t *testing.T) { + defer func() { + assert.NoError(t, os.Remove(testFile)) + }() + + feedbagStore, err := NewSQLiteUserStore(testFile) + assert.NoError(t, err) + + u := User{ + IdentScreenName: NewIdentScreenName("theuser"), + DisplayScreenName: "theUser", + } + err = u.HashPassword("thepassword") + assert.NoError(t, err) + + err = feedbagStore.InsertUser(u) + assert.NoError(t, err) + + err = u.HashPassword("thenewpassword") + assert.NoError(t, err) + + err = feedbagStore.SetUserPassword(u) + assert.NoError(t, err) + + gotUser, err := feedbagStore.User(u.IdentScreenName) + assert.NoError(t, err) + + valid := gotUser.ValidateHash(u.StrongMD5Pass) + assert.True(t, valid) +} + +func TestSQLiteUserStore_SetUserPassword_ErrNoUser(t *testing.T) { + defer func() { + assert.NoError(t, os.Remove(testFile)) + }() + + feedbagStore, err := NewSQLiteUserStore(testFile) + assert.NoError(t, err) + + u := User{ + IdentScreenName: NewIdentScreenName("theuser"), + DisplayScreenName: "theUser", + } + err = u.HashPassword("thepassword") + assert.NoError(t, err) + + err = feedbagStore.SetUserPassword(u) + assert.ErrorIs(t, err, ErrNoUser) + + // make sure previous transaction previously closed + err = feedbagStore.SetUserPassword(u) + assert.ErrorIs(t, err, ErrNoUser) +}