Add initial project structure with backend and frontend setup
- Created backend structure with Go, including main application logic and API endpoints. - Added Docker support for both development and production environments. - Introduced frontend using Nuxt 3 with Tailwind CSS for styling. - Included configuration files for Docker and environment variables. - Established basic documentation for contributing, development, and deployment processes. - Set up .gitignore and .dockerignore files to manage ignored files in the repository.
This commit is contained in:
175
internal/app/manage.go
Normal file
175
internal/app/manage.go
Normal file
@@ -0,0 +1,175 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.etcd.io/bbolt"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func (a *App) index(rw http.ResponseWriter, req *http.Request) {
|
||||
s := a.getSession(req)
|
||||
if s == nil {
|
||||
http.Redirect(rw, req, "/login", 302)
|
||||
return
|
||||
}
|
||||
|
||||
tokens := []string{}
|
||||
prefix := "http://example.com"
|
||||
a.db.View(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket([]byte("users"))
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
uRaw := b.Get([]byte(s.Username))
|
||||
if uRaw == nil {
|
||||
return nil
|
||||
}
|
||||
u := User{}
|
||||
json.Unmarshal(uRaw, &u)
|
||||
tokens = u.Tokens
|
||||
|
||||
config := tx.Bucket([]byte("config"))
|
||||
if config != nil {
|
||||
prefix = string(config.Get([]byte("prefix")))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
a.ExecuteTemplate(rw, "index.tmpl", struct {
|
||||
Page Page
|
||||
Session *Session
|
||||
UploadTokens []string
|
||||
Prefix string
|
||||
}{
|
||||
Page: a.getPage(req),
|
||||
Session: s,
|
||||
UploadTokens: tokens,
|
||||
Prefix: prefix,
|
||||
})
|
||||
}
|
||||
|
||||
func (a *App) login(rw http.ResponseWriter, req *http.Request) {
|
||||
if req.Method == "POST" {
|
||||
u := a.getUser(req.FormValue("user"), req.FormValue("pass"))
|
||||
if u != nil {
|
||||
session := make([]byte, 32)
|
||||
rand.Read(session)
|
||||
http.SetCookie(rw, &http.Cookie{
|
||||
Name: "session",
|
||||
Expires: time.Now().Add(time.Hour * 24 * 7),
|
||||
Value: hex.EncodeToString(session),
|
||||
})
|
||||
s := &Session{
|
||||
ID: hex.EncodeToString(session),
|
||||
Username: req.FormValue("user"),
|
||||
TempAdmin: u.Auths.Has("tempadmin"),
|
||||
}
|
||||
a.saveSession(s)
|
||||
http.Redirect(rw, req, "/", 302)
|
||||
return
|
||||
}
|
||||
}
|
||||
a.ExecuteTemplate(rw, "login.tmpl", struct {
|
||||
Page Page
|
||||
}{
|
||||
Page: a.getPage(req),
|
||||
})
|
||||
}
|
||||
|
||||
func (a *App) logout(rw http.ResponseWriter, req *http.Request) {
|
||||
s := a.getSession(req)
|
||||
if s != nil {
|
||||
a.deleteSession(s)
|
||||
}
|
||||
http.Redirect(rw, req, "/login", 302)
|
||||
return
|
||||
}
|
||||
|
||||
func (a *App) generateToken(rw http.ResponseWriter, req *http.Request) {
|
||||
s := a.getSession(req)
|
||||
if s == nil || !s.Auths.Has(AUTH_UPLOAD) {
|
||||
http.Redirect(rw, req, "/", 302)
|
||||
return
|
||||
}
|
||||
tokenRaw := make([]byte, 16)
|
||||
_, err := rand.Read(tokenRaw)
|
||||
if err != nil {
|
||||
rw.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
token := hex.EncodeToString(tokenRaw)
|
||||
a.db.Update(func(tx *bbolt.Tx) error {
|
||||
ub, err := tx.CreateBucketIfNotExists([]byte("users"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uRaw := ub.Get([]byte(s.Username))
|
||||
if uRaw == nil {
|
||||
return nil
|
||||
}
|
||||
u := User{}
|
||||
err = json.Unmarshal(uRaw, &u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Tokens = append(u.Tokens, token)
|
||||
buf, err := json.Marshal(u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ub.Put([]byte(s.Username), buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := tx.CreateBucketIfNotExists([]byte("tokens"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.Put([]byte(token), []byte(s.Username))
|
||||
})
|
||||
http.Redirect(rw, req, "/", 302)
|
||||
}
|
||||
|
||||
func (a *App) changePassword(rw http.ResponseWriter, req *http.Request) {
|
||||
s := a.getSession(req)
|
||||
if s == nil {
|
||||
http.Redirect(rw, req, "/", 302)
|
||||
return
|
||||
}
|
||||
|
||||
if req.Method == "POST" {
|
||||
req.ParseForm()
|
||||
password := req.FormValue("pass")
|
||||
a.db.Update(func(tx *bbolt.Tx) error {
|
||||
users, err := tx.CreateBucketIfNotExists([]byte("users"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u := User{}
|
||||
raw := users.Get([]byte(s.Username))
|
||||
if raw != nil {
|
||||
json.Unmarshal(raw, &u)
|
||||
}
|
||||
if password != "" {
|
||||
u.Pass, _ = bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
}
|
||||
raw, _ = json.Marshal(u)
|
||||
users.Put([]byte(s.Username), raw)
|
||||
return nil
|
||||
})
|
||||
http.Redirect(rw, req, "/", 302)
|
||||
}
|
||||
|
||||
a.ExecuteTemplate(rw, "password.tmpl", struct {
|
||||
Page Page
|
||||
Session *Session
|
||||
}{
|
||||
Page: a.getPage(req),
|
||||
Session: s,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user