package services import ( "context" "ms-auth/internal/lib" "ms-auth/internal/storage" ) type SessionProvider interface { CreateSession(ctx context.Context, userId int32) error ReadSessionByToken(ctx context.Context, token string) (*storage.Session, error) ReadSessionByUserId(ctx context.Context, userId int32) (*storage.Session, error) UpdateSession(ctx context.Context, session *storage.Session) error DeleteSessionByToken(ctx context.Context, token string) error DeleteSessionByUserId(ctx context.Context, userId int32) error } // SessionService represents a service for managing sessions. type SessionService struct { sessionProvider SessionProvider userProvider UserProvider cfg *lib.Config } // NewSessionService creates a new SessionService instance. // // Parameters: // - sessionProvider: The SessionProvider implementation used by the SessionService. // - userProvider: The UserProvider implementation used by the SessionService. // - cfg: The lib.Config object used by the SessionService. // // Returns: // - *SessionService: A pointer to the SessionService instance. func NewSessionService(sessionProvider SessionProvider, userProvider UserProvider, cfg *lib.Config) *SessionService { return &SessionService{ sessionProvider: sessionProvider, userProvider: userProvider, cfg: cfg, } } // Create creates a new session for a user with the given handle and password. // // Parameters: // - ctx: The context.Context object for the request. // - handle: The handle (username or email) of the user. // - password: The password of the user. // // Returns: // - *string: A pointer to the token of the newly created session, or nil if there was an error. // - error: An error if the creation of the session or the retrieval of the session's token failed. func (s *SessionService) Create(ctx context.Context, handle, password string) (*string, error) { var ( err error user *storage.User ) if lib.ValidUsername(handle) == nil { user, err = s.userProvider.ReadUserByUsername(ctx, handle) } else if lib.ValidEmail(handle) == nil { user, err = s.userProvider.ReadUserByEmail(ctx, handle) } else { return nil, lib.ErrBadHandleOrPassword } if err != nil { return nil, err } err = user.ComparePassword(password) if err != nil { return nil, err } err = s.sessionProvider.CreateSession(ctx, user.Id) if err != nil { return nil, err } session, err := s.sessionProvider.ReadSessionByUserId(ctx, user.Id) if err != nil { return nil, err } token, err := session.Token(s.cfg.JWTSecret) if err != nil { return nil, err } return &token, nil } // Read retrieves the user ID associated with the given session token. // // Parameters: // - ctx: The context.Context object for the request. // - token: The session token. // // Returns: // - *int32: The user ID associated with the session token, or nil if an error occurs. // - error: An error object if any error occurs during the retrieval process. func (s *SessionService) Read(ctx context.Context, token string) (*int32, error) { session, err := s.sessionProvider.ReadSessionByToken(ctx, token) if err != nil { return nil, err } return session.UserId, nil } // Update updates the session associated with the given token. // // Parameters: // - ctx: The context.Context object for the request. // - token: The session token. // // Returns: // - error: An error object if any error occurs during the update process. func (s *SessionService) Update(ctx context.Context, token string) error { session, err := s.sessionProvider.ReadSessionByToken(ctx, token) if err != nil { return err } err = s.sessionProvider.UpdateSession(ctx, session) if err != nil { return err } return nil } // Delete deletes the session associated with the given token. // // Parameters: // - ctx: The context.Context object for the request. // - token: The session token. // // Returns: // - error: An error object if any error occurs during the deletion process. func (s *SessionService) Delete(ctx context.Context, token string) error { session, err := s.sessionProvider.ReadSessionByToken(ctx, token) if err != nil { return err } err = s.sessionProvider.DeleteSessionByUserId(ctx, *session.UserId) if err != nil { return err } return nil }