From 07aae642a726b016d6ea9f310ceac730cfc68bab Mon Sep 17 00:00:00 2001 From: kyy Date: Tue, 10 Feb 2026 10:15:44 +0900 Subject: [PATCH] =?UTF-8?q?golangci=20lint=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/auth_handler_client_test.go | 8 ++--- .../handler/auth_handler_consent_test.go | 8 ++--- .../handler/auth_handler_link_test.go | 18 ++++++----- .../handler/auth_handler_linked_test.go | 8 ++--- .../handler/auth_handler_oidc_test.go | 2 +- .../internal/handler/auth_handler_otp_test.go | 12 +++---- .../internal/handler/auth_handler_qr_test.go | 20 ++++++------ backend/internal/handler/common_test.go | 32 +++++++++++++------ backend/internal/handler/dev_handler_test.go | 16 +++++----- 9 files changed, 70 insertions(+), 54 deletions(-) diff --git a/backend/internal/handler/auth_handler_client_test.go b/backend/internal/handler/auth_handler_client_test.go index 65bc7308..7263b358 100644 --- a/backend/internal/handler/auth_handler_client_test.go +++ b/backend/internal/handler/auth_handler_client_test.go @@ -47,7 +47,7 @@ func TestRevokeLinkedRp_Success(t *testing.T) { req := httptest.NewRequest(http.MethodDelete, "/api/v1/user/rp/linked/app-1", nil) req.Header.Set("Cookie", "valid") - + resp, _ := app.Test(req, -1) assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Equal(t, 1, len(auditRepo.logs)) @@ -87,7 +87,7 @@ func TestListRpHistory_Aggregation(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/api/v1/user/rp/history", nil) req.Header.Set("Cookie", "valid") - + resp, _ := app.Test(req, -1) assert.Equal(t, http.StatusOK, resp.StatusCode) @@ -98,9 +98,9 @@ func TestListRpHistory_Aggregation(t *testing.T) { } `json:"items"` } json.NewDecoder(resp.Body).Decode(&res) - + assert.Equal(t, 1, len(res.Items)) assert.Equal(t, "app-1", res.Items[0].ClientID) // Newest event (revoked) should win assert.Equal(t, "revoked", res.Items[0].Status) -} \ No newline at end of file +} diff --git a/backend/internal/handler/auth_handler_consent_test.go b/backend/internal/handler/auth_handler_consent_test.go index 8e6edf12..72cdede1 100644 --- a/backend/internal/handler/auth_handler_consent_test.go +++ b/backend/internal/handler/auth_handler_consent_test.go @@ -42,7 +42,7 @@ func TestGetConsentRequest_Normal(t *testing.T) { }) client := &http.Client{Transport: transport} - + origDefault := http.DefaultClient http.DefaultClient = client defer func() { http.DefaultClient = origDefault }() @@ -104,7 +104,7 @@ func TestGetConsentRequest_Skip_AutoAccept(t *testing.T) { origDefault := http.DefaultClient http.DefaultClient = client defer func() { http.DefaultClient = origDefault }() - + consentRepo := &mockConsentRepo{} h := &AuthHandler{ @@ -121,7 +121,7 @@ func TestGetConsentRequest_Skip_AutoAccept(t *testing.T) { app := newConsentTestApp(h) req := httptest.NewRequest(http.MethodGet, "/api/v1/auth/consent?consent_challenge=challenge-skip", nil) - + resp, err := app.Test(req) assert.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) @@ -194,4 +194,4 @@ func TestAcceptConsentRequest_Normal(t *testing.T) { assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Equal(t, 1, len(auditRepo.logs)) -} \ No newline at end of file +} diff --git a/backend/internal/handler/auth_handler_link_test.go b/backend/internal/handler/auth_handler_link_test.go index 76139c85..331ac4f6 100644 --- a/backend/internal/handler/auth_handler_link_test.go +++ b/backend/internal/handler/auth_handler_link_test.go @@ -14,19 +14,21 @@ import ( // Mock services type mockEmailService struct{} + func (m *mockEmailService) SendEmail(to, subject, body string) error { return nil } type mockSmsService struct{} + func (m *mockSmsService) SendSms(to, content string) error { return nil } func TestEnchantedLinkFlow_Email_Success(t *testing.T) { redis := &mockRedisRepo{data: make(map[string]string)} // Force "Not Supported" for InitiateLinkLogin only to trigger custom Enchanted Link logic idp := &mockIdpProvider{ - userExists: true, + userExists: true, initiateLinkErr: domain.ErrNotSupported, } - + h := &AuthHandler{ RedisService: redis, IdpProvider: idp, @@ -48,9 +50,9 @@ func TestEnchantedLinkFlow_Email_Success(t *testing.T) { req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/enchanted-link/init", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") resp, _ := app.Test(req, -1) - + assert.Equal(t, http.StatusOK, resp.StatusCode) - + var initResp map[string]interface{} json.NewDecoder(resp.Body).Decode(&initResp) pendingRef := initResp["pendingRef"].(string) @@ -81,7 +83,7 @@ func TestEnchantedLinkFlow_Email_Success(t *testing.T) { req = httptest.NewRequest(http.MethodPost, "/api/v1/auth/enchanted-link/poll", bytes.NewReader(pollBody)) req.Header.Set("Content-Type", "application/json") resp, _ = app.Test(req, -1) - + assert.Equal(t, http.StatusOK, resp.StatusCode) var pollResp map[string]interface{} json.NewDecoder(resp.Body).Decode(&pollResp) @@ -95,7 +97,7 @@ func TestEnchantedLinkFlow_Sms_Success(t *testing.T) { userExists: true, initiateLinkErr: domain.ErrNotSupported, } - + h := &AuthHandler{ RedisService: redis, IdpProvider: idp, @@ -112,9 +114,9 @@ func TestEnchantedLinkFlow_Sms_Success(t *testing.T) { req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/enchanted-link/init", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") resp, _ := app.Test(req, -1) - + assert.Equal(t, http.StatusOK, resp.StatusCode) - + var initResp map[string]interface{} json.NewDecoder(resp.Body).Decode(&initResp) assert.NotEmpty(t, initResp["userCode"]) diff --git a/backend/internal/handler/auth_handler_linked_test.go b/backend/internal/handler/auth_handler_linked_test.go index c80ab12b..cc94931f 100644 --- a/backend/internal/handler/auth_handler_linked_test.go +++ b/backend/internal/handler/auth_handler_linked_test.go @@ -70,7 +70,7 @@ func TestListLinkedRps_PriorityAndAggregation(t *testing.T) { }) client := &http.Client{Transport: transport} - + origDefault := http.DefaultClient http.DefaultClient = client defer func() { @@ -87,7 +87,7 @@ func TestListLinkedRps_PriorityAndAggregation(t *testing.T) { }, }, } - + consentRepo := &mockConsentRepo{ consents: []domain.ClientConsent{ { @@ -132,7 +132,7 @@ func TestListLinkedRps_PriorityAndAggregation(t *testing.T) { json.NewDecoder(resp.Body).Decode(&res) assert.Equal(t, 3, len(res.Items)) - + statusMap := make(map[string]string) for _, item := range res.Items { statusMap[item.ID] = item.Status @@ -141,4 +141,4 @@ func TestListLinkedRps_PriorityAndAggregation(t *testing.T) { assert.Equal(t, "active", statusMap["client-active"]) assert.Equal(t, "inactive", statusMap["client-consent"]) assert.Equal(t, "inactive", statusMap["client-audit"]) -} \ No newline at end of file +} diff --git a/backend/internal/handler/auth_handler_oidc_test.go b/backend/internal/handler/auth_handler_oidc_test.go index 1f5fb069..8ba03109 100644 --- a/backend/internal/handler/auth_handler_oidc_test.go +++ b/backend/internal/handler/auth_handler_oidc_test.go @@ -175,4 +175,4 @@ func TestAcceptOidcLoginRequest_TokenFallbackToCookie(t *testing.T) { if gotSubject != "kratos-456" { t.Fatalf("unexpected subject: %v", gotSubject) } -} \ No newline at end of file +} diff --git a/backend/internal/handler/auth_handler_otp_test.go b/backend/internal/handler/auth_handler_otp_test.go index bda8fa47..09f6a191 100644 --- a/backend/internal/handler/auth_handler_otp_test.go +++ b/backend/internal/handler/auth_handler_otp_test.go @@ -14,7 +14,7 @@ import ( func TestHandleKratosCourierRelay_Email(t *testing.T) { redis := &mockRedisRepo{data: make(map[string]string)} emailSvc := &mockEmailService{} - + h := &AuthHandler{ RedisService: redis, EmailService: emailSvc, @@ -35,7 +35,7 @@ func TestHandleKratosCourierRelay_Email(t *testing.T) { body, _ := json.Marshal(reqBody) req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/kratos/courier", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") - + resp, _ := app.Test(req, -1) assert.Equal(t, http.StatusOK, resp.StatusCode) } @@ -67,10 +67,10 @@ func TestVerifySignupCode_Success(t *testing.T) { body, _ := json.Marshal(verifyBody) req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/signup/verify", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") - + resp, _ := app.Test(req, -1) assert.Equal(t, http.StatusOK, resp.StatusCode) - + var res map[string]interface{} json.NewDecoder(resp.Body).Decode(&res) assert.True(t, res["success"].(bool)) @@ -91,7 +91,7 @@ func TestVerifySignupCode_Invalid(t *testing.T) { app.Post("/api/v1/auth/signup/verify", h.VerifySignupCode) stateJSON, _ := json.Marshal(map[string]interface{}{ - "code": "111111", + "code": "111111", "expires_at": 9999999999, }) redis.data["signup:email:user@test.com"] = string(stateJSON) @@ -104,7 +104,7 @@ func TestVerifySignupCode_Invalid(t *testing.T) { body, _ := json.Marshal(verifyBody) req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/signup/verify", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") - + resp, _ := app.Test(req, -1) assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) } diff --git a/backend/internal/handler/auth_handler_qr_test.go b/backend/internal/handler/auth_handler_qr_test.go index 816cf39f..9089a948 100644 --- a/backend/internal/handler/auth_handler_qr_test.go +++ b/backend/internal/handler/auth_handler_qr_test.go @@ -20,7 +20,9 @@ type mockRedisRepo struct { } func (m *mockRedisRepo) Set(key, value string, ttl time.Duration) error { - if m.data == nil { m.data = make(map[string]string) } + if m.data == nil { + m.data = make(map[string]string) + } m.data[key] = value return nil } @@ -43,11 +45,11 @@ func (m *mockRedisRepo) StoreVerificationCode(phone, code string) error { } func (m *mockRedisRepo) GetVerificationCode(phone string) (string, error) { - return m.Get("sms:"+phone) + return m.Get("sms:" + phone) } func (m *mockRedisRepo) DeleteVerificationCode(phone string) error { - return m.Delete("sms:"+phone) + return m.Delete("sms:" + phone) } // --- Tests --- @@ -75,7 +77,7 @@ func TestQRLoginFlow_Success(t *testing.T) { req = httptest.NewRequest(http.MethodPost, "/api/v1/auth/qr/poll", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") resp, _ = app.Test(req, -1) - + // Expect authorization_pending (400) assert.Equal(t, http.StatusBadRequest, resp.StatusCode) var pollResp map[string]interface{} @@ -93,7 +95,7 @@ func TestQRLoginFlow_Success(t *testing.T) { req = httptest.NewRequest(http.MethodPost, "/api/v1/auth/qr/poll", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") resp, _ = app.Test(req, -1) - + assert.Equal(t, http.StatusOK, resp.StatusCode) var successResp map[string]interface{} @@ -129,7 +131,7 @@ func TestScanQRLogin_Success(t *testing.T) { } return httpResponse(r, http.StatusNotFound, "not found"), nil }) - + origDefault := http.DefaultClient http.DefaultClient = &http.Client{Transport: transport} defer func() { http.DefaultClient = origDefault }() @@ -147,7 +149,7 @@ func TestScanQRLogin_Success(t *testing.T) { func TestResolveConsentSubjects_TokenAndCookie(t *testing.T) { h := &AuthHandler{} - + transport := roundTripFunc(func(r *http.Request) (*http.Response, error) { if r.Header.Get("X-Session-Token") == "token-123" { return httpJSONAny(r, http.StatusOK, map[string]interface{}{ @@ -172,13 +174,13 @@ func TestResolveConsentSubjects_TokenAndCookie(t *testing.T) { } return httpResponse(r, http.StatusUnauthorized, "unauthorized"), nil }) - + origDefault := http.DefaultClient http.DefaultClient = &http.Client{Transport: transport} defer func() { http.DefaultClient = origDefault }() app := fiber.New() - + // Token case app.Get("/test-token", func(c *fiber.Ctx) error { subjects, err := h.resolveConsentSubjects(c) diff --git a/backend/internal/handler/common_test.go b/backend/internal/handler/common_test.go index 4069e356..80c7aff1 100644 --- a/backend/internal/handler/common_test.go +++ b/backend/internal/handler/common_test.go @@ -12,13 +12,13 @@ import ( // --- Mock IDP Provider --- type mockIdpProvider struct { - userExists bool - name string - signInInfo *domain.AuthInfo - issueSession *domain.AuthInfo - verifyCodeInfo *domain.AuthInfo - err error - initiateLinkErr error + userExists bool + name string + signInInfo *domain.AuthInfo + issueSession *domain.AuthInfo + verifyCodeInfo *domain.AuthInfo + err error + initiateLinkErr error } func (m *mockIdpProvider) Name() string { @@ -32,6 +32,7 @@ func (m *mockIdpProvider) GetMetadata() (*domain.IDPMetadata, error) { return ni func (m *mockIdpProvider) CreateUser(user *domain.BrokerUser, password string) (string, error) { return "mock-user-id", m.err } + func (m *mockIdpProvider) SignIn(loginID, password string) (*domain.AuthInfo, error) { return m.signInInfo, m.err } @@ -44,20 +45,23 @@ func (m *mockIdpProvider) IssueSession(loginID string) (*domain.AuthInfo, error) SessionToken: &domain.Token{JWT: "valid-jwt", SessionID: "valid-sid"}, }, m.err } + func (m *mockIdpProvider) InitiateLinkLogin(loginID, returnTo string) (*domain.LinkLoginInit, error) { if m.initiateLinkErr != nil { return nil, m.initiateLinkErr } return &domain.LinkLoginInit{FlowID: "mock-flow-id", Mode: "code"}, m.err } + func (m *mockIdpProvider) VerifyLoginCode(loginID, flowID, code string) (*domain.AuthInfo, error) { return m.verifyCodeInfo, m.err } -func (m *mockIdpProvider) GetPasswordPolicy() (*domain.PasswordPolicy, error) { return nil, m.err } +func (m *mockIdpProvider) GetPasswordPolicy() (*domain.PasswordPolicy, error) { return nil, m.err } func (m *mockIdpProvider) InitiatePasswordReset(loginID, redirectUrl string) error { return m.err } func (m *mockIdpProvider) VerifyPasswordResetToken(token string) (*domain.AuthInfo, error) { return nil, m.err } + func (m *mockIdpProvider) UpdateUserPassword(loginID, newPassword string, r *http.Request) error { return m.err } @@ -72,9 +76,11 @@ func (m *mockAuditRepo) Create(log *domain.AuditLog) error { m.logs = append(m.logs, *log) return nil } + func (m *mockAuditRepo) FindPage(ctx context.Context, limit int, cursor *domain.AuditCursor) ([]domain.AuditLog, error) { return m.logs, nil } + func (m *mockAuditRepo) FindByUserAndEvents(ctx context.Context, userID string, eventTypes []string, limit int) ([]domain.AuditLog, error) { var results []domain.AuditLog for _, log := range m.logs { @@ -101,6 +107,7 @@ func (m *mockConsentRepo) Upsert(ctx context.Context, consent *domain.ClientCons m.consents = append(m.consents, *consent) return nil } + func (m *mockConsentRepo) ListBySubject(ctx context.Context, subject string) ([]domain.ClientConsent, error) { var results []domain.ClientConsent for _, c := range m.consents { @@ -114,6 +121,7 @@ func (m *mockConsentRepo) Delete(ctx context.Context, clientID, subject string) func (m *mockConsentRepo) List(ctx context.Context, clientID string, limit, offset int) ([]domain.ClientConsentWithTenantInfo, int64, error) { return nil, 0, nil } + func (m *mockConsentRepo) ListByTenant(ctx context.Context, clientID, tenantID string, limit, offset int) ([]domain.ClientConsentWithTenantInfo, int64, error) { return nil, 0, nil } @@ -125,13 +133,17 @@ type mockSecretRepo struct { } func (m *mockSecretRepo) Upsert(ctx context.Context, clientID, secret string) error { - if m.secrets == nil { m.secrets = make(map[string]string) } + if m.secrets == nil { + m.secrets = make(map[string]string) + } m.secrets[clientID] = secret return nil } + func (m *mockSecretRepo) GetByID(ctx context.Context, clientID string) (string, error) { return m.secrets[clientID], nil } + func (m *mockSecretRepo) Delete(ctx context.Context, clientID string) error { delete(m.secrets, clientID) return nil @@ -164,4 +176,4 @@ func httpJSONAny(r *http.Request, code int, data any) *http.Response { Body: io.NopCloser(bytes.NewBuffer(body)), Request: r, } -} \ No newline at end of file +} diff --git a/backend/internal/handler/dev_handler_test.go b/backend/internal/handler/dev_handler_test.go index 27311048..4c491c73 100644 --- a/backend/internal/handler/dev_handler_test.go +++ b/backend/internal/handler/dev_handler_test.go @@ -20,7 +20,7 @@ func TestListClients_Success(t *testing.T) { {"client_id": "client-2", "client_name": "App Two", "metadata": map[string]interface{}{"status": "inactive"}}, }), nil } - return httpJSONAny(r, http.StatusNotFound, map[string]string{"error":"not found"}), nil + return httpJSONAny(r, http.StatusNotFound, map[string]string{"error": "not found"}), nil }) h := &DevHandler{ @@ -55,7 +55,7 @@ func TestGetClient_Success(t *testing.T) { "metadata": map[string]interface{}{"status": "active"}, }), nil } - return httpJSONAny(r, http.StatusNotFound, map[string]string{"error":"not found"}), nil + return httpJSONAny(r, http.StatusNotFound, map[string]string{"error": "not found"}), nil }) h := &DevHandler{ @@ -82,7 +82,7 @@ func TestGetClient_Success(t *testing.T) { func TestGetClient_NotFound(t *testing.T) { transport := roundTripFunc(func(r *http.Request) (*http.Response, error) { - return httpJSONAny(r, http.StatusNotFound, map[string]string{"error":"not found"}), nil + return httpJSONAny(r, http.StatusNotFound, map[string]string{"error": "not found"}), nil }) h := &DevHandler{ @@ -109,12 +109,12 @@ func TestCreateClient_Success(t *testing.T) { "client_secret": "secret-123", }), nil } - return httpJSONAny(r, http.StatusInternalServerError, map[string]string{"error":"hydra error"}), nil + return httpJSONAny(r, http.StatusInternalServerError, map[string]string{"error": "hydra error"}), nil }) secretRepo := &mockSecretRepo{secrets: make(map[string]string)} redisRepo := &mockRedisRepo{data: make(map[string]string)} - + h := &DevHandler{ Hydra: &service.HydraAdminService{ AdminURL: "http://hydra.test", @@ -127,13 +127,13 @@ func TestCreateClient_Success(t *testing.T) { app.Post("/api/v1/dev/clients", h.CreateClient) body, _ := json.Marshal(map[string]interface{}{ - "client_name": "New App", - "type": "confidential", + "client_name": "New App", + "type": "confidential", "redirectUris": []string{"http://localhost/cb"}, }) req := httptest.NewRequest(http.MethodPost, "/api/v1/dev/clients", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") - + resp, _ := app.Test(req, -1) assert.Equal(t, http.StatusCreated, resp.StatusCode)