Przeglądaj źródła

encapsulate cookie logic within AuthService

Mike 2 lat temu
rodzic
commit
51b4d44c94

+ 2 - 5
.mockery.yaml

@@ -17,9 +17,6 @@ packages:
       OnlineNotifier:
         config:
           filename: "mock_online_notifier_test.go"
-      CookieCracker:
-        config:
-          filename: "mock_cookie_cracker_test.go"
   github.com/mk6i/retro-aim-server/server/http:
     interfaces:
       UserManager:
@@ -89,9 +86,9 @@ packages:
       LegacyBuddyListManager:
         config:
           filename: "mock_legacy_buddy_list_manager_test.go"
-      CookieIssuer:
+      CookieBaker:
         config:
-          filename: "mock_cookie_issuer_test.go"
+          filename: "mock_cookie_baker_test.go"
       BuddyBroadcaster:
         config:
           filename: "mock_buddy_broadcaster_test.go"

+ 5 - 11
cmd/server/main.go

@@ -77,7 +77,6 @@ func main() {
 				OServiceHandler:   handler.NewOServiceHandler(logger, oServiceService),
 				PermitDenyHandler: handler.NewPermitDenyHandler(logger, foodgroupService),
 			}),
-			CookieCracker:  cookieBaker,
 			Logger:         logger,
 			OnlineNotifier: oServiceService,
 			ListenAddr:     net.JoinHostPort("", cfg.BOSPort),
@@ -101,7 +100,6 @@ func main() {
 			}),
 			Logger:         logger,
 			OnlineNotifier: oServiceService,
-			CookieCracker:  cookieBaker,
 		}.Start()
 		wg.Done()
 	}(logger)
@@ -124,7 +122,6 @@ func main() {
 			Logger:         logger,
 			OnlineNotifier: oServiceService,
 			ListenAddr:     net.JoinHostPort("", cfg.ChatNavPort),
-			CookieCracker:  cookieBaker,
 		}.Start()
 		wg.Done()
 	}(logger)
@@ -142,7 +139,6 @@ func main() {
 				AlertHandler:    handler.NewAlertHandler(logger),
 				OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
 			}),
-			CookieCracker:  cookieBaker,
 			Logger:         logger,
 			OnlineNotifier: oServiceService,
 			ListenAddr:     net.JoinHostPort("", cfg.AlertPort),
@@ -158,9 +154,8 @@ func main() {
 		oServiceService := foodgroup.NewOServiceServiceForBART(cfg, logger, buddyService)
 
 		oscar.BOSServer{
-			AuthService:   authService,
-			Config:        cfg,
-			CookieCracker: cookieBaker,
+			AuthService: authService,
+			Config:      cfg,
 			Handler: handler.NewBARTRouter(handler.Handlers{
 				BARTHandler:     handler.NewBARTHandler(logger, bartService),
 				OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
@@ -176,10 +171,9 @@ func main() {
 		authHandler := foodgroup.NewAuthService(cfg, sessionManager, feedbagStore, chatRegistry, adjListBuddyListStore, cookieBaker, nil)
 
 		oscar.AuthServer{
-			AuthService:   authHandler,
-			Config:        cfg,
-			Logger:        logger,
-			CookieCracker: cookieBaker,
+			AuthService: authHandler,
+			Config:      cfg,
+			Logger:      logger,
 		}.Start()
 		wg.Done()
 	}(logger)

+ 21 - 8
foodgroup/auth.go

@@ -21,7 +21,7 @@ func NewAuthService(
 	userManager UserManager,
 	chatRegistry ChatRegistry,
 	legacyBuddyListManager LegacyBuddyListManager,
-	cookieIssuer CookieIssuer,
+	cookieBaker CookieBaker,
 	buddyUpdateBroadcaster BuddyBroadcaster,
 ) *AuthService {
 	return &AuthService{
@@ -30,7 +30,7 @@ func NewAuthService(
 		legacyBuddyListManager: legacyBuddyListManager,
 		sessionManager:         sessionManager,
 		userManager:            userManager,
-		cookieIssuer:           cookieIssuer,
+		cookieBaker:            cookieBaker,
 		buddyUpdateBroadcaster: buddyUpdateBroadcaster,
 	}
 }
@@ -42,18 +42,23 @@ type AuthService struct {
 	buddyUpdateBroadcaster BuddyBroadcaster
 	chatRegistry           ChatRegistry
 	config                 config.Config
-	cookieIssuer           CookieIssuer
+	cookieBaker            CookieBaker
 	legacyBuddyListManager LegacyBuddyListManager
 	sessionManager         SessionManager
 	userManager            UserManager
 }
 
 // RegisterChatSession creates and returns a chat room session.
-func (s AuthService) RegisterChatSession(loginCookie []byte) (*state.Session, error) {
+func (s AuthService) RegisterChatSession(authCookie []byte) (*state.Session, error) {
+	token, err := s.cookieBaker.Crack(authCookie)
+	if err != nil {
+		return nil, err
+	}
 	c := chatLoginCookie{}
-	if err := wire.Unmarshal(&c, bytes.NewBuffer(loginCookie)); err != nil {
+	if err := wire.Unmarshal(&c, bytes.NewBuffer(token)); err != nil {
 		return nil, err
 	}
+
 	room, chatSessMgr, err := s.chatRegistry.Retrieve(c.ChatCookie)
 	if err != nil {
 		return nil, err
@@ -65,20 +70,28 @@ func (s AuthService) RegisterChatSession(loginCookie []byte) (*state.Session, er
 	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(screenName state.IdentScreenName) (*state.Session, error) {
-	u, err := s.userManager.User(screenName)
+func (s AuthService) RegisterBOSSession(authCookie []byte) (*state.Session, error) {
+	screenName, err := s.cookieBaker.Crack(authCookie)
+	if err != nil {
+		return nil, err
+	}
+
+	u, err := s.userManager.User(state.NewIdentScreenName(string(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
 }
 
@@ -252,7 +265,7 @@ func (s AuthService) login(
 			}
 		}
 
-		cookie, err := s.cookieIssuer.Issue([]byte(screenName))
+		cookie, err := s.cookieBaker.Issue([]byte(screenName))
 		if err != nil {
 			return wire.TLVRestBlock{}, fmt.Errorf("failed to make auth cookie: %w", err)
 		}

+ 52 - 33
foodgroup/auth_test.go

@@ -389,16 +389,16 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) {
 					Return(params.err)
 			}
 			sessionManager := newMockSessionManager(t)
-			cookieIssuer := newMockCookieIssuer(t)
+			cookieBaker := newMockCookieBaker(t)
 			for _, params := range tc.mockParams.cookieIssuerParams {
-				cookieIssuer.EXPECT().
+				cookieBaker.EXPECT().
 					Issue(params.data).
 					Return(params.cookie, params.err)
 			}
 
 			svc := AuthService{
 				config:         tc.cfg,
-				cookieIssuer:   cookieIssuer,
+				cookieBaker:    cookieBaker,
 				sessionManager: sessionManager,
 				userManager:    userManager,
 			}
@@ -747,15 +747,15 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) {
 					Return(params.err)
 			}
 			sessionManager := newMockSessionManager(t)
-			cookieIssuer := newMockCookieIssuer(t)
+			cookieBaker := newMockCookieBaker(t)
 			for _, params := range tc.mockParams.cookieIssuerParams {
-				cookieIssuer.EXPECT().
+				cookieBaker.EXPECT().
 					Issue(params.data).
 					Return(params.cookie, params.err)
 			}
 			svc := AuthService{
 				config:         tc.cfg,
-				cookieIssuer:   cookieIssuer,
+				cookieBaker:    cookieBaker,
 				sessionManager: sessionManager,
 				userManager:    userManager,
 			}
@@ -936,16 +936,8 @@ func TestAuthService_BUCPChallengeRequest(t *testing.T) {
 }
 
 func TestAuthService_RegisterChatSession_HappyPath(t *testing.T) {
-	cookie := "chat-1234"
 	sess := newTestSession("screen-name")
 
-	c := chatLoginCookie{
-		ChatCookie: cookie,
-		ScreenName: sess.IdentScreenName().String(),
-	}
-	buf := &bytes.Buffer{}
-	assert.NoError(t, wire.Marshal(c, buf))
-
 	sessionManager := newMockSessionManager(t)
 	sessionManager.EXPECT().
 		AddSession(sess.DisplayScreenName()).
@@ -958,26 +950,38 @@ func TestAuthService_RegisterChatSession_HappyPath(t *testing.T) {
 			DisplayScreenName: sess.DisplayScreenName(),
 		}, nil)
 
+	chatCookie := "the-chat-cookie"
 	chatRegistry := newMockChatRegistry(t)
 	chatRegistry.EXPECT().
-		Retrieve(cookie).
+		Retrieve(chatCookie).
 		Return(state.ChatRoom{}, sessionManager, nil)
 
-	cookieIssuer := newMockCookieIssuer(t)
+	c := chatLoginCookie{
+		ChatCookie: chatCookie,
+		ScreenName: sess.IdentScreenName().String(),
+	}
+	chatCookieBuf := &bytes.Buffer{}
+	assert.NoError(t, wire.Marshal(c, chatCookieBuf))
+
+	authCookie := []byte("the-auth-cookie")
+	cookieBaker := newMockCookieBaker(t)
+	cookieBaker.EXPECT().
+		Crack(authCookie).
+		Return(chatCookieBuf.Bytes(), nil)
 
-	svc := NewAuthService(config.Config{}, nil, userManager, chatRegistry, nil, cookieIssuer, nil)
+	svc := NewAuthService(config.Config{}, nil, userManager, chatRegistry, nil, cookieBaker, nil)
 
-	have, err := svc.RegisterChatSession(buf.Bytes())
+	have, err := svc.RegisterChatSession(authCookie)
 	assert.NoError(t, err)
 	assert.Equal(t, sess, have)
 }
 
-func TestAuthService_RegisterBOSSession_ChatNotFound(t *testing.T) {
-	cookie := "chat-1234"
+func TestAuthService_RegisterChatSession_ChatNotFound(t *testing.T) {
+	chatCookie := "the-chat-cookie"
 	sess := newTestSession("screen-name")
 
 	c := chatLoginCookie{
-		ChatCookie: cookie,
+		ChatCookie: chatCookie,
 		ScreenName: sess.IdentScreenName().String(),
 	}
 	loginCookie := &bytes.Buffer{}
@@ -985,13 +989,18 @@ func TestAuthService_RegisterBOSSession_ChatNotFound(t *testing.T) {
 
 	chatRegistry := newMockChatRegistry(t)
 	chatRegistry.EXPECT().
-		Retrieve(cookie).
+		Retrieve(chatCookie).
 		Return(state.ChatRoom{}, nil, state.ErrChatRoomNotFound)
 
-	cookieIssuer := newMockCookieIssuer(t)
-	svc := NewAuthService(config.Config{}, nil, nil, chatRegistry, nil, cookieIssuer, nil)
+	authCookie := []byte("the-auth-cookie")
+	cookieBaker := newMockCookieBaker(t)
+	cookieBaker.EXPECT().
+		Crack(authCookie).
+		Return(loginCookie.Bytes(), nil)
+
+	svc := NewAuthService(config.Config{}, nil, nil, chatRegistry, nil, cookieBaker, nil)
 
-	_, err := svc.RegisterChatSession(loginCookie.Bytes())
+	_, err := svc.RegisterChatSession(authCookie)
 	assert.ErrorIs(t, err, state.ErrChatRoomNotFound)
 }
 
@@ -1003,16 +1012,21 @@ func TestAuthService_RegisterBOSSession_HappyPath(t *testing.T) {
 		AddSession(sess.DisplayScreenName()).
 		Return(sess)
 
-	cookieIssuer := newMockCookieIssuer(t)
+	authCookie := []byte(`the-auth-cookie`)
+
+	cookieBaker := newMockCookieBaker(t)
+	cookieBaker.EXPECT().
+		Crack(authCookie).
+		Return([]byte("screen-name"), 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)
+	svc := NewAuthService(config.Config{}, sessionManager, userManager, nil, nil, cookieBaker, nil)
 
-	have, err := svc.RegisterBOSSession(sess.IdentScreenName())
+	have, err := svc.RegisterBOSSession(authCookie)
 	assert.NoError(t, err)
 	assert.Equal(t, sess, have)
 }
@@ -1025,16 +1039,21 @@ func TestAuthService_RegisterBOSSession_SessionNotFound(t *testing.T) {
 		AddSession(sess.DisplayScreenName()).
 		Return(nil)
 
-	cookieIssuer := newMockCookieIssuer(t)
+	authCookie := []byte(`the-auth-cookie`)
+	cookieBaker := newMockCookieBaker(t)
+
+	cookieBaker.EXPECT().
+		Crack(authCookie).
+		Return([]byte("screen-name"), 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)
+	svc := NewAuthService(config.Config{}, sessionManager, userManager, nil, nil, cookieBaker, nil)
 
-	have, err := svc.RegisterBOSSession(sess.IdentScreenName())
+	have, err := svc.RegisterBOSSession(authCookie)
 	assert.NoError(t, err)
 	assert.Nil(t, have)
 }
@@ -1172,9 +1191,9 @@ func TestAuthService_SignoutChat(t *testing.T) {
 				Retrieve(tt.chatRoom.Cookie).
 				Return(tt.chatRoom, chatSessionManager, tt.wantErr)
 
-			cookieIssuer := newMockCookieIssuer(t)
+			cookieBaker := newMockCookieBaker(t)
 
-			svc := NewAuthService(config.Config{}, nil, nil, chatRegistry, nil, cookieIssuer, nil)
+			svc := NewAuthService(config.Config{}, nil, nil, chatRegistry, nil, cookieBaker, nil)
 
 			err := svc.SignoutChat(nil, tt.userSession)
 			assert.ErrorIs(t, err, tt.wantErr)

+ 148 - 0
foodgroup/mock_cookie_baker_test.go

@@ -0,0 +1,148 @@
+// Code generated by mockery v2.40.1. DO NOT EDIT.
+
+package foodgroup
+
+import mock "github.com/stretchr/testify/mock"
+
+// mockCookieBaker is an autogenerated mock type for the CookieBaker type
+type mockCookieBaker struct {
+	mock.Mock
+}
+
+type mockCookieBaker_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *mockCookieBaker) EXPECT() *mockCookieBaker_Expecter {
+	return &mockCookieBaker_Expecter{mock: &_m.Mock}
+}
+
+// Crack provides a mock function with given fields: data
+func (_m *mockCookieBaker) Crack(data []byte) ([]byte, error) {
+	ret := _m.Called(data)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Crack")
+	}
+
+	var r0 []byte
+	var r1 error
+	if rf, ok := ret.Get(0).(func([]byte) ([]byte, error)); ok {
+		return rf(data)
+	}
+	if rf, ok := ret.Get(0).(func([]byte) []byte); ok {
+		r0 = rf(data)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]byte)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func([]byte) error); ok {
+		r1 = rf(data)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockCookieBaker_Crack_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Crack'
+type mockCookieBaker_Crack_Call struct {
+	*mock.Call
+}
+
+// Crack is a helper method to define mock.On call
+//   - data []byte
+func (_e *mockCookieBaker_Expecter) Crack(data interface{}) *mockCookieBaker_Crack_Call {
+	return &mockCookieBaker_Crack_Call{Call: _e.mock.On("Crack", data)}
+}
+
+func (_c *mockCookieBaker_Crack_Call) Run(run func(data []byte)) *mockCookieBaker_Crack_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].([]byte))
+	})
+	return _c
+}
+
+func (_c *mockCookieBaker_Crack_Call) Return(_a0 []byte, _a1 error) *mockCookieBaker_Crack_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockCookieBaker_Crack_Call) RunAndReturn(run func([]byte) ([]byte, error)) *mockCookieBaker_Crack_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Issue provides a mock function with given fields: data
+func (_m *mockCookieBaker) Issue(data []byte) ([]byte, error) {
+	ret := _m.Called(data)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Issue")
+	}
+
+	var r0 []byte
+	var r1 error
+	if rf, ok := ret.Get(0).(func([]byte) ([]byte, error)); ok {
+		return rf(data)
+	}
+	if rf, ok := ret.Get(0).(func([]byte) []byte); ok {
+		r0 = rf(data)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]byte)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func([]byte) error); ok {
+		r1 = rf(data)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockCookieBaker_Issue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Issue'
+type mockCookieBaker_Issue_Call struct {
+	*mock.Call
+}
+
+// Issue is a helper method to define mock.On call
+//   - data []byte
+func (_e *mockCookieBaker_Expecter) Issue(data interface{}) *mockCookieBaker_Issue_Call {
+	return &mockCookieBaker_Issue_Call{Call: _e.mock.On("Issue", data)}
+}
+
+func (_c *mockCookieBaker_Issue_Call) Run(run func(data []byte)) *mockCookieBaker_Issue_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].([]byte))
+	})
+	return _c
+}
+
+func (_c *mockCookieBaker_Issue_Call) Return(_a0 []byte, _a1 error) *mockCookieBaker_Issue_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockCookieBaker_Issue_Call) RunAndReturn(run func([]byte) ([]byte, error)) *mockCookieBaker_Issue_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// newMockCookieBaker creates a new instance of mockCookieBaker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func newMockCookieBaker(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *mockCookieBaker {
+	mock := &mockCookieBaker{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}

+ 0 - 90
foodgroup/mock_cookie_issuer_test.go

@@ -1,90 +0,0 @@
-// Code generated by mockery v2.40.1. DO NOT EDIT.
-
-package foodgroup
-
-import mock "github.com/stretchr/testify/mock"
-
-// mockCookieIssuer is an autogenerated mock type for the CookieIssuer type
-type mockCookieIssuer struct {
-	mock.Mock
-}
-
-type mockCookieIssuer_Expecter struct {
-	mock *mock.Mock
-}
-
-func (_m *mockCookieIssuer) EXPECT() *mockCookieIssuer_Expecter {
-	return &mockCookieIssuer_Expecter{mock: &_m.Mock}
-}
-
-// Issue provides a mock function with given fields: data
-func (_m *mockCookieIssuer) Issue(data []byte) ([]byte, error) {
-	ret := _m.Called(data)
-
-	if len(ret) == 0 {
-		panic("no return value specified for Issue")
-	}
-
-	var r0 []byte
-	var r1 error
-	if rf, ok := ret.Get(0).(func([]byte) ([]byte, error)); ok {
-		return rf(data)
-	}
-	if rf, ok := ret.Get(0).(func([]byte) []byte); ok {
-		r0 = rf(data)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]byte)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func([]byte) error); ok {
-		r1 = rf(data)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// mockCookieIssuer_Issue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Issue'
-type mockCookieIssuer_Issue_Call struct {
-	*mock.Call
-}
-
-// Issue is a helper method to define mock.On call
-//   - data []byte
-func (_e *mockCookieIssuer_Expecter) Issue(data interface{}) *mockCookieIssuer_Issue_Call {
-	return &mockCookieIssuer_Issue_Call{Call: _e.mock.On("Issue", data)}
-}
-
-func (_c *mockCookieIssuer_Issue_Call) Run(run func(data []byte)) *mockCookieIssuer_Issue_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].([]byte))
-	})
-	return _c
-}
-
-func (_c *mockCookieIssuer_Issue_Call) Return(_a0 []byte, _a1 error) *mockCookieIssuer_Issue_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *mockCookieIssuer_Issue_Call) RunAndReturn(run func([]byte) ([]byte, error)) *mockCookieIssuer_Issue_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// newMockCookieIssuer creates a new instance of mockCookieIssuer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func newMockCookieIssuer(t interface {
-	mock.TestingT
-	Cleanup(func())
-}) *mockCookieIssuer {
-	mock := &mockCookieIssuer{}
-	mock.Mock.Test(t)
-
-	t.Cleanup(func() { mock.AssertExpectations(t) })
-
-	return mock
-}

+ 2 - 2
foodgroup/oservice.go

@@ -512,7 +512,7 @@ func NewOServiceServiceForBOS(
 	messageRelayer MessageRelayer,
 	legacyBuddyListManager LegacyBuddyListManager,
 	logger *slog.Logger,
-	cookieIssuer CookieIssuer,
+	cookieIssuer CookieBaker,
 	buddyUpdateBroadcaster BuddyBroadcaster,
 	cr *state.ChatRegistry,
 ) *OServiceServiceForBOS {
@@ -545,7 +545,7 @@ func NewOServiceServiceForBOS(
 type OServiceServiceForBOS struct {
 	OServiceService
 	chatRegistry           *state.ChatRegistry
-	cookieIssuer           CookieIssuer
+	cookieIssuer           CookieBaker
 	legacyBuddyListManager LegacyBuddyListManager
 	messageRelayer         MessageRelayer
 }

+ 2 - 2
foodgroup/oservice_test.go

@@ -250,7 +250,7 @@ func TestOServiceServiceForBOS_ServiceRequest(t *testing.T) {
 					Maybe()
 				chatRegistry.Register(*tc.chatRoom, sessionManager)
 			}
-			cookieIssuer := newMockCookieIssuer(t)
+			cookieIssuer := newMockCookieBaker(t)
 			for _, params := range tc.mockParams.cookieIssuerParams {
 				cookieIssuer.EXPECT().
 					Issue(params.data).
@@ -1336,7 +1336,7 @@ func TestOServiceService_RateParamsQuery(t *testing.T) {
 }
 
 func TestOServiceServiceForBOS_OServiceHostOnline(t *testing.T) {
-	cookieIssuer := newMockCookieIssuer(t)
+	cookieIssuer := newMockCookieBaker(t)
 	svc := NewOServiceServiceForBOS(config.Config{}, nil, nil, slog.Default(), cookieIssuer, nil, nil)
 
 	want := wire.SNACMessage{

+ 1 - 1
foodgroup/test_helpers.go

@@ -281,7 +281,7 @@ type whoAddedUserParams []struct {
 }
 
 // cookieIssuerParams is the list of parameters passed at the mock
-// CookieIssuer.Issue call site
+// CookieBaker.Issue call site
 type cookieIssuerParams []struct {
 	data   []byte
 	cookie []byte

+ 2 - 1
foodgroup/types.go

@@ -113,7 +113,8 @@ type BARTManager interface {
 	BARTRetrieve(itemHash []byte) ([]byte, error)
 }
 
-type CookieIssuer interface {
+type CookieBaker interface {
+	Crack(data []byte) ([]byte, error)
 	Issue(data []byte) ([]byte, error)
 }
 

+ 2 - 3
server/oscar/auth.go

@@ -18,8 +18,8 @@ type AuthService interface {
 	BUCPChallenge(bodyIn wire.SNAC_0x17_0x06_BUCPChallengeRequest, newUUID func() uuid.UUID) (wire.SNACMessage, 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)
+	RegisterBOSSession(authCookie []byte) (*state.Session, error)
+	RegisterChatSession(authCookie []byte) (*state.Session, error)
 	Signout(ctx context.Context, sess *state.Session) error
 	SignoutChat(ctx context.Context, sess *state.Session) error
 }
@@ -30,7 +30,6 @@ type AuthServer struct {
 	AuthService
 	config.Config
 	Logger *slog.Logger
-	CookieCracker
 }
 
 // Start starts the authentication server and listens for new connections.

+ 1 - 8
server/oscar/bos.go

@@ -9,7 +9,6 @@ import (
 	"os"
 
 	"github.com/mk6i/retro-aim-server/config"
-	"github.com/mk6i/retro-aim-server/state"
 	"github.com/mk6i/retro-aim-server/wire"
 )
 
@@ -24,7 +23,6 @@ type OnlineNotifier interface {
 // service.
 type BOSServer struct {
 	AuthService
-	CookieCracker
 	Handler
 	ListenAddr string
 	Logger     *slog.Logger
@@ -78,12 +76,7 @@ func (rt BOSServer) handleNewConnection(ctx context.Context, rwc io.ReadWriteClo
 		return errors.New("unable to get session id from payload")
 	}
 
-	screenName, err := rt.CookieCracker.Crack(authCookie)
-	if err != nil {
-		return err
-	}
-
-	sess, err := rt.RegisterBOSSession(state.NewIdentScreenName(string(screenName)))
+	sess, err := rt.RegisterBOSSession(authCookie)
 	if err != nil {
 		return err
 	}

+ 1 - 7
server/oscar/bos_test.go

@@ -81,7 +81,7 @@ func TestBOSService_handleNewConnection(t *testing.T) {
 
 	authService := newMockAuthService(t)
 	authService.EXPECT().
-		RegisterBOSSession(state.NewIdentScreenName("user_screen_name")).
+		RegisterBOSSession([]byte("the-cookie")).
 		Return(sess, nil)
 	authService.EXPECT().
 		Signout(mock.Anything, sess).
@@ -98,11 +98,6 @@ func TestBOSService_handleNewConnection(t *testing.T) {
 			Body: wire.SNAC_0x01_0x03_OServiceHostOnline{},
 		})
 
-	cookieCracker := newMockCookieCracker(t)
-	cookieCracker.EXPECT().
-		Crack([]byte("the-cookie")).
-		Return([]byte("user_screen_name"), nil)
-
 	router := newMockHandler(t)
 	router.EXPECT().
 		Handle(mock.Anything, sess, mock.Anything, mock.Anything, mock.Anything).
@@ -115,7 +110,6 @@ func TestBOSService_handleNewConnection(t *testing.T) {
 
 	rt := BOSServer{
 		AuthService:    authService,
-		CookieCracker:  cookieCracker,
 		Handler:        router,
 		Logger:         slog.Default(),
 		OnlineNotifier: onlineNotifier,

+ 2 - 9
server/oscar/chat.go

@@ -21,7 +21,6 @@ type ChatServer struct {
 	Logger *slog.Logger
 	OnlineNotifier
 	config.Config
-	CookieCracker
 }
 
 // Start creates a TCP server that implements that chat flow.
@@ -63,18 +62,12 @@ func (rt ChatServer) handleNewConnection(ctx context.Context, rwc io.ReadWriteCl
 		return err
 	}
 
-	var ok bool
-	loginCookie, ok := flap.Slice(wire.OServiceTLVTagsLoginCookie)
+	authCookie, ok := flap.Slice(wire.OServiceTLVTagsLoginCookie)
 	if !ok {
 		return errors.New("unable to get login cookie from payload")
 	}
 
-	token, err := rt.CookieCracker.Crack(loginCookie)
-	if err != nil {
-		return err
-	}
-
-	chatSess, err := rt.RegisterChatSession(token)
+	chatSess, err := rt.RegisterChatSession(authCookie)
 	if err != nil {
 		return err
 	}

+ 1 - 7
server/oscar/chat_test.go

@@ -67,7 +67,7 @@ func TestChatService_handleNewConnection(t *testing.T) {
 
 	authService := newMockAuthService(t)
 	authService.EXPECT().
-		RegisterChatSession([]byte(`user-screen-name`)).
+		RegisterChatSession([]byte(`the-chat-login-cookie`)).
 		Return(sess, nil)
 	authService.EXPECT().
 		SignoutChat(mock.Anything, sess).
@@ -84,11 +84,6 @@ func TestChatService_handleNewConnection(t *testing.T) {
 			Body: wire.SNAC_0x01_0x03_OServiceHostOnline{},
 		})
 
-	cookieCracker := newMockCookieCracker(t)
-	cookieCracker.EXPECT().
-		Crack([]byte(`the-chat-login-cookie`)).
-		Return([]byte(`user-screen-name`), nil)
-
 	bosRouter := newMockHandler(t)
 	bosRouter.EXPECT().
 		Handle(mock.Anything, sess, mock.Anything, mock.Anything, mock.Anything).
@@ -96,7 +91,6 @@ func TestChatService_handleNewConnection(t *testing.T) {
 
 	rt := ChatServer{
 		AuthService:    authService,
-		CookieCracker:  cookieCracker,
 		Handler:        bosRouter,
 		Logger:         slog.Default(),
 		OnlineNotifier: onlineNotifier,

+ 25 - 25
server/oscar/mock_auth_test.go

@@ -197,9 +197,9 @@ func (_c *mockAuthService_FLAPLogin_Call) RunAndReturn(run func(wire.FLAPSignonF
 	return _c
 }
 
-// RegisterBOSSession provides a mock function with given fields: screenName
-func (_m *mockAuthService) RegisterBOSSession(screenName state.IdentScreenName) (*state.Session, error) {
-	ret := _m.Called(screenName)
+// RegisterBOSSession provides a mock function with given fields: authCookie
+func (_m *mockAuthService) RegisterBOSSession(authCookie []byte) (*state.Session, error) {
+	ret := _m.Called(authCookie)
 
 	if len(ret) == 0 {
 		panic("no return value specified for RegisterBOSSession")
@@ -207,19 +207,19 @@ func (_m *mockAuthService) RegisterBOSSession(screenName state.IdentScreenName)
 
 	var r0 *state.Session
 	var r1 error
-	if rf, ok := ret.Get(0).(func(state.IdentScreenName) (*state.Session, error)); ok {
-		return rf(screenName)
+	if rf, ok := ret.Get(0).(func([]byte) (*state.Session, error)); ok {
+		return rf(authCookie)
 	}
-	if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.Session); ok {
-		r0 = rf(screenName)
+	if rf, ok := ret.Get(0).(func([]byte) *state.Session); ok {
+		r0 = rf(authCookie)
 	} else {
 		if ret.Get(0) != nil {
 			r0 = ret.Get(0).(*state.Session)
 		}
 	}
 
-	if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok {
-		r1 = rf(screenName)
+	if rf, ok := ret.Get(1).(func([]byte) error); ok {
+		r1 = rf(authCookie)
 	} else {
 		r1 = ret.Error(1)
 	}
@@ -233,14 +233,14 @@ type mockAuthService_RegisterBOSSession_Call struct {
 }
 
 // RegisterBOSSession is a helper method to define mock.On call
-//   - screenName state.IdentScreenName
-func (_e *mockAuthService_Expecter) RegisterBOSSession(screenName interface{}) *mockAuthService_RegisterBOSSession_Call {
-	return &mockAuthService_RegisterBOSSession_Call{Call: _e.mock.On("RegisterBOSSession", screenName)}
+//   - authCookie []byte
+func (_e *mockAuthService_Expecter) RegisterBOSSession(authCookie interface{}) *mockAuthService_RegisterBOSSession_Call {
+	return &mockAuthService_RegisterBOSSession_Call{Call: _e.mock.On("RegisterBOSSession", authCookie)}
 }
 
-func (_c *mockAuthService_RegisterBOSSession_Call) Run(run func(screenName state.IdentScreenName)) *mockAuthService_RegisterBOSSession_Call {
+func (_c *mockAuthService_RegisterBOSSession_Call) Run(run func(authCookie []byte)) *mockAuthService_RegisterBOSSession_Call {
 	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(state.IdentScreenName))
+		run(args[0].([]byte))
 	})
 	return _c
 }
@@ -250,14 +250,14 @@ func (_c *mockAuthService_RegisterBOSSession_Call) Return(_a0 *state.Session, _a
 	return _c
 }
 
-func (_c *mockAuthService_RegisterBOSSession_Call) RunAndReturn(run func(state.IdentScreenName) (*state.Session, error)) *mockAuthService_RegisterBOSSession_Call {
+func (_c *mockAuthService_RegisterBOSSession_Call) RunAndReturn(run func([]byte) (*state.Session, error)) *mockAuthService_RegisterBOSSession_Call {
 	_c.Call.Return(run)
 	return _c
 }
 
-// RegisterChatSession provides a mock function with given fields: loginCookie
-func (_m *mockAuthService) RegisterChatSession(loginCookie []byte) (*state.Session, error) {
-	ret := _m.Called(loginCookie)
+// RegisterChatSession provides a mock function with given fields: authCookie
+func (_m *mockAuthService) RegisterChatSession(authCookie []byte) (*state.Session, error) {
+	ret := _m.Called(authCookie)
 
 	if len(ret) == 0 {
 		panic("no return value specified for RegisterChatSession")
@@ -266,10 +266,10 @@ func (_m *mockAuthService) RegisterChatSession(loginCookie []byte) (*state.Sessi
 	var r0 *state.Session
 	var r1 error
 	if rf, ok := ret.Get(0).(func([]byte) (*state.Session, error)); ok {
-		return rf(loginCookie)
+		return rf(authCookie)
 	}
 	if rf, ok := ret.Get(0).(func([]byte) *state.Session); ok {
-		r0 = rf(loginCookie)
+		r0 = rf(authCookie)
 	} else {
 		if ret.Get(0) != nil {
 			r0 = ret.Get(0).(*state.Session)
@@ -277,7 +277,7 @@ func (_m *mockAuthService) RegisterChatSession(loginCookie []byte) (*state.Sessi
 	}
 
 	if rf, ok := ret.Get(1).(func([]byte) error); ok {
-		r1 = rf(loginCookie)
+		r1 = rf(authCookie)
 	} else {
 		r1 = ret.Error(1)
 	}
@@ -291,12 +291,12 @@ type mockAuthService_RegisterChatSession_Call struct {
 }
 
 // RegisterChatSession is a helper method to define mock.On call
-//   - loginCookie []byte
-func (_e *mockAuthService_Expecter) RegisterChatSession(loginCookie interface{}) *mockAuthService_RegisterChatSession_Call {
-	return &mockAuthService_RegisterChatSession_Call{Call: _e.mock.On("RegisterChatSession", loginCookie)}
+//   - authCookie []byte
+func (_e *mockAuthService_Expecter) RegisterChatSession(authCookie interface{}) *mockAuthService_RegisterChatSession_Call {
+	return &mockAuthService_RegisterChatSession_Call{Call: _e.mock.On("RegisterChatSession", authCookie)}
 }
 
-func (_c *mockAuthService_RegisterChatSession_Call) Run(run func(loginCookie []byte)) *mockAuthService_RegisterChatSession_Call {
+func (_c *mockAuthService_RegisterChatSession_Call) Run(run func(authCookie []byte)) *mockAuthService_RegisterChatSession_Call {
 	_c.Call.Run(func(args mock.Arguments) {
 		run(args[0].([]byte))
 	})

+ 0 - 90
server/oscar/mock_cookie_cracker_test.go

@@ -1,90 +0,0 @@
-// Code generated by mockery v2.40.1. DO NOT EDIT.
-
-package oscar
-
-import mock "github.com/stretchr/testify/mock"
-
-// mockCookieCracker is an autogenerated mock type for the CookieCracker type
-type mockCookieCracker struct {
-	mock.Mock
-}
-
-type mockCookieCracker_Expecter struct {
-	mock *mock.Mock
-}
-
-func (_m *mockCookieCracker) EXPECT() *mockCookieCracker_Expecter {
-	return &mockCookieCracker_Expecter{mock: &_m.Mock}
-}
-
-// Crack provides a mock function with given fields: data
-func (_m *mockCookieCracker) Crack(data []byte) ([]byte, error) {
-	ret := _m.Called(data)
-
-	if len(ret) == 0 {
-		panic("no return value specified for Crack")
-	}
-
-	var r0 []byte
-	var r1 error
-	if rf, ok := ret.Get(0).(func([]byte) ([]byte, error)); ok {
-		return rf(data)
-	}
-	if rf, ok := ret.Get(0).(func([]byte) []byte); ok {
-		r0 = rf(data)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]byte)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func([]byte) error); ok {
-		r1 = rf(data)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// mockCookieCracker_Crack_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Crack'
-type mockCookieCracker_Crack_Call struct {
-	*mock.Call
-}
-
-// Crack is a helper method to define mock.On call
-//   - data []byte
-func (_e *mockCookieCracker_Expecter) Crack(data interface{}) *mockCookieCracker_Crack_Call {
-	return &mockCookieCracker_Crack_Call{Call: _e.mock.On("Crack", data)}
-}
-
-func (_c *mockCookieCracker_Crack_Call) Run(run func(data []byte)) *mockCookieCracker_Crack_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].([]byte))
-	})
-	return _c
-}
-
-func (_c *mockCookieCracker_Crack_Call) Return(_a0 []byte, _a1 error) *mockCookieCracker_Crack_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *mockCookieCracker_Crack_Call) RunAndReturn(run func([]byte) ([]byte, error)) *mockCookieCracker_Crack_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// newMockCookieCracker creates a new instance of mockCookieCracker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func newMockCookieCracker(t interface {
-	mock.TestingT
-	Cleanup(func())
-}) *mockCookieCracker {
-	mock := &mockCookieCracker{}
-	mock.Mock.Test(t)
-
-	t.Cleanup(func() { mock.AssertExpectations(t) })
-
-	return mock
-}

+ 0 - 5
server/oscar/types.go

@@ -1,5 +0,0 @@
-package oscar
-
-type CookieCracker interface {
-	Crack(data []byte) ([]byte, error)
-}