Spaces:
Paused
Paused
emergency repair: fix keys privacy and build error
Browse files- internal/handler/keys.go +66 -111
internal/handler/keys.go
CHANGED
|
@@ -1,136 +1,91 @@
|
|
| 1 |
package handler
|
| 2 |
-
|
| 3 |
import (
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
|
|
|
| 10 |
)
|
| 11 |
-
|
| 12 |
type KeyData struct {
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
}
|
| 20 |
type KeyStore struct {
|
| 21 |
-
|
| 22 |
-
|
| 23 |
}
|
| 24 |
-
|
| 25 |
var store = &KeyStore{Keys: make(map[string]*KeyData)}
|
| 26 |
var storePath = "/data/keys.json"
|
| 27 |
-
|
| 28 |
func init() {
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
}
|
| 34 |
-
if store.Keys == nil {
|
| 35 |
-
store.Keys = make(map[string]*KeyData)
|
| 36 |
-
}
|
| 37 |
}
|
| 38 |
func saveStore() {
|
| 39 |
-
|
| 40 |
-
|
| 41 |
}
|
| 42 |
func TrackUsage(key string, tokens int) {
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
saveStore()
|
| 53 |
-
}
|
| 54 |
}
|
| 55 |
func CheckAndTrack(key string, tokens int) (bool, string) {
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
if _, ok := store.Keys[key]; ok {
|
| 62 |
-
return true, ""
|
| 63 |
-
}
|
| 64 |
-
return false, "Key invalida"
|
| 65 |
}
|
| 66 |
func GenerateKey(name string) string {
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
store.mu.Unlock()
|
| 77 |
-
return key
|
| 78 |
}
|
| 79 |
func HandleGenKey(w http.ResponseWriter, r *http.Request) {
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
key := GenerateKey(name)
|
| 85 |
-
json.NewEncoder(w).Encode(map[string]string{"key": key, "name": name})
|
| 86 |
}
|
| 87 |
func HandleStats(w http.ResponseWriter, r *http.Request) {
|
| 88 |
-
store.mu.Lock()
|
| 89 |
-
defer store.mu.Unlock()
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
}
|
| 98 |
-
|
| 99 |
-
publicKeys := make(map[string]KeyPublic)
|
| 100 |
-
for k, v := range store.Keys {
|
| 101 |
-
masked := k[:8] + "..."
|
| 102 |
-
publicKeys[masked] = KeyPublic{
|
| 103 |
-
Name: v.Name,
|
| 104 |
-
Key: masked,
|
| 105 |
-
Requests: v.Requests,
|
| 106 |
-
Tokens: v.Tokens,
|
| 107 |
-
}
|
| 108 |
-
}
|
| 109 |
-
json.NewEncoder(w).Encode(map[string]interface{}{"keys": publicKeys})
|
| 110 |
-
}
|
| 111 |
-
publicKeys := make(map[string]KeyPublic)
|
| 112 |
-
for k, v := range store.Keys {
|
| 113 |
-
// Mostramos solo el prefijo y los primeros 3 caracteres de la key
|
| 114 |
-
masked := k[:8] + "..."
|
| 115 |
-
publicKeys[masked] = KeyPublic{
|
| 116 |
-
Name: v.Name,
|
| 117 |
-
Key: masked,
|
| 118 |
-
Requests: v.Requests,
|
| 119 |
-
Tokens: v.Tokens,
|
| 120 |
-
}
|
| 121 |
-
}
|
| 122 |
-
json.NewEncoder(w).Encode(map[string]interface{}{"keys": publicKeys})
|
| 123 |
-
}
|
| 124 |
-
|
| 125 |
func HandleSecretReveal(w http.ResponseWriter, r *http.Request) {
|
| 126 |
-
store.mu.Lock()
|
| 127 |
-
defer store.mu.Unlock()
|
| 128 |
-
|
| 129 |
-
fmt.Fprintf(w, "<
|
| 130 |
-
fmt.Fprintf(w, "<
|
| 131 |
-
fmt.Fprintf(w, "<table border='1' cellpadding='10' style='border-color:#0f0;'><tr><th>NOMBRE</th><th>KEY COMPLETA</th></tr>")
|
| 132 |
-
for _, k := range store.Keys {
|
| 133 |
-
fmt.Fprintf(w, "<tr><td>%s</td><td><code style='background:#111;padding:5px;'>%s</code></td></tr>", k.Name, k.Key)
|
| 134 |
-
}
|
| 135 |
-
fmt.Fprintf(w, "</table></body></html>")
|
| 136 |
}
|
|
|
|
| 1 |
package handler
|
|
|
|
| 2 |
import (
|
| 3 |
+
"encoding/json"
|
| 4 |
+
"fmt"
|
| 5 |
+
"math/rand"
|
| 6 |
+
"net/http"
|
| 7 |
+
"os"
|
| 8 |
+
"sync"
|
| 9 |
+
"time"
|
| 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 |
+
Created time.Time `json:"created"`
|
| 17 |
+
LastUsed time.Time `json:"last_used"`
|
| 18 |
}
|
| 19 |
type KeyStore struct {
|
| 20 |
+
mu sync.Mutex
|
| 21 |
+
Keys map[string]*KeyData `json:"keys"`
|
| 22 |
}
|
|
|
|
| 23 |
var store = &KeyStore{Keys: make(map[string]*KeyData)}
|
| 24 |
var storePath = "/data/keys.json"
|
|
|
|
| 25 |
func init() {
|
| 26 |
+
os.MkdirAll("/data", 0755)
|
| 27 |
+
data, err := os.ReadFile(storePath)
|
| 28 |
+
if err == nil { json.Unmarshal(data, store) }
|
| 29 |
+
if store.Keys == nil { store.Keys = make(map[string]*KeyData) }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
}
|
| 31 |
func saveStore() {
|
| 32 |
+
data, _ := json.MarshalIndent(store, "", " ")
|
| 33 |
+
os.WriteFile(storePath, data, 0644)
|
| 34 |
}
|
| 35 |
func TrackUsage(key string, tokens int) {
|
| 36 |
+
if key == "free" { return }
|
| 37 |
+
store.mu.Lock()
|
| 38 |
+
defer store.mu.Unlock()
|
| 39 |
+
if kd, ok := store.Keys[key]; ok {
|
| 40 |
+
kd.Requests++
|
| 41 |
+
kd.Tokens += tokens
|
| 42 |
+
kd.LastUsed = time.Now()
|
| 43 |
+
saveStore()
|
| 44 |
+
}
|
|
|
|
|
|
|
| 45 |
}
|
| 46 |
func CheckAndTrack(key string, tokens int) (bool, string) {
|
| 47 |
+
if key == "free" { return true, "" }
|
| 48 |
+
store.mu.Lock()
|
| 49 |
+
defer store.mu.Unlock()
|
| 50 |
+
if _, ok := store.Keys[key]; ok { return true, "" }
|
| 51 |
+
return false, "Key invalida"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
}
|
| 53 |
func GenerateKey(name string) string {
|
| 54 |
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
| 55 |
+
b := make([]byte, 8)
|
| 56 |
+
for i := range b { b[i] = chars[rand.Intn(len(chars))] }
|
| 57 |
+
key := "RWPX-" + string(b)
|
| 58 |
+
store.mu.Lock()
|
| 59 |
+
store.Keys[key] = &KeyData{Name: name, Key: key, Created: time.Now()}
|
| 60 |
+
saveStore()
|
| 61 |
+
store.mu.Unlock()
|
| 62 |
+
return key
|
|
|
|
|
|
|
| 63 |
}
|
| 64 |
func HandleGenKey(w http.ResponseWriter, r *http.Request) {
|
| 65 |
+
name := r.FormValue("name")
|
| 66 |
+
if name == "" { name = "usuario" }
|
| 67 |
+
key := GenerateKey(name)
|
| 68 |
+
json.NewEncoder(w).Encode(map[string]string{"key": key, "name": name})
|
|
|
|
|
|
|
| 69 |
}
|
| 70 |
func HandleStats(w http.ResponseWriter, r *http.Request) {
|
| 71 |
+
store.mu.Lock()
|
| 72 |
+
defer store.mu.Unlock()
|
| 73 |
+
type Pub struct { Name string `json:"name"`; Key string `json:"key"`; Requests int `json:"requests"`; Tokens int `json:"tokens"` }
|
| 74 |
+
res := make(map[string]Pub)
|
| 75 |
+
for k, v := range store.Keys { masked := k[:8] + "..."; res[masked] = Pub{Name: v.Name, Key: masked, Requests: v.Requests, Tokens: v.Tokens} }
|
| 76 |
+
json.NewEncoder(w).Encode(map[string]interface{}{"keys": res})
|
| 77 |
+
}
|
| 78 |
+
func HandleReset(w http.ResponseWriter, r *http.Request) {
|
| 79 |
+
store.mu.Lock()
|
| 80 |
+
for _, v := range store.Keys { v.Requests = 0; v.Tokens = 0 }
|
| 81 |
+
saveStore()
|
| 82 |
+
store.mu.Unlock()
|
| 83 |
+
w.Write([]byte("Reset OK"))
|
| 84 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
func HandleSecretReveal(w http.ResponseWriter, r *http.Request) {
|
| 86 |
+
store.mu.Lock()
|
| 87 |
+
defer store.mu.Unlock()
|
| 88 |
+
fmt.Fprintf(w, "<html><body style='background:#000;color:#0f0;font-family:monospace;'><h2>MU/TH/UR 6000 - MASTER ACCESS</h2>")
|
| 89 |
+
for _, k := range store.Keys { fmt.Fprintf(w, "<p>%s: %s</p>", k.Name, k.Key) }
|
| 90 |
+
fmt.Fprintf(w, "</body></html>")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
}
|