Allow admins to access ticket details

This commit is contained in:
Tiago Yamamoto 2026-01-03 19:41:44 -03:00
parent 3e530516e1
commit 1ad571e1c1
3 changed files with 31 additions and 11 deletions

View file

@ -695,7 +695,7 @@ func (h *CoreHandlers) CreateTicket(w http.ResponseWriter, r *http.Request) {
// Create initial message if provided // Create initial message if provided
if req.Message != "" { if req.Message != "" {
_, _ = h.ticketService.AddMessage(r.Context(), ticket.ID, userID, req.Message) _, _ = h.ticketService.AddMessage(r.Context(), ticket.ID, userID, req.Message, false)
} }
w.WriteHeader(http.StatusCreated) w.WriteHeader(http.StatusCreated)
@ -759,7 +759,11 @@ func (h *CoreHandlers) GetTicket(w http.ResponseWriter, r *http.Request) {
} }
} }
ticket, messages, err := h.ticketService.GetTicket(r.Context(), id, userID) roleVal := r.Context().Value(middleware.ContextRoles)
roles := middleware.ExtractRoles(roleVal)
isAdmin := hasAdminRole(roles)
ticket, messages, err := h.ticketService.GetTicket(r.Context(), id, userID, isAdmin)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusNotFound) http.Error(w, err.Error(), http.StatusNotFound)
return return
@ -810,7 +814,11 @@ func (h *CoreHandlers) AddMessage(w http.ResponseWriter, r *http.Request) {
return return
} }
msg, err := h.ticketService.AddMessage(r.Context(), id, userID, req.Message) roleVal := r.Context().Value(middleware.ContextRoles)
roles := middleware.ExtractRoles(roleVal)
isAdmin := hasAdminRole(roles)
msg, err := h.ticketService.AddMessage(r.Context(), id, userID, req.Message, isAdmin)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return

View file

@ -61,15 +61,21 @@ func (s *TicketService) ListTickets(ctx context.Context, userID string) ([]model
return tickets, nil return tickets, nil
} }
func (s *TicketService) GetTicket(ctx context.Context, ticketID string, userID string) (*models.Ticket, []models.TicketMessage, error) { func (s *TicketService) GetTicket(ctx context.Context, ticketID string, userID string, isAdmin bool) (*models.Ticket, []models.TicketMessage, error) {
// 1. Get Ticket // 1. Get Ticket
queryTicket := ` queryTicket := `
SELECT id, user_id, subject, status, priority, created_at, updated_at SELECT id, user_id, subject, status, priority, created_at, updated_at
FROM tickets FROM tickets
WHERE id = $1 AND user_id = $2 WHERE id = $1
` `
args := []any{ticketID}
if !isAdmin {
queryTicket += " AND user_id = $2"
args = append(args, userID)
}
var t models.Ticket var t models.Ticket
err := s.DB.QueryRowContext(ctx, queryTicket, ticketID, userID).Scan( err := s.DB.QueryRowContext(ctx, queryTicket, args...).Scan(
&t.ID, &t.UserID, &t.Subject, &t.Status, &t.Priority, &t.CreatedAt, &t.UpdatedAt, &t.ID, &t.UserID, &t.Subject, &t.Status, &t.Priority, &t.CreatedAt, &t.UpdatedAt,
) )
if err != nil { if err != nil {
@ -106,10 +112,16 @@ func (s *TicketService) GetTicket(ctx context.Context, ticketID string, userID s
return &t, messages, nil return &t, messages, nil
} }
func (s *TicketService) AddMessage(ctx context.Context, ticketID string, userID string, message string) (*models.TicketMessage, error) { func (s *TicketService) AddMessage(ctx context.Context, ticketID string, userID string, message string, isAdmin bool) (*models.TicketMessage, error) {
// Verify ticket ownership first (or admin access, but keeping simple for now) // Verify ticket ownership first (or admin access)
var count int var count int
err := s.DB.QueryRowContext(ctx, "SELECT COUNT(*) FROM tickets WHERE id = $1 AND user_id = $2", ticketID, userID).Scan(&count) query := "SELECT COUNT(*) FROM tickets WHERE id = $1 AND user_id = $2"
args := []any{ticketID, userID}
if isAdmin {
query = "SELECT COUNT(*) FROM tickets WHERE id = $1"
args = []any{ticketID}
}
err := s.DB.QueryRowContext(ctx, query, args...).Scan(&count)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -53,7 +53,7 @@ func TestTicketService_CRUD(t *testing.T) {
WithArgs("ticket-id"). WithArgs("ticket-id").
WillReturnResult(sqlmock.NewResult(1, 1)) WillReturnResult(sqlmock.NewResult(1, 1))
msg, err := service.AddMessage(ctx, "ticket-id", "user-id", "reply") msg, err := service.AddMessage(ctx, "ticket-id", "user-id", "reply", false)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, msg) assert.NotNil(t, msg)
@ -89,7 +89,7 @@ func TestTicketService_Extended(t *testing.T) {
WillReturnRows(sqlmock.NewRows([]string{"id", "ticket_id", "user_id", "message", "created_at"}). WillReturnRows(sqlmock.NewRows([]string{"id", "ticket_id", "user_id", "message", "created_at"}).
AddRow("msg-1", "ticket-id", "user-id", "msg body", time.Now())) AddRow("msg-1", "ticket-id", "user-id", "msg body", time.Now()))
tTicket, tMsgs, err := service.GetTicket(ctx, "ticket-id", "user-id") tTicket, tMsgs, err := service.GetTicket(ctx, "ticket-id", "user-id", false)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "ticket-id", tTicket.ID) assert.Equal(t, "ticket-id", tTicket.ID)
assert.Len(t, tMsgs, 1) assert.Len(t, tMsgs, 1)