Skip to content

Feat/firebase#8

Open
Sasvidu wants to merge 2 commits intomainfrom
feat/firebase
Open

Feat/firebase#8
Sasvidu wants to merge 2 commits intomainfrom
feat/firebase

Conversation

@Sasvidu
Copy link
Copy Markdown
Contributor

@Sasvidu Sasvidu commented Jul 8, 2025

Scaffold Firebase auth endpoint and middleware
Remove old routes

@Sasvidu Sasvidu requested a review from prdai July 8, 2025 21:04
@Sasvidu Sasvidu self-assigned this Jul 8, 2025
@Sasvidu Sasvidu added the enhancement New feature or request label Jul 8, 2025
Copy link
Copy Markdown

@prdai prdai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not sure if these comments are valid since I do not have much experience with Go, hopefully they make sense, so I am going to add them as comments, thanks

// AuthMiddleware is a middleware to verify Firebase ID tokens
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
credentialsJSON := os.Getenv("FIREBASE_CREDENTIALS_JSON")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would moving the firebase initialization and credential initalization to something like internal/config/firebase.go be better? also as far as I know i think we need to load the credential's json file and then pass it in the initlization?

}

// GetUserFromContext retrieves the user from the request context
func GetUserFromContext(c *gin.Context) *auth.Token {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it retrieves the user shouldn't it return a user object? or its uuid?

@prdai prdai moved this to In Progress in TradeSymphony ReVamp MVP 1.0 Jul 9, 2025
@prdai prdai moved this from In Progress to In Review in TradeSymphony ReVamp MVP 1.0 Jul 11, 2025
@prdai prdai requested a review from Copilot July 11, 2025 20:39
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR replaces the existing custom GORM-based authentication (including user/session/password-reset) with Firebase Auth, removing legacy routes and middleware and introducing a new /auth/check endpoint backed by Firebase.

  • Completely removes old models, handlers, and middleware for user registration, sessions, and password reset.
  • Adds AuthMiddleware to verify Firebase ID tokens and a CheckAuth handler for health checks of authenticated users.
  • Updates application routing and dependencies (adds Firebase and Google API modules, removes DB init, rate limiter, and API key auth).

Reviewed Changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/models/user.go Removed legacy User model
internal/models/session.go Removed legacy Session model
internal/models/password_reset.go Removed legacy PasswordReset model
internal/middleware/ratelimit.go Removed custom rate limiter middleware
internal/middleware/apikey.go Removed API key auth middleware
internal/middleware/auth.go Added Firebase Auth middleware and GetUserFromContext
internal/handlers/auth.go Removed old auth/register/login handlers, added CheckAuth
internal/handlers/password_reset.go Removed custom password reset handlers
internal/config/database.go Removed database init and migrations
go.mod Added firebase.google.com/go and Google API dependencies
application.go Updated routing to use Firebase, removed DB/rate/APIKey setup
.example.env Updated example env vars for Firebase setup
Comments suppressed due to low confidence (2)

internal/middleware/auth.go:72

  • [nitpick] Consider adding a doc comment for GetUserFromContext to explain the expected context key and return value, improving clarity for other developers.
func GetUserFromContext(c *gin.Context) *auth.Token {

internal/middleware/auth.go:17

  • New middleware should have unit tests covering scenarios like missing header, invalid token, and valid token to ensure correct behavior.
func AuthMiddleware() gin.HandlerFunc {

Comment on lines +16 to +51
// AuthMiddleware is a middleware to verify Firebase ID tokens
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
credentialsJSON := os.Getenv("FIREBASE_CREDENTIALS_JSON")
if credentialsJSON == "" {
log.Println("FIREBASE_CREDENTIALS_JSON environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase credentials not configured"})
return
}
opt := option.WithCredentialsJSON([]byte(credentialsJSON))

projectID := os.Getenv("FIREBASE_PROJECT_ID")
if projectID == "" {
log.Println("FIREBASE_PROJECT_ID environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase project ID not configured"})
return
}
config := &firebase.Config{
ProjectID: projectID,
}

app, err := firebase.NewApp(context.Background(), config, opt)
if err != nil {
log.Printf("error initializing app: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error initializing app"})
return
}

client, err := app.Auth(context.Background())
if err != nil {
log.Printf("error getting Auth client: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error getting Auth client"})
return
}


Copy link

Copilot AI Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initializing the Firebase App on every request can add significant latency. Consider initializing the Firebase App and Auth client once (e.g., in an init() function or during application startup) and reusing the client in the middleware.

Suggested change
// AuthMiddleware is a middleware to verify Firebase ID tokens
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
credentialsJSON := os.Getenv("FIREBASE_CREDENTIALS_JSON")
if credentialsJSON == "" {
log.Println("FIREBASE_CREDENTIALS_JSON environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase credentials not configured"})
return
}
opt := option.WithCredentialsJSON([]byte(credentialsJSON))
projectID := os.Getenv("FIREBASE_PROJECT_ID")
if projectID == "" {
log.Println("FIREBASE_PROJECT_ID environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase project ID not configured"})
return
}
config := &firebase.Config{
ProjectID: projectID,
}
app, err := firebase.NewApp(context.Background(), config, opt)
if err != nil {
log.Printf("error initializing app: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error initializing app"})
return
}
client, err := app.Auth(context.Background())
if err != nil {
log.Printf("error getting Auth client: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error getting Auth client"})
return
}
var (
firebaseApp *firebase.App
authClient *auth.Client
)
func InitFirebase() {
credentialsJSON := os.Getenv("FIREBASE_CREDENTIALS_JSON")
if credentialsJSON == "" {
log.Fatal("FIREBASE_CREDENTIALS_JSON environment variable not set")
}
opt := option.WithCredentialsJSON([]byte(credentialsJSON))
projectID := os.Getenv("FIREBASE_PROJECT_ID")
if projectID == "" {
log.Fatal("FIREBASE_PROJECT_ID environment variable not set")
}
config := &firebase.Config{
ProjectID: projectID,
}
var err error
firebaseApp, err = firebase.NewApp(context.Background(), config, opt)
if err != nil {
log.Fatalf("error initializing Firebase app: %v", err)
}
authClient, err = firebaseApp.Auth(context.Background())
if err != nil {
log.Fatalf("error initializing Auth client: %v", err)
}
}
// AuthMiddleware is a middleware to verify Firebase ID tokens
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +51
// AuthMiddleware is a middleware to verify Firebase ID tokens
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
credentialsJSON := os.Getenv("FIREBASE_CREDENTIALS_JSON")
if credentialsJSON == "" {
log.Println("FIREBASE_CREDENTIALS_JSON environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase credentials not configured"})
return
}
opt := option.WithCredentialsJSON([]byte(credentialsJSON))

projectID := os.Getenv("FIREBASE_PROJECT_ID")
if projectID == "" {
log.Println("FIREBASE_PROJECT_ID environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase project ID not configured"})
return
}
config := &firebase.Config{
ProjectID: projectID,
}

app, err := firebase.NewApp(context.Background(), config, opt)
if err != nil {
log.Printf("error initializing app: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error initializing app"})
return
}

client, err := app.Auth(context.Background())
if err != nil {
log.Printf("error getting Auth client: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error getting Auth client"})
return
}


Copy link

Copilot AI Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeated calls to firebase.NewApp and app.Auth in the middleware can be expensive. Move app and client initialization out of the request handler to improve throughput.

Suggested change
// AuthMiddleware is a middleware to verify Firebase ID tokens
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
credentialsJSON := os.Getenv("FIREBASE_CREDENTIALS_JSON")
if credentialsJSON == "" {
log.Println("FIREBASE_CREDENTIALS_JSON environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase credentials not configured"})
return
}
opt := option.WithCredentialsJSON([]byte(credentialsJSON))
projectID := os.Getenv("FIREBASE_PROJECT_ID")
if projectID == "" {
log.Println("FIREBASE_PROJECT_ID environment variable not set")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Firebase project ID not configured"})
return
}
config := &firebase.Config{
ProjectID: projectID,
}
app, err := firebase.NewApp(context.Background(), config, opt)
if err != nil {
log.Printf("error initializing app: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error initializing app"})
return
}
client, err := app.Auth(context.Background())
if err != nil {
log.Printf("error getting Auth client: %v\n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "error getting Auth client"})
return
}
var (
authClient *auth.Client
)
func InitFirebase() {
credentialsJSON := os.Getenv("FIREBASE_CREDENTIALS_JSON")
if credentialsJSON == "" {
log.Fatal("FIREBASE_CREDENTIALS_JSON environment variable not set")
}
opt := option.WithCredentialsJSON([]byte(credentialsJSON))
projectID := os.Getenv("FIREBASE_PROJECT_ID")
if projectID == "" {
log.Fatal("FIREBASE_PROJECT_ID environment variable not set")
}
config := &firebase.Config{
ProjectID: projectID,
}
app, err := firebase.NewApp(context.Background(), config, opt)
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
client, err := app.Auth(context.Background())
if err != nil {
log.Fatalf("error getting Auth client: %v\n", err)
}
authClient = client
}
// AuthMiddleware is a middleware to verify Firebase ID tokens
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {

Copilot uses AI. Check for mistakes.

// Start server
if err := r.Run(":8080"); err != nil {
if err := r.Run(":5005"); err != nil {
Copy link

Copilot AI Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding the server port makes it harder to configure in different environments. Consider reading the port from an environment variable with a default fallback.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

3 participants