Skip to content

Instantly share code, notes, and snippets.

@giulioungaretti
Created March 8, 2017 10:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giulioungaretti/72e37d0875f448edfc86a3751a5bbdf3 to your computer and use it in GitHub Desktop.
Save giulioungaretti/72e37d0875f448edfc86a3751a5bbdf3 to your computer and use it in GitHub Desktop.
simple file server with simple basic auth
//
// main.go
package main
import (
"fmt"
"net/http"
"os"
"github.com/gorilla/securecookie"
log "github.com/sirupsen/logrus"
)
var cookieHandler = securecookie.New(
securecookie.GenerateRandomKey(64),
securecookie.GenerateRandomKey(32))
func main() {
http.HandleFunc("/", indexPageHandler)
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/logout", logoutHandler)
fs := http.FileServer(http.Dir("."))
http.Handle("/logs/", someMiddleware(http.StripPrefix("/logs/", fs)))
port := 9999
log.Infof("Runing on %d", port)
address := fmt.Sprintf(":%d", port)
err := http.ListenAndServeTLS(address, "server.crt", "server.key", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func someMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
userName := getUserName(r)
log.Debugf("Username %s logged in", userName)
// get host name
hostName, err := os.Hostname()
if err != nil {
hostName = "Fridge"
}
if userName != "" {
log.Info("Serving /logs")
fmt.Fprintf(w, internalPage, hostName, userName)
h.ServeHTTP(w, r)
} else {
log.Info("Redirect")
log.Infof("%+v", r)
http.Redirect(w, r, "/", 302)
}
})
}
const indexPage = `
<h1>Login</h1>
<form method="post" action="/login">
<label for="name">User name</label>
<input type="text" id="name" name="name">
<label for="password">Password</label>
<input type="password" id="password" name="password">
<button type="submit">Login</button>
</form>
`
func indexPageHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, indexPage)
}
const internalPage = `
<h1>%s log files</h1>
<hr>
<small>User: %s</small>
<form method="post" action="/logout">
<button type="submit">Logout</button>
</form>
`
func loginHandler(w http.ResponseWriter, r *http.Request) {
name := r.FormValue("name")
pass := r.FormValue("password")
redirectTarget := "/logs"
if name == "oxford" && pass == "H1_d9ghjL" {
// dumb simple hardcoded credential check!
// prob need to store in a db
setSession(name, w)
} else {
http.Error(w, "authorization failed", http.StatusUnauthorized)
return
}
http.Redirect(w, r, redirectTarget, 302)
}
func logoutHandler(response http.ResponseWriter, request *http.Request) {
clearSession(response)
http.Redirect(response, request, "/", 302)
}
func setSession(userName string, response http.ResponseWriter) {
value := map[string]string{
"name": userName,
}
if encoded, err := cookieHandler.Encode("session", value); err == nil {
cookie := &http.Cookie{
Name: "session",
Value: encoded,
Path: "/",
// die after one hour!
MaxAge: 3600,
}
http.SetCookie(response, cookie)
}
}
func getUserName(request *http.Request) (userName string) {
if cookie, err := request.Cookie("session"); err == nil {
cookieValue := make(map[string]string)
if err = cookieHandler.Decode("session", cookie.Value, &cookieValue); err == nil {
userName = cookieValue["name"]
}
}
return userName
}
func clearSession(response http.ResponseWriter) {
cookie := &http.Cookie{
Name: "session",
Value: "",
Path: "/",
MaxAge: -1,
}
http.SetCookie(response, cookie)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment