Skip to content
This repository has been archived by the owner on Sep 23, 2021. It is now read-only.

Commit

Permalink
Merge pull request #25 from msoedov/restore_session
Browse files Browse the repository at this point in the history
Restore previous session
  • Loading branch information
msoedov authored Jan 19, 2018
2 parents ce0bc91 + d477077 commit 39531f0
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 60 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ src/
slides/
main
node_modules
hacker-slides
4 changes: 2 additions & 2 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ func Test(t *testing.T) {
g.Describe("App api", func() {
var cookie string

g.It("Should return 200 on / ", func() {
g.It("Should return 302 on / to redirect to file name ", func() {
w := client("GET", "/", "")

g.Assert(w.Code).Equal(200)
g.Assert(w.Code).Equal(302)
cookie = w.HeaderMap.Get(Cookie)
})

Expand Down
56 changes: 56 additions & 0 deletions auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package auth

import (
"encoding/base64"
"fmt"
"os"
"strconv"

log "github.com/Sirupsen/logrus"
"github.com/gin-gonic/gin"
)

func Header(c *gin.Context, key string) string {
if values, _ := c.Request.Header[key]; len(values) > 0 {
return values[0]
}
return ""
}

func BasicAuth() gin.HandlerFunc {
realm := "Authorization Required"
realm = "Basic realm=" + strconv.Quote(realm)
user := os.Getenv("USER")
password := os.Getenv("PASSWORD")
enabled := isEnabled(user, password)
if enabled {
log.Warn("Auth mode enabled")
log.Warn(fmt.Sprintf("Visit http://%s:%s@0.0.0.0:8080", user, password))
}
return func(c *gin.Context) {
header := Header(c, "Authorization")
if enabled && header != authorizationHeader(user, password) {
// Credentials doesn't match, we return 401 and abort handlers chain.
c.Header("WWW-Authenticate", realm)
c.AbortWithStatus(401)
return
}
c.Next()
}
}

func isEnabled(user, password string) bool {
switch {
case user == "":
return false
case password == "":
return false
default:
return true
}
}

func authorizationHeader(user, password string) string {
base := user + ":" + password
return "Basic " + base64.StdEncoding.EncodeToString([]byte(base))
}
25 changes: 25 additions & 0 deletions files/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package files

import (
"io/ioutil"
"time"
)

var epoch = time.Unix(1494505756, 0)

func LatestFileIn(path string) (latest string) {
files, err := ioutil.ReadDir(path)
if err != nil {
return ""
}
latestTime := epoch
for _, f := range files {
path := f.Name()
pathModifiedAt := f.ModTime()
if pathModifiedAt.After(latestTime) {
latestTime = pathModifiedAt
latest = path
}
}
return
}
81 changes: 24 additions & 57 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,65 +1,24 @@
package main

import (
"encoding/base64"
"errors"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"

log "github.com/Sirupsen/logrus"
haikunator "github.com/atrox/haikunatorgo"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/msoedov/hacker-slides/auth"
"github.com/msoedov/hacker-slides/files"
)

const sessionHeader = "slide-session"

func Header(c *gin.Context, key string) string {
if values, _ := c.Request.Header[key]; len(values) > 0 {
return values[0]
}
return ""
}

func BasicAuth() gin.HandlerFunc {
realm := "Authorization Required"
realm = "Basic realm=" + strconv.Quote(realm)
user := os.Getenv("USER")
password := os.Getenv("PASSWORD")
enabled := isEnabled(user, password)
if enabled {
log.Warn("Auth mode enabled")
log.Warn(fmt.Sprintf("Visit http://%s:%s@0.0.0.0:8080", user, password))
}
return func(c *gin.Context) {
header := Header(c, "Authorization")
if enabled && header != authorizationHeader(user, password) {
// Credentials doesn't match, we return 401 and abort handlers chain.
c.Header("WWW-Authenticate", realm)
c.AbortWithStatus(401)
return
}
c.Next()
}
}

func isEnabled(user, password string) bool {
switch {
case user == "":
return false
case password == "":
return false
default:
return true
}
}

func authorizationHeader(user, password string) string {
base := user + ":" + password
return "Basic " + base64.StdEncoding.EncodeToString([]byte(base))
func SlidePath(name string) string {
return fmt.Sprintf("slides/%s.md", name)
}

func NewApp() *gin.Engine {
Expand All @@ -68,30 +27,38 @@ func NewApp() *gin.Engine {

store := sessions.NewCookieStore([]byte("secret"))
r.Use(sessions.Sessions(sessionHeader, store))
r.Use(BasicAuth())
r.Use(auth.BasicAuth())

r.LoadHTMLGlob("templates/*.tmpl")
r.Static("/static", "./static")

r.GET("/", func(c *gin.Context) {

fname := c.Param("name")
isNew := c.Query("new")
latest := files.LatestFileIn("slides")
log.WithFields(log.Fields{
"name": fname,
}).Info("Restore?")
"name": latest,
"isNew": isNew,
}).Info("Restoring latest point")

var path, name string
if latest == "" || isNew != "" {
haikunator := haikunator.New()
haikunator.TokenLength = 0
name = haikunator.Haikunate()
} else {
name = strings.Replace(latest, ".md", "", 1)
}
path = SlidePath(name)

haikunator := haikunator.New()
haikunator.TokenLength = 0
name := haikunator.Haikunate()
path := fmt.Sprintf("slides/%s.md", name)
log.WithFields(log.Fields{
"path": path,
}).Info("A new session")
session := sessions.Default(c)
session.Set("name", path)
session.Save()

c.HTML(200, "index.tmpl", gin.H{
c.Writer.Header().Set("Location", fmt.Sprintf("/stash/edit/%s", name))
c.HTML(302, "index.tmpl", gin.H{
"pubTo": path,
})
})
Expand Down Expand Up @@ -176,7 +143,7 @@ func NewApp() *gin.Engine {
if strings.HasSuffix(name, ".md") {
name = name[0 : len(name)-3]
}
path := fmt.Sprintf("slides/%s.md", name)
path := SlidePath(name)
session := sessions.Default(c)
session.Set("name", path)
session.Save()
Expand All @@ -196,7 +163,7 @@ func NewApp() *gin.Engine {
if strings.HasSuffix(name, ".md") {
name = name[0 : len(name)-3]
}
path := fmt.Sprintf("slides/%s.md", name)
path := SlidePath(name)
session := sessions.Default(c)
session.Set("name", path)
session.Save()
Expand Down
3 changes: 2 additions & 1 deletion templates/index.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
<body>
<div id="edit-pane">
<div id="controls">
<a href="/stash" target="_blank" onclick="save();"> Stash</a> |
<a href="/?new=true" target="_blank" onclick="save();"> New</a> |
<a href="/stash" target="_blank" onclick="save();"> Stash</a> |
<a href="/published/{{ .pubTo}}" target="_blank" onclick="save();"> Present</a> |
<a href="/published/{{ .pubTo}}?print-pdf" target="_blank" onclick="save();"> Pdf</a>
</div>
Expand Down

0 comments on commit 39531f0

Please sign in to comment.