Checkpoint

This commit is contained in:
Arti Zirk 2023-07-28 16:09:54 +03:00
parent 846a610c58
commit d1348d1af9
5 changed files with 202 additions and 18 deletions

3
.env Normal file
View File

@ -0,0 +1,3 @@
KDOORPI_API_ALLOWED=http://127.0.0.1:3333/allowed
KDOORPI_API_LONGPOLL=http://127.0.0.1:3333/longpoll
KDOORPI_API_KEY=keykey

1
go.mod
View File

@ -3,6 +3,7 @@ module godoor
go 1.18 go 1.18
require ( require (
github.com/joho/godotenv v1.5.1 // indirect
github.com/warthog618/gpiod v0.8.0 // indirect github.com/warthog618/gpiod v0.8.0 // indirect
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/warthog618/gpiod v0.8.0 h1:qxH9XVvWHpTxzWFSndBcujFyNH5zVRzHM63tcmm85o4= github.com/warthog618/gpiod v0.8.0 h1:qxH9XVvWHpTxzWFSndBcujFyNH5zVRzHM63tcmm85o4=
github.com/warthog618/gpiod v0.8.0/go.mod h1:a7Csa+IJtDBZ39++zC/6Srjo01qWejt/5velrDWuNkY= github.com/warthog618/gpiod v0.8.0/go.mod h1:a7Csa+IJtDBZ39++zC/6Srjo01qWejt/5velrDWuNkY=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=

View File

@ -1,10 +1,15 @@
package main package main
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/joho/godotenv"
"io" "io"
"net/http" "net/http"
"os"
"os/signal"
"syscall"
) )
import "time" import "time"
@ -17,27 +22,91 @@ type card struct {
UidHash string `json:"uid_hash"` UidHash string `json:"uid_hash"`
} }
type cardToken struct { type cardList struct {
Token card `json:"token"` AllowedUids []struct {
Token card `json:"token"`
} `json:"allowed_uids"`
} }
type cardList struct { type simpleUids struct {
AllowedUids []cardToken `json:"allowed_uids"` tokens []string
} }
type ValidUids map[string]bool // bool has no meaning type ValidUids map[string]bool // bool has no meaning
type Config struct {
door string
uid_salt string
api struct {
allowed string
longpoll string
swipe string
key string
}
}
var config Config
func main() { func main() {
wiegand := WiegandSetup(wiegand_a, wiegand_b, wiegand_bit_timeout, solenoid) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
client := http.Client{} godotenv.Load()
req, err := http.NewRequest(http.MethodGet, "urlrul", nil)
config.door = os.Getenv("KDOORPI_DOOR")
config.api.allowed = os.Getenv("KDOORPI_API_ALLOWED")
config.api.longpoll = os.Getenv("KDOORPI_API_LONGPOLL")
config.api.swipe = os.Getenv("KDOORPI_API_SWIPE")
config.api.key = os.Getenv("KDOORPI_API_KEY")
config.uid_salt = os.Getenv("KDOORPI_UID_SALT")
//wiegand := WiegandSetup(wiegand_a, wiegand_b, wiegand_bit_timeout, solenoid)
http.DefaultClient.Timeout = 60
reloadTokens()
//go wiegand.cardRunner(validUids)
waitEvents()
fmt.Printf("Sleeping\n")
<-ctx.Done()
fmt.Printf("Cleanup\n")
// cleanup
}
func waitEvents() {
req, err := http.NewRequest(http.MethodGet, config.api.longpoll, nil)
if err != nil { if err != nil {
panic(err) panic(err)
} }
req.Header.Add("KEY", "keykey") req.Header.Add("KEY", config.api.key)
resp, err := client.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", resp)
_, err = io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", resp)
}
func reloadTokens() {
req, err := http.NewRequest(http.MethodGet, config.api.allowed, nil)
if err != nil {
panic(err)
}
req.Header.Add("KEY", config.api.key)
resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -60,13 +129,4 @@ func main() {
fmt.Printf("%d: %+v\n", i, val.Token.UidHash) fmt.Printf("%d: %+v\n", i, val.Token.UidHash)
validUids[val.Token.UidHash] = false validUids[val.Token.UidHash] = false
} }
go wiegand.cardRunner(validUids)
fmt.Printf("Sleeping\n")
for {
time.Sleep(time.Second)
fmt.Printf(".")
}
} }

View File

@ -0,0 +1,118 @@
// really stupid test door server
package main
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"os"
)
type DoorBoyServer struct {
longPollers map[string]chan string
}
type card struct {
UidHash string `json:"uid_hash"`
}
type cardToken struct {
Token card `json:"token"`
}
type cardList struct {
AllowedUids []cardToken `json:"allowed_uids"`
}
func getRoot(w http.ResponseWriter, r *http.Request) {
fmt.Printf("got / request\n")
io.WriteString(w, "This is my website!\n")
}
func getAllowed(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
keys := cardList{
AllowedUids: []cardToken{
{card{UidHash: "0a0b0c0d0e0f"}},
{card{UidHash: "112233445566"}},
{card{UidHash: "aabbccddeeff"}},
},
}
respJson, _ := json.Marshal(keys)
_, err := w.Write(respJson)
if err != nil {
return
}
}
func writeAndFlush(writer http.ResponseWriter, buffer []byte) error {
_, err := writer.Write(buffer)
if err != nil {
return err
}
if f, ok := writer.(http.Flusher); ok {
f.Flush()
}
return nil
}
func (doorboyserver *DoorBoyServer) getLongPoll(w http.ResponseWriter, r *http.Request) {
err := writeAndFlush(w, []byte("data: response-generator-started\n\n"))
if err != nil {
return
}
events := make(chan string)
doorboyserver.longPollers[r.RemoteAddr] = events
err = writeAndFlush(w, []byte("data: watch-stream-opened\n\n"))
if err != nil {
delete(doorboyserver.longPollers, r.RemoteAddr)
return
}
d := <-events // get door open event
_, err = w.Write([]byte("data: "))
if err != nil {
delete(doorboyserver.longPollers, r.RemoteAddr)
return
}
_, err = w.Write([]byte(d))
if err != nil {
delete(doorboyserver.longPollers, r.RemoteAddr)
return
}
err = writeAndFlush(w, []byte("\n\n"))
if err != nil {
delete(doorboyserver.longPollers, r.RemoteAddr)
return
}
delete(doorboyserver.longPollers, r.RemoteAddr)
}
func (doobserver *DoorBoyServer) postOpenDoor(w http.ResponseWriter, r *http.Request) {
fmt.Println("longPollers:")
for key, value := range doobserver.longPollers {
fmt.Println(" Key:", key, "Value:", value)
value <- "workshop"
}
w.Write([]byte("OK"))
}
func main() {
doorboyserver := DoorBoyServer{longPollers: map[string]chan string{}}
http.HandleFunc("/", getRoot)
http.HandleFunc("/allowed", getAllowed)
http.HandleFunc("/longpoll", doorboyserver.getLongPoll)
http.HandleFunc("/open", doorboyserver.postOpenDoor)
err := http.ListenAndServe(":3333", nil)
if errors.Is(err, http.ErrServerClosed) {
fmt.Printf("server closed\n")
} else if err != nil {
fmt.Printf("error starting server: %s\n", err)
os.Exit(1)
}
}