Add Template layouts, load session hashkey
This commit is contained in:
42
main.go
42
main.go
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -24,6 +25,7 @@ var store auth.AuthStore
|
||||
const HTPASSWD_FILE = ".htpasswd"
|
||||
|
||||
type UserLogin struct {
|
||||
IsLogin bool
|
||||
Email string `form:"email" binding:"required"`
|
||||
Password string `form:"password" binding:"required"`
|
||||
}
|
||||
@@ -34,16 +36,23 @@ func init() {
|
||||
flag.StringVar(&LEDGER_INIT, "i", "", "ledger initiation file")
|
||||
flag.StringVar(&WORKING_DIR, "w", "", "ledger working directory")
|
||||
flag.StringVar(&HOST, "b", "127.0.0.1:8000", "binding address")
|
||||
var hashKey string
|
||||
flag.StringVar(&hashKey, "s", "", "session secret")
|
||||
var hashKeyString string
|
||||
flag.StringVar(&hashKeyString, "s", "", "session secret")
|
||||
flag.Parse()
|
||||
|
||||
if hashKey == "" {
|
||||
hashKey = string(securecookie.GenerateRandomKey(32))
|
||||
log.Printf("Generate random session key: %s", hashKey)
|
||||
}
|
||||
var hashKey []byte
|
||||
var err error
|
||||
store, err = auth.New(HTPASSWD_FILE, []byte(hashKey))
|
||||
|
||||
if hashKeyString == "" {
|
||||
hashKey = securecookie.GenerateRandomKey(32)
|
||||
log.Printf("Generate random session key: %s", base64.StdEncoding.EncodeToString(hashKey))
|
||||
} else {
|
||||
hashKey, err = base64.StdEncoding.DecodeString(hashKeyString)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
store, err = auth.New(HTPASSWD_FILE, hashKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -53,22 +62,26 @@ func main() {
|
||||
r := gin.Default()
|
||||
r.HTMLRender = loadTemplates("templates")
|
||||
|
||||
r.GET("/", func(c *gin.Context) {
|
||||
HTML(c, 200, "index.html", nil)
|
||||
})
|
||||
|
||||
r.GET("/signup", func(c *gin.Context) {
|
||||
c.HTML(200, "signup.html", nil)
|
||||
HTML(c, 200, "signup.html", nil)
|
||||
})
|
||||
|
||||
r.GET("/signin", func(c *gin.Context) {
|
||||
c.HTML(200, "signin.html", nil)
|
||||
HTML(c, 200, "signin.html", nil)
|
||||
})
|
||||
|
||||
r.POST("/signup", signup)
|
||||
|
||||
r.POST("/signin", signin)
|
||||
|
||||
authZone := r.Group("", basicAuth)
|
||||
authZone := r.Group("", authenticate)
|
||||
|
||||
authZone.GET("/dashboard", func(c *gin.Context) {
|
||||
c.HTML(200, "index.html", struct {
|
||||
HTML(c, 200, "dashboard.html", struct {
|
||||
Templates []*template.Template
|
||||
Scripts map[string][]string
|
||||
}{
|
||||
@@ -89,11 +102,10 @@ func main() {
|
||||
log.Println(err, c.Request.Form)
|
||||
return
|
||||
}
|
||||
c.HTML(200, "new.html", struct {
|
||||
HTML(c, 200, "new.html", struct {
|
||||
Tx string
|
||||
}{tx})
|
||||
})
|
||||
|
||||
authZone.POST("/submit", func(c *gin.Context) {
|
||||
tx := c.PostForm("tx")
|
||||
if err := appendToFile(tx); err != nil {
|
||||
@@ -101,7 +113,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
c.HTML(200, "success.html", struct {
|
||||
HTML(c, 200, "success.html", struct {
|
||||
Tx string
|
||||
}{tx})
|
||||
})
|
||||
@@ -118,7 +130,7 @@ func main() {
|
||||
log.Fatal(r.Run(HOST))
|
||||
}
|
||||
|
||||
func basicAuth(c *gin.Context) {
|
||||
func authenticate(c *gin.Context) {
|
||||
cookie, err := c.Cookie("session")
|
||||
if err == http.ErrNoCookie {
|
||||
c.Redirect(303, "/signin")
|
||||
|
||||
@@ -5,11 +5,11 @@ import "github.com/gin-gonic/gin"
|
||||
func signup(c *gin.Context) {
|
||||
var user UserLogin
|
||||
if err := c.ShouldBind(&user); err != nil {
|
||||
c.HTML(400, "signup.html", err)
|
||||
HTML(c, 400, "signup.html", err)
|
||||
return
|
||||
}
|
||||
if err := store.Register(user.Email, user.Password); err != nil {
|
||||
c.HTML(400, "signup.html", err)
|
||||
HTML(c, 400, "signup.html", err)
|
||||
return
|
||||
}
|
||||
signin(c)
|
||||
@@ -18,12 +18,12 @@ func signup(c *gin.Context) {
|
||||
func signin(c *gin.Context) {
|
||||
var user UserLogin
|
||||
if err := c.ShouldBind(&user); err != nil {
|
||||
c.HTML(400, "signin.html", err)
|
||||
HTML(c, 400, "signin.html", err)
|
||||
return
|
||||
}
|
||||
token, err := store.Login(user.Email, user.Password)
|
||||
if err != nil {
|
||||
c.HTML(401, "signin.html", err)
|
||||
HTML(c, 401, "signin.html", err)
|
||||
return
|
||||
}
|
||||
c.SetCookie("session", token, 60*60*24*7, "", "", false, false)
|
||||
|
||||
19
template.go
19
template.go
@@ -5,6 +5,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gin-contrib/multitemplate"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func loadTemplates(templatesDir string) multitemplate.Renderer {
|
||||
@@ -25,3 +26,21 @@ func loadTemplates(templatesDir string) multitemplate.Renderer {
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type Data interface{}
|
||||
|
||||
type Page struct {
|
||||
Data
|
||||
User UserLogin
|
||||
}
|
||||
|
||||
func HTML(c *gin.Context, status int, name string, data interface{}) {
|
||||
output := Page{
|
||||
Data: data,
|
||||
}
|
||||
_, ok := c.Get("user")
|
||||
if ok {
|
||||
output.User = c.MustGet("user").(UserLogin)
|
||||
}
|
||||
c.HTML(status, name, output)
|
||||
}
|
||||
|
||||
20
templates/dashboard.html
Normal file
20
templates/dashboard.html
Normal file
@@ -0,0 +1,20 @@
|
||||
{{ define "main" }}
|
||||
<h1>Ledger Quick Note</h1>
|
||||
<form action="/new" method="POST">
|
||||
<label>Action:
|
||||
{{ range .Templates }}
|
||||
<input type="radio" name="action" value="{{ .Name }}">{{ .Name }}</option>
|
||||
{{ end }}
|
||||
</label><br>
|
||||
<label>Amount: <input name="amount" type="number"></label><br>
|
||||
<label>Account: <input name="account" type="text"></label></br>
|
||||
<label>Tx Name: <input name="name" type="text"></label></br>
|
||||
<input type="submit">
|
||||
</form>
|
||||
<h2>Scripts</h2>
|
||||
<ul>
|
||||
{{ range $k, $v := .Scripts }}
|
||||
<li><a href="/exec?name={{ $k }}">{{ $k }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
@@ -1,20 +1,3 @@
|
||||
{{ define "main" }}
|
||||
<h1>Ledger Quick Note</h1>
|
||||
<form action="/new" method="POST">
|
||||
<label>Action:
|
||||
{{ range .Templates }}
|
||||
<input type="radio" name="action" value="{{ .Name }}">{{ .Name }}</option>
|
||||
{{ end }}
|
||||
</label><br>
|
||||
<label>Amount: <input name="amount" type="number"></label><br>
|
||||
<label>Account: <input name="account" type="text"></label></br>
|
||||
<label>Tx Name: <input name="name" type="text"></label></br>
|
||||
<input type="submit">
|
||||
</form>
|
||||
<h2>Scripts</h2>
|
||||
<ul>
|
||||
{{ range $k, $v := .Scripts }}
|
||||
<li><a href="/exec?name={{ $k }}">{{ $k }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
{{ block "main" . }}
|
||||
<nav>
|
||||
{{ with .User }}
|
||||
{{ .Email }}
|
||||
{{ end }}
|
||||
</nav>
|
||||
{{ block "main" .Data }}
|
||||
|
||||
{{ end }}
|
||||
</body>
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
{{ define "main" }}
|
||||
<p><strong>Success</strong></p>
|
||||
<pre><code>{{ .Tx }}</code></pre>
|
||||
<p><a href="/">Back to home</a></p>
|
||||
<p><a href="/dashboard">Back to home</a></p>
|
||||
{{ end }}
|
||||
|
||||
Reference in New Issue
Block a user