Various small fixes

This commit is contained in:
Noah 2017-11-26 19:44:36 -08:00
parent 4a7a87c306
commit cd575ffb1e
6 changed files with 168 additions and 163 deletions

View File

@ -4,6 +4,7 @@ package jsondb
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -26,6 +27,7 @@ var (
// New initializes the JSON database. // New initializes the JSON database.
func New(root string) *DB { func New(root string) *DB {
log.Info("Initialized JsonDB at root: %s", root)
return &DB{ return &DB{
Root: root, Root: root,
} }
@ -60,14 +62,17 @@ func (db *DB) Commit(document string, v interface{}) error {
path := db.toPath(document) path := db.toPath(document)
// Ensure the directory tree is ready. // Ensure the directory tree is ready.
db.makePath(path) err := db.makePath(path)
// Write the document.
err := db.writeJSON(path, v)
if err != nil { if err != nil {
return err return err
} }
// Write the document.
err = db.writeJSON(path, v)
if err != nil {
return fmt.Errorf("failed to write JSON to path %s: %s", path, err.Error())
}
return nil return nil
} }
@ -107,7 +112,7 @@ func (db *DB) ListAll(path string) ([]string, error) {
func (db *DB) makePath(path string) error { func (db *DB) makePath(path string) error {
parts := strings.Split(path, string(filepath.Separator)) parts := strings.Split(path, string(filepath.Separator))
parts = parts[:len(parts)-1] // pop off the filename parts = parts[:len(parts)-1] // pop off the filename
directory := filepath.Join(parts...) directory := "/" + filepath.Join(parts...)
if _, err := os.Stat(directory); err != nil { if _, err := os.Stat(directory); err != nil {
log.Debug("[JsonDB] Create directory: %s", directory) log.Debug("[JsonDB] Create directory: %s", directory)

View File

@ -44,8 +44,9 @@ func (b *Blog) Session(r *http.Request) *sessions.Session {
func (b *Blog) CSRFMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { func (b *Blog) CSRFMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
if r.Method == "POST" { if r.Method == "POST" {
session := b.Session(r) session := b.Session(r)
token, ok := session.Values["csrf"].(string) token := b.GenerateCSRFToken(w, r, session)
if !ok || token != r.FormValue("_csrf") { if token != r.FormValue("_csrf") {
log.Error("CSRF Mismatch: expected %s, got %s", r.FormValue("_csrf"), token)
b.Forbidden(w, r, "Failed to validate CSRF token. Please try your request again.") b.Forbidden(w, r, "Failed to validate CSRF token. Please try your request again.")
return return
} }

View File

@ -85,7 +85,7 @@ func (b *Blog) ResolvePath(path string) (Filepath, error) {
} }
debug("Resolving filepath for URI: %s", path) debug("Resolving filepath for URI: %s", path)
for _, root := range []string{b.DocumentRoot, b.UserRoot} { for _, root := range []string{b.UserRoot, b.DocumentRoot} {
if len(root) == 0 { if len(root) == 0 {
continue continue
} }

View File

@ -4,6 +4,7 @@ import (
"html/template" "html/template"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/kirsle/blog/core/forms" "github.com/kirsle/blog/core/forms"
"github.com/kirsle/blog/core/models/settings" "github.com/kirsle/blog/core/models/settings"
@ -108,6 +109,7 @@ func (b *Blog) RenderTemplate(w http.ResponseWriter, r *http.Request, path strin
// Useful template functions. // Useful template functions.
t := template.New(filepath.Absolute).Funcs(template.FuncMap{ t := template.New(filepath.Absolute).Funcs(template.FuncMap{
"StringsJoin": strings.Join, "StringsJoin": strings.Join,
"Now": time.Now,
"RenderPost": b.RenderPost, "RenderPost": b.RenderPost,
"RenderComments": func(subject string, ids ...string) template.HTML { "RenderComments": func(subject string, ids ...string) template.HTML {
session := b.Session(r) session := b.Session(r)

View File

@ -1,4 +1,4 @@
{{ define "title" }}WTF?{{ end }} {{ define "title" }}{{ end }}
{{ define "scripts" }}{{ end }} {{ define "scripts" }}{{ end }}
{{ define "layout" }} {{ define "layout" }}

View File

@ -2,162 +2,159 @@
{{ define "content" }} {{ define "content" }}
<form action="/admin/settings" method="POST"> <form action="/admin/settings" method="POST">
<input type="hidden" name="_csrf" value="{{ .CSRF }}"> <input type="hidden" name="_csrf" value="{{ .CSRF }}">
<div class="card">
{{ with .Data.s }}
<div class="card-body">
<h3>The Basics</h3>
<div class="form-group"> {{ with .Data.s }}
<label for="title">Title</label> <h3>The Basics</h3>
<input type="text"
class="form-control"
name="title"
value="{{ .Site.Title }}"
placeholder="Website Title">
</div>
<div class="form-group">
<label for="admin-email">Admin Email</label>
<small class="text-muted">For getting notifications about comments, etc.</small>
<input type="text"
class="form-control"
name="admin-email"
value="{{ .Site.AdminEmail }}"
placeholder="name@domain.com">
</div>
<div class="form-group">
<label for="admin-email">URL Root</label>
<small class="text-muted d-block">
The base absolute URL to your website. This is used to generate
emails such as comment notifications. If not provided, these
emails will not be sent.
</small>
<input type="text"
class="form-control"
name="url"
value="{{ .Site.URL }}"
placeholder="https://www.example.com/">
</div>
<h3>Redis Cache</h3>
<p>
Using a <a href="https://redis.io/" target="_blank">Redis</a> cache can
boost the performance of the JSON database by caching documents in
memory instead of always reading from disk.
</p>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox"
class="form-check-input"
name="redis-enabled"
value="true"
{{ if .Redis.Enabled }}checked{{ end }}>
Enable Redis
</label>
</div>
<div class="form-group">
<label for="redis-host">Redis Host</label>
<input type="text"
class="form-control"
name="redis-host"
value="{{ .Redis.Host }}"
placeholder="localhost">
</div>
<div class="form-group">
<label for="redis-port">Port</label>
<input type="text"
class="form-control"
name="redis-port"
value="{{ .Redis.Port }}"
placeholder="6379">
</div>
<div class="form-group">
<label for="redis-db">DB Number</label>
<small class="text-muted">0-15</small>
<input type="text"
class="form-control"
name="redis-db"
value="{{ .Redis.DB }}"
placeholder="0">
</div>
<div class="form-group">
<label for="redis-prefix">Key Prefix</label>
<small class="text-muted">(optional)</small>
<input type="text"
class="form-control"
name="redis-prefix"
value="{{ .Redis.Prefix }}"
placeholder="blog:">
</div>
<h3>Email Settings</h3>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox"
class="form-check-input"
name="mail-enabled"
value="true"
{{ if .Mail.Enabled }}checked{{ end }}>
Enable email to be sent by this site
</label>
</div>
<div class="form-group">
<label for="mail-sender">Sender Address</label>
<input type="email"
name="mail-sender"
id="mail-sender"
class="form-control"
value="{{ .Mail.Sender }}"
placeholder="no-reply@example.com">
</div>
<div class="form-group">
<label for="mail-host">SMTP Host</label>
<input type="text"
class="form-control"
name="mail-host"
id="mail-host"
value="{{ .Mail.Host }}"
placeholder="localhost">
</div>
<div class="form-group">
<label for="mail-port">SMTP Port</label>
<input type="text"
class="form-control"
name="mail-port"
id="mail-port"
value="{{ .Mail.Port }}"
placeholder="25">
</div>
<div class="form-group">
<label for="mail-username">SMTP Username</label>
<small class="text-muted">(optional)</small>
<input type="text"
class="form-control"
name="mail-username"
value="{{ .Mail.Username }}"
placeholder="">
</div>
<div class="form-group">
<label for="mail-password">SMTP Password</label>
<small class="text-muted">(optional)</small>
<input type="text"
class="form-control"
name="mail-password"
value="{{ .Mail.Password }}"
placeholder="">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Save Settings</button>
<a href="/admin" class="btn btn-secondary">Cancel</a>
</div>
<div class="form-group">
<label for="title">Title</label>
<input type="text"
class="form-control"
name="title"
value="{{ .Site.Title }}"
placeholder="Website Title">
</div> </div>
{{ end }}
</div> <div class="form-group">
<label for="admin-email">Admin Email</label>
<small class="text-muted">For getting notifications about comments, etc.</small>
<input type="text"
class="form-control"
name="admin-email"
value="{{ .Site.AdminEmail }}"
placeholder="name@domain.com">
</div>
<div class="form-group">
<label for="admin-email">URL Root</label>
<small class="text-muted d-block">
The base absolute URL to your website. This is used to generate
emails such as comment notifications. If not provided, these
emails will not be sent.
</small>
<input type="text"
class="form-control"
name="url"
value="{{ .Site.URL }}"
placeholder="https://www.example.com/">
</div>
<h3>Redis Cache</h3>
<p>
Using a <a href="https://redis.io/" target="_blank">Redis</a> cache can
boost the performance of the JSON database by caching documents in
memory instead of always reading from disk.
</p>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox"
class="form-check-input"
name="redis-enabled"
value="true"
{{ if .Redis.Enabled }}checked{{ end }}>
Enable Redis
</label>
</div>
<div class="form-group">
<label for="redis-host">Redis Host</label>
<input type="text"
class="form-control"
name="redis-host"
value="{{ .Redis.Host }}"
placeholder="localhost">
</div>
<div class="form-group">
<label for="redis-port">Port</label>
<input type="text"
class="form-control"
name="redis-port"
value="{{ .Redis.Port }}"
placeholder="6379">
</div>
<div class="form-group">
<label for="redis-db">DB Number</label>
<small class="text-muted">0-15</small>
<input type="text"
class="form-control"
name="redis-db"
value="{{ .Redis.DB }}"
placeholder="0">
</div>
<div class="form-group">
<label for="redis-prefix">Key Prefix</label>
<small class="text-muted">(optional)</small>
<input type="text"
class="form-control"
name="redis-prefix"
value="{{ .Redis.Prefix }}"
placeholder="blog:">
</div>
<h3>Email Settings</h3>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox"
class="form-check-input"
name="mail-enabled"
value="true"
{{ if .Mail.Enabled }}checked{{ end }}>
Enable email to be sent by this site
</label>
</div>
<div class="form-group">
<label for="mail-sender">Sender Address</label>
<input type="email"
name="mail-sender"
id="mail-sender"
class="form-control"
value="{{ .Mail.Sender }}"
placeholder="no-reply@example.com">
</div>
<div class="form-group">
<label for="mail-host">SMTP Host</label>
<input type="text"
class="form-control"
name="mail-host"
id="mail-host"
value="{{ .Mail.Host }}"
placeholder="localhost">
</div>
<div class="form-group">
<label for="mail-port">SMTP Port</label>
<input type="text"
class="form-control"
name="mail-port"
id="mail-port"
value="{{ .Mail.Port }}"
placeholder="25">
</div>
<div class="form-group">
<label for="mail-username">SMTP Username</label>
<small class="text-muted">(optional)</small>
<input type="text"
class="form-control"
name="mail-username"
value="{{ .Mail.Username }}"
placeholder="">
</div>
<div class="form-group">
<label for="mail-password">SMTP Password</label>
<small class="text-muted">(optional)</small>
<input type="text"
class="form-control"
name="mail-password"
value="{{ .Mail.Password }}"
placeholder="">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Save Settings</button>
<a href="/admin" class="btn btn-secondary">Cancel</a>
</div>
{{ end }}
</form> </form>
{{ end }} {{ end }}