Browse Source

nginx实现的权限控制,但是没有进程测试

tuonian 1 year ago
parent
commit
d115a7a0ba

+ 47 - 0
server/controllers/check.go

@@ -0,0 +1,47 @@
+package controllers
+
+import (
+	"errors"
+	"github.com/astaxie/beego/logs"
+	"github.com/astaxie/beego/orm"
+	"server/middleware"
+	"server/models"
+	"strconv"
+)
+
+// CheckNginxPermission 从path中获取nginx的参数
+func (c *BaseController) CheckNginxPermission() (*models.Nginx, error) {
+	idStr := c.getParam(":id")
+	id, err := strconv.Atoi(idStr)
+	if err != nil {
+		logs.Warn("strconv.Atoi(idStr) fail", idStr)
+		c.setCode(-1).setMsg("请传递正确的参数!").json()
+		return nil, err
+	}
+	return c.CheckNginxPermissionById(id)
+}
+
+// CheckNginxPermissionById 验证权限,如果无权操作该nginx,返回nil,否则返回
+func (c *BaseController) CheckNginxPermissionById(nginxId int) (*models.Nginx, error) {
+	current := c.RequiredUser()
+	if current == nil {
+		middleware.WriteForbidden(c.Ctx.ResponseWriter)
+		return nil, errors.New("当前未登录,无法操作")
+	}
+	if nginxId < 1 {
+		c.setCode(-1).setMsg("Nginx ID must gt 0!").json()
+		return nil, errors.New("nginx ID must gt 0!")
+	}
+	nginx := models.Nginx{Id: nginxId}
+	o := orm.NewOrm()
+	err := o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return nil, err
+	}
+	if !current.IsAdmin() && current.Account != nginx.Uid {
+		c.Forbidden()
+		return nil, errors.New("forbidden")
+	}
+	return &nginx, nil
+}

+ 4 - 0
server/controllers/default.go

@@ -102,3 +102,7 @@ func (c *BaseController) GetUser(required bool) *models.User {
 func (c *BaseController) RequiredUser() *models.User {
 	return c.GetUser(true)
 }
+
+func (c *BaseController) Forbidden() {
+	c.setCode(403).setMsg("您没有权限操作该实例!").json()
+}

+ 95 - 95
server/controllers/nginx.go

@@ -6,7 +6,6 @@ import (
 	"github.com/astaxie/beego/orm"
 	"server/models"
 	ngx "server/nginx"
-	"strconv"
 )
 
 type NginxController struct {
@@ -15,15 +14,18 @@ type NginxController struct {
 
 const ReplacePassword = "******"
 
-// Get getAll
+// Get getAll,
+// 管理员获取全部,非管理员或者自己名下的
 func (c *NginxController) Get() {
-	user := c.RequiredUser()
-	if user == nil {
+	current := c.RequiredUser()
+	if current == nil {
 		return
 	}
-
 	o := orm.NewOrm()
-	qs := o.QueryTable("nginx").Filter("Uid", user.Account)
+	qs := o.QueryTable("nginx")
+	if !current.IsAdmin() {
+		qs = qs.Filter("Uid", current.Account)
+	}
 	var list []*models.Nginx
 	_, err := qs.All(&list)
 	for i := range list {
@@ -32,7 +34,6 @@ func (c *NginxController) Get() {
 			item.Password = ReplacePassword
 		}
 	}
-
 	if err != nil {
 		c.ErrorJson(err)
 		return
@@ -43,6 +44,10 @@ func (c *NginxController) Get() {
 
 // Post add nginx instance
 func (c *NginxController) Post() {
+	current := c.RequiredUser()
+	if current == nil {
+		return
+	}
 	var nginx models.Nginx
 	err := json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
 	if err != nil {
@@ -52,29 +57,12 @@ func (c *NginxController) Post() {
 	}
 	nginx.Check()
 	o := orm.NewOrm()
-	var saveErr error
-	if nginx.Id == 0 {
-		_, err = o.Insert(&nginx)
-		saveErr = err
-	} else {
-		tmp := models.Nginx{
-			Id: nginx.Id,
-		}
-		err = o.Read(&tmp)
-		if err != nil {
-			c.ErrorJson(err)
-			return
-		}
-		if nginx.Password == ReplacePassword {
-			nginx.Password = tmp.Password
-		}
-		nginx.HttpConf = tmp.HttpConf
-		_, err = o.Update(&nginx)
-		saveErr = err
-	}
 
-	if saveErr != nil {
-		c.ErrorJson(saveErr)
+	nginx.Uid = current.Account
+	_, err = o.Insert(&nginx)
+
+	if err != nil {
+		c.ErrorJson(err)
 		return
 	}
 	logs.Info("post", nginx)
@@ -97,59 +85,95 @@ func (c *NginxController) Post() {
 	c.setData(nginx).json()
 }
 
-// StartNginx startNginx
-func (c *NginxController) StartNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
+// Update modify nginx instance
+// post /nginx/:id
+func (c *NginxController) Update() {
+
+	exist, err := c.CheckNginxPermission()
 	if err != nil {
-		c.ErrorJson(err)
 		return
 	}
-	var nginx = models.Nginx{
-		Id: id,
+
+	var nginx models.Nginx
+	err = json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
+	if err != nil {
+		logs.Error(err, string(c.Ctx.Input.RequestBody))
+		c.ErrorJson(err)
+		return
 	}
+	nginx.Id = exist.Id
+	nginx.Uid = exist.Uid
+	nginx.Check()
 	o := orm.NewOrm()
-	err = o.Read(&nginx)
+
+	if nginx.Password == ReplacePassword {
+		nginx.Password = exist.Password
+	}
+	nginx.HttpConf = exist.HttpConf
+	_, err = o.Update(&nginx)
+
 	if err != nil {
 		c.ErrorJson(err)
 		return
 	}
+	logs.Info("post", nginx)
+
 	instance := ngx.GetInstance(&nginx)
+	err = instance.Connect()
+	if err != nil {
+		c.setCode(1).setMsg(err.Error()).setData(nginx)
+		c.json()
+		return
+	}
+	out, err := instance.GetVersion()
+	if err != nil {
+		c.setCode(1).setMsg(err.Error()).setData(nginx)
+		c.json()
+		return
+	}
+	nginx.VersionInfo = out
+	_, _ = o.Update(&nginx, "VersionInfo")
+	c.setData(nginx).json()
+}
+
+// StartNginx startNginx
+// post /nginx/:id/start
+func (c *NginxController) StartNginx() {
+
+	nginx, err := c.CheckNginxPermission()
+	if err != nil {
+		return
+	}
+
+	instance := ngx.GetInstance(nginx)
 	err = instance.Start()
 	isRun, msg := instance.Status()
 	c.setData(isRun).setMsg(msg).json()
 }
 
 // StopNginx add nginx instance
+// post /nginx/:id/stop
 func (c *NginxController) StopNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-
-	var nginx = models.Nginx{
-		Id: id,
-	}
-	o := orm.NewOrm()
-	err = o.Read(&nginx)
+	nginx, err := c.CheckNginxPermission()
 	if err != nil {
-		c.ErrorJson(err)
 		return
 	}
-	instance := ngx.GetInstance(&nginx)
+	instance := ngx.GetInstance(nginx)
 	err = instance.Stop()
 	isRun, msg := instance.Status()
 	c.setData(isRun).setMsg(msg).json()
 }
 
 // RefreshHttp nginx detail data
+// post /nginx/:id/http/refresh
 func (c *NginxController) RefreshHttp() {
+	exist, err := c.CheckNginxPermission()
+	if err != nil {
+		return
+	}
+
 	var nginx models.Nginx
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
+	err = json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
 	if err != nil {
 		logs.Error(err, string(c.Ctx.Input.RequestBody))
 		c.ErrorJson(err)
@@ -165,37 +189,24 @@ func (c *NginxController) RefreshHttp() {
 			c.ErrorJson(err)
 			return
 		}
+		exist.HttpConf = nginx.HttpConf
+		exist.HttpData = nginx.HttpData
 	}
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	ins := ngx.GetInstance(&nginx)
-	err = ins.RefreshHttp(nginx)
+
+	ins := ngx.GetInstance(exist)
+	err = ins.RefreshHttp(*exist)
 	if err != nil {
 		c.ErrorJson(err)
 		return
 	}
-	c.setData(nginx)
 	c.json()
 }
 
 // GetNginx nginx detail data
+// get /nginx/:id
 func (c *NginxController) GetNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	o := orm.NewOrm()
-
-	var nginx = models.Nginx{Id: id}
-	err = o.Read(&nginx)
+	nginx, err := c.CheckNginxPermission()
 	if err != nil {
-		c.ErrorJson(err)
 		return
 	}
 	if nginx.Password != "" {
@@ -203,8 +214,10 @@ func (c *NginxController) GetNginx() {
 	}
 	c.addRespData("nginx", nginx)
 
+	o := orm.NewOrm()
+
 	var servers []models.ServerHost
-	_, err = o.QueryTable((*models.ServerHost)(nil)).Filter("NginxId", id).All(&servers)
+	_, err = o.QueryTable((*models.ServerHost)(nil)).Filter("NginxId", nginx.Id).All(&servers)
 	if err != nil {
 		c.ErrorJson(err)
 		return
@@ -214,15 +227,14 @@ func (c *NginxController) GetNginx() {
 }
 
 // DelNginx delete a instance
+// delete /nginx/:id
 func (c *NginxController) DelNginx() {
-	id, err := c.getIntParam(":id")
+	nginx, err := c.CheckNginxPermission()
 	if err != nil {
-		c.ErrorJson(err)
 		return
 	}
 	o := orm.NewOrm()
-	nginx := models.Nginx{Id: id}
-	count, err := o.Delete(&nginx)
+	count, err := o.Delete(nginx, "Id")
 	if err != nil {
 		c.ErrorJson(err)
 	} else {
@@ -230,26 +242,14 @@ func (c *NginxController) DelNginx() {
 	}
 }
 
-// StopNginx add nginx instance
+// StatusNginx add nginx instance
+// post /nginx/:id/status
 func (c *NginxController) StatusNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
+	nginx, err := c.CheckNginxPermission()
 	if err != nil {
-		c.ErrorJson(err)
 		return
 	}
-
-	var nginx = models.Nginx{
-		Id: id,
-	}
-	o := orm.NewOrm()
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	instance := ngx.GetInstance(&nginx)
+	instance := ngx.GetInstance(nginx)
 	isRun, msg := instance.Status()
 	c.setData(isRun).setMsg(msg).json()
 }

+ 12 - 0
server/models/user.go

@@ -1,5 +1,7 @@
 package models
 
+import "strings"
+
 // User 用户表
 type User struct {
 	Id int `orm:"pk;auto" json:"id"`
@@ -12,3 +14,13 @@ type User struct {
 	Password string `json:"password"`
 	Remark   string `json:"remark"`
 }
+
+func (u *User) IsAdmin() bool {
+	if len(u.Roles) == 0 {
+		return false
+	}
+	if strings.Index(strings.ToUpper(u.Roles), "ADMIN") > -1 {
+		return true
+	}
+	return false
+}

+ 2 - 1
server/routers/router.go

@@ -17,9 +17,10 @@ func init() {
 	config := config2.Config
 	ns := beego.NewNamespace(config.BaseApi,
 		beego.NSRouter("/nginx", &controllers.NginxController{}),
+		beego.NSRouter("/nginx/:id", &controllers.NginxController{}, "post:Update"),
 		beego.NSRouter("/nginx/:id", &controllers.NginxController{}, "get:GetNginx"),
 		beego.NSRouter("/nginx/:id", &controllers.NginxController{}, "delete:DelNginx"),
-		beego.NSRouter("/http/refresh", &controllers.NginxController{}, "post:RefreshHttp"),
+		beego.NSRouter("/nginx/:id/http/refresh", &controllers.NginxController{}, "post:RefreshHttp"),
 		beego.NSRouter("/nginx/:id/start", &controllers.NginxController{}, "post:StartNginx"),
 		beego.NSRouter("/nginx/:id/stop", &controllers.NginxController{}, "post:StopNginx"),
 		beego.NSRouter("/nginx/:id/status", &controllers.NginxController{}, "post:StatusNginx"),

+ 8 - 2
src/api/nginx.ts

@@ -16,13 +16,19 @@ export const NginxApis= {
   findAll: () => request.get<BaseResp<INginx[]>>('/nginx'),
   // eslint-disable-next-line @typescript-eslint/ban-ts-comment
   // @ts-ignore
-  updateOrAdd: (data: Partial<INginx>) => request.post<BaseResp<INginx>>('/nginx', data, { disableErrorMsg: true, timeout: 60000 } as any),
+  updateOrAdd: (data: Partial<INginx>) => {
+    if (data.id){
+      return request.post<BaseResp<INginx>>(`/nginx/${data.id}`, data, { disableErrorMsg: true, timeout: 60000 } as any)
+    }else {
+      return request.post<BaseResp<INginx>>('/nginx', data, { disableErrorMsg: true, timeout: 60000 } as any)
+    }
+  },
   /**
    * 同步配置文件到本地,仅需要传递id  和httpConf, httpData 三个参数
    * @param nginx
    */
   refreshHttp: (nginx: RefreshHttpData) => {
-    return request.post('/http/refresh', nginx, { timeout: 60000 })
+    return request.post(`/nginx/${nginx.id}/http/refresh`, nginx, { timeout: 60000 })
   },
   getNginx: (id:number) => request.get<BaseResp<{nginx: INginx, servers: IServerHost[]}>>(`/nginx/${id}`),
   delNginx: (id:number) => request.delete(`/nginx/${id}`),