109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package auth
 | 
						|
 | 
						|
import (
 | 
						|
	"CatsOfMastodonBotGo/internal/config"
 | 
						|
	"bytes"
 | 
						|
	"encoding/json"
 | 
						|
	"io"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
 | 
						|
	"go.uber.org/zap"
 | 
						|
)
 | 
						|
 | 
						|
type GiteaOAuth2Handler struct {
 | 
						|
	cfg *config.Config
 | 
						|
	logger *zap.Logger
 | 
						|
}
 | 
						|
 | 
						|
func NewGiteaOauth2Token(cfg *config.Config) *GiteaOAuth2Handler {
 | 
						|
	return &GiteaOAuth2Handler{cfg: cfg}
 | 
						|
}
 | 
						|
 | 
						|
func (g *GiteaOAuth2Handler) GetGiteaLoginURL(redirectHost string) (string, error) {
 | 
						|
	if g.cfg.GiteaOauthInstance == "" {
 | 
						|
		return "", nil
 | 
						|
	}
 | 
						|
	
 | 
						|
	if redirectHost == "" {
 | 
						|
		g.logger.Error("Redirect host not provided")
 | 
						|
		return "", nil
 | 
						|
	}
 | 
						|
	
 | 
						|
	authUrl := g.cfg.GiteaOauthInstance + "/login/oauth/authorize?client_id=" + g.cfg.GiteaOauthClientID + "&redirect_uri=" + "http://" + redirectHost + "/admin/oauth/gitea/callback&scope=openid&response_type=code&response_mode=form_post"
 | 
						|
	return authUrl, nil
 | 
						|
}
 | 
						|
 | 
						|
func (g *GiteaOAuth2Handler) GetGiteaUserEmailByCode(code string) (string, error) {
 | 
						|
 | 
						|
	if g.cfg.GiteaOauthInstance == "" {
 | 
						|
        g.logger.Error("Instance URL not provided")
 | 
						|
		return "", nil
 | 
						|
	}
 | 
						|
	// No need to verify since we are accesing the gitea once and only for the email
 | 
						|
	accessToken, err := g.getGiteaAccessTokenByCode(code)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	userInfoUrl := g.cfg.GiteaOauthInstance + "/login/oauth/userinfo"
 | 
						|
	
 | 
						|
	req, err := http.NewRequest("POST", userInfoUrl, nil)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	req.Header.Set("Authorization", "Bearer "+accessToken)
 | 
						|
	req.Header.Set("Accept", "application/json")
 | 
						|
 | 
						|
	resp, err := http.DefaultClient.Do(req)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	defer resp.Body.Close()
 | 
						|
 | 
						|
	body, err := io.ReadAll(resp.Body)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	var userInfo struct {
 | 
						|
		Email string `json:"email"`
 | 
						|
	}
 | 
						|
    
 | 
						|
	if err := json.Unmarshal(body, &userInfo); err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	return userInfo.Email, nil
 | 
						|
}
 | 
						|
 | 
						|
func (g *GiteaOAuth2Handler) getGiteaAccessTokenByCode(code string) (string, error) {
 | 
						|
	form := url.Values{}
 | 
						|
	form.Add("client_id", g.cfg.GiteaOauthClientID)
 | 
						|
	form.Add("client_secret", g.cfg.GiteaOauthClientSecret)
 | 
						|
	form.Add("code", code)
 | 
						|
	form.Add("grant_type", "authorization_code")
 | 
						|
 | 
						|
	req, err := http.NewRequest("POST", g.cfg.GiteaOauthInstance+"/login/oauth/access_token", bytes.NewBufferString(form.Encode()))
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 | 
						|
	req.Header.Set("Accept", "application/json")
 | 
						|
 | 
						|
	resp, err := http.DefaultClient.Do(req)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	defer resp.Body.Close()
 | 
						|
 | 
						|
	body, _ := io.ReadAll(resp.Body)
 | 
						|
	var tokenResp struct {
 | 
						|
		AccessToken string `json:"access_token"`
 | 
						|
	}
 | 
						|
	if err := json.Unmarshal(body, &tokenResp); err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
 | 
						|
	return tokenResp.AccessToken, nil
 | 
						|
} |