Spaces:
Paused
Paused
fix genkey returns RWPX key
Browse files- internal/handler/keys.go +75 -16
internal/handler/keys.go
CHANGED
|
@@ -1,21 +1,80 @@
|
|
| 1 |
package handler
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
var s = &Store{Keys: make(map[string]*KeyData)}
|
| 6 |
const p = "/data/keys.json"
|
| 7 |
-
|
| 8 |
-
func
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
func HandleSecretReveal(w http.ResponseWriter, r *http.Request) {
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
|
|
|
|
|
|
| 21 |
}
|
|
|
|
| 1 |
package handler
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"encoding/json"
|
| 5 |
+
"math/rand"
|
| 6 |
+
"net/http"
|
| 7 |
+
"os"
|
| 8 |
+
"sync"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
type KeyData struct {
|
| 12 |
+
Name string `json:"name"`
|
| 13 |
+
Key string `json:"key"`
|
| 14 |
+
Requests int `json:"requests"`
|
| 15 |
+
Tokens int `json:"tokens"`
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
type Store struct {
|
| 19 |
+
mu sync.Mutex
|
| 20 |
+
Keys map[string]*KeyData `json:"keys"`
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
var s = &Store{Keys: make(map[string]*KeyData)}
|
| 24 |
const p = "/data/keys.json"
|
| 25 |
+
|
| 26 |
+
func init() {
|
| 27 |
+
os.MkdirAll("/data", 0755)
|
| 28 |
+
f, _ := os.ReadFile(p)
|
| 29 |
+
json.Unmarshal(f, &s)
|
| 30 |
+
if s.Keys == nil { s.Keys = make(map[string]*KeyData) }
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
func save() {
|
| 34 |
+
b, _ := json.MarshalIndent(s, "", " ")
|
| 35 |
+
os.WriteFile(p, b, 0644)
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
func CheckAndTrack(k string, t int) (bool, string) {
|
| 39 |
+
if k == "free" { return true, "" }
|
| 40 |
+
s.mu.Lock(); defer s.mu.Unlock()
|
| 41 |
+
if kd, ok := s.Keys[k]; ok { kd.Requests++; kd.Tokens += t; save(); return true, "" }
|
| 42 |
+
return false, "Key invalida"
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
func GenerateKey(n string) string {
|
| 46 |
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
| 47 |
+
b := make([]byte, 8)
|
| 48 |
+
for i := range b { b[i] = chars[rand.Intn(len(chars))] }
|
| 49 |
+
k := "RWPX-" + string(b)
|
| 50 |
+
s.mu.Lock(); defer s.mu.Unlock()
|
| 51 |
+
s.Keys[k] = &KeyData{Name: n, Key: k}
|
| 52 |
+
save()
|
| 53 |
+
return k
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
func HandleGenKey(w http.ResponseWriter, r *http.Request) {
|
| 57 |
+
n := r.FormValue("name")
|
| 58 |
+
if n == "" { n = "User" }
|
| 59 |
+
k := GenerateKey(n)
|
| 60 |
+
w.Header().Set("Content-Type", "application/json")
|
| 61 |
+
resp := map[string]string{"key": k, "name": n}
|
| 62 |
+
json.NewEncoder(w).Encode(resp)
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
func HandleStats(w http.ResponseWriter, r *http.Request) {
|
| 66 |
+
s.mu.Lock(); defer s.mu.Unlock()
|
| 67 |
+
w.Header().Set("Content-Type", "application/json")
|
| 68 |
+
json.NewEncoder(w).Encode(s)
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
func HandleSecretReveal(w http.ResponseWriter, r *http.Request) {
|
| 72 |
+
if r.URL.Query().Get("token") != "rowlet2026" { w.WriteHeader(403); return }
|
| 73 |
+
s.mu.Lock(); defer s.mu.Unlock()
|
| 74 |
+
w.Header().Set("Content-Type", "text/html")
|
| 75 |
+
w.Write([]byte("<body style='background:#000;color:#0f0;font-family:monospace;'>"))
|
| 76 |
+
for _, k := range s.Keys {
|
| 77 |
+
w.Write([]byte("<p>" + k.Name + ": " + k.Key + "</p>"))
|
| 78 |
+
}
|
| 79 |
+
w.Write([]byte("</body>"))
|
| 80 |
}
|