package gapi import ( "context" "errors" "strings" db "github.com/FernandoJVideira/api_tmpl/internal/db/sqlc" "github.com/FernandoJVideira/api_tmpl/internal/domain/role" "github.com/FernandoJVideira/api_tmpl/internal/service" "github.com/FernandoJVideira/api_tmpl/internal/val" "github.com/FernandoJVideira/api_tmpl/pb" "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func (s *Server) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*pb.UpdateUserResponse, error) { authPayload, err := s.authorizeUser(ctx, []string{role.AdminRole, role.MemberRole}) if err != nil { return nil, unauthenticatedError(err) } if authPayload.Role != role.AdminRole && authPayload.Username != req.GetUsername() { return nil, status.Errorf(codes.PermissionDenied, "cannot update other user's information") } violations := validateUpdateUserRequest(req) if violations != nil { return nil, invalidArgumentError(violations) } updateReq := service.UserUpdateRequest{ Username: req.GetUsername(), } // Set FullName if provided if req.FullName != nil { fullName := req.GetFullName() updateReq.FullName = &fullName } // Set Email if provided if req.Email != nil { email := req.GetEmail() updateReq.Email = &email } user, err := s.userService.UpdateUser(ctx, updateReq) if err != nil { if errors.Is(err, db.ErrRecordNotFound) || strings.Contains(err.Error(), "not found") { return nil, status.Errorf(codes.NotFound, "user not found: %v", err) } return nil, status.Errorf(codes.Internal, "failed to update user: %v", err) } resp := &pb.UpdateUserResponse{ User: convertUser(*user), } return resp, nil } func validateUpdateUserRequest(req *pb.UpdateUserRequest) (violations []*errdetails.BadRequest_FieldViolation) { if err := val.ValidateUsername(req.GetUsername()); err != nil { violations = append(violations, fieldViolation("username", err)) } if req.FullName != nil { if err := val.ValidateFullName(req.GetFullName()); err != nil { violations = append(violations, fieldViolation("full_name", err)) } } if req.Password != nil { if err := val.ValidatePassword(req.GetPassword()); err != nil { violations = append(violations, fieldViolation("password", err)) } } if req.Email != nil { if err := val.ValidateEmail(req.GetEmail()); err != nil { violations = append(violations, fieldViolation("email", err)) } } return violations } func unauthenticatedError(err error) error { return status.Errorf(codes.Unauthenticated, "unauthenticated: %v", err) }