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
This commit is contained in:
		
							parent
							
								
									3d9de8ba11
								
							
						
					
					
						commit
						bb91aff5fd
					
				
					 2 changed files with 89 additions and 60 deletions
				
			
		
							
								
								
									
										89
									
								
								routes/auth.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								routes/auth.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -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"}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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 |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Cipher Vance
						Cipher Vance