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

Commit c99e884

Browse files
authored
Merge pull request #16 from msoedov/pr14
#14 Optional basic auth
2 parents 8e9f736 + cb7ee99 commit c99e884

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

Readme.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This repo is a reworked version of [Sandstorm Hacker Slides](https://github.com/
1616
- Pdf print
1717
- [Demo version](https://murmuring-sierra-54081.herokuapp.com)
1818
- Tiny 10 Mb docker image
19+
- Optional Basic auth
1920

2021

2122
| Edit mode | Published |
@@ -45,9 +46,23 @@ And then you can just open [http://127.0.0.1:8080](http://127.0.0.1:8080) and it
4546
Run with docker
4647

4748
```shell
48-
docker run -it -p 8080:8080 -v $(pwd)/slides:/app/slides msoedov/hacker-slides
49+
docker run -it -p 8080:8080 -v $(pwd)/slides:/app/slides msoedov/hacker-slides
4950
```
5051

52+
Basic auth (disabled by default)
53+
```shell
54+
USER=bob PASSWORD=password1 go run main.go
55+
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
56+
- using env: export GIN_MODE=release
57+
- using code: gin.SetMode(gin.ReleaseMode)
58+
59+
WARN[0000] Auth mode enabled
60+
WARN[0000] Visit http://bob:password1@0.0.0.0:8080
61+
```
62+
63+
```shell
64+
docker run -it -p 8080:8080 -e USER=bob -e PASSWORD=password1 -v $(pwd)/slides:/app/slides msoedov/hacker-slides
65+
```
5166

5267
Getting Help
5368
------------

main.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package main
22

33
import (
4+
"encoding/base64"
45
"errors"
56
"fmt"
67
"io/ioutil"
78
"os"
9+
"strconv"
810
"strings"
911

1012
log "github.com/Sirupsen/logrus"
@@ -15,12 +17,58 @@ import (
1517

1618
const sessionHeader = "slide-session"
1719

20+
func Header(c *gin.Context, key string) string {
21+
if values, _ := c.Request.Header[key]; len(values) > 0 {
22+
return values[0]
23+
}
24+
return ""
25+
}
26+
27+
func BasicAuth() gin.HandlerFunc {
28+
realm := "Authorization Required"
29+
realm = "Basic realm=" + strconv.Quote(realm)
30+
user := os.Getenv("USER")
31+
password := os.Getenv("PASSWORD")
32+
enabled := isEnabled(user, password)
33+
if enabled {
34+
log.Warn("Auth mode enabled")
35+
log.Warn(fmt.Sprintf("Visit http://%s:%s@0.0.0.0:8080", user, password))
36+
}
37+
return func(c *gin.Context) {
38+
header := Header(c, "Authorization")
39+
if enabled && header != authorizationHeader(user, password) {
40+
// Credentials doesn't match, we return 401 and abort handlers chain.
41+
c.Header("WWW-Authenticate", realm)
42+
c.AbortWithStatus(401)
43+
return
44+
}
45+
c.Next()
46+
}
47+
}
48+
49+
func isEnabled(user, password string) bool {
50+
switch {
51+
case user == "":
52+
return false
53+
case password == "":
54+
return false
55+
default:
56+
return true
57+
}
58+
}
59+
60+
func authorizationHeader(user, password string) string {
61+
base := user + ":" + password
62+
return "Basic " + base64.StdEncoding.EncodeToString([]byte(base))
63+
}
64+
1865
func NewApp() *gin.Engine {
1966

2067
r := gin.Default()
2168

2269
store := sessions.NewCookieStore([]byte("secret"))
2370
r.Use(sessions.Sessions(sessionHeader, store))
71+
r.Use(BasicAuth())
2472

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

0 commit comments

Comments
 (0)