package user import ( "errors" "nixcn-cms/internal/exception" "nixcn-cms/service/service_user" "nixcn-cms/tracer" "nixcn-cms/utils" "github.com/gin-gonic/gin" "github.com/google/uuid" ) // AdminUpdate modifies another user's profile. Lv40+ only. // // @Summary Admin Update User // @Description Lv40+ operators may update any user with a strictly lower permission_level. Editable fields: all profile fields plus permission_level (new value must be below operator's own level). // @Tags User // @Accept json // @Produce json // @Security Bearer // @Param user_id path string true "Target User ID" // @Param payload body service_user.UserInfoUpdateData true "Fields to update" // @Success 200 {object} utils.RespStatus{data=nil} // @Failure 400 {object} utils.RespStatus{data=nil} "Invalid Input" // @Failure 403 {object} utils.RespStatus{data=nil} "Permission Matrix Violation" // @Failure 404 {object} utils.RespStatus{data=nil} "Target User Not Found" // @Failure 500 {object} utils.RespStatus{data=nil} "Internal Server Error" // @Router /user/update/{user_id} [patch] func (self *UserHandler) AdminUpdate(c *gin.Context) { ctx, span := tracer.StartSpan( c.Request.Context(), "api_user", "admin_update", ) defer span.End() ctx = exception.ContextWithEndpoint(ctx, exception.EndpointUserAdminUpdate) ctx = exception.ContextWithService(ctx, exception.ServiceEndpoint) operatorIdOrig, ok := c.Get("user_id") if !ok { errorCode := exception.New( exception.WithStatus(exception.StatusUser), exception.WithType(exception.TypeCommon), exception.WithOriginal(exception.CommonErrorMissingUserId), exception.WithError(errors.New("Missing UserId")), ).Throw(ctx).String() utils.HttpResponse(c, 403, errorCode) return } operatorId, err := uuid.Parse(operatorIdOrig.(string)) if err != nil { errorCode := exception.New( exception.WithStatus(exception.StatusServer), exception.WithType(exception.TypeCommon), exception.WithOriginal(exception.CommonErrorUuidParseFailed), exception.WithError(err), ).Throw(ctx).String() utils.HttpResponse(c, 500, errorCode) return } permissionLevelOrig, ok := c.Get("permission_level") if !ok { errorCode := exception.New( exception.WithStatus(exception.StatusUser), exception.WithType(exception.TypeCommon), exception.WithOriginal(exception.CommonErrorPermissionDenied), exception.WithError(errors.New("Missing PermissionLevel")), ).Throw(ctx).String() utils.HttpResponse(c, 403, errorCode) return } targetId, err := uuid.Parse(c.Param("user_id")) if err != nil { errorCode := exception.New( exception.WithStatus(exception.StatusUser), exception.WithType(exception.TypeCommon), exception.WithOriginal(exception.CommonErrorInvalidInput), exception.WithError(errors.New("invalid user_id")), ).Throw(ctx).String() utils.HttpResponse(c, 400, errorCode) return } var data service_user.UserInfoData if err := c.ShouldBindJSON(&data); err != nil { errorCode := exception.New( exception.WithStatus(exception.StatusUser), exception.WithType(exception.TypeCommon), exception.WithOriginal(exception.CommonErrorInvalidInput), exception.WithError(err), ).Throw(ctx).String() utils.HttpResponse(c, 400, errorCode) return } result := self.svc.UpdateInfo(&service_user.UserInfoPayload{ Context: ctx, UserId: targetId, OperatorId: operatorId, OperatorLevel: permissionLevelOrig.(uint), Data: &data, }) if result.Common.Exception.Original != exception.CommonSuccess { utils.HttpResponse(c, result.Common.HttpCode, result.Common.Exception.String()) return } utils.HttpResponse(c, result.Common.HttpCode, result.Common.Exception.String()) }