Skip to content

Commit 244f90e

Browse files
committed
feat: Add Just Eat
1 parent 2a39ad4 commit 244f90e

File tree

7 files changed

+191
-51
lines changed

7 files changed

+191
-51
lines changed

dominos.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ func linkDominos(c *gin.Context) {
123123
wiis, _ := c.Get("wiis")
124124
wwfc, _ := c.Get("wwfc")
125125
dominos, _ := c.Get("dominos")
126+
justEat, _ := c.Get("just_eat")
126127
uid, _ := c.Get("uid")
127128

128129
// Toggle the linkage
@@ -134,9 +135,10 @@ func linkDominos(c *gin.Context) {
134135

135136
payload := map[string]any{
136137
"attributes": map[string]any{
137-
"wiis": wiis,
138-
"wwfc": wwfc,
139-
"dominos": dominos,
138+
"wiis": wiis,
139+
"wwfc": wwfc,
140+
"dominos": dominos,
141+
"just_eat": justEat,
140142
},
141143
}
142144

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ require (
2929
github.com/json-iterator/go v1.1.12 // indirect
3030
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
3131
github.com/leodido/go-urn v1.4.0 // indirect
32+
github.com/logrusorgru/aurora/v4 v4.0.0 // indirect
3233
github.com/mattn/go-isatty v0.0.20 // indirect
3334
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
3435
github.com/modern-go/reflect2 v1.0.2 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
165165
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
166166
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
167167
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
168+
github.com/logrusorgru/aurora/v4 v4.0.0 h1:sRjfPpun/63iADiSvGGjgA1cAYegEWMPCJdUpJYn9JA=
169+
github.com/logrusorgru/aurora/v4 v4.0.0/go.mod h1:lP0iIa2nrnT/qoFXcOZSrZQpJ1o6n2CUf/hyHi2Q4ZQ=
168170
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
169171
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
170172
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=

just_eat.go

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"github.com/WiiLink24/AccountManager/middleware"
7+
"github.com/logrusorgru/aurora/v4"
8+
"log"
9+
"net"
10+
"net/http"
11+
"os"
12+
"os/signal"
13+
"strings"
14+
"syscall"
15+
)
16+
17+
const SocketSuccess = `{"success": true}`
18+
19+
type JustEatPayload struct {
20+
WiiNumber string `json:"wii_number"`
21+
Auth string `json:"auth"`
22+
}
23+
24+
type SocketFailResponse struct {
25+
Success bool `json:"success"`
26+
Error string `json:"error"`
27+
}
28+
29+
func socketFail(err error) []byte {
30+
data, _ := json.Marshal(SocketFailResponse{
31+
Success: false,
32+
Error: err.Error(),
33+
})
34+
return data
35+
}
36+
37+
func justEatSocketListen() {
38+
// Remove if it didn't gracefully exit for some reason
39+
os.Remove("/tmp/eater.sock")
40+
41+
socket, err := net.Listen("unix", "/tmp/eater.sock")
42+
checkError(err)
43+
44+
defer socket.Close()
45+
c := make(chan os.Signal, 1)
46+
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
47+
go func() {
48+
<-c
49+
os.Remove("/tmp/eater.sock")
50+
os.Exit(0)
51+
}()
52+
53+
log.Printf("%s", aurora.Green("UNIX socket connected."))
54+
log.Printf("%s %s\n", aurora.Green("Listening on UNIX socket:"), socket.Addr())
55+
56+
// Listen forever
57+
for {
58+
conn, err := socket.Accept()
59+
if err != nil {
60+
log.Print(aurora.Red("Socket Accept ERROR: "), err.Error(), "\n")
61+
}
62+
63+
go func(conn net.Conn) {
64+
defer conn.Close()
65+
buf := make([]byte, 4096)
66+
67+
n, err := conn.Read(buf)
68+
if err != nil {
69+
log.Print(aurora.Red("Socket Read ERROR: "), err.Error(), "\n")
70+
return
71+
}
72+
73+
reply := []byte(SocketSuccess)
74+
payload := strings.Replace(string(buf[:n]), "\n", "", -1)
75+
76+
var justEatPayload JustEatPayload
77+
err = json.Unmarshal([]byte(payload), &justEatPayload)
78+
if err != nil {
79+
log.Print(aurora.Red("Unmarshal ERROR: "), err.Error(), "\n")
80+
conn.Write(append(socketFail(err), []byte("\n")...))
81+
return
82+
}
83+
84+
claims, status := middleware.GetClaims(verifier, justEatPayload.Auth)
85+
if status != http.StatusOK {
86+
log.Print(aurora.Red("Authentication failure."), "\n")
87+
conn.Write(append(socketFail(errors.New("authentication error")), []byte("\n")...))
88+
return
89+
}
90+
91+
// Toggle the linkage
92+
if claims.JustEat[justEatPayload.WiiNumber] {
93+
claims.JustEat[justEatPayload.WiiNumber] = false
94+
} else {
95+
claims.JustEat[justEatPayload.WiiNumber] = true
96+
}
97+
98+
// Now send off to authentik.
99+
newPayload := map[string]any{
100+
"attributes": map[string]any{
101+
"wiis": claims.Wiis,
102+
"wwfc": claims.WWFC,
103+
"dominos": claims.Dominos,
104+
"just_eat": claims.JustEat,
105+
},
106+
}
107+
108+
err = updateUserRequest(claims.UserId, newPayload)
109+
if err != nil {
110+
log.Print(aurora.Red("Authentication failure."), "\n")
111+
conn.Write(append(socketFail(err), []byte("\n")...))
112+
return
113+
}
114+
115+
_, err = conn.Write(append(reply, []byte("\n")...))
116+
if err != nil {
117+
log.Print(aurora.Red("Socket Write ERROR: "), err.Error(), "\n")
118+
return
119+
}
120+
}(conn)
121+
}
122+
}

link.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func link(c *gin.Context) {
109109
wwfc = append(wwfc.([]string), strconv.Itoa(int(ngId)))
110110
}
111111

112-
// Finally for Dominos
112+
// For Dominos
113113
dominos, ok := c.Get("dominos")
114114
if !ok {
115115
c.JSON(http.StatusOK, gin.H{
@@ -126,6 +126,23 @@ func link(c *gin.Context) {
126126
dMap[wiiNumber] = false
127127
}
128128

129+
// Same thing for Just Eat
130+
justEat, ok := c.Get("just_eat")
131+
if !ok {
132+
c.JSON(http.StatusOK, gin.H{
133+
"success": false,
134+
"error": "failed to get Just Eat data",
135+
})
136+
}
137+
138+
eatMap := justEat.(map[string]bool)
139+
if len(eatMap) == 0 {
140+
eatMap = map[string]bool{wiiNumber: false}
141+
} else if _, ok := eatMap[wiiNumber]; !ok {
142+
// Dictionary is not empty, and the current Wii Number is not present.
143+
eatMap[wiiNumber] = false
144+
}
145+
129146
uid, ok := c.Get("uid")
130147
if !ok {
131148
c.JSON(http.StatusOK, gin.H{
@@ -136,9 +153,10 @@ func link(c *gin.Context) {
136153

137154
payload := map[string]any{
138155
"attributes": map[string]any{
139-
"wiis": wiis,
140-
"wwfc": wwfc,
141-
"dominos": dMap,
156+
"wiis": wiis,
157+
"wwfc": wwfc,
158+
"dominos": dMap,
159+
"just_eat": eatMap,
142160
},
143161
}
144162

main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ func main() {
8282
api.GET("/user", getUser)
8383
}
8484

85+
// Start the socket
86+
go justEatSocketListen()
87+
8588
// Start the server
8689
fmt.Printf("Starting HTTP connection (%s)...\nNot using the usual port for HTTP?\nBe sure to use a proxy, otherwise the Wii can't connect!\n", config.Address)
8790
log.Fatalln(r.Run(config.Address))

middleware/middleware.go

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@ import (
99
"net/http"
1010
)
1111

12+
type Claims struct {
13+
Email string `json:"email"`
14+
Username string `json:"preferred_username"`
15+
Name string `json:"name"`
16+
UserId string `json:"sub"`
17+
Groups []string `json:"groups"`
18+
Wiis []string `json:"wiis"`
19+
WWFC []string `json:"wwfc"`
20+
Dominos map[string]bool `json:"dominos"`
21+
JustEat map[string]bool `json:"just_eat"`
22+
}
23+
24+
func GetClaims(verifier *oidc.IDTokenVerifier, tokenString string) (*Claims, int) {
25+
// Verify the OpenID Connect idToken.
26+
ctx := context.Background()
27+
idToken, err := verifier.Verify(ctx, tokenString)
28+
if err != nil {
29+
return nil, http.StatusFound
30+
}
31+
32+
var claims Claims
33+
if err = idToken.Claims(&claims); err != nil {
34+
return nil, http.StatusTemporaryRedirect
35+
}
36+
37+
return &claims, http.StatusOK
38+
}
39+
1240
func AuthenticationMiddleware(verifier *oidc.IDTokenVerifier) gin.HandlerFunc {
1341
return func(c *gin.Context) {
1442
tokenString, err := c.Cookie("token")
@@ -18,27 +46,9 @@ func AuthenticationMiddleware(verifier *oidc.IDTokenVerifier) gin.HandlerFunc {
1846
return
1947
}
2048

21-
// Verify the OpenID Connect idToken.
22-
ctx := context.Background()
23-
idToken, err := verifier.Verify(ctx, tokenString)
24-
if err != nil {
25-
c.Redirect(http.StatusFound, "/login")
26-
c.Abort()
27-
return
28-
}
29-
30-
// Parse custom claims if needed.
31-
var claims struct {
32-
UserId string `json:"sub"`
33-
Email string `json:"email"`
34-
Username string `json:"preferred_username"`
35-
Wiis []string `json:"wiis"`
36-
WWFC []string `json:"wwfc"`
37-
Dominos map[string]bool `json:"dominos"`
38-
}
39-
40-
if err = idToken.Claims(&claims); err != nil {
41-
c.Redirect(http.StatusTemporaryRedirect, "/login")
49+
claims, status := GetClaims(verifier, tokenString)
50+
if status != http.StatusOK {
51+
c.Redirect(status, "/login")
4252
c.Abort()
4353
return
4454
}
@@ -63,6 +73,7 @@ func AuthenticationMiddleware(verifier *oidc.IDTokenVerifier) gin.HandlerFunc {
6373
c.Set("wiis", claims.Wiis)
6474
c.Set("wwfc", claims.WWFC)
6575
c.Set("dominos", claims.Dominos)
76+
c.Set("just_eat", claims.JustEat)
6677
c.Next()
6778
}
6879
}
@@ -77,29 +88,9 @@ func AuthenticationPOSTMiddleware(verifier *oidc.IDTokenVerifier) gin.HandlerFun
7788
return
7889
}
7990

80-
// Verify the OpenID Connect idToken.
81-
ctx := context.Background()
82-
idToken, err := verifier.Verify(ctx, tokenString)
83-
if err != nil {
84-
c.Status(http.StatusUnauthorized)
85-
c.Abort()
86-
return
87-
}
88-
89-
// Parse custom claims if needed.
90-
var claims struct {
91-
Email string `json:"email"`
92-
Username string `json:"preferred_username"`
93-
Name string `json:"name"`
94-
UserId string `json:"sub"`
95-
Groups []string `json:"groups"`
96-
Wiis []string `json:"wiis"`
97-
WWFC []string `json:"wwfc"`
98-
Dominos map[string]bool `json:"dominos"`
99-
}
100-
101-
if err = idToken.Claims(&claims); err != nil {
102-
c.Status(http.StatusInternalServerError)
91+
claims, status := GetClaims(verifier, tokenString)
92+
if status != http.StatusOK {
93+
c.Redirect(status, "/login")
10394
c.Abort()
10495
return
10596
}
@@ -108,6 +99,7 @@ func AuthenticationPOSTMiddleware(verifier *oidc.IDTokenVerifier) gin.HandlerFun
10899
c.Set("wiis", claims.Wiis)
109100
c.Set("wwfc", claims.WWFC)
110101
c.Set("dominos", claims.Dominos)
102+
c.Set("just_eat", claims.JustEat)
111103
c.Next()
112104
}
113105
}

0 commit comments

Comments
 (0)