继上一篇添加数据库后,本篇新增删除用户功能
效果:点击提交后,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,正在慢慢优化。。。