yjp 1 年間 前
コミット
acc2e200df

+ 6 - 5
convenient/domain/auth/auth.go

@@ -97,7 +97,7 @@ var permissionGroups = map[string][][]string{
 	},
 }
 
-func (simple *Simple) init(i *infrastructure.Infrastructure) {
+func (simple *Simple) init(urlPrefix string, i *infrastructure.Infrastructure) {
 	dbExecutor := i.DBExecutor()
 
 	adminUserExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
@@ -130,7 +130,7 @@ func (simple *Simple) init(i *infrastructure.Infrastructure) {
 				Base:        entity.Base{ID: permissionID},
 				Name:        perm[0],
 				Description: perm[0],
-				Resource:    perm[1],
+				Resource:    urlPrefix + perm[1],
 				Action:      perm[2],
 				UserIDFields: entity.UserIDFields{
 					CreateUserID:     adminUserID,
@@ -317,7 +317,7 @@ func (simple *Simple) bind(binder *binding.Binder) {
 			err = database.Update(dbExecutor, &sql.UpdateExecuteParams{
 				TableName: userTableName,
 				TableRow: sql.NewTableRow().Add(user.ColumnToken, token).
-					Add(user.FieldLastLoginTime, time.Now()),
+					Add(user.ColumnLastLoginTime, time.Now().Local()),
 				Conditions: sql.NewConditions().Equal(entity.ColumnID, existUser.ID),
 			})
 			if err != nil {
@@ -425,8 +425,9 @@ func (simple *Simple) bind(binder *binding.Binder) {
 }
 
 func BindAuth(app *application.App, simple *Simple) {
-	binder := binding.NewBinder(app.ChooseRouter(api.RouterPrefix, ""), app.Infrastructure())
+	prefixRootRouter := app.ChooseRouter(api.RouterPrefix, "")
+	binder := binding.NewBinder(prefixRootRouter, app.Infrastructure())
 
-	simple.init(app.Infrastructure())
+	simple.init(prefixRootRouter.BasePath(), app.Infrastructure())
 	simple.bind(binder)
 }

+ 64 - 0
convenient/domain/auth/middlewares/middlewares.go

@@ -2,11 +2,14 @@ package middlewares
 
 import (
 	"git.sxidc.com/go-framework/baize/convenient/domain/auth/jwt_tools"
+	"git.sxidc.com/go-framework/baize/convenient/domain/auth/permission"
+	"git.sxidc.com/go-framework/baize/convenient/domain/auth/role"
 	"git.sxidc.com/go-framework/baize/convenient/domain/auth/user"
 	"git.sxidc.com/go-framework/baize/framework/binding"
 	"git.sxidc.com/go-framework/baize/framework/core/api"
 	"git.sxidc.com/go-framework/baize/framework/core/api/response"
 	"git.sxidc.com/go-framework/baize/framework/core/domain"
+	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/sql"
@@ -68,6 +71,67 @@ func Authentication(dbSchema string, jwtSecretKey string) binding.Middleware {
 			return
 		}
 
+		// 获取用户的角色
+		roleIDResults, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{
+			TableName:     domain.RelationTableName(dbSchema, &user.Entity{}, &role.Entity{}),
+			SelectColumns: []string{domain.RelationColumnName(&role.Entity{})},
+			Conditions:    sql.NewConditions().Equal(domain.RelationColumnName(&user.Entity{}), userInfo.GetID()),
+			PageNo:        0,
+			PageSize:      0,
+		})
+		if err != nil {
+			respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error()))
+			c.Abort()
+			return
+		}
+
+		if totalCount == 0 {
+			respFunc(c, http.StatusUnauthorized, nil, errors.New("用户没有权限访问该资源: 没有分配角色"))
+			c.Abort()
+			return
+		}
+
+		roleIDs := make([]string, 0)
+		for _, roleIDResult := range roleIDResults {
+			roleIDs = append(roleIDs, roleIDResult.ColumnValueString(domain.RelationColumnName(&role.Entity{})))
+		}
+
+		// 查找权限
+		permissionIDResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
+			TableName:     domain.TableName(dbSchema, &permission.Entity{}),
+			SelectColumns: []string{entity.ColumnID},
+			Conditions: sql.NewConditions().Equal(permission.ColumnResource, c.FullPath()).
+				Equal(permission.ColumnAction, c.Request.Method),
+		})
+		if err != nil {
+			if database.IsErrorDBRecordNotExist(err) {
+				respFunc(c, http.StatusUnauthorized, nil, errors.New("用户没有权限访问该资源: 没有分配权限"))
+			} else {
+				respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error()))
+			}
+
+			c.Abort()
+			return
+		}
+
+		// 查询用户权限
+		permissionExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
+			TableName: domain.RelationTableName(dbSchema, &role.Entity{}, &permission.Entity{}),
+			Conditions: sql.NewConditions().In(domain.RelationColumnName(&role.Entity{}), roleIDs).
+				Equal(domain.RelationColumnName(&permission.Entity{}), permissionIDResult.ColumnValueString(entity.ColumnID)),
+		})
+		if err != nil {
+			respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error()))
+			c.Abort()
+			return
+		}
+
+		if !permissionExist {
+			respFunc(c, http.StatusUnauthorized, nil, errors.New("用户没有权限访问该资源: 角色中没有该权限"))
+			c.Abort()
+			return
+		}
+
 		// 设置用户上下文
 		c.SetUserInfo(userInfo)
 

+ 77 - 82
framework/binding/bind_item.go

@@ -52,108 +52,103 @@ func (item *BindItem[O]) bind(binder *Binder, middlewares ...Middleware) {
 		}
 	}
 
-	// 给单个路由增加中间件
-	handlers := []api.Handler{
-		func(c *api.Context) {
-			var params request.Params
-
-			// 有请求数据
-			if item.RequestParams != nil {
-				requestParamsType := reflect.TypeOf(item.RequestParams)
-				if !reflectutils.IsTypeStructOrStructPointer(requestParamsType) {
-					item.SendResponseFunc(c, http.StatusOK, outputZero, errors.New("请求参数不是结构或结构指针"))
-					return
-				}
+	apiMiddlewares := make([]api.Handler, len(middlewares))
+	for i, middleware := range middlewares {
+		innerMiddleware := middleware
+		apiMiddlewares[i] = func(c *api.Context) {
+			innerMiddleware(c, binder.i)
+		}
+	}
 
-				if requestParamsType.Kind() == reflect.Pointer {
-					params = reflect.New(requestParamsType.Elem()).Interface().(request.Params)
-				} else {
-					params = reflect.New(requestParamsType).Interface().(request.Params)
-				}
+	handlers := append(apiMiddlewares, func(c *api.Context) {
+		var params request.Params
 
-				// 将请求数据解析到请求参数中
-				if item.BindRequestParamsFunc != nil {
-					err := item.BindRequestParamsFunc(c, params)
+		// 有请求数据
+		if item.RequestParams != nil {
+			requestParamsType := reflect.TypeOf(item.RequestParams)
+			if !reflectutils.IsTypeStructOrStructPointer(requestParamsType) {
+				item.SendResponseFunc(c, http.StatusOK, outputZero, errors.New("请求参数不是结构或结构指针"))
+				return
+			}
+
+			if requestParamsType.Kind() == reflect.Pointer {
+				params = reflect.New(requestParamsType.Elem()).Interface().(request.Params)
+			} else {
+				params = reflect.New(requestParamsType).Interface().(request.Params)
+			}
+
+			// 将请求数据解析到请求参数中
+			if item.BindRequestParamsFunc != nil {
+				err := item.BindRequestParamsFunc(c, params)
+				if err != nil {
+					item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
+					return
+				}
+			} else {
+				switch item.Method {
+				case http.MethodPost:
+					fallthrough
+				case http.MethodPut:
+					err := request.BindJsonBody(c, params)
 					if err != nil {
 						item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
 						return
 					}
-				} else {
-					switch item.Method {
-					case http.MethodPost:
-						fallthrough
-					case http.MethodPut:
-						err := request.BindJsonBody(c, params)
-						if err != nil {
-							item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
-							return
-						}
-					case http.MethodDelete:
-						fallthrough
-					case http.MethodGet:
-						err := request.BindQueryParams(c, params)
-						if err != nil {
-							item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
-							return
-						}
+				case http.MethodDelete:
+					fallthrough
+				case http.MethodGet:
+					err := request.BindQueryParams(c, params)
+					if err != nil {
+						item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
+						return
 					}
 				}
 			}
+		}
 
-			// 进行领域对象转化
-			var domainObjects []domain.Object
-			if item.FormDomainObjectsFunc != nil {
-				innerDomainObjects, err := item.FormDomainObjectsFunc(c, params)
-				if err != nil {
-					item.SendResponseFunc(c, http.StatusOK, outputZero, err)
-					return
-				}
+		// 进行领域对象转化
+		var domainObjects []domain.Object
+		if item.FormDomainObjectsFunc != nil {
+			innerDomainObjects, err := item.FormDomainObjectsFunc(c, params)
+			if err != nil {
+				item.SendResponseFunc(c, http.StatusOK, outputZero, err)
+				return
+			}
 
-				domainObjects = innerDomainObjects
-			} else {
-				if item.Objects != nil && len(item.Objects) != 0 {
-					for _, object := range item.Objects {
-						if object == nil {
-							continue
-						}
+			domainObjects = innerDomainObjects
+		} else {
+			if item.Objects != nil && len(item.Objects) != 0 {
+				for _, object := range item.Objects {
+					if object == nil {
+						continue
+					}
 
-						objectType := reflect.TypeOf(object)
-						if !reflectutils.IsTypeStructOrStructPointer(objectType) {
-							item.SendResponseFunc(c, http.StatusOK, outputZero, errors.New("领域对象不是结构或结构指针"))
-							return
-						}
+					objectType := reflect.TypeOf(object)
+					if !reflectutils.IsTypeStructOrStructPointer(objectType) {
+						item.SendResponseFunc(c, http.StatusOK, outputZero, errors.New("领域对象不是结构或结构指针"))
+						return
+					}
 
-						obj := reflect.New(reflectutils.PointerTypeElem(objectType)).Interface().(domain.Object)
+					obj := reflect.New(reflectutils.PointerTypeElem(objectType)).Interface().(domain.Object)
 
-						if params != nil {
-							err := request.AssignRequestParamsToDomainObject(params, obj)
-							if err != nil {
-								item.SendResponseFunc(c, http.StatusOK, outputZero, err)
-								return
-							}
+					if params != nil {
+						err := request.AssignRequestParamsToDomainObject(params, obj)
+						if err != nil {
+							item.SendResponseFunc(c, http.StatusOK, outputZero, err)
+							return
 						}
-
-						domainObjects = append(domainObjects, obj)
 					}
+
+					domainObjects = append(domainObjects, obj)
 				}
 			}
-
-			// 执行业务函数
-			outputModel, err := item.ServiceFunc(c, params, domainObjects, binder.i)
-			item.SendResponseFunc(c, http.StatusOK, outputModel, err)
-			return
-		},
-	}
-
-	apiMiddlewares := make([]api.Handler, len(middlewares))
-	for i, middleware := range middlewares {
-		innerMiddleware := middleware
-		apiMiddlewares[i] = func(c *api.Context) {
-			innerMiddleware(c, binder.i)
 		}
-	}
 
-	handlers = append(handlers, apiMiddlewares...)
+		// 执行业务函数
+		outputModel, err := item.ServiceFunc(c, params, domainObjects, binder.i)
+		item.SendResponseFunc(c, http.StatusOK, outputModel, err)
+		return
+	})
 
 	// 所有的函数加入到执行链中
 	binder.router.AddRoute(item.Method, item.Path, handlers...)

+ 1 - 1
framework/core/infrastructure/database/sql/value.go

@@ -9,7 +9,7 @@ import (
 )
 
 const (
-	timeWriteFormat = time.DateTime + ".000000 +08:00"
+	timeWriteFormat = time.DateTime + ".000000+08"
 )
 
 func toSqlValue(value any) (string, error) {