From fdf572cd3d09ba1a9836d6616e127608fc8d8388 Mon Sep 17 00:00:00 2001 From: ericprd Date: Fri, 7 Mar 2025 17:39:26 +0800 Subject: [PATCH] feat: refactor auth package and add get users for staff --- internal/accessor/module.go | 2 +- internal/accessor/staff/create.go | 2 +- internal/accessor/staff/get_by_email.go | 2 +- internal/accessor/staff/get_by_id.go | 2 +- internal/accessor/staff/get_users.go | 27 +++++++++ internal/accessor/staff/impl.go | 6 +- internal/accessor/staff/update.go | 2 +- .../{user_repository => user}/create_user.go | 0 .../get_user_by_email.go | 0 .../get_user_by_id.go | 0 .../get_user_profile.go | 0 .../{user_repository => user}/impl.go | 0 internal/api/http/auth/module.go | 15 ----- internal/api/http/router.go | 6 +- internal/api/http/staffhttp/get_users.go | 59 +++++++++++++++++++ .../login_staff.go => staffhttp/login.go} | 4 +- internal/api/http/staffhttp/module.go | 13 ++++ .../api/http/{auth => staffhttp}/profile.go | 40 +------------ .../register.go} | 4 +- .../api/http/{auth => staffhttp}/update.go | 4 +- .../{auth/login_user.go => user/login.go} | 4 +- internal/api/http/user/module.go | 9 +++ internal/api/http/user/profile.go | 46 +++++++++++++++ .../register_user.go => user/register.go} | 4 +- internal/enums/jwt/jwt_claims.go | 1 + internal/services/auth/get_users.go | 7 +++ internal/services/auth/impl.go | 3 +- internal/services/news/impl.go | 2 +- internal/utilities/utils/jwt.go | 17 ++++-- 29 files changed, 203 insertions(+), 78 deletions(-) create mode 100644 internal/accessor/staff/get_users.go rename internal/accessor/{user_repository => user}/create_user.go (100%) rename internal/accessor/{user_repository => user}/get_user_by_email.go (100%) rename internal/accessor/{user_repository => user}/get_user_by_id.go (100%) rename internal/accessor/{user_repository => user}/get_user_profile.go (100%) rename internal/accessor/{user_repository => user}/impl.go (100%) delete mode 100644 internal/api/http/auth/module.go create mode 100644 internal/api/http/staffhttp/get_users.go rename internal/api/http/{auth/login_staff.go => staffhttp/login.go} (98%) create mode 100644 internal/api/http/staffhttp/module.go rename internal/api/http/{auth => staffhttp}/profile.go (54%) rename internal/api/http/{auth/register_staff.go => staffhttp/register.go} (97%) rename internal/api/http/{auth => staffhttp}/update.go (97%) rename internal/api/http/{auth/login_user.go => user/login.go} (98%) create mode 100644 internal/api/http/user/module.go create mode 100644 internal/api/http/user/profile.go rename internal/api/http/{auth/register_user.go => user/register.go} (97%) create mode 100644 internal/services/auth/get_users.go diff --git a/internal/accessor/module.go b/internal/accessor/module.go index b210390..90c6679 100644 --- a/internal/accessor/module.go +++ b/internal/accessor/module.go @@ -9,7 +9,7 @@ import ( subscriberepository "legalgo-BE-go/internal/accessor/subscribe" subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribeplan" tagrepository "legalgo-BE-go/internal/accessor/tag" - userrepository "legalgo-BE-go/internal/accessor/user_repository" + userrepository "legalgo-BE-go/internal/accessor/user" "go.uber.org/fx" ) diff --git a/internal/accessor/staff/create.go b/internal/accessor/staff/create.go index 14e2d95..c4822dc 100644 --- a/internal/accessor/staff/create.go +++ b/internal/accessor/staff/create.go @@ -4,7 +4,7 @@ import ( staffdomain "legalgo-BE-go/internal/domain/staff" ) -func (ur *impl) Create(spec staffdomain.Staff) error { +func (ur *accessor) Create(spec staffdomain.Staff) error { if err := ur.db.Create(&spec).Error; err != nil { return err } diff --git a/internal/accessor/staff/get_by_email.go b/internal/accessor/staff/get_by_email.go index 2868741..e670730 100644 --- a/internal/accessor/staff/get_by_email.go +++ b/internal/accessor/staff/get_by_email.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm" ) -func (sr *impl) GetStaffByEmail(email string) (*staffdomain.Staff, error) { +func (sr *accessor) GetStaffByEmail(email string) (*staffdomain.Staff, error) { var staff staffdomain.Staff if email == "" { diff --git a/internal/accessor/staff/get_by_id.go b/internal/accessor/staff/get_by_id.go index 5e52f7b..d1d6490 100644 --- a/internal/accessor/staff/get_by_id.go +++ b/internal/accessor/staff/get_by_id.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" ) -func (sr *impl) GetStaffByID(ID string) (*staffdomain.Staff, error) { +func (sr *accessor) GetStaffByID(ID string) (*staffdomain.Staff, error) { var staff staffdomain.Staff if ID == "" { diff --git a/internal/accessor/staff/get_users.go b/internal/accessor/staff/get_users.go new file mode 100644 index 0000000..a6c7268 --- /dev/null +++ b/internal/accessor/staff/get_users.go @@ -0,0 +1,27 @@ +package staffrepository + +import userdomain "legalgo-BE-go/internal/domain/user" + +func (a *accessor) GetUsers() ([]userdomain.UserProfile, error) { + var usersRaw []userdomain.User + if err := a.db. + Preload("Subscribe"). + Preload("Subscribe.SubscribePlan"). + Find(&usersRaw). + Error; err != nil { + return nil, err + } + + users := []userdomain.UserProfile{} + + for _, user := range usersRaw { + users = append(users, userdomain.UserProfile{ + ID: user.ID, + Email: user.Email, + Phone: user.Phone, + Subscribe: user.Subscribe, + }) + } + + return users, nil +} diff --git a/internal/accessor/staff/impl.go b/internal/accessor/staff/impl.go index 1c05d5c..633d125 100644 --- a/internal/accessor/staff/impl.go +++ b/internal/accessor/staff/impl.go @@ -3,19 +3,21 @@ package staffrepository import ( "legalgo-BE-go/database" staffdomain "legalgo-BE-go/internal/domain/staff" + userdomain "legalgo-BE-go/internal/domain/user" ) -type impl struct { +type accessor struct { db *database.DB } type Staff interface { GetStaffByEmail(string) (*staffdomain.Staff, error) GetStaffByID(string) (*staffdomain.Staff, error) + GetUsers() ([]userdomain.UserProfile, error) Create(staffdomain.Staff) error Update(staffdomain.Staff) error } func New(db *database.DB) Staff { - return &impl{db} + return &accessor{db} } diff --git a/internal/accessor/staff/update.go b/internal/accessor/staff/update.go index f5af3f8..67030a8 100644 --- a/internal/accessor/staff/update.go +++ b/internal/accessor/staff/update.go @@ -5,7 +5,7 @@ import ( "legalgo-BE-go/internal/utilities/utils" ) -func (ur *impl) Update(spec staffdomain.Staff) error { +func (ur *accessor) Update(spec staffdomain.Staff) error { val, err := utils.StructToMap(spec) if err != nil { return err diff --git a/internal/accessor/user_repository/create_user.go b/internal/accessor/user/create_user.go similarity index 100% rename from internal/accessor/user_repository/create_user.go rename to internal/accessor/user/create_user.go diff --git a/internal/accessor/user_repository/get_user_by_email.go b/internal/accessor/user/get_user_by_email.go similarity index 100% rename from internal/accessor/user_repository/get_user_by_email.go rename to internal/accessor/user/get_user_by_email.go diff --git a/internal/accessor/user_repository/get_user_by_id.go b/internal/accessor/user/get_user_by_id.go similarity index 100% rename from internal/accessor/user_repository/get_user_by_id.go rename to internal/accessor/user/get_user_by_id.go diff --git a/internal/accessor/user_repository/get_user_profile.go b/internal/accessor/user/get_user_profile.go similarity index 100% rename from internal/accessor/user_repository/get_user_profile.go rename to internal/accessor/user/get_user_profile.go diff --git a/internal/accessor/user_repository/impl.go b/internal/accessor/user/impl.go similarity index 100% rename from internal/accessor/user_repository/impl.go rename to internal/accessor/user/impl.go diff --git a/internal/api/http/auth/module.go b/internal/api/http/auth/module.go deleted file mode 100644 index 320e1de..0000000 --- a/internal/api/http/auth/module.go +++ /dev/null @@ -1,15 +0,0 @@ -package authhttp - -import "go.uber.org/fx" - -var Module = fx.Module("auth-api", - fx.Invoke( - LoginStaff, - LoginUser, - RegisterUser, - RegisterStaff, - UpdateStaff, - GetStaffProfile, - GetUserProfile, - ), -) diff --git a/internal/api/http/router.go b/internal/api/http/router.go index 5ea6eb4..c476ba5 100644 --- a/internal/api/http/router.go +++ b/internal/api/http/router.go @@ -1,12 +1,13 @@ package internalhttp import ( - authhttp "legalgo-BE-go/internal/api/http/auth" categoryhttp "legalgo-BE-go/internal/api/http/category" newshttp "legalgo-BE-go/internal/api/http/news" osshttp "legalgo-BE-go/internal/api/http/oss" + staffhttp "legalgo-BE-go/internal/api/http/staffhttp" subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan" taghttp "legalgo-BE-go/internal/api/http/tag" + userhttp "legalgo-BE-go/internal/api/http/user" "github.com/go-chi/chi/v5" "github.com/go-chi/cors" @@ -21,12 +22,13 @@ var Module = fx.Module("router", initRouter, validator.New, ), - authhttp.Module, + staffhttp.Module, subscribeplanhttp.Module, taghttp.Module, categoryhttp.Module, newshttp.Module, osshttp.Module, + userhttp.Module, ) func initRouter() chi.Router { diff --git a/internal/api/http/staffhttp/get_users.go b/internal/api/http/staffhttp/get_users.go new file mode 100644 index 0000000..3d55c40 --- /dev/null +++ b/internal/api/http/staffhttp/get_users.go @@ -0,0 +1,59 @@ +package staffhttp + +import ( + authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth" + authsvc "legalgo-BE-go/internal/services/auth" + "legalgo-BE-go/internal/utilities/response" + "legalgo-BE-go/internal/utilities/utils" + "net/http" + + "github.com/go-chi/chi/v5" +) + +func GetUsers( + router chi.Router, + authSvc authsvc.Auth, +) { + router.With(authmiddleware.Authorize()).Get("/staff/users", func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + staffDetail, err := utils.GetTokenDetail(r) + if err != nil { + response.RespondJsonErrorWithCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + "failed to get staff token", + ) + return + } + + if staffDetail.Role != "staff" { + response.RespondJsonErrorWithCode( + ctx, + w, + err, + response.ErrUnauthorized.Code, + response.ErrUnauthorized.HttpCode, + "unauthorized", + ) + return + } + + users, err := authSvc.GetUsers() + if err != nil { + response.RespondJsonErrorWithCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + "failed to get users", + ) + return + } + + response.RespondJsonSuccess(ctx, w, users) + }) +} diff --git a/internal/api/http/auth/login_staff.go b/internal/api/http/staffhttp/login.go similarity index 98% rename from internal/api/http/auth/login_staff.go rename to internal/api/http/staffhttp/login.go index 498fb1c..650c2c9 100644 --- a/internal/api/http/auth/login_staff.go +++ b/internal/api/http/staffhttp/login.go @@ -1,4 +1,4 @@ -package authhttp +package staffhttp import ( "net/http" @@ -14,7 +14,7 @@ import ( "github.com/redis/go-redis/v9" ) -func LoginStaff( +func Login( router chi.Router, authSvc authsvc.Auth, validate *validator.Validate, diff --git a/internal/api/http/staffhttp/module.go b/internal/api/http/staffhttp/module.go new file mode 100644 index 0000000..ee3df16 --- /dev/null +++ b/internal/api/http/staffhttp/module.go @@ -0,0 +1,13 @@ +package staffhttp + +import "go.uber.org/fx" + +var Module = fx.Module("auth-api", + fx.Invoke( + Login, + Register, + Update, + GetProfile, + GetUsers, + ), +) diff --git a/internal/api/http/auth/profile.go b/internal/api/http/staffhttp/profile.go similarity index 54% rename from internal/api/http/auth/profile.go rename to internal/api/http/staffhttp/profile.go index e6c8f9c..8324a64 100644 --- a/internal/api/http/auth/profile.go +++ b/internal/api/http/staffhttp/profile.go @@ -1,4 +1,4 @@ -package authhttp +package staffhttp import ( authsvc "legalgo-BE-go/internal/services/auth" @@ -9,7 +9,7 @@ import ( "github.com/go-chi/chi/v5" ) -func GetStaffProfile( +func GetProfile( router chi.Router, authSvc authsvc.Auth, ) { @@ -44,39 +44,3 @@ func GetStaffProfile( response.RespondJsonSuccess(ctx, w, staffProfile) }) } - -func GetUserProfile( - router chi.Router, - authSvc authsvc.Auth, -) { - router.Get("/user/profile", func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - destructedToken, err := utils.GetTokenDetail(r) - if err != nil { - response.ResponseWithErrorCode( - ctx, - w, - err, - response.ErrBadRequest.Code, - response.ErrBadRequest.HttpCode, - err.Error(), - ) - return - } - - userProfile, err := authSvc.GetUserProfile(destructedToken.Email) - if err != nil { - response.ResponseWithErrorCode( - ctx, - w, - err, - response.ErrBadRequest.Code, - response.ErrBadRequest.HttpCode, - err.Error(), - ) - return - } - - response.RespondJsonSuccess(ctx, w, userProfile) - }) -} diff --git a/internal/api/http/auth/register_staff.go b/internal/api/http/staffhttp/register.go similarity index 97% rename from internal/api/http/auth/register_staff.go rename to internal/api/http/staffhttp/register.go index 1429838..0d891eb 100644 --- a/internal/api/http/auth/register_staff.go +++ b/internal/api/http/staffhttp/register.go @@ -1,4 +1,4 @@ -package authhttp +package staffhttp import ( "net/http" @@ -14,7 +14,7 @@ import ( "github.com/redis/go-redis/v9" ) -func RegisterStaff( +func Register( router chi.Router, validate *validator.Validate, authSvc authsvc.Auth, diff --git a/internal/api/http/auth/update.go b/internal/api/http/staffhttp/update.go similarity index 97% rename from internal/api/http/auth/update.go rename to internal/api/http/staffhttp/update.go index a644358..eb99046 100644 --- a/internal/api/http/auth/update.go +++ b/internal/api/http/staffhttp/update.go @@ -1,4 +1,4 @@ -package authhttp +package staffhttp import ( "errors" @@ -11,7 +11,7 @@ import ( "github.com/go-chi/chi/v5" ) -func UpdateStaff( +func Update( router chi.Router, authSvc authsvc.Auth, ) { diff --git a/internal/api/http/auth/login_user.go b/internal/api/http/user/login.go similarity index 98% rename from internal/api/http/auth/login_user.go rename to internal/api/http/user/login.go index c69c9df..fa072f0 100644 --- a/internal/api/http/auth/login_user.go +++ b/internal/api/http/user/login.go @@ -1,4 +1,4 @@ -package authhttp +package userhttp import ( responsedomain "legalgo-BE-go/internal/domain/reponse" @@ -13,7 +13,7 @@ import ( "github.com/redis/go-redis/v9" ) -func LoginUser( +func Login( router chi.Router, authSvc authsvc.Auth, validate *validator.Validate, diff --git a/internal/api/http/user/module.go b/internal/api/http/user/module.go new file mode 100644 index 0000000..79b119c --- /dev/null +++ b/internal/api/http/user/module.go @@ -0,0 +1,9 @@ +package userhttp + +import "go.uber.org/fx" + +var Module = fx.Module("user-http", fx.Invoke( + Register, + Login, + GetProfile, +)) diff --git a/internal/api/http/user/profile.go b/internal/api/http/user/profile.go new file mode 100644 index 0000000..13b98d6 --- /dev/null +++ b/internal/api/http/user/profile.go @@ -0,0 +1,46 @@ +package userhttp + +import ( + authsvc "legalgo-BE-go/internal/services/auth" + "legalgo-BE-go/internal/utilities/response" + "legalgo-BE-go/internal/utilities/utils" + "net/http" + + "github.com/go-chi/chi/v5" +) + +func GetProfile( + router chi.Router, + authSvc authsvc.Auth, +) { + router.Get("/user/profile", func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + destructedToken, err := utils.GetTokenDetail(r) + if err != nil { + response.ResponseWithErrorCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + err.Error(), + ) + return + } + + userProfile, err := authSvc.GetUserProfile(destructedToken.Email) + if err != nil { + response.ResponseWithErrorCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + err.Error(), + ) + return + } + + response.RespondJsonSuccess(ctx, w, userProfile) + }) +} diff --git a/internal/api/http/auth/register_user.go b/internal/api/http/user/register.go similarity index 97% rename from internal/api/http/auth/register_user.go rename to internal/api/http/user/register.go index 01ea918..1b86c11 100644 --- a/internal/api/http/auth/register_user.go +++ b/internal/api/http/user/register.go @@ -1,4 +1,4 @@ -package authhttp +package userhttp import ( responsedomain "legalgo-BE-go/internal/domain/reponse" @@ -13,7 +13,7 @@ import ( "github.com/redis/go-redis/v9" ) -func RegisterUser( +func Register( router chi.Router, validate *validator.Validate, authSvc authsvc.Auth, diff --git a/internal/enums/jwt/jwt_claims.go b/internal/enums/jwt/jwt_claims.go index 50bb4f1..495ee0e 100644 --- a/internal/enums/jwt/jwt_claims.go +++ b/internal/enums/jwt/jwt_claims.go @@ -9,4 +9,5 @@ const ( SESSION_ID JWTClaim = "sid" ISSUED_AT JWTClaim = "iat" RESOURCES JWTClaim = "resources" + ROLE JWTClaim = "role" ) diff --git a/internal/services/auth/get_users.go b/internal/services/auth/get_users.go new file mode 100644 index 0000000..1025d32 --- /dev/null +++ b/internal/services/auth/get_users.go @@ -0,0 +1,7 @@ +package authsvc + +import userdomain "legalgo-BE-go/internal/domain/user" + +func (i *impl) GetUsers() ([]userdomain.UserProfile, error) { + return i.staffRepo.GetUsers() +} diff --git a/internal/services/auth/impl.go b/internal/services/auth/impl.go index fe7e766..2908c92 100644 --- a/internal/services/auth/impl.go +++ b/internal/services/auth/impl.go @@ -4,7 +4,7 @@ import ( staffrepository "legalgo-BE-go/internal/accessor/staff" subscriberepository "legalgo-BE-go/internal/accessor/subscribe" subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribeplan" - userrepository "legalgo-BE-go/internal/accessor/user_repository" + userrepository "legalgo-BE-go/internal/accessor/user" staffdomain "legalgo-BE-go/internal/domain/staff" userdomain "legalgo-BE-go/internal/domain/user" ) @@ -20,6 +20,7 @@ type Auth interface { LoginAsStaff(staffdomain.StaffLogin) (string, error) RegisterStaff(staffdomain.StaffRegister) (string, error) GetStaffProfile(string) (*staffdomain.StaffProfile, error) + GetUsers() ([]userdomain.UserProfile, error) UpdateStaff(staffdomain.Staff) error LoginAsUser(userdomain.UserLogin) (string, error) diff --git a/internal/services/news/impl.go b/internal/services/news/impl.go index ac7f300..84ae3e3 100644 --- a/internal/services/news/impl.go +++ b/internal/services/news/impl.go @@ -4,7 +4,7 @@ import ( categoryrepository "legalgo-BE-go/internal/accessor/category" newsrepository "legalgo-BE-go/internal/accessor/news" tagrepository "legalgo-BE-go/internal/accessor/tag" - userrepository "legalgo-BE-go/internal/accessor/user_repository" + userrepository "legalgo-BE-go/internal/accessor/user" newsdomain "legalgo-BE-go/internal/domain/news" ) diff --git a/internal/utilities/utils/jwt.go b/internal/utilities/utils/jwt.go index f8dd16a..8aa2b60 100644 --- a/internal/utilities/utils/jwt.go +++ b/internal/utilities/utils/jwt.go @@ -34,10 +34,10 @@ type ClaimOption func(options jwt.MapClaims) func GenerateToken(data authdomain.AuthToken) (string, error) { now := timeutils.Now() claims := jwt.MapClaims{ - "email": data.Email, - "role": data.Role, - "session_id": data.SessionID, - "exp": now.Add(time.Minute * time.Duration(config.REDIS_TIMEOUT)).Unix(), + string(jwtclaimenum.EMAIL): data.Email, + string(jwtclaimenum.ROLE): data.Role, + string(jwtclaimenum.SESSION_ID): data.SessionID, + string(jwtclaimenum.EXPIRED_AT): now.Add(time.Minute * time.Duration(config.REDIS_TIMEOUT)).Unix(), } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) @@ -79,10 +79,19 @@ func DestructToken(s string) (authdomain.AuthToken, error) { } sessionId, ok := claims[string(jwtclaimenum.SESSION_ID)].(string) + if !ok { + return data, errors.New("invalid session_id") + } + + role, ok := claims[string(jwtclaimenum.ROLE)].(string) + if !ok { + return data, errors.New("invalid role") + } data = authdomain.AuthToken{ Email: email, SessionID: sessionId, + Role: role, } return data, nil