package auth import ( "CatsOfMastodonBotGo/internal/config" "bytes" "encoding/json" "io" "net/http" "net/url" ) type GiteaOAuth2Handler struct { ClientID string ClientSecret string InstanceUrl string } var GiteaOauth2HandlerInstance *GiteaOAuth2Handler func InitGiteaOauth2Token() { GiteaOauth2HandlerInstance = &GiteaOAuth2Handler{ ClientID: config.Config.GiteaOauthClientID, ClientSecret: config.Config.GiteaOauthClientSecret, InstanceUrl: config.Config.GiteaOauthInstance, } } func (g *GiteaOAuth2Handler) GetGiteaLoginURL (redirectHost string) (string) { authUrl := g.InstanceUrl + "/login/oauth/authorize?client_id=" + g.ClientID + "&redirect_uri=" + redirectHost + "/oath/gitea&scope=openid&response_type=code&response_mode=form_post" return authUrl } func (g *GiteaOAuth2Handler) GetGiteaUserEmailByCode(code string) (string, error) { accessToken, err := getGiteaAccessTokenByCode(code) if err != nil { return "", err } req, err := http.NewRequest("POST", g.InstanceUrl+"/login/oauth/userinfo", 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 getGiteaAccessTokenByCode(code string) (string, error) { form := url.Values{} form.Add("client_id", GiteaOauth2HandlerInstance.ClientID) form.Add("client_secret", GiteaOauth2HandlerInstance.ClientSecret) form.Add("code", code) form.Add("grant_type", "authorization_code") req, err := http.NewRequest("POST", GiteaOauth2HandlerInstance.InstanceUrl+"/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 }