aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaroline Larimore <caroline@larimo.re>2025-01-21 21:27:15 -0800
committerCaroline Larimore <caroline@larimo.re>2025-01-21 21:27:15 -0800
commit8772226e2e7a2b7d6fcd862ec5e14b4efb77ab39 (patch)
treeaf464f3b5c477e2ee1800b1ab48cdb38bd0ead6e
Initial Commit
-rw-r--r--LICENSE21
-rw-r--r--README.md3
-rw-r--r--go.mod5
-rw-r--r--go.sum2
-rw-r--r--status.go92
5 files changed, 123 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..24dbe72
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Caroline Larimore
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8d0c22f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# status
+
+Just something I threw together real quick for an incredibly specific and niche use case (displaying silly little messages on my girlfriend's dashboard)
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..89ce7a1
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/CartConnoisseur/status
+
+go 1.23.4
+
+require golang.org/x/crypto v0.32.0
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..2f9c45b
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
+golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
diff --git a/status.go b/status.go
new file mode 100644
index 0000000..c06c877
--- /dev/null
+++ b/status.go
@@ -0,0 +1,92 @@
+package main
+
+import (
+ "bufio"
+ "io"
+ "log"
+ "net/http"
+ "os"
+ "os/user"
+ "strings"
+
+ "golang.org/x/crypto/bcrypt"
+)
+
+func main() {
+ var msg string = ""
+ var adminHash []byte
+ var userHash []byte
+
+ user, err := user.Current()
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+
+ file, err := os.Open(user.HomeDir + "/.status/auth")
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+ defer file.Close()
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := scanner.Text()
+
+ if after, found := strings.CutPrefix(line, "admin:"); found {
+ adminHash = []byte(after)
+ }
+
+ if after, found := strings.CutPrefix(line, "user:"); found {
+ userHash = []byte(after)
+ }
+ }
+
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ username, password, ok := r.BasicAuth()
+ if ok {
+ err := bcrypt.CompareHashAndPassword(userHash, []byte(username+password))
+ if err != nil {
+ deny(w)
+ return
+ }
+
+ w.Write([]byte(msg))
+ return
+ }
+
+ deny(w)
+ })
+
+ http.HandleFunc("/update", func(w http.ResponseWriter, r *http.Request) {
+ username, password, ok := r.BasicAuth()
+ if ok {
+ err := bcrypt.CompareHashAndPassword(adminHash, []byte(username+password))
+ if err != nil {
+ deny(w)
+ return
+ }
+
+ if r.Method == "POST" {
+ buf, err := io.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "Failed to read request body", http.StatusInternalServerError)
+ return
+ }
+
+ log.Print(string(buf))
+ msg = string(buf)
+ w.Write([]byte("success"))
+ return
+ }
+ }
+
+ deny(w)
+ })
+
+ log.Fatal(http.ListenAndServe(":8080", nil))
+}
+
+func deny(w http.ResponseWriter) {
+ w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
+ http.Error(w, "Unauthorized", http.StatusUnauthorized)
+}