LCOV - code coverage report
Current view: top level - adapter/http/middleware - resolve_user.go Coverage Total Hit
Test: coverage.lcov Lines: 26.9 % 52 14
Test Date: 2026-04-14 06:42:22 Functions: - 0 0

            Line data    Source code
       1              : package middleware
       2              : 
       3              : import (
       4              :         "net/http"
       5              : 
       6              :         "github.com/gin-gonic/gin"
       7              : 
       8              :         "resume/internal/adapter/http/handlerutil"
       9              :         "resume/internal/domain/repository"
      10              :         "resume/internal/shared/apperr"
      11              :         "resume/internal/shared/ctx/auth"
      12              : )
      13              : 
      14              : // ResolveUser は、Firebase UID からユーザー情報を解決するミドルウェアです。
      15              : type ResolveUser struct {
      16              :         userRepo repository.UserRepository
      17              : }
      18              : 
      19              : // NewResolveUser は、ユーザー解決ミドルウェアを初期化して返します。
      20            2 : func NewResolveUser(userRepo repository.UserRepository) *ResolveUser {
      21            2 :         return &ResolveUser{userRepo: userRepo}
      22            2 : }
      23              : 
      24              : // InjectResolveUser --- 1) 認証“任意”版: 認証が入っていれば user_id を解決・セット。無ければ素通り。
      25            0 : func (m *ResolveUser) InjectResolveUser() gin.HandlerFunc {
      26            0 :         return func(c *gin.Context) {
      27            0 :                 // OPTIONS は素通り(CORSプリフライト対策。RequireAuth と合わせる)
      28            0 :                 if c.Request.Method == http.MethodOptions {
      29            0 :                         c.Next()
      30            0 :                         return
      31            0 :                 }
      32              : 
      33            0 :                 claims, ok := auth.From(c.Request.Context())
      34            0 :                 if !ok || claims.UID == "" {
      35            0 :                         // 認証なし → そのまま素通り
      36            0 :                         c.Next()
      37            0 :                         return
      38            0 :                 }
      39              : 
      40            0 :                 u, err := m.userRepo.FindByUID(c.Request.Context(), claims.UID)
      41            0 :                 if err != nil {
      42            0 :                         handlerutil.WriteError(c, apperr.Wrap(apperr.CodeInternal, "failed to load user", err, nil))
      43            0 :                         return
      44            0 :                 }
      45            0 :                 if u == nil || u.ID == 0 {
      46            0 :                         // 「任意」版なので未登録でも素通り(必要ならここで消すこともできる)
      47            0 :                         c.Next()
      48            0 :                         return
      49            0 :                 }
      50              : 
      51            0 :                 auth.SetUserID(c, uint64(u.ID))
      52            0 :                 c.Next()
      53              :         }
      54              : }
      55              : 
      56              : // RequireResolveUser --- 2) 認証“必須”版: ユーザー未登録や解決失敗ならエラーで打ち切り。
      57            2 : func (m *ResolveUser) RequireResolveUser() gin.HandlerFunc {
      58            3 :         return func(c *gin.Context) {
      59            1 :                 // OPTIONS は素通り
      60            1 :                 if c.Request.Method == http.MethodOptions {
      61            0 :                         c.Next()
      62            0 :                         return
      63            0 :                 }
      64              : 
      65            1 :                 claims, ok := auth.From(c.Request.Context())
      66            1 :                 if !ok || claims.UID == "" {
      67            0 :                         handlerutil.WriteError(c, apperr.New(apperr.CodeUnauthorized, "unauthorized", nil))
      68            0 :                         return
      69            0 :                 }
      70              : 
      71            1 :                 u, err := m.userRepo.FindByUID(c.Request.Context(), claims.UID)
      72            1 :                 if err != nil {
      73            0 :                         handlerutil.WriteError(c, apperr.Wrap(apperr.CodeInternal, "failed to load user", err, nil))
      74            0 :                         return
      75            0 :                 }
      76            1 :                 if u == nil || u.ID == 0 {
      77            0 :                         // チーム方針で 401/404/412 のどれかに揃えてOK。ここは 401 に寄せています。
      78            0 :                         handlerutil.WriteError(c, apperr.New(apperr.CodeUnauthorized, "user not registered", nil))
      79            0 :                         return
      80            0 :                 }
      81              : 
      82            1 :                 auth.SetUserID(c, uint64(u.ID))
      83            1 :                 c.Next()
      84              :         }
      85              : }
        

Generated by: LCOV version 2.3.1-1