Skip to content

Commit f4630c4

Browse files
committed
update according to last API changes
1 parent b097b9e commit f4630c4

File tree

3 files changed

+215
-20
lines changed

3 files changed

+215
-20
lines changed

src/dao/user.go

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func NewUserDao() *UserDao {
2727
}
2828

2929
func (d *UserDao) GetUsers(c context.Context, limit *int, offset *int) []api.UserResponse {
30-
query := "SELECT username, name, surname, email FROM users LIMIT $1 OFFSET $2"
30+
query := "SELECT user_id, username, name, surname, email, role FROM users LIMIT $1 OFFSET $2"
3131
params := []any{20, 0}
3232
if limit != nil {
3333
params[0] = *limit
@@ -46,40 +46,47 @@ func (d *UserDao) GetUsers(c context.Context, limit *int, offset *int) []api.Use
4646

4747
for rows.Next() {
4848
var user api.UserResponse
49-
if err := rows.Scan(&user.Username, &user.Name, &user.Surname, &user.Email); err != nil {
49+
var roleStr string
50+
if err := rows.Scan(&user.Id, &user.Username, &user.Name, &user.Surname, &user.Email, &roleStr); err != nil {
5051
fmt.Printf("row scan error: %v\n", err.Error())
5152
continue
5253
}
54+
user.Role = api.UserResponseRole(roleStr)
5355
users = append(users, user)
5456
}
5557
return users
5658
}
5759

58-
func (d *UserDao) AddUser(c context.Context, user api.UserRequest) error {
59-
query := "INSERT INTO users (username, name, surname, email, password, role) VALUES ($1, $2, $3, $4, $5, $6)"
60-
_, err := d.db.Exec(c, query, user.Username, user.Name, user.Surname, user.Email, user.Password, user.Role)
60+
func (d *UserDao) AddUser(c context.Context, user api.UserRequest) (int64, error) {
61+
query := "INSERT INTO users (username, name, surname, email, password, role) VALUES ($1, $2, $3, $4, $5, $6) RETURNING user_id"
62+
row := d.db.QueryRow(c, query, user.Username, user.Name, user.Surname, user.Email, user.Password, user.Role)
63+
64+
var id int64
65+
err := row.Scan(&id)
6166
if err != nil {
6267
if strings.Contains(err.Error(), "UNIQUE constraint failed") {
63-
return ErrUserAlreadyExists
68+
return 0, ErrUserAlreadyExists
6469
}
65-
return fmt.Errorf("failed to add user: %w", err)
70+
return 0, fmt.Errorf("failed to add user: %w", err)
6671
}
67-
return nil
72+
return id, nil
6873
}
6974

7075
func (d *UserDao) GetUser(c context.Context, username string) (*api.UserResponse, error) {
71-
query := "SELECT username, name, surname, email FROM users WHERE username = $1"
76+
query := "SELECT user_id, username, name, surname, email, role FROM users WHERE username = $1"
7277
rows, err := d.db.Query(c, query, username)
7378
if err != nil {
7479
return nil, fmt.Errorf("db error: %w", err)
7580
}
7681
defer rows.Close()
7782

7883
var user api.UserResponse
84+
var roleStr string
7985
if rows.Next() {
80-
if err := rows.Scan(&user.Username, &user.Name, &user.Surname, &user.Email); err != nil {
86+
if err := rows.Scan(&user.Id, &user.Username, &user.Name, &user.Surname, &user.Email, &roleStr); err != nil {
8187
return nil, fmt.Errorf("failed to scan user: %w", err)
8288
}
89+
user.Role = api.UserResponseRole(roleStr)
8390
return &user, nil
8491
}
8592
return nil, ErrUserNotFound
@@ -147,9 +154,9 @@ func (d *UserDao) DeleteUser(c context.Context, username string) error {
147154
return nil
148155
}
149156

150-
func (d *UserDao) UpdateUser(c context.Context, username string, user api.UserRequest) error {
151-
query := "UPDATE users SET name = $1, surname = $2, email = $3 WHERE username = $4"
152-
result, err := d.db.Exec(c, query, user.Name, user.Surname, user.Email, username)
157+
func (d *UserDao) UpdateUser(c context.Context, username string, user api.UpdateUserRequest) error {
158+
query := "UPDATE users SET name = $1, surname = $2, email = $3, password = $4 WHERE username = $4"
159+
result, err := d.db.Exec(c, query, user.Name, user.Surname, user.Email, user.Password, username)
153160
if err != nil {
154161
if strings.Contains(err.Error(), "UNIQUE constraint failed") {
155162
return ErrUserAlreadyExists
@@ -163,3 +170,54 @@ func (d *UserDao) UpdateUser(c context.Context, username string, user api.UserRe
163170
}
164171
return nil
165172
}
173+
174+
func (d *UserDao) GetUserById(c context.Context, id int64) (*api.UserResponse, error) {
175+
query := "SELECT user_id, username, name, surname, email, role FROM users WHERE user_id = $1"
176+
rows, err := d.db.Query(c, query, id)
177+
if err != nil {
178+
return nil, fmt.Errorf("db error: %w", err)
179+
}
180+
defer rows.Close()
181+
182+
var user api.UserResponse
183+
var roleStr string
184+
if rows.Next() {
185+
if err := rows.Scan(&user.Id, &user.Username, &user.Name, &user.Surname, &user.Email, &roleStr); err != nil {
186+
return nil, fmt.Errorf("failed to scan user: %w", err)
187+
}
188+
user.Role = api.UserResponseRole(roleStr)
189+
return &user, nil
190+
}
191+
return nil, ErrUserNotFound
192+
}
193+
194+
func (d *UserDao) UpdateUserById(c context.Context, id int64, user api.UserRequest) error {
195+
query := "UPDATE users SET username = $1, name = $2, surname = $3, email = $4 WHERE user_id = $5"
196+
result, err := d.db.Exec(c, query, user.Username, user.Name, user.Surname, user.Email, id)
197+
if err != nil {
198+
if strings.Contains(err.Error(), "UNIQUE constraint failed") {
199+
return ErrUserAlreadyExists
200+
}
201+
return fmt.Errorf("failed to update user by ID: %w", err)
202+
}
203+
204+
rowsAffected := result.RowsAffected()
205+
if rowsAffected == 0 {
206+
return ErrUserNotFound
207+
}
208+
return nil
209+
}
210+
211+
func (d *UserDao) DeleteUserById(c context.Context, id int64) error {
212+
query := "DELETE FROM users WHERE user_id = $1"
213+
result, err := d.db.Exec(c, query, id)
214+
if err != nil {
215+
return fmt.Errorf("failed to delete user by ID: %w", err)
216+
}
217+
218+
rowsAffected := result.RowsAffected()
219+
if rowsAffected == 0 {
220+
return ErrUserNotFound
221+
}
222+
return nil
223+
}

src/handlers/session.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ func (h *SessionHandlers) Register(c *gin.Context) {
3333
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
3434
return
3535
}
36-
if user.Role == api.Controller || user.Role == api.Admin {
37-
c.JSON(http.StatusForbidden, gin.H{"error": "Cannot register as" + user.Role + ", permission denied"})
36+
if *user.Role == api.UserRequestRoleAdmin || *user.Role == api.UserRequestRoleController {
37+
c.JSON(http.StatusForbidden, gin.H{"error": "Cannot register as" + *user.Role + ", permission denied"})
3838
}
3939
// Check if the user already exists
4040
_, err := h.dao.GetUser(c.Request.Context(), user.Username)
@@ -43,11 +43,13 @@ func (h *SessionHandlers) Register(c *gin.Context) {
4343
return
4444
}
4545
// Add the user to the database
46-
if err := h.dao.AddUser(c.Request.Context(), user); err != nil {
46+
var id int64
47+
id, err = h.dao.AddUser(c.Request.Context(), user)
48+
if err != nil {
4749
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to add user"})
4850
return
4951
}
50-
token, err := jwt.GenerateToken(user.Username, user.Role)
52+
token, err := jwt.GenerateToken(user.Username, *user.Role)
5153
if err != nil {
5254
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
5355
return
@@ -58,6 +60,8 @@ func (h *SessionHandlers) Register(c *gin.Context) {
5860
ExpiresIn: int(jwt.TOKEN_EXPIRATION_TIME.Seconds()),
5961
TokenType: "Bearer",
6062
User: api.UserResponse{
63+
Id: id,
64+
Role: api.UserResponseRole(*user.Role),
6165
Username: user.Username,
6266
Email: user.Email,
6367
Name: user.Name,
@@ -107,10 +111,12 @@ func (h *SessionHandlers) Login(c *gin.Context) {
107111
ExpiresIn: int(jwt.TOKEN_EXPIRATION_TIME.Seconds()),
108112
TokenType: "Bearer",
109113
User: api.UserResponse{
114+
Id: user.Id,
110115
Username: user.Username,
111116
Email: user.Email,
112117
Name: user.Name,
113118
Surname: user.Surname,
119+
Role: api.UserResponseRole(role),
114120
},
115121
}
116122
c.JSON(http.StatusOK, sessionResponse)
@@ -160,10 +166,12 @@ func (h *SessionHandlers) GetSession(c *gin.Context) {
160166
ExpiresIn: int(jwt.TOKEN_EXPIRATION_TIME.Seconds()),
161167
TokenType: "Bearer",
162168
User: api.UserResponse{
169+
Id: user.Id,
163170
Username: user.Username,
164171
Email: user.Email,
165172
Name: user.Name,
166173
Surname: user.Surname,
174+
Role: api.UserResponseRole(roleStr),
167175
},
168176
}
169177
c.JSON(http.StatusOK, sessionResponse)

src/handlers/user.go

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ func (uh *UserHandlers) UpdateUser(c *gin.Context) {
143143
return
144144
}
145145

146-
var userRequest api.UserRequest
147-
if err := c.ShouldBindJSON(&userRequest); err != nil {
146+
var userUpdateRequest api.UpdateUserRequest
147+
if err := c.ShouldBindJSON(&userUpdateRequest); err != nil {
148148
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
149149
return
150150
}
151151

152-
if err := uh.dao.UpdateUser(c.Request.Context(), usernameStr, userRequest); err != nil {
152+
if err := uh.dao.UpdateUser(c.Request.Context(), usernameStr, userUpdateRequest); err != nil {
153153
if err == dao.ErrUserNotFound {
154154
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
155155
return
@@ -168,3 +168,132 @@ func (uh *UserHandlers) UpdateUser(c *gin.Context) {
168168

169169
c.JSON(http.StatusOK, gin.H{"message": "user updated successfully"})
170170
}
171+
172+
func (uh *UserHandlers) GetUserById(c *gin.Context, id int64) {
173+
username := c.Request.Context().Value("username")
174+
if username == nil {
175+
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
176+
return
177+
}
178+
_, ok := username.(string)
179+
if !ok {
180+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get username"})
181+
return
182+
}
183+
role := c.Request.Context().Value("role")
184+
if role == nil {
185+
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
186+
return
187+
}
188+
roleStr, ok := role.(string)
189+
if !ok {
190+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get role"})
191+
return
192+
}
193+
if roleStr != "admin" {
194+
c.JSON(http.StatusForbidden, gin.H{"error": "forbidden"})
195+
return
196+
}
197+
198+
user, err := uh.dao.GetUserById(c.Request.Context(), id)
199+
if err != nil {
200+
if errors.Is(err, dao.ErrUserNotFound) {
201+
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
202+
return
203+
}
204+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get user by ID"})
205+
return
206+
}
207+
208+
c.JSON(http.StatusOK, user)
209+
}
210+
211+
func (uh *UserHandlers) UpdateUserById(c *gin.Context, id int64) {
212+
username := c.Request.Context().Value("username")
213+
if username == nil {
214+
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
215+
return
216+
}
217+
_, ok := username.(string)
218+
if !ok {
219+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get username"})
220+
return
221+
}
222+
role := c.Request.Context().Value("role")
223+
if role == nil {
224+
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
225+
return
226+
}
227+
roleStr, ok := role.(string)
228+
if !ok {
229+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get role"})
230+
return
231+
}
232+
if roleStr != "admin" {
233+
c.JSON(http.StatusForbidden, gin.H{"error": "forbidden"})
234+
return
235+
}
236+
237+
var userRequest api.UserRequest
238+
if err := c.ShouldBindJSON(&userRequest); err != nil {
239+
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
240+
return
241+
}
242+
243+
if err := uh.dao.UpdateUserById(c.Request.Context(), id, userRequest); err != nil {
244+
if errors.Is(err, dao.ErrUserNotFound) {
245+
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
246+
return
247+
}
248+
if err == dao.ErrUserAlreadyExists {
249+
c.JSON(http.StatusConflict, gin.H{"error": "email already in use"})
250+
return
251+
}
252+
if errors.Is(err, dao.ErrInvalidUser) {
253+
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user data"})
254+
return
255+
}
256+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update user by ID"})
257+
return
258+
}
259+
260+
c.JSON(http.StatusOK, gin.H{"message": "user updated successfully"})
261+
}
262+
263+
func (uh *UserHandlers) DeleteUserById(c *gin.Context, id int64) {
264+
username := c.Request.Context().Value("username")
265+
if username == nil {
266+
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
267+
return
268+
}
269+
_, ok := username.(string)
270+
if !ok {
271+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get username"})
272+
return
273+
}
274+
role := c.Request.Context().Value("role")
275+
if role == nil {
276+
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
277+
return
278+
}
279+
roleStr, ok := role.(string)
280+
if !ok {
281+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get role"})
282+
return
283+
}
284+
if roleStr != "admin" {
285+
c.JSON(http.StatusForbidden, gin.H{"error": "forbidden"})
286+
return
287+
}
288+
289+
if err := uh.dao.DeleteUserById(c.Request.Context(), id); err != nil {
290+
if errors.Is(err, dao.ErrUserNotFound) {
291+
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
292+
return
293+
}
294+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to delete user by ID"})
295+
return
296+
}
297+
298+
c.JSON(http.StatusOK, gin.H{"message": "user deleted successfully"})
299+
}

0 commit comments

Comments
 (0)