aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorMitchell Riedstra <mitch@riedstra.dev>2023-01-03 23:49:41 -0500
committerMitchell Riedstra <mitch@riedstra.dev>2023-01-03 23:49:41 -0500
commitc71b37eb23d4c8af7ab983de34c6da5be9363f3a (patch)
treefa699de5d31008b17529d799df00a9a3290c52bf /main.go
parent61612c8e1861ac704bbe592a623a41f12ebc9c11 (diff)
downloadpaste-master.tar.gz
paste-master.tar.xz
Tweak index handler to always load the frontend.HEADv0.0.1masterdev
Also add Nginx testing script, logging options and some docs.
Diffstat (limited to 'main.go')
-rw-r--r--main.go56
1 files changed, 49 insertions, 7 deletions
diff --git a/main.go b/main.go
index 2e55100..d61be41 100644
--- a/main.go
+++ b/main.go
@@ -73,6 +73,8 @@ func main() {
var (
listen = ":6130"
idBytes = "8"
+ logRequestsF = "false"
+ logRequests bool
debugF = "false"
debug bool
genhash = false
@@ -105,9 +107,13 @@ func main() {
EnvFlagString(fl, &proxyURL, "sp", "STATIC_PROXY",
"What server do we proxy to for static content?")
EnvFlagString(fl, &jwtKey, "jwt", "JWT_KEY",
- "If supplied use the value as the JWT key instead of a random value")
+ "If supplied use the value as the JWT key instead of a random value\n"+
+ "Please understand this is not a good idea. Use a random key if "+
+ "possible\n")
EnvFlagString(fl, &sessionHours, "hours", "SESSION_HOURS",
"How many hours should login sessions last?")
+ EnvFlagString(fl, &logRequestsF, "log", "LOG_REQUESTS",
+ "Do we do full request logs, or are we quiet?")
fl.BoolVar(&genhash, "genhash", genhash,
"Interactively prompt for a password and spit out a hash\n")
version := fl.Bool("v", false, "Print version then exit")
@@ -129,6 +135,11 @@ func main() {
logger.Println("Warning invalid value for debug: ", debugF)
}
+ logRequests, err = strconv.ParseBool(logRequestsF)
+ if err != nil {
+ logger.Println("Warning invalid value for logRequests: ", logRequestsF)
+ }
+
if debug {
logger.SetFlags(log.LstdFlags | log.Llongfile)
}
@@ -184,8 +195,14 @@ func main() {
logger.Println("listening on: ", listen)
+ handler := app.Handler()
+
+ if logRequests {
+ handler = httpRequestLogger(handler)
+ }
+
srv := &http.Server{
- Handler: logRequests(app.Handler()),
+ Handler: handler,
Addr: listen,
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
@@ -220,7 +237,7 @@ func getProxyHandler(proxyURL string) (http.Handler, error) {
return rp, nil
}
-func logRequests(next http.Handler) http.Handler {
+func httpRequestLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logger.Printf("%s %s %s \"%s\" \"%s\"\n",
r.RemoteAddr, r.Method, r.URL.Path, r.UserAgent(), r.Referer())
@@ -283,10 +300,12 @@ func (a *App) Handler() http.Handler {
"/api/v1/login": loginHandler(a.users, a.jwtKey, a.sessionHours),
"/api/v1/logout": logoutHandler(),
- "/": http.FileServer(http.FS(a.static)),
+ "/_app/": http.FileServer(http.FS(a.static)),
+ "/": a.HandleIndex(a.static),
}
if a.staticHandler != nil {
+ delete(handlers, "/_app")
handlers["/"] = a.staticHandler
}
@@ -317,6 +336,13 @@ func (a *App) Handler() http.Handler {
return mux
}
+// LoadUsersFromEnviron lets you build a very basic user store from scraping
+// the environment variables alone. Environment variables are in the form of
+// `USER_<username>=<hash>` For example in a shell script:
+//
+// export USER_mitch='$2a$10$MdpHOxqyaxVwX7tBmch/MOnuq5jgcy7ciCUGwixVR43SchyDtxLVW'
+//
+// Will then be picked up and put into the map as mitch: <hash_above>
func LoadUsersFromEnviron() UsersMap {
users := map[string]string{}
for _, entry := range os.Environ() {
@@ -335,6 +361,22 @@ func LoadUsersFromEnviron() UsersMap {
return users
}
+func (a *App) HandleIndex(f fs.FS) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ pth := filepath.Clean(r.URL.Path)
+ fh, err := f.Open(pth)
+ if err != nil {
+ fh, err = f.Open("index.html")
+ if err != nil {
+ sendPlain(Response{w, http.StatusInternalServerError,
+ "Internal server error", nil}, nil)
+ }
+ }
+
+ _, _ = io.Copy(w, fh)
+ })
+}
+
func genTokenKey() string {
r := make([]byte, 16) // 128 bits
_, err := rand.Read(r)
@@ -453,12 +495,11 @@ func (users UsersMap) HasValidPlainAuth(r *http.Request) bool {
// it's invalid or there are any errors.
func getCookie(r *http.Request, name string) string {
c, err := r.Cookie(name)
- // Normally I'd also check c.Valid()... Expires is optional, but
- // apparently makes it invalid?
+ // Normally I'd also check c.Valid()... Expires is optional, but apparently
+ // makes it invalid? Either way duration is handled by the JWT
if err != nil {
return ""
}
- fmt.Printf("Cookie value: '%s'\n", c.Value)
return c.Value
}
@@ -534,6 +575,7 @@ func loginHandler(users UsersMap, jwtKey string, sessionHours int,
HttpOnly: true,
SameSite: http.SameSiteStrictMode,
Value: ss,
+ Secure: true,
})
http.Redirect(w, r, "/", http.StatusFound)