package handlers import ( "os" "gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/logger" "gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/repositories" "github.com/gin-gonic/gin" "golang.org/x/oauth2" "golang.org/x/oauth2/endpoints" ) type AuthHandlers struct { repo repositories.AuthRepository logger *logger.Logger config *oauth2.Config } func NewAuthHandlers(repo repositories.AuthRepository) *AuthHandlers { clientID := os.Getenv("GITHUB_CLIENT_ID") clientSecret := os.Getenv("GITHUB_CLIENT_SECRET") redirectURL := os.Getenv("REDIRECT_URL") if clientID == "" || clientSecret == "" { panic("GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET must be set") } if redirectURL == "" { redirectURL = "http://localhost:8080/api/v1/callback/github" } return &AuthHandlers{ repo: repo, logger: logger.New(false), config: &oauth2.Config{ ClientID: clientID, ClientSecret: clientSecret, RedirectURL: redirectURL, Scopes: []string{"user:email"}, Endpoint: endpoints.GitHub, }, } } // LoginGithub godoc // @Summary Start GitHub OAuth login // @Description Redirects to GitHub authorization // @Tags auth // @Success 302 // @Router /api/v1/auth/github [get] func (h *AuthHandlers) LoginGithub(c *gin.Context) { url := h.config.AuthCodeURL("state", oauth2.AccessTypeOnline) h.logger.Info("Redirect to GitHub: " + url) c.Redirect(302, url) } // CallbackGithub godoc // @Summary GitHub OAuth callback // @Description Exchanges authorization code for access token // @Tags auth // @Param code query string true "Authorization code" // @Produce json // @Success 200 {object} map[string]interface{} "Access token" // @Failure 400 {object} map[string]string "Missing code" // @Failure 500 {object} map[string]string "Exchange failed" // @Router /callback/github [get] func (h *AuthHandlers) CallbackGithub(c *gin.Context) { h.logger.Info("CallbackGithub called") code := c.Query("code") if code == "" { h.logger.Error("missing code") c.JSON(400, gin.H{"error": "missing code"}) return } h.logger.Info("Processing code: " + code[:10] + "...") token, err := h.config.Exchange(c.Request.Context(), code) if err != nil { h.logger.Error("Exchange failed: " + err.Error()) c.JSON(500, gin.H{"error": "exchange failed", "details": err.Error()}) return } h.logger.Info("200 OK - token received") c.JSON(200, gin.H{"token": token}) }