feat(user): add user modification API and handler
implement user modification functionality including: - new endpoint /userMgr/modify - database update function DBUpdateUser - request/response structures - handler with proper authentication and validation - updated API documentation - marked as completed in README checklist
This commit is contained in:
@@ -62,7 +62,8 @@ For detailed API documentation, please see [docs/api.md](docs/api.md)
|
|||||||
- [x] Add Windows boot service support
|
- [x] Add Windows boot service support
|
||||||
- [x] Add session list API
|
- [x] Add session list API
|
||||||
- [x] Add session management API
|
- [x] Add session management API
|
||||||
- [ ] Add user config modify API
|
- [x] Add user config modify API
|
||||||
|
- [x] Add user type modify API
|
||||||
- [x] Add frpc instance running status management API
|
- [x] Add frpc instance running status management API
|
||||||
- [x] Add frpc instance log display API
|
- [x] Add frpc instance log display API
|
||||||
- [x] Fix random database lock when processing logs
|
- [x] Fix random database lock when processing logs
|
||||||
|
|||||||
+13
@@ -346,6 +346,19 @@ func DBQuerySpecificUser(userID int) (User, error) { // Query user by ID
|
|||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DBUpdateUser(userID int, username, passwd string) error {
|
||||||
|
var err error
|
||||||
|
if passwd == "" {
|
||||||
|
_, err = db.Exec("UPDATE userLogin SET username = ? WHERE userID = ?", username, userID)
|
||||||
|
} else {
|
||||||
|
_, err = db.Exec("UPDATE userLogin SET username = ?, passwd = ? WHERE userID = ?", username, passwd, userID)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update user: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func DBUpdateUserType (userID int, newType string) error {
|
func DBUpdateUserType (userID int, newType string) error {
|
||||||
_, err := db.Exec("UPDATE userLogin SET type = ? WHERE userID = ?", newType, userID)
|
_, err := db.Exec("UPDATE userLogin SET type = ? WHERE userID = ?", newType, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+33
@@ -277,6 +277,39 @@ X-Timestamp: 1704067200000
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Modify User
|
||||||
|
|
||||||
|
**Endpoint**: `/userMgr/modify`
|
||||||
|
**Method**: POST
|
||||||
|
**Content-Type**: application/json
|
||||||
|
**Auth Required**: Yes (token)
|
||||||
|
**Permission Level**: visitor
|
||||||
|
|
||||||
|
**Request Headers**:
|
||||||
|
```
|
||||||
|
X-Token: your_token
|
||||||
|
X-Timestamp: 1704067200000
|
||||||
|
```
|
||||||
|
|
||||||
|
**Request Body**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"userID": 1,
|
||||||
|
"username": "user123",
|
||||||
|
"passwd": "NewPass123!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "User updated successfully"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Modify User Type
|
## Modify User Type
|
||||||
|
|
||||||
**Endpoint**: `/userMgr/modifyType`
|
**Endpoint**: `/userMgr/modifyType`
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func setupRoutes() {
|
|||||||
http.HandleFunc("/userMgr/create", CreateUserHandler)
|
http.HandleFunc("/userMgr/create", CreateUserHandler)
|
||||||
http.HandleFunc("/userMgr/remove", RemoveUserHandler)
|
http.HandleFunc("/userMgr/remove", RemoveUserHandler)
|
||||||
http.HandleFunc("/userMgr/list", ListUserHandler)
|
http.HandleFunc("/userMgr/list", ListUserHandler)
|
||||||
|
http.HandleFunc("/userMgr/modify", ModifyUserHandler)
|
||||||
http.HandleFunc("/userMgr/modifyType", ModifyUserTypeHandler)
|
http.HandleFunc("/userMgr/modifyType", ModifyUserTypeHandler)
|
||||||
|
|
||||||
http.HandleFunc("/sessionMgr/list", ListActiveSessionsHandler)
|
http.HandleFunc("/sessionMgr/list", ListActiveSessionsHandler)
|
||||||
|
|||||||
+57
-7
@@ -25,6 +25,12 @@ type CreateUserRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ModifyUserRequest struct {
|
type ModifyUserRequest struct {
|
||||||
|
UserID int `json:"userID"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Passwd string `json:"passwd"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyUserTypeRequest struct {
|
||||||
UserID int `json:"userID"`
|
UserID int `json:"userID"`
|
||||||
Type string `json:"newType"`
|
Type string `json:"newType"`
|
||||||
}
|
}
|
||||||
@@ -315,11 +321,10 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
postLog.Info(fmt.Sprintf("[CreateUserHandler] User \"%s\" created successfully with ID: %d", req.Username, userID))
|
postLog.Info(fmt.Sprintf("[CreateUserHandler] User \"%s\" created successfully with ID: %d", req.Username, userID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ModifyUserTypeHandler (w http.ResponseWriter, r *http.Request) {
|
func ModifyUserHandler (w http.ResponseWriter, r *http.Request) {
|
||||||
_, err := Auth(w, r, http.MethodPost, "superuser")
|
_, err := Auth(w, r, http.MethodPost, "user", "admin", "superuser")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
SendErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("Auth failed: %v", err))
|
||||||
postLog.Warning(fmt.Sprintf("[ModifyUserHandler] Auth failed: %v", err))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,23 +343,68 @@ func ModifyUserTypeHandler (w http.ResponseWriter, r *http.Request) {
|
|||||||
postLog.Warning(fmt.Sprintf("[ModifyUserHandler] Invalid request format: %v", err))
|
postLog.Warning(fmt.Sprintf("[ModifyUserHandler] Invalid request format: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.UserID == 0 {
|
if req.UserID == 0 {
|
||||||
SendErrorResponse(w, http.StatusBadRequest, "UserID is required")
|
SendErrorResponse(w, http.StatusBadRequest, "UserID is required")
|
||||||
postLog.Warning("[ModifyUserHandler] ModifyUser failed: UserID is empty")
|
postLog.Warning("[ModifyUserHandler] ModifyUser failed: UserID is empty")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.Username == "" {
|
||||||
|
SendErrorResponse(w, http.StatusBadRequest, "Username is required")
|
||||||
|
postLog.Warning("[ModifyUserHandler] ModifyUser failed: username is empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DBUpdateUser(req.UserID, req.Username, req.Passwd); err != nil {
|
||||||
|
SendErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||||
|
postLog.Error(fmt.Sprintf("[ModifyUserHandler] Failed to update user [%d]: %v", req.UserID, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
SendSuccessResponse(w, "User updated successfully", nil)
|
||||||
|
postLog.Info(fmt.Sprintf("[ModifyUserHandler] User [%d]%s updated successfully to: %s", req.UserID, GetUsernameByID(req.UserID), req.Username))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ModifyUserTypeHandler (w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, err := Auth(w, r, http.MethodPost, "superuser")
|
||||||
|
if err != nil {
|
||||||
|
SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||||
|
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] Auth failed: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||||
|
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] Failed to read request body: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
var req ModifyUserTypeRequest
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &req); err != nil {
|
||||||
|
SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
||||||
|
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] Invalid request format: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.UserID == 0 {
|
||||||
|
SendErrorResponse(w, http.StatusBadRequest, "UserID is required")
|
||||||
|
postLog.Warning("[ModifyUserTypeHandler] ModifyUserType failed: UserID is empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
if req.Type != "admin" && req.Type != "visitor" && req.Type != "superuser" {
|
if req.Type != "admin" && req.Type != "visitor" && req.Type != "superuser" {
|
||||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid type: must be 'admin' or 'visitor' or 'superuser'")
|
SendErrorResponse(w, http.StatusBadRequest, "Invalid type: must be 'admin' or 'visitor' or 'superuser'")
|
||||||
postLog.Warning(fmt.Sprintf("[ModifyUserHandler] ModifyUser failed: invalid type: %s", req.Type))
|
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] ModifyUserType failed: invalid type: %s", req.Type))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := DBUpdateUserType(req.UserID, req.Type); err != nil {
|
if err := DBUpdateUserType(req.UserID, req.Type); err != nil {
|
||||||
SendErrorResponse(w, http.StatusInternalServerError, err.Error())
|
SendErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||||
postLog.Error(fmt.Sprintf("[ModifyUserHandler] Failed to update user type [%d]: %v", req.UserID, err))
|
postLog.Error(fmt.Sprintf("[ModifyUserTypeHandler] Failed to update user type [%d]: %v", req.UserID, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
SendSuccessResponse(w, "User type updated successfully", nil)
|
SendSuccessResponse(w, "User type updated successfully", nil)
|
||||||
postLog.Info(fmt.Sprintf("[ModifyUserHandler] User [%d]%s type updated successfully to: %s", req.UserID, GetUsernameByID(req.UserID), req.Type))
|
postLog.Info(fmt.Sprintf("[ModifyUserTypeHandler] User [%d]%s type updated successfully to: %s", req.UserID, GetUsernameByID(req.UserID), req.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveUserHandler(w http.ResponseWriter, r *http.Request) {
|
func RemoveUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
Reference in New Issue
Block a user