Skip to content

Commit 651fa90

Browse files
[API-68] Implement auth middleware
1 parent bccd821 commit 651fa90

2 files changed

Lines changed: 84 additions & 0 deletions

File tree

api/auth_middleware.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package api
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/ethereum/go-ethereum/common"
8+
"github.com/ethereum/go-ethereum/crypto"
9+
"github.com/gofiber/fiber/v2"
10+
)
11+
12+
const (
13+
messageHeader = "Encoded-Data-Message"
14+
signatureHeader = "Encoded-Data-Signature"
15+
)
16+
17+
// Recover user id and wallet from signature headers
18+
func (app *ApiServer) recoverAuthorityFromSignatureHeaders(c *fiber.Ctx) (int32, string) {
19+
message := c.Get(messageHeader)
20+
signature := c.Get(signatureHeader)
21+
22+
if message == "" || signature == "" {
23+
return 0, ""
24+
}
25+
26+
encodedToRecover := []byte(message)
27+
prefixedMessage := []byte(fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(encodedToRecover), encodedToRecover))
28+
finalHash := crypto.Keccak256Hash(prefixedMessage)
29+
signatureBytes := common.FromHex(signature)
30+
if signatureBytes[64] >= 27 {
31+
signatureBytes[64] -= 27
32+
}
33+
34+
publicKey, err := crypto.SigToPub(finalHash.Bytes(), signatureBytes)
35+
if err != nil {
36+
return 0, ""
37+
}
38+
39+
recoveredAddr := crypto.PubkeyToAddress(*publicKey)
40+
walletLower := strings.ToLower(recoveredAddr.Hex())
41+
42+
var userId int32
43+
err = app.pool.QueryRow(
44+
c.Context(),
45+
`
46+
SELECT user_id FROM users
47+
WHERE
48+
wallet = $1
49+
AND is_current = true
50+
ORDER BY created_at ASC
51+
LIMIT 1
52+
`,
53+
walletLower,
54+
).Scan(&userId)
55+
56+
if err != nil {
57+
return 0, walletLower
58+
}
59+
60+
return userId, walletLower
61+
}
62+
63+
// Middleware to set authedUserId and authedWallet in context
64+
func (app *ApiServer) authMiddleware(c *fiber.Ctx) error {
65+
userId, wallet := app.recoverAuthorityFromSignatureHeaders(c)
66+
c.Locals("authedUserId", userId)
67+
c.Locals("authedWallet", wallet)
68+
69+
return c.Next()
70+
}
71+
72+
func (app *ApiServer) getAuthedUserId(c *fiber.Ctx) int32 {
73+
return int32(c.Locals("authedUserId").(int32))
74+
}
75+
76+
// Middleware that asserts authedUserId is valid
77+
func (app *ApiServer) requiresAuthMiddleware(c *fiber.Ctx) error {
78+
authedUserId := app.getAuthedUserId(c)
79+
if authedUserId == 0 {
80+
return fiber.NewError(fiber.StatusUnauthorized, "You must be logged in to make this request")
81+
}
82+
return c.Next()
83+
}

api/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ func NewApiServer(config config.Config) *ApiServer {
115115
// resolve myId
116116
app.Use(app.isFullMiddleware)
117117
app.Use(app.resolveMyIdMiddleware)
118+
app.Use(app.authMiddleware)
118119

119120
v1 := app.Group("/v1")
120121
v1Full := app.Group("/v1/full")

0 commit comments

Comments
 (0)