From 8f28d0705129f0a18c33893de15edf56bb75b661 Mon Sep 17 00:00:00 2001 From: Adrien Date: Sun, 5 May 2024 21:10:09 +0200 Subject: [PATCH] Almost working auth --- database.go | 69 +++++++----- dbschema/default.esdl | 11 +- dbschema/migrations/00013-m1frbbh.edgeql | 6 ++ dbschema/migrations/00014-m1ipsij.edgeql | 14 +++ dbschema/migrations/00015-m1pknui.edgeql | 8 ++ dbschema/migrations/00016-m1t2tdd.edgeql | 10 ++ login.go | 128 +++++++++++++++++++++++ main.go | 7 +- static/jade.png | Bin 18698 -> 23648 bytes static/jade_dark.png | Bin 5317 -> 27417 bytes views/chat.html | 1 + views/layouts/main.html | 2 + views/login.html | 32 ------ views/partials/message-bot.html | 2 +- views/partials/navbar.html | 11 +- 15 files changed, 238 insertions(+), 63 deletions(-) create mode 100644 dbschema/migrations/00013-m1frbbh.edgeql create mode 100644 dbschema/migrations/00014-m1ipsij.edgeql create mode 100644 dbschema/migrations/00015-m1pknui.edgeql create mode 100644 dbschema/migrations/00016-m1t2tdd.edgeql create mode 100644 login.go delete mode 100644 views/login.html diff --git a/database.go b/database.go index 1537312..486e4df 100644 --- a/database.go +++ b/database.go @@ -11,7 +11,6 @@ import ( var edgeCtx context.Context var edgeClient *edgedb.Client -var CurrentUser User type User struct { ID edgedb.UUID `edgedb:"id"` @@ -74,22 +73,15 @@ func init() { log.Fatal(err) } - // Get the user test@example.com - var user User - err = client.QuerySingle(ctx, ` - SELECT User { id, email, name, setting } FILTER .email = $0 LIMIT 1 - `, &user, "test@example.com") + // TODO Change + edgeCtx = ctx + var clientUUID edgedb.UUID + clientUUID, err = edgedb.ParseUUID("9323365e-0b09-11ef-8f41-c3575d386283") if err != nil { - fmt.Println("Error in edgedb.QuerySingle: in init") + fmt.Println("Error in edgedb.ParseUUID: in init") log.Fatal(err) } - CurrentUser = user - - fmt.Print("Current User: ") - fmt.Println(CurrentUser) - - edgeCtx = ctx - edgeClient = client + edgeClient = client.WithGlobals(map[string]interface{}{"current_user_id": clientUUID}) } func getLastArea() edgedb.UUID { @@ -99,7 +91,7 @@ func getLastArea() edgedb.UUID { filter .conversation.name = 'Default' AND .conversation.user.id = $0 order by .position desc limit 1 - `, &inserted, CurrentUser.ID) + `, &inserted, getCurrentUserID()) if err != nil { fmt.Println("Error in edgedb.QuerySingle: in getLastArea") log.Fatal(err) @@ -107,21 +99,43 @@ func getLastArea() edgedb.UUID { return inserted.id } +func getCurrentUserID() edgedb.UUID { + var result User + err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser LIMIT 1;", &result) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in getCurrentUserID") + fmt.Println(err) + + } + return result.ID +} + +func checkIfLogin() bool { + var result User + err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser LIMIT 1;", &result) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in checkIfLogin") + fmt.Println(err) + return false + } + return true +} + func insertArea() edgedb.UUID { // Insert a new area. var inserted struct{ id edgedb.UUID } err := edgeClient.QuerySingle(edgeCtx, ` WITH - positionVar := count((SELECT Area FILTER .conversation.name = 'Default' AND .conversation.user.id = $0)) + 1 + positionVar := count((SELECT Area FILTER .conversation.name = 'Default' AND .conversation.user = global currentUser)) + 1 INSERT Area { position := positionVar, conversation := ( SELECT Conversation - FILTER .name = 'Default' AND .user.id = $0 + FILTER .name = 'Default' AND .user = global currentUser LIMIT 1 ) } - `, &inserted, CurrentUser.ID) + `, &inserted) if err != nil { fmt.Println("Error in edgedb.QuerySingle: in insertArea") log.Fatal(err) @@ -144,11 +158,11 @@ func insertUserMessage(content string) edgedb.UUID { ), conversation := ( SELECT Conversation - FILTER .name = 'Default' AND .user.id = $3 + FILTER .name = 'Default' AND .user = global currentUser LIMIT 1 ) } - `, &inserted, "user", content, lastAreaID, CurrentUser.ID) + `, &inserted, "user", content, lastAreaID) if err != nil { fmt.Println("Error in edgedb.QuerySingle: in insertUserMessage") log.Fatal(err) @@ -167,16 +181,16 @@ func insertBotMessage(content string, selected bool, model string) edgedb.UUID { selected := $3, conversation := ( SELECT Conversation - FILTER .name = 'Default' AND .user.id = $4 + FILTER .name = 'Default' AND .user = global currentUser LIMIT 1 ), area := ( SELECT Area - FILTER .id = $5 + FILTER .id = $4 LIMIT 1 ) } - `, &inserted, "bot", model, content, selected, CurrentUser.ID, lastAreaID) + `, &inserted, "bot", model, content, selected, lastAreaID) if err != nil { fmt.Println("Error in edgedb.QuerySingle: in insertBotMessage") log.Fatal(err) @@ -185,6 +199,11 @@ func insertBotMessage(content string, selected bool, model string) edgedb.UUID { } func getAllMessages() []Message { + // If no CurrentUser, return an empty array + if !checkIfLogin() { + return []Message{} + } + var messages []Message err := edgeClient.Query(edgeCtx, ` @@ -195,9 +214,9 @@ func getAllMessages() []Message { role, content, date - } FILTER .conversation.name = 'Default' AND .conversation.user.id = $0 + } FILTER .conversation.name = 'Default' AND .conversation.user = global currentUser ORDER BY .date ASC - `, &messages, CurrentUser.ID) + `, &messages) if err != nil { fmt.Println("Error in edgedb.Query: in getAllMessages") fmt.Println(err) diff --git a/dbschema/default.esdl b/dbschema/default.esdl index cf9ca93..521cf3c 100644 --- a/dbschema/default.esdl +++ b/dbschema/default.esdl @@ -1,8 +1,15 @@ +using extension auth; + module default { + global current_user_id: uuid; + global currentUser := ( + select User + filter .id = global current_user_id + ); + type User { - required email: str; - required name: str; required setting: Setting; + required identity: ext::auth::Identity; } type Key { diff --git a/dbschema/migrations/00013-m1frbbh.edgeql b/dbschema/migrations/00013-m1frbbh.edgeql new file mode 100644 index 0000000..5e0331e --- /dev/null +++ b/dbschema/migrations/00013-m1frbbh.edgeql @@ -0,0 +1,6 @@ +CREATE MIGRATION m1frbbhs2tdrqsle67rgzwazozf3qp4xylmnepeacjodtdtcpmqzgq + ONTO m16dflw7c2tzuugatxe7g7ngx6ddn6eczk7a7a6oo5zlixscu565ta +{ + CREATE EXTENSION pgcrypto VERSION '1.3'; + CREATE EXTENSION auth VERSION '1.0'; +}; diff --git a/dbschema/migrations/00014-m1ipsij.edgeql b/dbschema/migrations/00014-m1ipsij.edgeql new file mode 100644 index 0000000..400b157 --- /dev/null +++ b/dbschema/migrations/00014-m1ipsij.edgeql @@ -0,0 +1,14 @@ +CREATE MIGRATION m1ipsijwf3e65w6mvm2622aekxdgvd5hpdlej6mrn2twfbsh47s4mq + ONTO m1frbbhs2tdrqsle67rgzwazozf3qp4xylmnepeacjodtdtcpmqzgq +{ + ALTER TYPE default::User { + CREATE REQUIRED LINK identity: ext::auth::Identity { + SET REQUIRED USING ({}); + }; + }; + CREATE GLOBAL default::currentUser := (SELECT + default::User + FILTER + (.identity ?= GLOBAL ext::auth::ClientTokenIdentity) + ); +}; diff --git a/dbschema/migrations/00015-m1pknui.edgeql b/dbschema/migrations/00015-m1pknui.edgeql new file mode 100644 index 0000000..ca3d978 --- /dev/null +++ b/dbschema/migrations/00015-m1pknui.edgeql @@ -0,0 +1,8 @@ +CREATE MIGRATION m1pknuisxcvpidw4gpdqip6qkiohucqgzmv3rcbli3dyvk2hlbmvaa + ONTO m1ipsijwf3e65w6mvm2622aekxdgvd5hpdlej6mrn2twfbsh47s4mq +{ + ALTER TYPE default::User { + DROP PROPERTY email; + DROP PROPERTY name; + }; +}; diff --git a/dbschema/migrations/00016-m1t2tdd.edgeql b/dbschema/migrations/00016-m1t2tdd.edgeql new file mode 100644 index 0000000..dc893ce --- /dev/null +++ b/dbschema/migrations/00016-m1t2tdd.edgeql @@ -0,0 +1,10 @@ +CREATE MIGRATION m1t2tddtq2grfxf4ldn6aj4yotvwiqclsrks6chobvs33d5mcd62mq + ONTO m1pknuisxcvpidw4gpdqip6qkiohucqgzmv3rcbli3dyvk2hlbmvaa +{ + CREATE GLOBAL default::current_user_id -> std::uuid; + ALTER GLOBAL default::currentUser USING (SELECT + default::User + FILTER + (.id = GLOBAL default::current_user_id) + ); +}; diff --git a/login.go b/login.go new file mode 100644 index 0000000..216cb97 --- /dev/null +++ b/login.go @@ -0,0 +1,128 @@ +package main + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/gofiber/fiber/v2" +) + +const EDGEDB_AUTH_BASE_URL = "http://127.0.0.1:10700/db/main/ext/auth" + +func generatePKCE() (string, string) { + verifier := make([]byte, 32) + _, err := rand.Read(verifier) + if err != nil { + panic(err) + } + + challenge := sha256.Sum256(verifier) + return base64.RawURLEncoding.EncodeToString(verifier), base64.RawURLEncoding.EncodeToString(challenge[:]) +} + +func handleUiSignIn(c *fiber.Ctx) error { + verifier, challenge := generatePKCE() + + fmt.Println("handleUiSignIn verifier: " + verifier) + fmt.Println("handleUiSignIn challenge: " + challenge) + + redirectURL := fmt.Sprintf("%s/ui/signin?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge) + + c.Cookie(&fiber.Cookie{ + Name: "jade-edgedb-pkce-verifier", + Value: verifier, + HTTPOnly: true, + Path: "/", + Secure: true, + SameSite: "Strict", + }) + + return c.Redirect(redirectURL, fiber.StatusMovedPermanently) +} + +func handleUiSignUp(c *fiber.Ctx) error { + verifier, challenge := generatePKCE() + + fmt.Println("handleUiSignUp verifier: " + verifier) + fmt.Println("handleUiSignUp challenge: " + challenge) + + redirectURL := fmt.Sprintf("%s/ui/signup?challenge=%s", EDGEDB_AUTH_BASE_URL, challenge) + + c.Cookie(&fiber.Cookie{ + Name: "jade-edgedb-pkce-verifier", + Value: verifier, + HTTPOnly: true, + Path: "/", + Secure: true, + SameSite: "Strict", + }) + + return c.Redirect(redirectURL, fiber.StatusMovedPermanently) +} + +func handleCallbackSignup(c *fiber.Ctx) error { + code := c.Query("code") + fmt.Println("Callback signup code: " + code) + + verifier := c.Cookies("jade-edgedb-pkce-verifier") + if verifier == "" { + return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?") + } + + return c.SendString("OK") +} + +func handleCallback(c *fiber.Ctx) error { + code := c.Query("code") + if code == "" { + error := c.Query("error") + return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("OAuth callback is missing 'code'. OAuth provider responded with error: %s", error)) + } + + verifier := c.Cookies("jade-edgedb-pkce-verifier") + if verifier == "" { + return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?") + } + + fmt.Println("handleCallback code: " + code) + fmt.Println("handleCallback verifier: " + verifier) + + codeExchangeURL := fmt.Sprintf("%s/token?code=%s&verifier=%s", EDGEDB_AUTH_BASE_URL, code, verifier) + resp, err := http.Get(codeExchangeURL) + if err != nil { + return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", err.Error())) + } + defer resp.Body.Close() + + if resp.StatusCode != fiber.StatusOK { + body, _ := io.ReadAll(resp.Body) + return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", string(body))) + } + + var tokenResponse struct { + AuthToken string `json:"auth_token"` + } + err = json.NewDecoder(resp.Body).Decode(&tokenResponse) + if err != nil { + return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error decoding auth server response: %s", err.Error())) + } + + c.Cookie(&fiber.Cookie{ + Name: "edgedb-auth-token", + Value: tokenResponse.AuthToken, + HTTPOnly: true, + Path: "/", + Secure: true, + SameSite: "Strict", + }) + + fmt.Println("Login successful") + fmt.Println("edgedb-auth-token: " + tokenResponse.AuthToken) + + return c.SendStatus(fiber.StatusNoContent) +} diff --git a/main.go b/main.go index 24fad16..be59e8e 100644 --- a/main.go +++ b/main.go @@ -12,13 +12,11 @@ import ( var userTmpl *pongo2.Template var botTmpl *pongo2.Template var modelsPopoverTmpl *pongo2.Template -var conversationsPopoverTmpl *pongo2.Template func main() { botTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-bot.html")) userTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-user.html")) modelsPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/modelsPopover.html")) - conversationsPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/conversationsPopover.html")) // Import HTML using django engine/template engine := django.New("./views", ".html") @@ -45,6 +43,11 @@ func main() { app.Get("/generateMultipleMessages", GenerateMultipleMessages) // Generate multiple messages app.Get("/messageContent", GetMessageContentHandler) + app.Get("/auth/ui/signin", handleUiSignIn) + app.Get("/auth/ui/signup", handleUiSignUp) + app.Get("/auth/callback", handleCallback) + app.Get("/auth/callbackSignup", handleCallbackSignup) + app.Get("test", func(c *fiber.Ctx) error { fmt.Println("test") return c.SendString("") diff --git a/static/jade.png b/static/jade.png index f30210c175dc4cc0105068c0ad2b4d5e8ce46e18..0e2034409d8be0631df6910b5e21a1d5462c6bbb 100644 GIT binary patch literal 23648 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 ojA} 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 literal 18698 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 IW_9I%01%6M`~Uy| diff --git a/static/jade_dark.png b/static/jade_dark.png index 62cd7ae329c01577e73f713c5d35c6ecef4bc7e4..4f8dfca8634120bb32f0edc3188128b67186ab52 100644 GIT binary patch literal 27417 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 GXa55b!0Sr@ diff --git a/views/chat.html b/views/chat.html index c9ed4f6..bd39682 100644 --- a/views/chat.html +++ b/views/chat.html @@ -1,4 +1,5 @@
+ diff --git a/views/layouts/main.html b/views/layouts/main.html index e9ce60d..3180c44 100644 --- a/views/layouts/main.html +++ b/views/layouts/main.html @@ -53,6 +53,8 @@ gap: 10px; } + + diff --git a/views/login.html b/views/login.html deleted file mode 100644 index 97e0b1a..0000000 --- a/views/login.html +++ /dev/null @@ -1,32 +0,0 @@ -
- - - -
-
-
- -
- - - -
-
-
-
-
\ No newline at end of file diff --git a/views/partials/message-bot.html b/views/partials/message-bot.html index e04bcd9..dc80da9 100644 --- a/views/partials/message-bot.html +++ b/views/partials/message-bot.html @@ -8,7 +8,7 @@ hx-target="#content-{{ ConversationAreaId }}" onclick="toggleGrayscale(this)">
User Image + style="filter: grayscale(100%);" {% endif %} title="{{ message.Name }}">
diff --git a/views/partials/navbar.html b/views/partials/navbar.html index 6e236c6..3b02ab6 100644 --- a/views/partials/navbar.html +++ b/views/partials/navbar.html @@ -10,7 +10,16 @@ \ No newline at end of file