diff --git a/pkg/api/api.go b/pkg/api/api.go index 9049b09..ebfedc5 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -83,8 +83,11 @@ func NewAPI(config Config) (*API, error) { apiMux.HandleFunc("/login", api.HandleLogin) apiMux.HandleFunc("/register", api.HandleRegister) apiMux.HandleFunc("/logout", api.LoginAsAnonymous) + apiMux.HandleFunc("/get_user_info", api.HandleGetUserInfo) apiMux.HandleFunc("/get_users", api.HandleGetUsers) apiMux.HandleFunc("/update_user_active", api.HandleUpdateUserActive) + apiMux.HandleFunc("/update_username", api.HandleUpdateUsername) + apiMux.HandleFunc("/update_user_password", api.HandleUpdateUserPassword) // tag apiMux.HandleFunc("/get_tags", api.HandleGetTags) apiMux.HandleFunc("/get_tag_info", api.HandleGetTagInfo) diff --git a/pkg/api/handle_error.go b/pkg/api/handle_error.go index 347dc2a..e0fe2d0 100644 --- a/pkg/api/handle_error.go +++ b/pkg/api/handle_error.go @@ -13,6 +13,7 @@ var ( ErrEmpty = errors.New("Empty field detected, please fill in all fields") ErrAnonymous = errors.New("Anonymous user detected, please login") ErrNotActive = errors.New("User is not active") + ErrWrongPassword = errors.New("Wrong password") ) type Error struct { diff --git a/pkg/api/handle_user.go b/pkg/api/handle_user.go index cabe04f..f8f5adf 100644 --- a/pkg/api/handle_user.go +++ b/pkg/api/handle_user.go @@ -245,3 +245,125 @@ func (api *API) HandleUpdateUserActive(w http.ResponseWriter, r *http.Request) { } api.HandleOK(w, r) } + +type UpdateUsernameRequest struct { + ID int64 `json:"id"` + Username string `json:"username"` +} + +func (api *API) HandleUpdateUsername(w http.ResponseWriter, r *http.Request) { + req := &UpdateUsernameRequest{} + + err := json.NewDecoder(r.Body).Decode(req) + if err != nil { + api.HandleError(w, r, err) + return + } + + user, err := api.Db.GetUserById(req.ID) + if err != nil { + api.HandleError(w, r, err) + return + } + + userID, err := api.GetUserID(w, r) + if err != nil { + api.HandleError(w, r, err) + return + } + + if user.ID != userID && user.Role != database.RoleAdmin { + api.HandleError(w, r, ErrNotAdmin) + return + } + + err = api.Db.UpdateUsername(req.ID, req.Username) + if err != nil { + api.HandleError(w, r, err) + return + } + + api.HandleOK(w, r) +} + +type GetUserInfoRequest struct { + ID int64 `json:"id"` +} + +type GetUserInfoResponse struct { + User *database.User `json:"user"` +} + +func (api *API) HandleGetUserInfo(w http.ResponseWriter, r *http.Request) { + req := &GetUserInfoRequest{} + err := json.NewDecoder(r.Body).Decode(req) + if err != nil { + api.HandleError(w, r, err) + return + } + + user, err := api.Db.GetUserById(req.ID) + if err != nil { + api.HandleError(w, r, err) + return + } + + ret := &GetUserInfoResponse{ + User: user, + } + + err = json.NewEncoder(w).Encode(ret) + if err != nil { + api.HandleError(w, r, err) + return + } +} + +type UpdateUserPasswordRequest struct { + ID int64 `json:"id"` + OldPassword string `json:"old_password"` + NewPassword string `json:"new_password"` +} + +func (api *API) HandleUpdateUserPassword(w http.ResponseWriter, r *http.Request) { + req := &UpdateUserPasswordRequest{} + err := json.NewDecoder(r.Body).Decode(req) + if err != nil { + api.HandleError(w, r, err) + return + } + + user, err := api.Db.GetUserById(req.ID) + if err != nil { + api.HandleError(w, r, err) + return + } + + userID, err := api.GetUserID(w, r) + if err != nil { + api.HandleError(w, r, err) + return + } + + currentUser, err := api.Db.GetUserById(userID) + if err != nil { + api.HandleError(w, r, err) + return + } + + if currentUser.Role != database.RoleAdmin { + _, err := api.Db.Login(user.Username, req.OldPassword) + if err != nil { + api.HandleError(w, r, ErrWrongPassword) + return + } + } + + err = api.Db.UpdateUserPassword(req.ID, req.NewPassword) + if err != nil { + api.HandleError(w, r, err) + return + } + + api.HandleOK(w, r) +} diff --git a/pkg/database/method_user.go b/pkg/database/method_user.go index cb092c1..6f2a52b 100644 --- a/pkg/database/method_user.go +++ b/pkg/database/method_user.go @@ -92,3 +92,19 @@ func (database *Database) UpdateUserActive(id int64, active bool) error { } return nil } + +func (database *Database) UpdateUsername(id int64, username string) error { + _, err := database.stmt.updateUsername.Exec(username, id) + if err != nil { + return err + } + return nil +} + +func (database *Database) UpdateUserPassword(id int64, password string) error { + _, err := database.stmt.updateUserPassword.Exec(password, id) + if err != nil { + return err + } + return nil +} diff --git a/pkg/database/sql_stmt.go b/pkg/database/sql_stmt.go index fa415ac..dfb36f6 100644 --- a/pkg/database/sql_stmt.go +++ b/pkg/database/sql_stmt.go @@ -186,6 +186,10 @@ var getUserByIdQuery = `SELECT id, username, role, active, avatar_id FROM users var updateUserActiveQuery = `UPDATE users SET active = ? WHERE id = ?;` +var updateUsernameQuery = `UPDATE users SET username = ? WHERE id = ?;` + +var updateUserPasswordQuery = `UPDATE users SET password = ? WHERE id = ?;` + var getAnonymousUserQuery = `SELECT id, username, role, avatar_id FROM users WHERE role = 0 LIMIT 1;` var insertTagQuery = `INSERT INTO tags (name, description, created_by_user_id) VALUES (?, ?, ?);` @@ -283,6 +287,8 @@ type Stmt struct { getUsers *sql.Stmt getUserById *sql.Stmt updateUserActive *sql.Stmt + updateUsername *sql.Stmt + updateUserPassword *sql.Stmt getAnonymousUser *sql.Stmt insertTag *sql.Stmt getTag *sql.Stmt @@ -553,6 +559,18 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) { return nil, err } + // init updateUsername + stmt.updateUsername, err = sqlConn.Prepare(updateUsernameQuery) + if err != nil { + return nil, err + } + + // init updateUserPassword + stmt.updateUserPassword, err = sqlConn.Prepare(updateUserPasswordQuery) + if err != nil { + return nil, err + } + // init getAnonymousUser stmt.getAnonymousUser, err = sqlConn.Prepare(getAnonymousUserQuery) if err != nil { diff --git a/web/src/App.css b/web/src/App.css index 9cdbd75..68ca5ed 100644 --- a/web/src/App.css +++ b/web/src/App.css @@ -92,3 +92,8 @@ dialog { display: flex; justify-content: space-between; } +.horizontal { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} diff --git a/web/src/component/Manage.js b/web/src/component/Manage.js index 99f11c9..7857a8f 100644 --- a/web/src/component/Manage.js +++ b/web/src/component/Manage.js @@ -17,6 +17,15 @@ function Manage(props) { Login )} + {props.user.role !== 0 && ( + + )} {props.user.role !== 0 && ( +
+ setOldPassword(e.target.value)} + /> + setNewPassword(e.target.value)} + /> + setNewPasswordConfirm(e.target.value)} + /> + +
+

Reviews

+ {reviews.map((review) => ( + + ))} ); }