formatting
This commit is contained in:
parent
5c18b9938d
commit
e1afb206ae
11 changed files with 97 additions and 6 deletions
|
|
@ -5,6 +5,8 @@ import "os"
|
|||
type (
|
||||
Config struct {
|
||||
DatabaseURL string
|
||||
VpubDatabaseURL string
|
||||
VpubAESKey string
|
||||
SessionKey string
|
||||
Env string
|
||||
CertFile string
|
||||
|
|
@ -22,6 +24,8 @@ type (
|
|||
func New() *Config {
|
||||
return &Config{
|
||||
DatabaseURL: os.Getenv("DATABASE_URL"),
|
||||
VpubDatabaseURL: os.Getenv("VPUB_DATABASE_URL"),
|
||||
VpubAESKey: os.Getenv("VPUB_AES_KEY"),
|
||||
SessionKey: os.Getenv("SESSION_KEY"),
|
||||
Env: os.Getenv("ENV"),
|
||||
CertFile: os.Getenv("CERT_FILE"),
|
||||
|
|
|
|||
7
main.go
7
main.go
|
|
@ -5,6 +5,7 @@ import (
|
|||
"log"
|
||||
"status/config"
|
||||
"status/storage"
|
||||
"status/vpub"
|
||||
"status/web"
|
||||
)
|
||||
|
||||
|
|
@ -15,7 +16,11 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
data := storage.New(db)
|
||||
v, err := vpub.New(cfg.VpubDatabaseURL, []byte(cfg.VpubAESKey))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Fatal(
|
||||
web.Serve(data, cfg),
|
||||
web.Serve(data, v, cfg),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
45
vpub/vpub.go
Normal file
45
vpub/vpub.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package vpub
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Vpub struct {
|
||||
db *sql.DB
|
||||
key []byte
|
||||
}
|
||||
|
||||
func New(databaseURL string, key []byte) (Vpub, error) {
|
||||
db, err := sql.Open("postgres", databaseURL)
|
||||
return Vpub{db: db, key: key}, err
|
||||
}
|
||||
|
||||
func EncryptAES(key []byte, plaintext string) string {
|
||||
c, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return ""
|
||||
}
|
||||
out := make([]byte, len(plaintext))
|
||||
c.Encrypt(out, []byte(plaintext))
|
||||
return hex.EncodeToString(out)
|
||||
}
|
||||
|
||||
func (v Vpub) FindOrCreateKey(name string) string {
|
||||
padded := fmt.Sprintf("%16s", name)
|
||||
key := EncryptAES(v.key, padded)[0:20]
|
||||
|
||||
query := `
|
||||
insert into keys (key) values ($1) ON CONFLICT do nothing
|
||||
`
|
||||
|
||||
_, err := v.db.Exec(query, key[:20])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ var TplCommonMap = map[string]string{
|
|||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/">status.cafe</a>
|
||||
<a href="/">status.cafe</a> <a href="https://forum.status.cafe">forum</a>
|
||||
{{ if .logged }}
|
||||
<a href="/settings">settings</a> <a href="/users/{{ .logged }}">{{ .logged }}</a> (<a href="/logout">logout</a>)
|
||||
{{ else }}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"net/http"
|
||||
"status/config"
|
||||
"status/storage"
|
||||
"status/vpub"
|
||||
"status/web/session"
|
||||
)
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ type Handler struct {
|
|||
mux *mux.Router
|
||||
storage *storage.Storage
|
||||
sess *session.Session
|
||||
vpub vpub.Vpub
|
||||
}
|
||||
|
||||
func protectClickJacking(w http.ResponseWriter) {
|
||||
|
|
@ -43,13 +45,14 @@ func (h *Handler) getUser(r *http.Request) (string, error) {
|
|||
return user, err
|
||||
}
|
||||
|
||||
func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http.Handler, error) {
|
||||
func New(cfg *config.Config, sess *session.Session, data *storage.Storage, v vpub.Vpub) (http.Handler, error) {
|
||||
router := mux.NewRouter()
|
||||
h := &Handler{
|
||||
cfg: cfg,
|
||||
mux: router,
|
||||
storage: data,
|
||||
sess: sess,
|
||||
vpub: v,
|
||||
}
|
||||
h.initTpl()
|
||||
|
||||
|
|
@ -66,6 +69,7 @@ func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http
|
|||
|
||||
router.HandleFunc("/settings", h.showSettingsView).Methods(http.MethodGet)
|
||||
router.HandleFunc("/settings-update", h.updateSettings).Methods(http.MethodPost)
|
||||
router.HandleFunc("/forum-key", h.showKeyView).Methods(http.MethodGet)
|
||||
|
||||
router.HandleFunc("/add", h.showNewStatusView).Methods(http.MethodGet)
|
||||
router.HandleFunc("/add", h.saveStatus).Methods(http.MethodPost)
|
||||
|
|
|
|||
|
|
@ -148,6 +148,12 @@ var TplMap = map[string]string{
|
|||
{{ .csrfField }}
|
||||
{{ template "status_form" .status }}
|
||||
</form>
|
||||
{{ end }}`,
|
||||
"forum-key": `{{ define "content" }}
|
||||
<h1>Forum key</h1>
|
||||
|
||||
<p>Your forum key is:</p>
|
||||
<pre>{{ .key }}</pre>
|
||||
{{ end }}`,
|
||||
"index": `{{ define "head" }}
|
||||
<link rel="alternate" type="application/atom+xml" title="Atom feed" href="/feed.atom" />
|
||||
|
|
@ -180,6 +186,7 @@ var TplMap = map[string]string{
|
|||
</section>
|
||||
<section>
|
||||
<h2>Status stream</h2>
|
||||
<p class="flash">The <a href="https://forum.status.cafe">forum</a> has opened! <a href="/forum-key">Generate your key</a> to <a href="https://forum.status.cafe/register">register</a>. Best viewed with a hot beverage.</p>
|
||||
{{ range .statuses }}
|
||||
<article class="status">
|
||||
{{ template "status" . }}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<body>
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/">status.cafe</a>
|
||||
<a href="/">status.cafe</a> <a href="https://forum.status.cafe">forum</a>
|
||||
{{ if .logged }}
|
||||
<a href="/settings">settings</a> <a href="/users/{{ .logged }}">{{ .logged }}</a> (<a href="/logout">logout</a>)
|
||||
{{ else }}
|
||||
|
|
|
|||
6
web/handler/html/forum-key.html
Normal file
6
web/handler/html/forum-key.html
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{{ define "content" }}
|
||||
<h1>Forum key</h1>
|
||||
|
||||
<p>Your forum key is:</p>
|
||||
<pre>{{ .key }}</pre>
|
||||
{{ end }}
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
</section>
|
||||
<section>
|
||||
<h2>Status stream</h2>
|
||||
<p class="flash">The <a href="https://forum.status.cafe">forum</a> has opened! <a href="/forum-key">Generate your key</a> to <a href="https://forum.status.cafe/register">register</a>. Best viewed with a hot beverage.</p>
|
||||
{{ range .statuses }}
|
||||
<article class="status">
|
||||
{{ template "status" . }}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,24 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
func (h *Handler) showKeyView(w http.ResponseWriter, r *http.Request) {
|
||||
protectClickJacking(w)
|
||||
username, err := h.getUser(r)
|
||||
if err != nil {
|
||||
unauthorized(w, r)
|
||||
return
|
||||
}
|
||||
user, err := h.storage.UserByName(username)
|
||||
if err != nil {
|
||||
unauthorized(w, r)
|
||||
return
|
||||
}
|
||||
key := h.vpub.FindOrCreateKey(user.Name)
|
||||
h.renderLayout(w, "forum-key", map[string]interface{}{
|
||||
"key": key,
|
||||
}, username)
|
||||
}
|
||||
|
||||
func (h *Handler) showSettingsView(w http.ResponseWriter, r *http.Request) {
|
||||
protectClickJacking(w)
|
||||
username, err := h.getUser(r)
|
||||
|
|
|
|||
|
|
@ -7,14 +7,15 @@ import (
|
|||
"net/http"
|
||||
"status/config"
|
||||
"status/storage"
|
||||
"status/vpub"
|
||||
"status/web/handler"
|
||||
"status/web/session"
|
||||
)
|
||||
|
||||
func Serve(data *storage.Storage, cfg *config.Config) error {
|
||||
func Serve(data *storage.Storage, v vpub.Vpub, cfg *config.Config) error {
|
||||
var err error
|
||||
sess := session.New(cfg.SessionKey, data)
|
||||
s, err := handler.New(cfg, sess, data)
|
||||
s, err := handler.New(cfg, sess, data, v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue