继上一篇添加数据库后,本篇新增删除用户功能
Go语言之Gin框架,实现在web界面添加、删除vfstp用户功能(三)_删除用户
效果:点击提交后,vsftp用户将被删除
main.go内容

package main

import (
	"fmt"
	//导入打印模块
	"github.com/gin-gonic/gin"
	// 导入Gin框架
	"github.com/jinzhu/gorm"
	"net/http"
	"os"
	"os/exec"
	//导入exec linux命令模块
	_ "github.com/jinzhu/gorm/dialects/mysql"
)
var R  = gin.Default()
type UserInfo struct {
	Username string `form:"username" json:"username"`
	Password string `form:"password" json:"password"`
}
type User struct {
	gorm.Model  //gorm自带结构体,自带字段有ID、CreatedAt、UpdateAt、DeleteAt
	//ID       int64
	Name     string
	Password string   `gorm:"default:'Ftp@123.'"`
}
//更改表名为ftpuserlist
func (User) TableName() string {
	return "ftpuserlist"
}

func c2(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", nil)
	/*	r.POST("/form", func(c *gin.Context) {
		var u UserInfo
		err := c.ShouldBind(&u)
		if err != nil {
			c.JSON(http.StatusBadRequest,gin.H{
				"error": err.Error(),
			})
		}else {
			fmt.Printf("%#v\n",u)
			c.JSON(http.StatusOK,gin.H{
				"message": "ok",
			})
		}

	})*/
	//复制上面的代码,把/form改成/json即可
	R.POST("/useradd", func(c *gin.Context) {
		var u UserInfo
		err := c.ShouldBind(&u)

		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": err.Error(),
			})
		} else {
		//数据库连接
			db, err := gorm.Open("mysql", "root:root1234@(192.168.84.135:13306)/db?charset=utf8mb4&parseTime=True&loc=Local")
			if err != nil {
				panic(err)
			}
			defer db.Close()
			// 自动迁移
			db.AutoMigrate(&User{})
			//检索用户在数据库中是否存在
			var userlist User
			db.Where(&User{Name: u.Username}).Find(&userlist)
			if len(userlist.Name) != 0 {
				//若用户存在立即退出
				fmt.Printf("用户%v已存在,请重新输入!已有用户详细信息:%v", userlist.Name, userlist)
				c.JSON(http.StatusOK, gin.H{
					"message": "vsftp用户已存在",
				})
				return
			} else {
				//若不存在,在数据库中创建用户数据
				u := User{Name: u.Username, Password: u.Password}
				result := db.Create(&u)
				data := u.ID
				dataErr := result.Error
				datalist := result.RowsAffected
				fmt.Printf("第一个用户%v已创建完成,id为%v,返回错误为%v,此次插入数据库的记录条数%v\n", u.Name, data, dataErr, datalist)
				//db.Select("Name","Password","CreatedAt").Create(&u)
				//查询全部表数据
				var uall []User
				db.Find(&uall)
				fmt.Printf("全部数据:%v\n", uall)

				//查询指定字段
				/*				var nameandpassword User
								db.Select("name","password").Find(&nameandpassword)
								fmt.Printf("所有用户和密码%v\n",nameandpassword)*/

			}
			fmt.Printf("创建的用户名与密码为%v\n", u)
			c.JSON(http.StatusOK, gin.H{
				"message": "vsftp用户创建成功",
			})
		}
		ftpuser := u.Username + "\n"
		ftppassword := u.Password + "\n"

		fileObj, err := os.OpenFile("/etc/vsftpd/vsftpd_virtualuser.txt", os.O_APPEND|os.O_WRONLY, 0660)
		if err != nil {
			fmt.Println("writer file failed,err", err)
			return
		}
		defer fileObj.Close()
		fileObj.WriteString(ftpuser)
		fileObj.WriteString(ftppassword)

		sqlhandle1 := exec.Command("db_load", "-T", "-t", "hash", "-f", "/etc/vsftpd/vsftpd_virtualuser.txt", "/etc/vsftpd/vsftpd_virtualuser.db")
		chmodsql := exec.Command("chmod", "600", "/etc/vsftpd/vsftpd_virtualuser.db")
		useradd := exec.Command("useradd", "-d", "/ftp/company/"+u.Username, "FTP"+u.Username, "-s", "/sbin/nologin")
		chmoduser := exec.Command("chmod", "770", "/ftp/company/"+u.Username, "-R")
		gpasswd := exec.Command("gpasswd", "-a", "FTPcompany", "FTP"+u.Username)
		chown := exec.Command("chown", "FTP"+u.Username+":FTPcompany", "/ftp/company/"+u.Username, " -R")

		sqlhandle1.Output()
		//fmt.Println("数据库文件创建完成")
		chmodsql.Output()
		//fmt.Println("系统用户创建完毕")
		useradd.Output()
		//fmt.Println("系统用户创建完毕")
		chmoduser.Output()
		gpasswd.Output()
		chown.Output()

		fileObj1, err := os.OpenFile("/etc/vsftpd/vuserconfig/"+u.Username, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0660)
		if err != nil {
			fmt.Println("writer file failed,err", err)
			return
		}
		defer fileObj1.Close()
		fileObj1.WriteString("# 开启虚拟帐号登录\n" +
			"guest_enable=yes\n" +
			"# 设置 ftp 对应的系统帐号$addftpuser,虚拟账户将具有$addftpuser 系统用户的权限\n" +
			"guest_username=" +"FTP"+ u.Username + "\n" +
			"# 允许在文件系统写入权限\n" +
			"write_enable=yes\n" +
			"# 允许创建文件夹\n" +
			"anon_mkdir_write_enable=yes\n" +
			"# 限定传输速率为 5000KB/s\n" +
			"anon_max_rate=5000000\n" +
			"# 如果设置了可写权限,要加上配置项\n" +
			"allow_writeable_chroot=yes\n" +
			"# 默认家目录,可以修改\n" +
			"local_root=/ftp/company/" + u.Username + "\n" +
			"# 下载文件和目录权限\n" +
			"anon_world_readable_only=NO\n" +
			"# 创建文件和目录权限\n" +
			"anon_upload_enable=YES\n" +
			"# 上传覆盖文件和目录权限\n" +
			"anon_other_write_enable=YES")

	})
	R.POST("/userdel", func(c *gin.Context) {
		var u UserInfo
		err := c.ShouldBind(&u)

		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": err.Error(),
			})
		} else {
		//数据库连接
			db, err := gorm.Open("mysql", "root:root1234@(192.168.84.135:13306)/db?charset=utf8mb4&parseTime=True&loc=Local")
			if err != nil {
				panic(err)
			}
			defer db.Close()
			// 自动迁移
			db.AutoMigrate(&User{})
			//检索用户在数据库中是否存在
			var userlist User
			db.Where(&User{Name: u.Username}).Find(&userlist)
			if len(userlist.Name) == 0 {
				//若用户不存在立即退出
				fmt.Printf("用户%v不存在", userlist.Name)
				c.JSON(http.StatusOK, gin.H{
					"message": "删除的vsftp用户不存在,请重新输入",
				})
				return
			} else {
				//若存在,在数据库中删除用户数据
				//数据库中软删除用户数据
				var userdel []User
				db.Where("name=?", u.Username).Delete(&userdel)
				//删除Linux系统中的数,本想着把脚本语句全部写入到一个shell脚本中,执行shell脚本即可,但是失败了,会报错:status126,并不是权限问题。这里如果不引用这个写法
				//sed命令就会执行失败,这里很诡异。
				fileObj, err := os.OpenFile("./2.sh", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0770)
				if err != nil {
					fmt.Println("writer file failed,err", err)
					return
				}
				defer fileObj.Close()
				sed := exec.Command("sed", "-i","\""+"/"+userlist.Name+"/"+","+"+1d"+"\"","/etc/vsftpd/vsftpd_virtualuser.txt")
				shell1 := fmt.Sprint(sed)
				fileObj.WriteString(shell1+"\n")
				shelltxt := `./2.sh`
				shell7 := exec.Command("/bin/bash","-c",shell1) //这里按理说是应该写shelltxt的。但是不这么写,sed命令不好用
				fmt.Println(shell7)
				output, err := shell7.Output()
				if err != nil {
					fmt.Printf("Execute Shell:%s failed with error:%s", shelltxt, err.Error())
					return
				}
				fmt.Printf("Execute Shell:%s finished with output:\n%s", shelltxt, string(output))
				sqlhandle1 := exec.Command("db_load", "-T", "-t", "hash", "-f", "/etc/vsftpd/vsftpd_virtualuser.txt", "/etc/vsftpd/vsftpd_virtualuser.db")
				sqlhandle1.Output()
				chmodsql := exec.Command("chmod", "600", "/etc/vsftpd/vsftpd_virtualuser.db")
				chmodsql.Output()
				rmdir := exec.Command("rm","-rf" ,"/etc/vsftpd/vuserconfig/"+userlist.Name)
				rmdir.Output()
				gpasswd := exec.Command("gpasswd", "-d", "FTPcompany", "FTP"+userlist.Name)
				gpasswd.Output()
				userdel1 := exec.Command("userdel","-r","FTP"+userlist.Name)
				userdel1.Output()
				fmt.Printf("已删除用户名%v\n", u.Username)
				c.JSON(http.StatusOK, gin.H{
					"message": "vsftp用户:"+userlist.Name+"删除成功",
				})
			}

		}
	})
}
func main() {
	// 引用Gin框架开始

	R.LoadHTMLFiles("./index.html")
	R.GET("/index",c2)
		R.Run(":9090")

}

index.html内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>创建用户</title>
</head>
<body>
<form action="/useradd" method="post">
    添加用户名:
    <input type="text" name="username">
    密码:
    <input type="password" name="password">
    <input type="submit" value="提交">

</form>
<form action="/userdel" method="post">
    删除用户名:
    <input type="text" name="username">
    密码:
    <input type="password" name="password">
    <input type="submit" value="提交">

</form>
</body>
</html>

运行程序:

go run main.go

这里有很多需要修改的bug,正在慢慢优化。。。