feat: private directory (not complete)
This commit is contained in:
parent
f0a94070d2
commit
36a0a2c78a
8 changed files with 295 additions and 191 deletions
14
app.go
14
app.go
|
@ -46,11 +46,11 @@ func main() {
|
||||||
// init auth module
|
// init auth module
|
||||||
service.NewAuthService()
|
service.NewAuthService()
|
||||||
|
|
||||||
gin := gin.Default()
|
app := gin.Default()
|
||||||
routes.New(gin, ver, apiOnly)
|
routes.New(app, ver, apiOnly)
|
||||||
|
|
||||||
fmt.Fprintf(os.Stdout, "binding server at: http://0.0.0.0:%d\n", cnf.Port)
|
fmt.Fprintf(os.Stdout, "binding server at: http://0.0.0.0:%d\n", cnf.Port)
|
||||||
if err := gin.Run(fmt.Sprintf(":%d", cnf.Port)); err != nil {
|
if err = app.Run(fmt.Sprintf(":%d", cnf.Port)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print("new password: ")
|
fmt.Print("new password: ")
|
||||||
bytePassword, err := term.ReadPassword(int(syscall.Stdin))
|
bytePassword, err := term.ReadPassword(syscall.Stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read password: %v", err)
|
return fmt.Errorf("failed to read password: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ func main() {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
fmt.Print("type new password one more time: ")
|
fmt.Print("type new password one more time: ")
|
||||||
checkByte, err := term.ReadPassword(int(syscall.Stdin))
|
checkByte, err := term.ReadPassword(syscall.Stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read password: %v", err)
|
return fmt.Errorf("failed to read password: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auth := service.NewAuthService()
|
auth := service.NewAuthService()
|
||||||
if err := auth.Create(&service.Account{Username: username, Password: password}); err != nil {
|
if err = auth.Create(&service.Account{Username: username, Password: password}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ func main() {
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := command.Execute(); err != nil {
|
if err := command.Execute(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -20,6 +20,7 @@ require (
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.25.0 // indirect
|
github.com/go-playground/validator/v10 v10.25.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.5 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -33,6 +33,8 @@ github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PU
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
|
|
@ -14,11 +14,12 @@ func BasicAuth(ctx *gin.Context) {
|
||||||
var list = []string{"/settings"}
|
var list = []string{"/settings"}
|
||||||
|
|
||||||
for _, i := range list {
|
for _, i := range list {
|
||||||
if !strings.Contains(ctx.Request.URL.Path, i) {
|
if !strings.HasPrefix(ctx.Request.URL.Path, i) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
matches = true
|
matches = true
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matches {
|
if !matches {
|
||||||
|
|
|
@ -9,116 +9,121 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func authentication(group *gin.RouterGroup) {
|
func authentication(group *gin.RouterGroup) {
|
||||||
group.POST("/login", func(ctx *gin.Context) {
|
group.POST("/login", login)
|
||||||
auth := service.NewAuthService()
|
group.GET("/read", readAcc)
|
||||||
username := ctx.PostForm("username")
|
group.PATCH("/update", updateAcc)
|
||||||
password := ctx.PostForm("password")
|
group.DELETE("/delete", deleteAcc)
|
||||||
|
}
|
||||||
|
|
||||||
acc, err := auth.Read(username)
|
func login(ctx *gin.Context) {
|
||||||
if err != nil {
|
auth := service.NewAuthService()
|
||||||
ctx.JSON(401, gin.H{
|
username := ctx.PostForm("username")
|
||||||
"ok": 0,
|
password := ctx.PostForm("password")
|
||||||
"errno": "username or password not invalid",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, err := auth.Verify(username, password)
|
acc, err := auth.Read(username)
|
||||||
if err != nil || !ok {
|
if err != nil {
|
||||||
ctx.JSON(401, gin.H{
|
ctx.JSON(401, gin.H{
|
||||||
"ok": 0,
|
"ok": 0,
|
||||||
"errno": "username or password not invalid",
|
"errno": "username or password not invalid",
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.JSON(200, gin.H{
|
|
||||||
"ok": 1,
|
|
||||||
"token": auth.Token(acc.Username, acc.Password),
|
|
||||||
})
|
})
|
||||||
})
|
return
|
||||||
|
}
|
||||||
|
|
||||||
group.GET("/read", func(ctx *gin.Context) {
|
ok, err := auth.Verify(username, password)
|
||||||
auth := service.NewAuthService()
|
if err != nil || !ok {
|
||||||
username, password, ok := ctx.Request.BasicAuth()
|
ctx.JSON(401, gin.H{
|
||||||
if !ok {
|
"ok": 0,
|
||||||
ctx.Status(401)
|
"errno": "username or password not invalid",
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, err := auth.VerifyToken(username, password)
|
|
||||||
if err != nil {
|
|
||||||
ctx.JSON(500, gin.H{
|
|
||||||
"ok": 0,
|
|
||||||
"errno": "internal server error!",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
ctx.JSON(401, gin.H{
|
|
||||||
"ok": 0,
|
|
||||||
"errno": "unauthorized",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.JSON(200, gin.H{
|
|
||||||
"ok": 1,
|
|
||||||
"username": username,
|
|
||||||
})
|
})
|
||||||
})
|
return
|
||||||
|
}
|
||||||
|
|
||||||
group.PATCH("/update", func(ctx *gin.Context) {
|
ctx.JSON(200, gin.H{
|
||||||
auth := service.NewAuthService()
|
"ok": 1,
|
||||||
old := ctx.PostForm("password")
|
"token": auth.Token(acc.Username, acc.Password),
|
||||||
new := ctx.PostForm("new_password")
|
|
||||||
username, _, ok := ctx.Request.BasicAuth()
|
|
||||||
if !ok {
|
|
||||||
ctx.Status(401)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, err := auth.Verify(username, old)
|
|
||||||
if err != nil || !ok {
|
|
||||||
ctx.Status(401)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = auth.Update(username, new); err != nil {
|
|
||||||
ctx.Status(500)
|
|
||||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Status(200)
|
|
||||||
})
|
|
||||||
|
|
||||||
group.DELETE("/delete", func(ctx *gin.Context) {
|
|
||||||
auth := service.NewAuthService()
|
|
||||||
username, password, ok := ctx.Request.BasicAuth()
|
|
||||||
if !ok {
|
|
||||||
ctx.Status(401)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, err := auth.VerifyToken(username, password)
|
|
||||||
if err != nil {
|
|
||||||
ctx.Status(500)
|
|
||||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
ctx.Status(401)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = auth.Delete(username); err != nil {
|
|
||||||
ctx.Status(500)
|
|
||||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Status(200)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readAcc(ctx *gin.Context) {
|
||||||
|
auth := service.NewAuthService()
|
||||||
|
username, password, ok := ctx.Request.BasicAuth()
|
||||||
|
if !ok {
|
||||||
|
ctx.Status(401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ok, err := auth.VerifyToken(username, password)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "internal server error!",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
ctx.JSON(401, gin.H{
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "unauthorized",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, gin.H{
|
||||||
|
"ok": 1,
|
||||||
|
"username": username,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateAcc(ctx *gin.Context) {
|
||||||
|
auth := service.NewAuthService()
|
||||||
|
old := ctx.PostForm("password")
|
||||||
|
new := ctx.PostForm("new_password")
|
||||||
|
username, _, ok := ctx.Request.BasicAuth()
|
||||||
|
if !ok {
|
||||||
|
ctx.Status(401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ok, err := auth.Verify(username, old)
|
||||||
|
if err != nil || !ok {
|
||||||
|
ctx.Status(401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = auth.Update(username, new); err != nil {
|
||||||
|
ctx.Status(500)
|
||||||
|
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Status(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteAcc(ctx *gin.Context) {
|
||||||
|
auth := service.NewAuthService()
|
||||||
|
username, password, ok := ctx.Request.BasicAuth()
|
||||||
|
if !ok {
|
||||||
|
ctx.Status(401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ok, err := auth.VerifyToken(username, password)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(500)
|
||||||
|
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
ctx.Status(401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = auth.Delete(username); err != nil {
|
||||||
|
ctx.Status(500)
|
||||||
|
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Status(200)
|
||||||
|
}
|
||||||
|
|
|
@ -16,86 +16,16 @@ func New(app *gin.Engine, version *service.Version, apiOnly bool) {
|
||||||
app.Use(middleware.BasicAuth)
|
app.Use(middleware.BasicAuth)
|
||||||
|
|
||||||
api := app.Group("/api")
|
api := app.Group("/api")
|
||||||
{
|
api.GET("/path/*path", readPath)
|
||||||
api.GET("/path/*path", func(ctx *gin.Context) {
|
api.GET("/download/*path", downloadPath)
|
||||||
worker := service.NewWorkerService()
|
|
||||||
path := ctx.Param("path")
|
|
||||||
data, err := worker.Read(path)
|
|
||||||
if err != nil {
|
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
ctx.Status(404)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !data.IsDir {
|
api.POST("/private")
|
||||||
ctx.JSON(200, gin.H{
|
|
||||||
"ok": 1,
|
|
||||||
"path": path,
|
|
||||||
"total": data.FileSize,
|
|
||||||
"is_dir": false,
|
|
||||||
"entries": nil,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
raw, err := os.ReadDir(data.Path)
|
authentication(api.Group("/auth"))
|
||||||
if err != nil {
|
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
ctx.Status(500)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
entries := make([]service.DirEntry, 0)
|
api.GET("/version", func(ctx *gin.Context) {
|
||||||
for _, entry := range raw {
|
ctx.String(200, "%s", version.String())
|
||||||
finfo, err := entry.Info()
|
})
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
entries = append(entries, service.DirEntry{
|
|
||||||
Name: entry.Name(),
|
|
||||||
Path: filepath.Join(path, entry.Name()),
|
|
||||||
Date: finfo.ModTime().Unix(),
|
|
||||||
FileSize: uint64(finfo.Size()),
|
|
||||||
IsDir: finfo.IsDir(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.JSON(200, gin.H{
|
|
||||||
"ok": 1,
|
|
||||||
"path": path,
|
|
||||||
"total": data.FileSize,
|
|
||||||
"is_dir": true,
|
|
||||||
"entries": entries,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
api.GET("/download/*path", func(ctx *gin.Context) {
|
|
||||||
worker := service.NewWorkerService()
|
|
||||||
path := ctx.Param("path")
|
|
||||||
data, err := worker.Read(path)
|
|
||||||
if err != nil {
|
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
ctx.Status(404)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.IsDir {
|
|
||||||
ctx.String(400, "current path is not file")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.FileAttachment(data.Path, data.Name)
|
|
||||||
})
|
|
||||||
|
|
||||||
auth := api.Group("/auth")
|
|
||||||
authentication(auth)
|
|
||||||
|
|
||||||
api.GET("/version", func(ctx *gin.Context) {
|
|
||||||
ctx.String(200, "%s", version.String())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if apiOnly {
|
if apiOnly {
|
||||||
return
|
return
|
||||||
|
@ -112,3 +42,78 @@ func New(app *gin.Engine, version *service.Version, apiOnly bool) {
|
||||||
ctx.File("/web/assets/favicon.ico")
|
ctx.File("/web/assets/favicon.ico")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readPath(ctx *gin.Context) {
|
||||||
|
worker := service.NewWorkerService()
|
||||||
|
path := ctx.Param("path")
|
||||||
|
// TODO: prefix detect
|
||||||
|
// if strings.HasPrefix(path, "")
|
||||||
|
|
||||||
|
data, err := worker.Read(path)
|
||||||
|
if err != nil {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
ctx.Status(404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !data.IsDir {
|
||||||
|
ctx.JSON(200, gin.H{
|
||||||
|
"ok": 1,
|
||||||
|
"path": path,
|
||||||
|
"total": data.FileSize,
|
||||||
|
"is_dir": false,
|
||||||
|
"entries": nil,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, err := os.ReadDir(data.Path)
|
||||||
|
if err != nil {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
ctx.Status(500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
entries := make([]service.DirEntry, 0)
|
||||||
|
for _, entry := range raw {
|
||||||
|
finfo, err := entry.Info()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
entries = append(entries, service.DirEntry{
|
||||||
|
Name: entry.Name(),
|
||||||
|
Path: filepath.Join(path, entry.Name()),
|
||||||
|
Date: finfo.ModTime().Unix(),
|
||||||
|
FileSize: uint64(finfo.Size()),
|
||||||
|
IsDir: finfo.IsDir(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, gin.H{
|
||||||
|
"ok": 1,
|
||||||
|
"path": path,
|
||||||
|
"total": data.FileSize,
|
||||||
|
"is_dir": true,
|
||||||
|
"entries": entries,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadPath(ctx *gin.Context) {
|
||||||
|
worker := service.NewWorkerService()
|
||||||
|
path := ctx.Param("path")
|
||||||
|
data, err := worker.Read(path)
|
||||||
|
if err != nil {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
ctx.Status(404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.IsDir {
|
||||||
|
ctx.String(400, "current path is not file")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.FileAttachment(data.Path, data.Name)
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func init() {
|
||||||
username varchar(25),
|
username varchar(25),
|
||||||
password varchar(255),
|
password varchar(255),
|
||||||
salt varchar(50),
|
salt varchar(50),
|
||||||
primary key (username)
|
constraint PK_Account_ID primary key(username)
|
||||||
);
|
);
|
||||||
`))
|
`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
90
internal/service/priv.go
Normal file
90
internal/service/priv.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrivDirService struct{}
|
||||||
|
|
||||||
|
type PrivDir struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
DirName string `json:"dirname"`
|
||||||
|
Owner string `json:"owner"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
db, err := Open()
|
||||||
|
if err != nil {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
stmt, err := db.Prepare(strings.TrimSpace(`
|
||||||
|
create table PrivDir(
|
||||||
|
id varchar(36),
|
||||||
|
dirname varchar(250) unique,
|
||||||
|
owner varchar(25),
|
||||||
|
constraint PK_PrivDir_ID primary key(id),
|
||||||
|
constraint FK_Owner_ID foreign key(owner)
|
||||||
|
references(Account.username) on update cascade on delete cascade
|
||||||
|
);
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer stmt.Close()
|
||||||
|
|
||||||
|
if _, err = stmt.Exec(); err != nil {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPrivDirService() *PrivDirService {
|
||||||
|
return &PrivDirService{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sv *PrivDirService) CreatePriv(dirname string, acc *Account) error {
|
||||||
|
db, err := Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
id := uuid.NewString()
|
||||||
|
stmt, err := db.Prepare("insert into PrivDir(id, name, owner) values (?, ?, ?);")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer stmt.Close()
|
||||||
|
|
||||||
|
_, err = stmt.Exec(id, dirname, acc.Username)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sv *PrivDirService) ReadPriv(name string) (*PrivDir, error) {
|
||||||
|
db, err := Open()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
stmt, err := db.Prepare("select * from PrivDir where name = ?;")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer stmt.Close()
|
||||||
|
|
||||||
|
row := stmt.QueryRow(name)
|
||||||
|
var data PrivDir
|
||||||
|
|
||||||
|
if err = row.Scan(&data.Id, &data.DirName, &data.Owner); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
Loading…
Reference in a new issue