Skip to content

Commit

Permalink
feat: connected user email into DB and auth
Browse files Browse the repository at this point in the history
feat: connected user email into DB and auth
  • Loading branch information
telpirion authored Oct 21, 2024
2 parents ef2a996 + fa22a73 commit f92fc2e
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 21 deletions.
2 changes: 1 addition & 1 deletion db.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const (
SubCollectionName string = "Conversations"
)

var CollectionName string = "Herodotus"
var CollectionName string = "HerodotusDev"

type ConversationBit struct {
BotResponse string
Expand Down
41 changes: 28 additions & 13 deletions docs/Week1-DevelopmentLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,22 @@ Sources:

## Integrating Firestore

<<Unhappy>> Updating array fields in Firestore is hard. Too hard. Go doesn't support the `arrayUnion` operation in Firestore :/
<span style="background-color: red;">Unhappy</span> Updating array fields in Firestore is hard. Too hard. Go doesn't support the `arrayUnion` operation in Firestore :/

Switched to SubCollection of document

## Deploying Gemma model from Model Garden

<<Unhappy>> Try 1: tried deployment from Pantheon. I don't think it worked ... :/
<span style="background-color: red;">Unhappy</span> Try 1: tried deployment from Pantheon. I don't think it worked ... :/

The activity bar in Pantheon says that something is happening, but that's the only indication I have that a Gemma model is being deployed.

I'm going to use Gemini 1.5 Flash to continue prototyping.

<<Anxious>> I used the [official Gemma2 prediction sample](https://github.com/GoogleCloudPlatform/golang-samples/pull/4395/files) but
<span style="background-color: yellow;">Anxious</span> I used the [official Gemma2 prediction sample](https://github.com/GoogleCloudPlatform/golang-samples/pull/4395/files) but
the output is awful. I think we need to change the temperature, top-p, and top-k settings.

<<Unhappy>> Gemma2 responses are ... awful. Even with changing the top-p and temperature settings. It looks like the parameters setting
<span style="background-color: red;">Unhappy</span> Gemma2 responses are ... awful. Even with changing the top-p and temperature settings. It looks like the parameters setting
is not required; I will remove it.

Even with removing the temperature settings, the responses are garbage. If I were releasing this publicly, I would rely
Expand All @@ -100,8 +100,7 @@ Sources:

## Building Go on Cloud Shell


<<Unhappy>>Cloud Shell ran out of room with my successive Go builds. I had to clean the cache.
<span style="background-color: red;">Unhappy</span>Cloud Shell ran out of room with my successive Go builds. I had to clean the cache.

```sh
go clean -cache
Expand All @@ -113,7 +112,7 @@ Sources:

## Integrating Firebase auth

<<Unhappy>> Setting up my Authentication section ... To set up Google Auth, I need to provide a Web client ID and Web client secret.
<span style="background-color: red;">Unhappy</span> Setting up my Authentication section ... To set up Google Auth, I need to provide a Web client ID and Web client secret.
I'm sure that I can find it, but I have to go hunting around for it

After finally hacking something that works (not documented), I can't get the redirect to work.
Expand All @@ -131,14 +130,14 @@ Sources:

## Deploying

<<Unhappy>>I'm a novice with Dockerfiles. I wanted to make sure that all my Go and client files are deployed to the image.
<span style="background-color: red;">Unhappy</span>I'm a novice with Dockerfiles. I wanted to make sure that all my Go and client files are deployed to the image.
(They are.) But then I need to make sure that the application knows how to load them (it doesn't). How do I test
this?

I decided to build & run the Dockerfile locally (in Cloud Shell) to check that it works correct. The deployment
process to Cloud Run/Build is sooooo long and I want to make sure that I get it right.

<<Unhappy>>It's very frustrating that I can't install the Docker client on my work laptop. It would
<span style="background-color: red;">Unhappy</span>It's very frustrating that I can't install the Docker client on my work laptop. It would
be so much more convenient for me to build & run locally so that I can inspect the built artifacts and logs :/

To build & run from project root:
Expand Down Expand Up @@ -175,7 +174,7 @@ us-west1-docker.pkg.dev/${PROJECT_ID}/my-herodotus/base-image:v1
docker push us-west1-docker.pkg.dev/${PROJECT_ID}/my-herodotus/base-image:v1
```

<<Happy>> Deploying a new version of my web app from Artifact Registry was shockingly intuitive.
<span style="background-color: rgb(100, 200, 150);">Happy</span> Deploying a new version of my web app from Artifact Registry was shockingly intuitive.

Sources:

Expand All @@ -188,13 +187,29 @@ Sources:

The basic quickstart is in Python only :/.

<<Anxious>> The version of the tutorial in Go says "use standard logging," but it shows how to use the
<span style="background-color: yellow;">Anxious</span> The version of the tutorial in Go says "use standard logging," but it shows how to use the
cloud.google.com/go/logging library (not the standard `log` package).

<<Curious>> It seems like reinitializing the LoggingClient each time I need to log a message is
<span style="background-color: rgb(100, 150, 200);">Curious</span> It seems like reinitializing the LoggingClient each time I need to log a message is
a bit repetitive. I wonder if there is a better pattern for this?

Sources:

+ https://cloud.google.com/logging/docs/setup/go
+ https://cloud.google.com/logging/docs/write-query-log-entries-python
+ https://cloud.google.com/logging/docs/write-query-log-entries-python

# Hardening authentication (client- & server-side)

Realized over the weekend that users can navigate directly to /home without authenticating.

+ [x] Add a check (on the server) that the user's email is propogated.
+ [x] Add a check (in the JS) that the user has signed-in

TODO(telpirion): ensure that user emails are stored in a obfuscated manner

Sources:

+ https://gin-gonic.com/docs/examples/redirects/
+ https://firebase.google.com/docs/auth/web/manage-users

## Integrating Cloud Monitoring (Open Telemetry)
28 changes: 28 additions & 0 deletions js/userMsg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getAuth } from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-auth.js'

function processForm(e) {
//e.preventDefault();

// Emit 'msg' event for bot progress bar
const event = new Event("msg");
document.dispatchEvent(event);

// Get the user email address
const auth = getAuth();
const user = auth.currentUser;

// If the user hasn't signed in, redirect them to the sign-in page.
if (!user) {
window.location = `/?status=unauthorized`;
}
return true;
}

window.addEventListener("load", function() {
const form = document.getElementById("userMsg");
if (form.attachEvent) {
form.attachEvent("submit", processForm);
} else {
form.addEventListener("submit", processForm);
}
});
14 changes: 14 additions & 0 deletions js/validateAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { getAuth, onAuthStateChanged } from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-auth.js'

window.addEventListener("load", function () {
const auth = getAuth();
const user = auth.currentUser;

onAuthStateChanged(auth, (user) => {
if (user) {
const uid = user.uid;
} else {
window.location = `/?message=sign-in-required`;
}
});
});
34 changes: 29 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
)

var (
projectID string
userEmail string = "[email protected]"
r *gin.Engine
projectID string
userEmail string = "[email protected]"
userEmailParam string = "user"
)

type ClientError struct {
Expand All @@ -30,7 +32,7 @@ func main() {
}
LogInfo("Starting Herodotus...")

r := gin.Default()
r = gin.Default()
r.LoadHTMLGlob("templates/*")
r.Static("/js", "./js")
r.StaticFile("/favicon.ico", "./favicon.ico")
Expand All @@ -49,22 +51,31 @@ func login(c *gin.Context) {
}

func startConversation(c *gin.Context) {
params := c.Params
log.Println(params)

// extractParams will redirect if user isn't logged in.
userEmail = extractParams(c)

LogInfo("Start conversation request received")

c.HTML(http.StatusOK, "index.html", gin.H{
"Message": struct {
Message string
Email string
}{
Message: "Hello! I hear that you want to go on a trip somewhere. Tell me about it.",
Email: userEmail,
},
})
}

func respondToUser(c *gin.Context) {

// extractParams will redirect if user isn't logged in.
userEmail = extractParams(c)

LogInfo("Respond to user request received")

// Parse Form
c.Request.ParseForm()
userMsg := c.Request.Form["userMsg"][0]
log.Println(userMsg)
Expand Down Expand Up @@ -92,8 +103,10 @@ func respondToUser(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{
"Message": struct {
Message string
Email string
}{
Message: botResponse,
Email: userEmail,
},
})
}
Expand All @@ -110,3 +123,14 @@ func clientError(c *gin.Context) {
LogError(fmt.Sprintf("clientError: %s, %s, %s\n", cError.Code, cError.Message, cError.Email))
c.JSON(http.StatusOK, gin.H{"error": "message logged"})
}

func extractParams(c *gin.Context) string {
// Verify that the user is signed in before answering
userEmail = c.Query(userEmailParam)
if userEmail == "" {
LogWarning("User attempted to navigate directly to /home; redirected to sign-in")
c.Request.URL.Path = "/"
r.HandleContext(c)
}
return userEmail
}
4 changes: 3 additions & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@

{{ template "herodotus_msg.tmpl" .Message }}

{{ template "user_msg.tmpl" }}
{{ template "user_msg.tmpl" .Message }}
</div>
<script type="module" src="js/appInit.js"></script>
<script type="module" defer src="js/validateAuth.js"></script>
</body>
</html>
3 changes: 2 additions & 1 deletion templates/user_msg.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<article class="message is-primary">
<form action="/home" method="post">
<form id="userMsg" action="/home?user={{ .Email }}" method="post">
<div class="message-header">
<p>User</p>
<button class="button is-primary-dark-invert" type="submit">
Expand All @@ -15,4 +15,5 @@
</div>
</div>
</form>
<script type="module" defer src="js/userMsg.js"></script>
</article>

0 comments on commit f92fc2e

Please sign in to comment.