laserproxy: extend deadline to 60min & random changes

Change-Id: I2601d2da8da567d8dd6beecc630de911d5d161c3
diff --git a/hswaw/laserproxy/README.md b/hswaw/laserproxy/README.md
index 56af4b7..e843b00 100644
--- a/hswaw/laserproxy/README.md
+++ b/hswaw/laserproxy/README.md
@@ -16,6 +16,24 @@
 
 When a lock is taken, the Locker will notify a Proxy worker about this address. The Proxy will then perform the UDP proxying. As traffic is proxied, the Proxy will send bump updates to the Locker to extend the lock deadline.
 
+Development setup
+_________________
+
+Something similar to this should work for you locally enough to open the web app:
+
+    bazel run //hswaw/laserproxy -- -hspki_disable -laser_network 127.0.0.1 -client_network 127.0.0.1
+
+This will show you available flags you can pass:
+
+    bazel run //hswaw/laserproxy -- -h
+
+If you've never used `bazel`, this should work for y'all macOS newbs:
+
+    brew install bazel
+    brew install postgresql
+
+_TODO(q3k): move this to the bazel codelab once it's finished_
+
 Deployment
 ----------
 
diff --git a/hswaw/laserproxy/locker.go b/hswaw/laserproxy/locker.go
index 044e832..8080e9b 100644
--- a/hswaw/laserproxy/locker.go
+++ b/hswaw/laserproxy/locker.go
@@ -51,7 +51,7 @@
 	addr string
 }
 
-func (s *service) runLocker(ctx context.Context, ctrlC chan *lockCtrl) {
+func (s *service) runLocker(ctx context.Context, ctrlC chan *lockCtrl, ownershipDuration time.Duration) {
 	glog.Infof("Locker starting...")
 
 	var curNote string
@@ -94,7 +94,7 @@
 					won = true
 					curNote = ctrl.take.note
 					curAddr = ctrl.take.addr
-					curDeadline = time.Now().Add(15 * time.Minute)
+					curDeadline = time.Now().Add(ownershipDuration)
 					notify()
 					glog.Infof("Lock taken by %q %q", curNote, curAddr)
 				}
@@ -121,7 +121,7 @@
 				}()
 			case ctrl.bump != nil:
 				if curAddr != "" {
-					curDeadline = time.Now().Add(15 * time.Minute)
+					curDeadline = time.Now().Add(ownershipDuration)
 				}
 			case ctrl.subscribe != nil:
 				subscribers = append(subscribers, ctrl.subscribe.subscriber)
diff --git a/hswaw/laserproxy/main.go b/hswaw/laserproxy/main.go
index 07d7bcd..03c2bf8 100644
--- a/hswaw/laserproxy/main.go
+++ b/hswaw/laserproxy/main.go
@@ -22,6 +22,7 @@
 	flagLaserNetworkAddress = "10.11.0.1"
 	flagClientNetworkAddress = "10.8.1.2"
 	flagWebAddress = "127.0.0.1:8080"
+	flagOwnershipDuration = "1h"
 
 	tplIndex = template.Must(template.New("index.html").Parse(tpl.MustAssetString("index.html")))
 )
@@ -35,6 +36,7 @@
 	flag.StringVar(&flagLaserNetworkAddress, "laser_network", flagLaserNetworkAddress, "Address of proxy on laser network")
 	flag.StringVar(&flagClientNetworkAddress, "client_network", flagClientNetworkAddress, "Address of proxy on client network")
 	flag.StringVar(&flagWebAddress, "web_address", flagWebAddress, "Address and port to listen on for public web connections")
+	flag.StringVar(&flagOwnershipDuration, "timeout_duration", flagOwnershipDuration, "Time after which lasercutter lock will expire when not in use")
 
 	flag.Parse()
 	m := mirko.New()
@@ -63,13 +65,18 @@
 		glog.Fatalf("could not make laser UDP address: %v", err)
 	}
 
+	ownershipDuration, err := time.ParseDuration(flagOwnershipDuration)
+	if err != nil {
+		glog.Fatalf("could not parse timeout duration: %v", err)
+	}
+
 	ctx := m.Context()
 	s := &service{
 		lockCtrl: make(chan *lockCtrl),
 	}
 	updates := make(chan *lockUpdate)
 	go s.runProxy(ctx, updates, laserAddr, lisLaser, lisClient)
-	go s.runLocker(ctx, s.lockCtrl)
+	go s.runLocker(ctx, s.lockCtrl, ownershipDuration)
 	s.lockCtrl <- &lockCtrl{
 		subscribe: &lockCtrlSubscribe{
 			subscriber: updates,
@@ -103,7 +110,7 @@
 
 var (
 	sampleNames = []string{
-		"enleth", "radex", "qdot", "hans acker", "makłowicz",
+		"enleth", "radex", "qdot", "hans acker", "lars aser", "makłowicz",
 	}
 )
 
@@ -126,13 +133,13 @@
 	err := tplIndex.Execute(w, struct {
 		You bool
 		CurrentAddress string
-		CurrentNote string
+		CurrentName string
 		CurrentDeadline string
 		SampleName string
 	}{
 		You: cur.addr == remoteAddr(r),
 		CurrentAddress: cur.addr,
-		CurrentNote: cur.note,
+		CurrentName: cur.note,
 		CurrentDeadline: fmt.Sprintf("%d minute(s)", int(cur.deadline.Sub(time.Now()).Minutes())),
 		SampleName: sampleNames[rand.Intn(len(sampleNames))],
 	})
@@ -149,7 +156,7 @@
 	who := r.Form.Get("who")
 	prev := r.Form.Get("prev")
 	if who == "" {
-		fmt.Fprintf(w, "sorry, who are you? please specify a name")
+		fmt.Fprintf(w, "excuse me, who are you? please specify a name")
 		return
 	}
 
diff --git a/hswaw/laserproxy/tpl/index.html b/hswaw/laserproxy/tpl/index.html
index 2bd93e7..c9fab16 100644
--- a/hswaw/laserproxy/tpl/index.html
+++ b/hswaw/laserproxy/tpl/index.html
@@ -2,10 +2,10 @@
 <html lang="en">
     <head>
         <meta charset="utf-8">
-        <title>laserproxy</title>
+        <title>HSWAW Lasercutter</title>
     </head>
     <body>
-        <h1>warsaw hackerspace SOKÓŁ proxy</h1>
+        <h1>Warsaw Hackerspace Sokół Lasercutter Proxy</h1>
         {{ if eq .CurrentAddress "" }}
         <p>
             Currently <b>not</b> in use by anyone. Wanna lase something?
@@ -15,7 +15,7 @@
         </form>
         {{ else if .You }}
         <p>
-            Currently in use by <b>you</b> ({{ .CurrentNote }}, {{ .CurrentAddress }}). <b>Expires in {{ .CurrentDeadline }}.</b> This deadline will automatically extend as long as the laser is actively used.
+            Currently in use by <b>you</b> ({{ .CurrentName }}, {{ .CurrentAddress }}). <b>Expires in {{ .CurrentDeadline }}.</b> This deadline will automatically extend as long as the laser is actively used.
         </p>
         <p>
             To cut something, use LightBurn, and point it as <b>10.8.1.2</b> (as a 'Ruida' Ethernet/LAN controller).
@@ -25,15 +25,16 @@
         </form>
         {{ else }}
         <p>
-            Currently in use by '{{ .CurrentNote }}' ({{ .CurrentAddress }}). <b>Expires in {{ .CurrentDeadline }}</b>.
+            Currently in use by '{{ .CurrentName }}' ({{ .CurrentAddress }}). <b>Expires automatically in {{ .CurrentDeadline }}</b>.
         </p>
         <form action="/force" method="POST">
-            I need to use the laser now and I can't ask the current user ({{ .CurrentNote }}) to release the lock. <input type="submit" value="I want to forcefully release the lock" />, and am aware of the possible consequences of that.
+            I want to use the laser now, and I'm sure {{ .CurrentName }} is not using it. <input type="submit" value="I want to forcefully release the lock" />, and am aware that doing this will bring wrath onto me if someone <em>is</em> using the laser.
         </form>
         {{ end }}
         <p>
             <b>Confused by this?</b> See our <a href="https://wiki.hackerspace.pl/infra:tools:lasercutter">wiki entry about how to use the laser</a>.
         </p>
+        <p><small><a href="https://cs.hackerspace.pl/hscloud/-/tree/hswaw/laserproxy">source code</a></small></p>
 
         <script>
 let element = document.querySelector("#persist");