diff --git a/config/wk.yaml b/config/wk.yaml index 8341498..feb4e72 100644 --- a/config/wk.yaml +++ b/config/wk.yaml @@ -68,6 +68,7 @@ conversation: # 最近会话配置 # # 认证配置 # auth: +# on: true # 是否开启认证 # kind: 'jwt' # 认证方式 jwt: jwt认证 none: 无需认证 # # 用户配置 # #用户名:密码:资源:权限 *表示通配符 资源格式也可以是[资源ID:权限] diff --git a/internal/options/options.go b/internal/options/options.go index 3a65ea6..3fe8089 100644 --- a/internal/options/options.go +++ b/internal/options/options.go @@ -1134,6 +1134,9 @@ func (o *Options) configureAuth() { }) o.Auth.Users = usersCfgs + if len(usersCfgs) > 0 { + o.Auth.On = true + } node, err := snowflake.NewNode(int64(o.Cluster.NodeId)) if err != nil { diff --git a/internal/plugin/api.go b/internal/plugin/api.go index ecda1f7..9f33bf5 100644 --- a/internal/plugin/api.go +++ b/internal/plugin/api.go @@ -2,6 +2,7 @@ package plugin import ( "context" + "errors" "fmt" "io" "net/http" @@ -14,6 +15,8 @@ import ( "github.com/WuKongIM/WuKongIM/internal/service" "github.com/WuKongIM/WuKongIM/internal/types" "github.com/WuKongIM/WuKongIM/internal/types/pluginproto" + "github.com/WuKongIM/WuKongIM/pkg/auth" + "github.com/WuKongIM/WuKongIM/pkg/auth/resource" "github.com/WuKongIM/WuKongIM/pkg/network" "github.com/WuKongIM/WuKongIM/pkg/wkdb" "github.com/WuKongIM/WuKongIM/pkg/wkhttp" @@ -188,6 +191,12 @@ func (s *Server) handlePluginRoute(c *wkhttp.Context) { } func (s *Server) handleUpdatePluginConfig(c *wkhttp.Context) { + + if !options.G.Auth.HasPermissionWithContext(c, resource.Plugin.ConfigUpdate, auth.ActionWrite) { + c.ResponseErrorWithStatus(http.StatusForbidden, errors.New("没有权限")) + return + } + pluginNo := c.Param("plugin") var req struct { @@ -263,6 +272,12 @@ func (s *Server) handleUpdatePluginConfig(c *wkhttp.Context) { } func (s *Server) handlePluginBind(c *wkhttp.Context) { + + if !options.G.Auth.HasPermissionWithContext(c, resource.PluginUser.Add, auth.ActionWrite) { + c.ResponseErrorWithStatus(http.StatusForbidden, errors.New("没有权限")) + return + } + var req struct { PluginNo string `json:"plugin_no"` Uid string `json:"uid"` @@ -310,6 +325,12 @@ func (s *Server) handlePluginBind(c *wkhttp.Context) { } func (s *Server) handlePluginUnbind(c *wkhttp.Context) { + + if !options.G.Auth.HasPermissionWithContext(c, resource.PluginUser.Delete, auth.ActionWrite) { + c.ResponseErrorWithStatus(http.StatusForbidden, errors.New("没有权限")) + return + } + var req struct { PluginNo string `json:"plugin_no"` Uid string `json:"uid"` @@ -461,6 +482,11 @@ func (s *Server) searchPluginUsers(req wkdb.SearchPluginUserReq) ([]*pluginUserR } func (s *Server) handleUninstall(c *wkhttp.Context) { + if !options.G.Auth.HasPermissionWithContext(c, resource.Plugin.Uninstall, auth.ActionWrite) { + c.ResponseErrorWithStatus(http.StatusForbidden, errors.New("没有权限")) + return + } + var req struct { PluginNo string `json:"plugin_no"` // 插件编号 NodeId uint64 `json:"node_id"` // 插件所在节点 diff --git a/pkg/auth/resource/resource.go b/pkg/auth/resource/resource.go index fb9c58f..c1c83ae 100644 --- a/pkg/auth/resource/resource.go +++ b/pkg/auth/resource/resource.go @@ -14,6 +14,18 @@ var ClusterChannel = channel{ Stop: "clusterchannelStop", // 停止频道 } +// 插件资源 +var Plugin = plugin{ + Uninstall: "pluginUninstall", // 卸载插件 + ConfigUpdate: "pluginConfigUpdate", // 更新插件配置 +} + +// 插件用户资源 +var PluginUser = pluginUser{ + Add: "pluginUserAdd", // 添加插件用户 + Delete: "pluginUserDelete", // 删除插件用户 +} + type slot struct { Migrate Id } @@ -24,4 +36,14 @@ type channel struct { Stop Id } +type plugin struct { + Uninstall Id + ConfigUpdate Id +} + +type pluginUser struct { + Add Id + Delete Id +} + var All Id = "*" diff --git a/pkg/cluster/cluster/api_cluster.go b/pkg/cluster/cluster/api_cluster.go index 9f8a094..5d0b512 100644 --- a/pkg/cluster/cluster/api_cluster.go +++ b/pkg/cluster/cluster/api_cluster.go @@ -165,7 +165,7 @@ func (s *Server) channelClusterConfig(c *wkhttp.Context) { func (s *Server) channelStart(c *wkhttp.Context) { if !s.opts.Auth.HasPermissionWithContext(c, resource.ClusterChannel.Start, auth.ActionWrite) { - c.ResponseStatus(http.StatusUnauthorized) + c.ResponseErrorWithStatus(http.StatusForbidden, errors.New("没有权限")) return } @@ -202,7 +202,7 @@ func (s *Server) channelStart(c *wkhttp.Context) { func (s *Server) channelStop(c *wkhttp.Context) { if !s.opts.Auth.HasPermissionWithContext(c, resource.ClusterChannel.Stop, auth.ActionWrite) { - c.ResponseStatus(http.StatusUnauthorized) + c.ResponseErrorWithStatus(http.StatusForbidden, errors.New("没有权限")) return } diff --git a/pkg/cluster/cluster/api_slot.go b/pkg/cluster/cluster/api_slot.go index 1adb498..4985944 100644 --- a/pkg/cluster/cluster/api_slot.go +++ b/pkg/cluster/cluster/api_slot.go @@ -144,7 +144,7 @@ func (s *Server) slotMigrate(c *wkhttp.Context) { } if !s.opts.Auth.HasPermissionWithContext(c, resource.Slot.Migrate, auth.ActionWrite) { - c.ResponseStatus(http.StatusUnauthorized) + c.ResponseErrorWithStatus(http.StatusForbidden, errors.New("没有权限")) return } diff --git a/pkg/wkhttp/http.go b/pkg/wkhttp/http.go index 6b59bc3..fcfa8bc 100644 --- a/pkg/wkhttp/http.go +++ b/pkg/wkhttp/http.go @@ -83,6 +83,13 @@ func (c *Context) ResponseError(err error) { }) } +func (c *Context) ResponseErrorWithStatus(status int, err error) { + c.JSON(http.StatusBadRequest, gin.H{ + "msg": err.Error(), + "status": status, + }) +} + // ResponseOK 返回正确 func (c *Context) ResponseOK() { c.JSON(http.StatusOK, gin.H{