Changes
2 changed files (+152/-0)
-
-
@@ -0,0 +1,88 @@// SPDX-FileCopyrightText: 2025 Shota FUJI <pockawoooh@gmail.com> // SPDX-License-Identifier: AGPL-3.0-only package workspace import ( "context" "connectrpc.com/connect" "google.golang.org/protobuf/proto" errorV1 "pocka.jp/x/yamori/proto/go/error/v1" workspaceV2 "pocka.jp/x/yamori/proto/go/workspace/v2" "pocka.jp/x/yamori/backend/core/event" "pocka.jp/x/yamori/backend/core/projection" ) func getLoginUserSystemError(message string) *connect.Response[workspaceV2.GetLoginUserResponse] { return connect.NewResponse(&workspaceV2.GetLoginUserResponse{ Result: &workspaceV2.GetLoginUserResponse_SystemError{ SystemError: &errorV1.SystemError{ Message: proto.String(message), }, }, }) } func getLoginUserAuthError() *connect.Response[workspaceV2.GetLoginUserResponse] { return connect.NewResponse(&workspaceV2.GetLoginUserResponse{ Result: &workspaceV2.GetLoginUserResponse_AuthenticationError{ AuthenticationError: &errorV1.AuthenticationError{}, }, }) } func (s *Service) GetLoginUser( ctx context.Context, req *connect.Request[workspaceV2.GetLoginUserRequest], ) (*connect.Response[workspaceV2.GetLoginUserResponse], error) { logger := s.core.Logger.With( "service", "yamori.workspace.v2.WorkspaceService", "method", "GetLoginUser", ) header := req.Header() token, err := s.core.LoadTokenFromCookie(&header) if err != nil || token == nil { return getLoginUserAuthError(), nil } tx, err := s.core.DB.Begin() if err != nil { logger.Error("Failed to begin transaction", "error", err) return getLoginUserSystemError("Database error"), nil } defer tx.Rollback() users, err := projection.GetUsers(tx) if err != nil { logger.Error("Failed to read users projection", "error", err) return getLoginUserSystemError("Database error"), nil } secret, err := projection.GetLoginJwtSecret(tx) if err != nil { logger.Error("Failed to read login_jwt_secret projection", "error", err) return getLoginUserSystemError("Database error"), nil } if err := event.UpdateProjections(tx, users, secret); err != nil { logger.Error("Failed to update projections", "error", err) return getLoginUserSystemError("Database error"), nil } user, err := token.FindUser(secret, users) if err != nil { logger.Warn("Malformed token found", "error", err) return getLoginUserAuthError(), nil } return connect.NewResponse(&workspaceV2.GetLoginUserResponse{ Result: &workspaceV2.GetLoginUserResponse_Ok{ Ok: projectionUserToMessage(user), }, }), nil }
-
-
-
@@ -0,0 +1,64 @@// SPDX-FileCopyrightText: 2025 Shota FUJI <pockawoooh@gmail.com> // SPDX-License-Identifier: AGPL-3.0-only //go:build !js && !wasm package v2 import ( "context" "reflect" "testing" "connectrpc.com/connect" workspaceV2 "pocka.jp/x/yamori/proto/go/workspace/v2" "pocka.jp/x/yamori/proto/go/workspace/v2/v2connect" ) func TestGetLoginUserOK(t *testing.T) { server, jar := setupLogin(t) httpClient := server.Client() httpClient.Jar = jar client := v2connect.NewWorkspaceServiceClient(httpClient, server.URL()) res, err := client.GetLoginUser( context.Background(), connect.NewRequest(&workspaceV2.GetLoginUserRequest{}), ) if err != nil { t.Fatal(err) } v, ok := res.Msg.Result.(*workspaceV2.GetLoginUserResponse_Ok) if !ok { typeName := reflect.Indirect(reflect.ValueOf(res.Msg.Result)) t.Errorf("Expected ok, got %s", typeName.Type().Name()) } if v.Ok.GetName() != "alice" { t.Errorf("Expected the login user to be named `alice`, got `%s`", v.Ok.GetName()) } } func TestGetLoginUserNotLoggedIn(t *testing.T) { server := setupInitialAdmin(t) client := v2connect.NewWorkspaceServiceClient(server.Client(), server.URL()) res, err := client.GetLoginUser( context.Background(), connect.NewRequest(&workspaceV2.GetLoginUserRequest{}), ) if err != nil { t.Fatal(err) } _, ok := res.Msg.Result.(*workspaceV2.GetLoginUserResponse_AuthenticationError) if !ok { typeName := reflect.Indirect(reflect.ValueOf(res.Msg.Result)) t.Errorf("Expected authentication_error, got %s", typeName.Type().Name()) } }
-