package controllers import ( "58team_blog/internal/application/commands" "58team_blog/internal/application/queries" "58team_blog/internal/application/services" "58team_blog/internal/interfaces/api/mapper" "58team_blog/internal/interfaces/api/requests" "58team_blog/internal/interfaces/api/responses" "58team_blog/internal/utils" "log" "net/http" "strings" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type UserController struct { adminName string adminPass string service *services.UserService } func CreateUserController(service *services.UserService, adminName string, adminPass string) UserController { return UserController{ service: service, adminName: adminName, adminPass: adminPass, } } // @Summary Login // @Description Login user into system // @Tags user // @Accept json // @Produce json // @Param request body requests.LoginUserRequest true "User login data" // @Success 200 // @Failure 400 {object} responses.ErrorResponse // @Failure 401 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /login [post] func (r *UserController) Login(c *gin.Context) { session := sessions.Default(c) var request requests.LoginUserRequest if err := c.BindJSON(&request); err != nil { log.Println("User invalid request: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, err.Error()) c.JSON(resp.ErrorCode, resp) return } // Check admin login if request.Username == r.adminName && request.Password == r.adminPass { session.Set("user", uuid.NewString()) if err := session.Save(); err != nil { log.Println("User save session error: ", err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") c.JSON(resp.ErrorCode, resp) return } c.Status(http.StatusOK) return } user, err := r.service.FindByName(queries.UserFindByNameQuery{Name: request.Username}) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } pass, err := utils.EncryptPassword(request.Password) if err != nil { log.Println("User encrypt password error: ", err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") c.JSON(resp.ErrorCode, resp) return } if utils.CheckPassword(user.Result.Password, pass) { log.Println("Pass ", user.Result.Password, " != ", pass) resp := responses.CreateErrorResponse(http.StatusUnauthorized, "Authentication error") c.JSON(resp.ErrorCode, resp) return } session.Set("user", user.Result.Id.String()) if err := session.Save(); err != nil { log.Println("User save session error: ", err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") c.JSON(resp.ErrorCode, resp) return } c.Status(http.StatusOK) } // @Summary Create new user // @Description Creates new user in system // @Tags user // @Produce json // @Success 200 // @Failure 400 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /logout [get] // @Security BasicAuth func (r *UserController) Logout(c *gin.Context) { session := sessions.Default(c) user := session.Get("user") if user == nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid session token"}) return } session.Delete("user") if err := session.Save(); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save session"}) return } c.Status(http.StatusOK) } // @Summary Create new user // @Description Creates new user in system // @Tags user // @Accept json // @Produce json // @Param request body requests.CreateUserRequest true "User data" // @Success 201 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 409 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /team/ [post] // @Security BasicAuth func (r *UserController) Post(c *gin.Context) { var request requests.CreateUserRequest if err := c.BindJSON(&request); err != nil { log.Println("User invalid request: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, err.Error()) c.JSON(resp.ErrorCode, resp) return } encrypted_password, err := utils.EncryptPassword(request.Password) if err != nil { log.Println("User encrypt password error: ", err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") c.JSON(resp.ErrorCode, resp) return } cmd := commands.CreateUserCommand{ Username: request.Username, Password: encrypted_password, Role: request.Role, Name: request.Name, Speciality: request.Speciality, Description: request.Description, Skills: strings.Join(request.Skills, ";"), Avatar: request.Avatar, JoinDate: request.JoinDate, Projects: strings.Join(request.Projects, ";"), Motto: request.Motto, } user, err := r.service.Create(cmd) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserResult(user) c.JSON(http.StatusCreated, response) } // @Summary Find user by id // @Description Find user by id // @Tags user // @Accept json // @Produce json // @Param id path string true "user id" // @Success 200 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /team/{id} [get] func (r *UserController) FindById(c *gin.Context) { id_path := c.Param("id") id, err := uuid.Parse(id_path) if err != nil { log.Println("User id error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user id") c.JSON(resp.ErrorCode, resp) return } query := queries.UserFindByIdQuery{ Id: id, } user, err := r.service.FindById(query) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserFindByIdResult(user) c.JSON(http.StatusOK, response) } // @Summary Find user by username // @Description Find user by username // @Tags user // @Accept json // @Produce json // @Param name path string true "User name" // @Success 200 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /team/name/{name} [get] func (r *UserController) FindByName(c *gin.Context) { name := c.Param("name") query := queries.UserFindByNameQuery{ Name: name, } user, err := r.service.FindByName(query) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserFindByNameResult(user) c.JSON(http.StatusOK, response) } // @Summary Get all users // @Description Return all registered users // @Tags user // @Produce json // @Success 200 {object} responses.UserResponseList // @Failure 400 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /members/ [get] func (r *UserController) GetAll(c *gin.Context) { users, err := r.service.GetAll() if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } resp := mapper.ResponseFromUserGetAllResult(users) c.JSON(http.StatusOK, resp) } // @Summary Change user // @Description Change the user's name and password // @Tags user // @Accept json // @Produce json // @Param id path string true "User id" // @Param request body requests.PutUserRequest true "User data" // @Success 200 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /team/{id} [put] // @Security BasicAuth func (r *UserController) Put(c *gin.Context) { var request requests.PutUserRequest id_path := c.Param("id") id, err := uuid.Parse(id_path) if err != nil { log.Println("User id error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user ID") c.JSON(resp.ErrorCode, resp) return } if err := c.BindJSON(&request); err != nil { log.Println("User request error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, err.Error()) c.JSON(resp.ErrorCode, resp) return } password, err := utils.EncryptPassword(request.Password) if err != nil { log.Println("User password encrypt error: ", err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") c.JSON(resp.ErrorCode, resp) return } skills := strings.Join(request.Skills, ";") projects := strings.Join(request.Projects, ";") cmd := commands.UpdateUserCommand{ Id: id, Username: request.Username, Name: request.Name, Password: password, Role: request.Role, Speciality: request.Speciality, Description: request.Description, Skills: skills, Avatar: request.Avatar, Projects: projects, Motto: request.Motto, } user, err := r.service.Update(cmd) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserResult(user) c.JSON(http.StatusOK, response) } // @Summary Delete user // @Description Delete user // @Tags user // @Produce json // @Param id path string true "User id" // @Success 200 // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /team/{id} [delete] // @Security BasicAuth func (r *UserController) Delete(c *gin.Context) { id_path := c.Param("id") id, err := uuid.Parse(id_path) if err != nil { log.Println("User id error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user id") c.JSON(resp.ErrorCode, resp) return } cmd := commands.DeleteUserCommand{ Id: id, } if err := r.service.Delete(cmd); err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } c.Status(http.StatusOK) }