From bb91aff5fd457348f8f6ab387cd9a5e4c49fb584 Mon Sep 17 00:00:00 2001 From: Cipher Vance Date: Thu, 18 Sep 2025 20:06:37 -0500 Subject: [PATCH] feat: add authentication routes with Gin handlers - Create routes/auth.go with signup, login, and logout endpoints - Add JSON request binding and validation - Implement session management for user authentication - Add proper HTTP status codes and error responses --- routes/auth.go | 89 ++++++++++++++++++++++++++++++++++++++++ routes/user_auth/auth.py | 60 --------------------------- 2 files changed, 89 insertions(+), 60 deletions(-) create mode 100644 routes/auth.go delete mode 100644 routes/user_auth/auth.py diff --git a/routes/auth.go b/routes/auth.go new file mode 100644 index 0000000..5e290b8 --- /dev/null +++ b/routes/auth.go @@ -0,0 +1,89 @@ +package routes + +import ( + "net/http" + + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" + "gorm.io/gorm" + + "github.com/rideaware/rideaware-api/services" +) + +func RegisterAuthRoutes(r *gin.Engine, db *gorm.DB) { + userService := services.NewUserService(db) + + auth := r.Group("/auth") + { + auth.POST("/signup", signup(userService)) + auth.POST("/login", login(userService)) + auth.POST("/logout", logout()) + } +} + +func signup(userService *services.UserService) gin.HandlerFunc { + return func(c *gin.Context) { + var req struct { + Username string `json:"username" binding:"required"` + Email string `json:"email" binding:"required"` + Password string `json:"password" binding:"required"` + } + + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()}) + return + } + + user, err := userService.CreateUser(req.Username, req.Email, req.Password) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()}) + return + } + + c.JSON(http.StatusCreated, gin.H{ + "message": "User created successfully", + "username": user.Username, + "email": user.Email, + }) + } +} + +func login(userService *services.UserService) gin.HandlerFunc { + return func(c *gin.Context) { + var req struct { + Username string `json:"username" binding:"required"` + Password string `json:"password" binding:"required"` + } + + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + user, err := userService.VerifyUser(req.Username, req.Password) + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) + return + } + + // Set session + session := sessions.Default(c) + session.Set("user_id", user.ID) + session.Save() + + c.JSON(http.StatusOK, gin.H{ + "message": "Login successful", + "user_id": user.ID, + }) + } +} + +func logout() gin.HandlerFunc { + return func(c *gin.Context) { + session := sessions.Default(c) + session.Clear() + session.Save() + + c.JSON(http.StatusOK, gin.H{"message": "Logout successful"}) + } +} diff --git a/routes/user_auth/auth.py b/routes/user_auth/auth.py deleted file mode 100644 index 899d7ba..0000000 --- a/routes/user_auth/auth.py +++ /dev/null @@ -1,60 +0,0 @@ -from flask import Blueprint, request, jsonify, session -from services.UserService.user import UserService - -auth_bp = Blueprint("auth", __name__, url_prefix="/api") -user_service = UserService() - -@auth_bp.route("/signup", methods=["POST"]) -def signup(): - data = request.get_json() - if not data: - return jsonify({"message": "No data provided"}), 400 - - required_fields = ['username', 'password'] - for field in required_fields: - if not data.get(field): - return jsonify({"message": f"{field} is required"}), 400 - - try: - new_user = user_service.create_user( - username=data["username"], - password=data["password"], - email=data.get("email"), - first_name=data.get("first_name"), - last_name=data.get("last_name") - ) - - return jsonify({ - "message": "User created successfully", - "username": new_user.username, - "user_id": new_user.id - }), 201 - - except ValueError as e: - return jsonify({"message": str(e)}), 400 - except Exception as e: - # Log the error - print(f"Signup error: {e}") - return jsonify({"message": "Internal server error"}), 500 - -@auth_bp.route("/login", methods=["POST"]) -def login(): - data = request.get_json() - username = data.get("username") - password = data.get("password") - print(f"Login attempt: username={username}, password={password}") - try: - user = user_service.verify_user(username, password) - session["user_id"] = user.id - return jsonify({"message": "Login successful", "user_id": user.id}), 200 - except ValueError as e: - print(f"Login failed: {str(e)}") - return jsonify({"error": str(e)}), 401 - except Exception as e: - print(f"Login error: {e}") - return jsonify({"error": "Internal server error"}), 500 - -@auth_bp.route("/logout", methods=["POST"]) -def logout(): - session.clear() - return jsonify({"message": "Logout successful"}), 200 \ No newline at end of file